o
    i3                     @   s  U d dl mZmZmZ d dlmZmZ d dlmZ d dl	m
Z
mZ d dlmZ d dlmZ d dlmZmZ d dlmZ erQd d	lmZ d d
lmZ G dd deZG dd dZdddedefddZddddddeeef deee B dB dddeddfddZddddddeeef deee B dB dddeddfddZdd dd!dddeeef deee B dB ddd"ee B d#e!ed$f dB deddfd%d&Z"ddd'dddeeef deee B dB ddd#eee!ed$f f dB deddfd(d)Z#e Z$ee%d*< 	 ee$_ee$_dS )+    )AnyTYPE_CHECKINGProtocol)MutableSequenceCallable)config)dictionary_VRprivate_dictionary_VR)BytesLengthException)warn_and_log)BaseTag_LUT_DESCRIPTOR_TAGS)VR)Dataset)RawDataElementc                   @   sN   e Zd Zddddedeeef deee B dB dedB ded	dfd
dZ	dS )RawDataHook.encodingdsrawdatar   Nr   kwargsreturnc                K   s   d S )N )selfr   r   r   r   r   r   r   C/mnt/sdb/aimis/docanh/lib/python3.10/site-packages/pydicom/hooks.py__call__   s   zRawDataHook.__call__)
__name__
__module____qualname__r   dictstrr   r   r   r   r   r   r   r   r      s     
r   c                   @   sN   e Zd ZdZdddZdededdfdd	Zded
eee	f ddfddZ
dS )Hooksa  Management class for callback functions.

    .. versionadded:: 3.0

    .. warning::

        New instances of this class should not be created, instead use the instance
        imported with ``from pydicom.hooks import hooks``.

    **Available Hooks**

    For conversion of raw element data to :class:`~pydicom.dataelem.DataElement`
    using :func:`~pydicom.dataelem.convert_raw_data_element`:

    * ``"raw_element_vr"``: function to perform VR lookups for raw elements,
      default :func:`raw_element_vr`.
    * ``"raw_element_value"``: function to convert raw element values to types
      appropriate for the VR, default :func:`raw_element_value`.
    * ``"raw_element_kwargs"``: `kwargs` :class:`dict` passed to the callback
      functions.
    r   Nc                 C   s   |  |  i | _ dS )z$Initialize a new ``Hooks`` instance.N)raw_element_kwargs)r   r   r   r   __init__5   s   
zHooks.__init__hookfuncc                 C   sD   t |std|dkr|| _dS |dkr|| _dS td| d)a  Register the callback function `func` to a hook.

        Example
        -------

        .. code-block:: python

            from pydicom import dcmread
            from pydicom.hooks import hooks, raw_element_value_fix_separator

            hooks.register_callback(
                "raw_element_value", raw_element_value_fix_separator
            )
            kwargs = {"target_VRs": ("DS", "IS")}
            hooks.register_kwargs("raw_element_kwargs", kwargs)

            ds = dcmread("path/to/dataset.dcm")

        Parameters
        ----------
        hook : str
            The name of the hook to register the function to, allowed values
            ``"raw_element_vr"`` and ``"raw_element_value"``.
        func : Callable
            The callback function to use with the hook. Only one callback function can
            be used per hook. For details on the required function signatures please
            see the documentation for the corresponding calling function.
        z"'func' must be a callable functionraw_element_valueraw_element_vrUnknown hook ''N)callable	TypeErrorr'   r(   
ValueError)r   r%   r&   r   r   r   register_callback;   s   

zHooks.register_callbackr   c                 C   sB   t |tstdt|j d|dkr|| _dS td| d)a  Register a `kwargs` :class:`dict` to be passed to the corresponding
        callback function(s).

        Parameters
        ----------
        hook : str
            The name of the hook to register `kwargs` to, allowed value
            ``"raw_element_kwargs"``.
        kwargs : dict[str, Any]
            A :class:`dict` containing keyword arguments to be passed to the
            hook's corresponding callback function(s).
        z'kwargs' must be a dict, not 'r*   r#   r)   N)
isinstancer    r,   typer   r#   r-   )r   r%   r   r   r   r   register_kwargsb   s
   

zHooks.register_kwargs)r   N)r   r   r   __doc__r$   r!   r   r.   r    r   r1   r   r   r   r   r"      s
    
"'r"   r   zDataset | Nonetagr   c                 C   sn   |j rtjS | dur4|jd@ r4|jd> |jd? B }| |d}|r4zt||jW S  ty3   Y tj	S w tj	S )a  Return the VR for a known private tag, otherwise "UN".

    Parameters
    ----------
    ds : Dataset, optional
        The dataset needed for the private creator lookup.
        If not given, "UN" is returned.
    tag : BaseTag
        The private tag to lookup. The caller has to ensure that the
        tag is private.

    Returns
    -------
    str
        "LO" if the tag is a private creator, the VR of the private tag if
        found in the private dictionary, or "UN".
    Ni          )
is_private_creatorr   LOelementgroupgetr	   valueKeyErrorUN)r   r3   private_creator_tagprivate_creatorr   r   r   _private_vr_for_tagx   s   rA   Nr   r   r   r   r   r   c                K   s   | j }|du rHzt| j}W ni tyG   | jjr t|| j}n%| jjdkr*t j}nd| j }tj	j
tjkr;t|t j}t| d Y n1w |t jkrxtjrx| jjr[t|| j}n| jdu sgt| jdk rxzt| j}W n	 tyw   Y nw ||d< dS )a  Determine the VR to use for `raw`.

    .. versionadded:: 3.0

    Default callback function for the ``"raw_element_vr"`` hook.

    Parameters
    ----------
    raw : RawDataElement
        The raw data element to determine the VR for.
    data : dict[str, Any]
        A dict to store the results of the VR lookup, which should be added
        as ``{"VR": str}``.
    ds : pydicom.dataset.Dataset | None
        The dataset the element belongs to.
    **kwargs: dict[str, Any]
        Additional keyword arguments.
    Nr   z.VR lookup failed for the raw element with tag z - setting VR to 'UN'i  r   )r   r   r3   r=   
