1 /*
2  *
3  *  Copyright (C) 2016-2017, J. Riesmeier, Oldenburg, Germany
4  *  All rights reserved.  See COPYRIGHT file for details.
5  *
6  *  This software and supporting documentation are maintained by
7  *
8  *    OFFIS e.V.
9  *    R&D Division Health
10  *    Escherweg 2
11  *    D-26121 Oldenburg, Germany
12  *
13  *
14  *  Module: dcmsr
15  *
16  *  Author: Joerg Riesmeier
17  *
18  *  Purpose:
19  *    classes: DSRIncludedTemplateNodeCursor
20  *
21  */
22 
23 
24 #include "dcmtk/config/osconfig.h"   /* make sure OS specific configuration is included first */
25 
26 #include "dcmtk/dcmsr/dsritcsr.h"
27 #include "dcmtk/dcmsr/dsrdoctn.h"
28 #include "dcmtk/dcmsr/dsrtpltn.h"
29 #include "dcmtk/dcmsr/dsrstpl.h"
30 
31 
DSRIncludedTemplateNodeCursor()32 DSRIncludedTemplateNodeCursor::DSRIncludedTemplateNodeCursor()
33   : DSRTreeNodeCursor<DSRDocumentTreeNode>()
34 {
35 }
36 
37 
DSRIncludedTemplateNodeCursor(const DSRIncludedTemplateNodeCursor & cursor)38 DSRIncludedTemplateNodeCursor::DSRIncludedTemplateNodeCursor(const DSRIncludedTemplateNodeCursor &cursor)
39   : DSRTreeNodeCursor<DSRDocumentTreeNode>(cursor)
40 {
41 }
42 
43 
DSRIncludedTemplateNodeCursor(DSRDocumentTreeNode * node,const DSRPositionCounter * position)44 DSRIncludedTemplateNodeCursor::DSRIncludedTemplateNodeCursor(DSRDocumentTreeNode *node,
45                                                              const DSRPositionCounter *position)
46   : DSRTreeNodeCursor<DSRDocumentTreeNode>(node, position)
47 {
48 }
49 
50 
~DSRIncludedTemplateNodeCursor()51 DSRIncludedTemplateNodeCursor::~DSRIncludedTemplateNodeCursor()
52 {
53 }
54 
55 
operator =(const DSRIncludedTemplateNodeCursor & cursor)56 DSRIncludedTemplateNodeCursor &DSRIncludedTemplateNodeCursor::operator=(const DSRIncludedTemplateNodeCursor &cursor)
57 {
58     DSRTreeNodeCursor<DSRDocumentTreeNode>::operator=(cursor);
59     return *this;
60 }
61 
62 
operator =(DSRDocumentTreeNode * node)63 DSRIncludedTemplateNodeCursor &DSRIncludedTemplateNodeCursor::operator=(DSRDocumentTreeNode *node)
64 {
65     DSRTreeNodeCursor<DSRDocumentTreeNode>::operator=(node);
66     return *this;
67 }
68 
69 
getChildNode() const70 const DSRDocumentTreeNode *DSRIncludedTemplateNodeCursor::getChildNode() const
71 {
72     DSRDocumentTreeNode *node = NULL;
73     if (NodeCursor != NULL)
74     {
75         /* check for special case "included template" */
76         if (NodeCursor->getValueType() == DSRTypes::VT_includedTemplate)
77         {
78             DSRSubTemplate *subTempl = OFstatic_cast(DSRIncludedTemplateTreeNode *, NodeCursor)->getValue().get();
79             if (subTempl != NULL)
80             {
81                 /* get root node of referenced subtree */
82                 node = subTempl->getRoot();
83             }
84         } else {
85             /* standard case */
86             node = NodeCursor->getDown();
87         }
88     }
89     return node;
90 }
91 
92 
countChildNodes(const OFBool searchIntoSub) const93 size_t DSRIncludedTemplateNodeCursor::countChildNodes(const OFBool searchIntoSub) const
94 {
95     size_t count = 0;
96     if (NodeCursor != NULL)
97     {
98         /* do we have any children at all? */
99         DSRDocumentTreeNodeCursor cursor(*this);
100         if (cursor.goDown())
101         {
102             /* iterate over all child nodes */
103             do {
104                 ++count;
105             } while (cursor.iterate(searchIntoSub));
106         }
107     }
108     return count;
109 }
110 
111 
goDown()112 size_t DSRIncludedTemplateNodeCursor::goDown()
113 {
114     size_t nodeID = 0;
115     if (NodeCursor != NULL)
116     {
117         /* check for special case "included template" */
118         if (NodeCursor->getValueType() == DSRTypes::VT_includedTemplate)
119         {
120             DSRSubTemplate *subTempl = OFstatic_cast(DSRIncludedTemplateTreeNode *, NodeCursor)->getValue().get();
121             if (subTempl != NULL)
122             {
123                 NodeCursorStack.push(NodeCursor);
124                 /* go to root node of referenced subtree */
125                 NodeCursor = subTempl->getRoot();
126                 nodeID = NodeCursor->getIdent();
127                 Position.goDown();
128             }
129         }
130         /* standard case */
131         else if (NodeCursor->getDown() != NULL)
132         {
133             NodeCursorStack.push(NodeCursor);
134             NodeCursor = NodeCursor->getDown();
135             nodeID = NodeCursor->getIdent();
136             Position.goDown();
137         }
138     }
139     return nodeID;
140 }
141 
142 
iterate(const OFBool searchIntoSub)143 size_t DSRIncludedTemplateNodeCursor::iterate(const OFBool searchIntoSub)
144 {
145     size_t nodeID = 0;
146     if (NodeCursor != NULL)
147     {
148         /* perform "deep search", if specified */
149         if (searchIntoSub && hasChildNodes())
150             nodeID = goDown();
151         else if (NodeCursor->getNext() != NULL)
152         {
153             NodeCursor = NodeCursor->getNext();
154             nodeID = NodeCursor->getIdent();
155             /* check for special case: do not count "included template" nodes? */
156             if ((NodeCursor->getValueType() != DSRTypes::VT_includedTemplate) || !(Position.getFlags() & DSRTypes::PF_dontCountIncludedTemplateNodes))
157                 ++Position;
158         }
159         else if (searchIntoSub && !NodeCursorStack.empty())
160         {
161             do {
162                 if (!NodeCursorStack.empty())
163                 {
164                     NodeCursor = NodeCursorStack.top();
165                     NodeCursorStack.pop();
166                     Position.goUp();
167                 } else
168                     NodeCursor = NULL;
169             } while ((NodeCursor != NULL) && (NodeCursor->getNext() == NULL));
170             if (NodeCursor != NULL)
171             {
172                 if (NodeCursor->getNext() != NULL)
173                 {
174                     NodeCursor = NodeCursor->getNext();
175                     nodeID = NodeCursor->getIdent();
176                     /* check for special case: do not count "included template" nodes? */
177                     if ((NodeCursor->getValueType() != DSRTypes::VT_includedTemplate) || !(Position.getFlags() & DSRTypes::PF_dontCountIncludedTemplateNodes))
178                         ++Position;
179                 }
180             }
181         }
182     }
183     return nodeID;
184 }
185