3
ljN                 @   s   d dl mZ d dlZd dljjZd dlZd dlZd dlZd dl	m
Z
mZ d dlT d dlmZ d dlmZ d dlZd dlZd dlZddgZejeZejd  d	krd
d ZeZneZe
dZg fddZdd Zdd ZG dd de Z!dS )    )print_functionN)NodeIdvalueIsInternalType)*)opaque_type_mapping)CSVBSDTypeParserNodeSetgetSubTypesOf   c             C   s   | S )N )sr   r   d/mnt/data/dev_pub/qqyu/docker_elf/application/opensource/open62541/tools/nodeset_compiler/nodeset.pyunicode!   s    r   z	ns=0;i=45c             C   s   ||krg S t  }|j| x|jD ]}|jtkr$t  }|j| |j| |j|jkr||jr||jt	| | j
|j |d q$|j|jkr$|j r$|jt	| | j
|j |d q$W |S )N)	skipNodes)setadd
referencesreferenceType
hassubtypeupdatesourceid	isForwardr	   nodestarget)nodesetnoder   rerefZskipAllr   r   r   r	   -   s    



 c             C   s   dg}t j| jdd}d}d}x@|D ]8}d|j kr:d}nd|j krP|| }P |r$|| }q$W t|d	krtj|jd
}x<|d	 jD ].}|j	|j
krq|jj|krq|j|jj qW |j  |S )Nzhttp://opcfoundation.org/UA/zutf-8)encodingF z<namespaceuris>Tz</namespaceuris>r   ZNamespaceUris)codecsopennamelowerlendomparseStringgetElementsByTagName
childNodesnodeTypeELEMENT_NODE
firstChilddataappendclose)xmlfile
namespacesZinfileZ	foundURIsZnslinelinensurir   r   r   extractNamespaces=   s,    
r5   c             C   sL   i }xB| j D ]8}|j|jkr|jdr|jd}t|jj}|||< qW |S )zParses the <Alias> XML Element present in must XML NodeSet definitions.
       Contents the Alias element are stored in a dictionary for further
       dereferencing during pointer linkage (see linkOpenPointer()).ZAlias)r)   r*   r+   hasAttributegetAttributer   r,   r-   )
xmlelementaliasesZalZaliasstZaliasndr   r   r   buildAliasList]   s    

r:   c               @   s   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	d0ddZ
d1ddZdd Zdd Zdd Zd2ddZdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/S )3r   a   This class handles parsing XML description of namespaces, instantiating
        nodes, linking references, graphing the namespace and compiling a binary
        representation.

        Note that nodes assigned to this class are not restricted to having a
        single namespace ID. This class represents the entire physical address
        space of the binary representation and all nodes that are to be included
        in that segment of memory.
    c             C   s   i | _ i | _dg| _i | _d S )Nzhttp://opcfoundation.org/UA/)r   r9   r1   namespaceMapping)selfr   r   r   __init__u   s    zNodeSet.__init__c             C   s   x.| j j D ] }|j dkrtdt| qW x| j j D ]~}xx|jD ]n}|j|jksltdt| d |j| j krtdt| d |j	| j krHt
| j tdt| d qHW q<W d S )NFzFailed to sanitize node z
Reference z has an invalid sourcez has an unknown reference typez has an unknown target)r   valuessanitize	Exceptionstrr   r   r   r   r   printr1   )r<   nr   r   r   r   r?   {   s    
zNodeSet.sanitizec             C   s   || j kr| j j| d S )N)r1   r.   )r<   ZnsURLr   r   r   addNamespace   s    
zNodeSet.addNamespacec             C   s2   i | _ x&t|D ]\}}| jj|| j |< qW dS )zsCreates a dict that maps from the nsindex in the original nodeset to the
           nsindex in the combined nodesetN)r;   	enumerater1   index)r<   orig_namespacesrF   r#   r   r   r   createNamespaceMapping   s    zNodeSet.createNamespaceMappingc                s   t  fdd| jj D d S )Nc             3   s   | ]} |j jkr|V  qd S )N)
browseNamer#   ).0rC   )idstringr   r   	<genexpr>   s    z.NodeSet.getNodeByBrowseName.<locals>.<genexpr>)nextr   r>   )r<   rK   r   )rK   r   getNodeByBrowseName   s    zNodeSet.getNodeByBrowseNamec             C   s
   | j dS )NZRoot)rN   )r<   r   r   r   getRoot   s    zNodeSet.getRootFc             C   s   |j j }|d d dkr&|dd  }d }|dkr:t|}|dkrJt|}|dkrZt|}|dkrjt|}|dkrzt|}|dkrt|}|d	krt|}|d