is_privaterA   r9   ULr   settingsreading_validation_modeRAISEr>   r   replace_un_with_known_vrr<   len)r   r   r   r   r   vrmsgr   r   r   r(      s4   r(   c          
   
   K   s  ddl m} |d }z||| |}W nM ty( } z
t| d| j d}~w ty_ } z,| d| j d| j d}	tjsFt|	 d	t|	 d
 tj	|d< | j
}W Y d}~nd}~ww | jtv r|rt|trz|d dk r{|d  d7  < W n	 ty   Y nw ||d< dS )a  Convert the encoded value for `raw` to an appropriate type.

    .. versionadded:: 3.0

    Will set the VR to **UN** if unable to convert the value.

    Default callback function for the ``"raw_element_value"`` hook.

    Parameters
    ----------
    raw : RawDataElement
        The raw data element to determine the value for.
    data : dict[str, Any]
        A dict to store the results of the value conversion, which should be added
        as ``{"value": Any}``.
    encoding : str | MutableSequence[str] | None
        The character set encoding to use for text VRs.
    **kwargs: dict[str, Any]
        Additional keyword arguments.
    r   convert_valuer   z in tag Nz% This occurred while trying to parse z according to VR 'z'.z[ To replace this error with a warning set pydicom.config.convert_wrong_length_to_UN = True.z Setting VR to 'UN'.i   r<   )pydicom.valuesrL   NotImplementedErrorr3   r
   r   r   convert_wrong_length_to_UNr   r>   r<   r   r/   list	Exception)
r   r   r   r   r   rL   rI   r<   excrJ   r   r   r   r'      s>   

r'      ,)r   	separator
target_VRsrT   rU   .c                K   sf   |d }|r%||v r%t | jtr%t |tr|d}| j| j|dd} t| |f||d| dS )a>  Convenience function to fix values with an invalid multivalue separator.

    .. versionadded:: 3.0

    Alternative callback function for the ``"raw_element_value"`` hook.

    Example
    -------

    Fix **DS** and **IS** elements that use an invalid ":" character as the
    multivalue separator::

        from pydicom import dcmread
        from pydicom.hooks import hooks, raw_element_value_fix_separator

        hooks.register_callback(
            "raw_element_value",
            raw_element_value_fix_separator,
        )
        hooks.register_kwargs(
            "raw_element",
            {"target_VRs": ("DS", "IS"), "separator": b":"},
        )

        ds = dcmread("path/to/dataset.dcm")


    Parameters
    ----------
    raw : RawDataElement
        The raw data element to determine the value for.
    data : dict[str, Any]
        A dict to store the results of the value conversion, which should be added
        as ``{"value": Any}``.
    encoding : str | MutableSequence[str] | None
        The character set encoding to use for text VRs.
    separator : str | bytes, optional
        The invalid separator character to be replaced by an ASCII backslash (0x5C).
    target_VRs : tuple[str, ...], optional
        The VRs the fix should apply.
    **kwargs: dict[str, Any]
        Additional keyword arguments.
    r   ascii   \)r<   r   N)r/   r<   bytesr!   encode_replacereplacer'   )r   r   r   r   rT   rU   r   rI   r   r   r   raw_element_value_fix_separator  s   5

r\   )r   rU   c          
      K   s   ddl m} zt| |f||d| W dS  tyQ } z0|d }|rK||v rK|| D ]}	z||	| |d< |	|d< W  W Y d}~dS  tyJ   Y q+w |d}~ww )a  Convenience function to retry value conversion using a different VR.

    .. versionadded:: 3.0

    Alternative callback function for the ``"raw_element_value"`` hook.

    Example
    -------

    Retry the value conversion for **DS** elements using **US** or **SS**::

        from pydicom import dcmread
        from pydicom.hooks import hooks, raw_element_value_retry

        hooks.register_callback(
            "raw_element_value",
            raw_element_value_retry,
        )
        hooks.register_kwargs(
            "raw_element",
            {"target_VRs": {"DS": ("US", "SS")}},
        )

        ds = dcmread("path/to/dataset.dcm")

    Parameters
    ----------
    raw : RawDataElement
        The raw data element to determine the value for.
    data : dict[str, Any]
        A dict to store the results of the value conversion, which should be added
        as ``{"value": Any}``.
    encoding : str | MutableSequence[str] | None
        The character set encoding to use for text VRs.
    target_VRs : dict[str, tuple[str, ...]], optional
        The ``{VRs the fix should apply: tuple of alternative VRs to try}``.
    **kwargs: dict[str, Any]
        Additional keyword arguments.
    r   rK   r   r   r<   N)rM   rL   r'   rQ   )
r   r   r   r   rU   r   rL   rR   rI   	candidater   r   r   raw_element_value_retryT  s"   0r^   hooks)&typingr   r   r   collections.abcr   r   pydicomr   pydicom.datadictr   r	   pydicom.errorsr
   pydicom.miscr   pydicom.tagr   r   pydicom.valuerepr   pydicom.datasetr   pydicom.dataelemr   r   r"   r!   rA   r    r(   r'   rX   tupler\   r^   r_   __annotations__r   r   r   r   <module>   s   Z&

@

C
	
C

B