krt|}|d krd S ||_	||_
|S )N   ZuavariableobjectmethodZ
objecttypeZvariabletypeZ
methodtypeZdatatypeZreferencetype)	localNamer$   VariableNode
ObjectNode
MethodNodeObjectTypeNodeVariableTypeNodeDataTypeNodeReferenceTypeNodemodelUrihidden)r<   r8   r\   r]   ndtyper   r   r   r   
createNode   s2    
zNodeSet.createNodeTc             C   s"   || j krdS | j | }||_dS )NFT)r   r]   )r<   nodeIdr]   r   r   r   r   	hide_node   s
    

zNodeSet.hide_nodec             G   s    i }x|D ]}|j | q
W |S )z
        Given any number of dicts, shallow copy and merge into a new dict,
        precedence goes to key value pairs in latter dicts.
        )r   )r<   	dict_argsresult
dictionaryr   r   r   merge_dicts   s    
zNodeSet.merge_dictsc             C   sn   t jd|}|rN|jd}|j sN|| jkr0d S | jj|}dj||jd}t|}|| jkrdd S | j| S )Nzns=([^;]+);(.*)   zns={};{}rP   )	r   matchgroupisdigitr1   rF   formatr   r   )r<   ZidStrmr3   r`   r   r   r   getNodeByIDString   s    


zNodeSet.getNodeByIDStringc                s   fdd xj D ]jjkr`j| jkr2qtt fdd| jj j | jj _ qjjkrj| jkrzqtt fdd| jj j | jj _ qW | jj= d S )Nc                s&   | j |j kp$|j jkp"|j jk S )N)r   r   r   r   )rrt)r   r   r   	filterRef   s    z&NodeSet.remove_node.<locals>.filterRefc                s
    | S )Nr   )rn   )ro   rm   r   r   <lambda>   s    z%NodeSet.remove_node.<locals>.<lambda>c                s
    | S )Nr   )rn   )ro   rm   r   r   rp      s    )r   r   r   r   r   r   filter)r<   r   r   )ro   r   rm   r   remove_node   s     zNodeSet.remove_nodeUA_TYPESc             C   s:  |j  }|jtjr |jtj}tjdkr4|jd}tj	dd|}t
j|jd}t|dksjt|dkrzt| | jd |d }y(|jd	d jd
d }|jd j}W n tk
r   d }Y nX t|}	|d krt|	dkr|	d }|d krt| | jd x|	D ]}
| j|
 qW | j|	 xJ|jD ]@}|j|jkrDq.|jj }d|kr.| j| jt|| _q.W i }x|jD ]}|j|jkrq~| j|||}|sq~|j| j |j| j  ||_!|j"| j#krtdt$|j" || j#|j"< |||j"< q~W x.|j% D ]"}t&|t'r|j(| | j d qW d S )Nr
   r   zutf-8z<([/]?)uax:(.+?)([/]?)>z<\g<1>\g<2>\g<3>>	UANodeSetrf   z# contains no or more then 1 nodesetZModelsZModelZModelUrizQ does not define the nodeset URI in Models/Model/ModelUri or NamespaceUris array.r9   zXMLElement with duplicate ID )r;   )r
   r   ))read
startswithr!   BOM_UTF8lstripsysversion_infodecoder   subr&   r'   r(   r%   r@   Z	originXML
attributes	nodeValuer5   rD   rH   r)   r*   r+   rT   r$   re   r9   r:   r_   ZreplaceAliasesZreplaceNamespacesr;   
typesArrayr   r   rA   r>   
isinstancerZ   ZbuildEncoding)r<   r0   r]   r   fileContentnodesetsr   ZmodelTagr\   rG   r3   ndr^   Znewnodesr   rC   r   r   r   
addNodeSet   s\    







zNodeSet.addNodeSetc             C   sd   | j | }xD|jD ]:}|jjdkr|jjdkr| j |j }|jjdkr|jS qW tdt	| dS )a  
        The node should have a 'HasEncoding' forward reference which points to the encoding ids.
        These can be XML Encoding or Binary Encoding. Therefore we also need to check if the SymbolicName
        of the target node is "DefaultBinary"
        r   &   ZDefaultBinaryz+No DefaultBinary encoding defined for node N)
r   r   r   r3   ir   symbolicNamevaluer@   rA   )r<   r`   r   r   ZrefNoder   r   r   getBinaryEncodingIdForNode?  s    

z"NodeSet.getBinaryEncodingIdForNodec             C   s,   x&| j j D ]}t|tr|j|  qW d S )N)r   r>   r   rU   ZallocateValue)r<   rC   r   r   r   allocateVariablesM  s    
zNodeSet.allocateVariablesc             C   sV   |d krd S |j jtkr|S x4|jD ]*}|jr0q$|jjdkr$| j| j|j	 S q$W |S )N-   )
rI   r#   r   r   r   r   r   getBaseDataTyper   r   )r<   r   r   r   r   r   r   R  s    zNodeSet.getBaseDataTypec             C   s2   x,|j D ]"}|jjdkr|jr| j|j S qW d S )N(   )r   r   r   r   r   r   )r<   r   r   r   r   r   getNodeTypeDefinition^  s    zNodeSet.getNodeTypeDefinitionc             C   s   t |tr8t|s$tjd|  d S | jt| j|  S t |tr|jdkrPd S | j| }t |t	s~tjdt
| d  d S |S d S )NzNot a valid dataType string: r   zNode id z# is not reference a valid dataType.)r   string_typesr   loggererrorr   r   r9   r   rZ   rA   )r<   dataTypeZdataTypeNoder   r   r   getDataTypeNodee  s    




zNodeSet.getDataTypeNodec             C   s`   t  }|jt| | jdg  |jt| | jdg  |jt| | jdg  ttdd |S )NHierarchicalReferencesZHasEncodingZHasTypeDefinitionc             S   s   | j S )N)r   )xr   r   r   rp   z  s    z7NodeSet.getRelevantOrderingReferences.<locals>.<lambda>)r   r   r	   rN   listmap)r<   Zrelevant_typesr   r   r   getRelevantOrderingReferencesu  s
    z%NodeSet.getRelevantOrderingReferencesc             C   sX   xR| j j D ]D}x>|jj D ]0}t|j|j|j|j }| j |j jj	| qW qW d S )N)
r   r>   r   copyZ	Referencer   r   r   r   r   )r<   ur   Zbackr   r   r   addInverseReferences|  s    zNodeSet.addInverseReferencesc             C   s   t | | jd}ttdd |}xt| jj D ]f}|jjdkrL|jjd	krLq.|j	|}|d k	r.| j|j
 |_|jstdjt|j| j|j |_q.W d S )
Nr   c             S   s   | j S )N)r   )r   r   r   r   rp     s    z'NodeSet.setNodeParent.<locals>.<lambda>r   N   P   T   z#Node {}: Did not find parent node: )r   r   r   )r	   rN   r   r   r   r>   r   r3   r   ZgetParentReferencer   parentRuntimeErrorrj   rA   r   ZparentReference)r<   Zparentreftypesr   Z	parentrefr   r   r   setNodeParent  s    
zNodeSet.setNodeParentc          	   C   s  g | _ g }g }x~|D ]t}|jdkr(qt|jd}|j }|jtjrT|jtj}tj	dkrh|j
d}tjdd|}tj|jd}	t|	dkst|	d	krtd
|	d }
|
jd}x|D ]}|jdrtjd|jd jp|jd jdks|jdr|jd rtjd|jd jr|jdd jdd }tjddd}|jtj|jj |j  | j j|j |j  d|j }|j| qW qW x|D ]}t|jd}|j }|jtjr|jtj}tj	dkr|j
d}tjdd|}tj|jd}	t|	dkst|	d	kr$td
|	d }
|
jd}x|D ]}|jdrttjd|jd js|jd jdks|jdr<|jd r<tjd|jd jr<|jdd jdd }tjdd}|jtj|jj |j  |j d t!j"|}| j j|j t!j#|ddd}d|_$|j| q<W qW g }g }g }d}d}x|D ]}|j| qLW t%|||||||| j&| _'| j'j(  |j  d S ) Nz)deps/ua-nodeset/DI/Opc.Ua.Di.NodeSet2.xmlrbr
   r   zutf-8z<([/]?)uax:(.+?)([/]?)>z<\g<1>\g<2>\g<3>>rt   rf   z"contains no or more then 1 nodesetZ
UAVariableZSymbolicNamez.*_BinarySchemaZTypeDictionary_BinarySchemaZParentNodeIdzi=93Value
ByteStringFz.bsd)deletesuffixz	UA_TYPES#)r   zUTF-8
)newlinerm   Toutname)r
   r   )r
   r   ))Z	all_filesr#   r"   ru   rv   r!   rw   rx   ry   rz   r{   r   r|   r&   r'   r(   r%   r@   r6   rg   r}   r~   	fullmatchtempfileZNamedTemporaryFilewritebase64	b64decoder,   flushr.   r/   seekioBufferedReaderTextIOWrappermoder   r1   parsercreate_types)r<   existinginfilesbsdFileZ
import_bsdtype_bsdr0   Znodeset_baser   r   r   ZvariableNodesr   Ztype_contentfZbsdZbftmp
opaque_mapselected_typestype_csv
no_builtinr   r   r   r   generateParser  s    




Z



d



zNodeSet.generateParserN)F)T)Frs   )__name__
__module____qualname____doc__r=   r?   rD   rH   rN   rO   r_   ra   re   rl   rr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   j   s,   	



K)"Z
__future__r   ry   xml.dom.minidomr&   minidomloggingr!   r   	datatypesr   r   r   r   type_parserr   r   r   r   __all__	getLoggerr   r   rz   r   rA   r   Z
basestringr   r	   r5   r:   rR   r   r   r   r   r   <module>   s.   
 