0024157: Parallelization of assembly part of BO
[occt.git] / src / XmlObjMgt / XmlObjMgt.cxx
CommitLineData
b311480e 1// Created on: 2001-07-18
2// Created by: Julia DOROVSKIKH
3// Copyright (c) 2001-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
20//AGV 150202: Add parameter isClearText to SetStringValue()
7fd59977 21
22#include <XmlObjMgt.ixx>
23#include <XmlObjMgt_Document.hxx>
24#include <LDOM_Text.hxx>
25
26#include <errno.h>
27#include <stdio.h>
28
29static const char aRefPrefix [] = "/document/label";
30static const char aRefElem1 [] = "/label[@tag=";
31static const char aRefElem2 [] = "]";
32
33//=======================================================================
34//function : IdString
35//purpose : return name of ID attribute to be used everywhere
36//=======================================================================
37
38const XmlObjMgt_DOMString& XmlObjMgt::IdString ()
39{
40 static const LDOMString aString ("id");
41 return aString;
42}
43
44//=======================================================================
45//function : SetStringValue
46//purpose : Add theData as the last child text node to theElement
47//remark : Set isClearText to True if only you guarantee that the string
48// does not contain '&', '<', '>', '\"', '\'', etc.
49//=======================================================================
50
51void XmlObjMgt::SetStringValue (XmlObjMgt_Element& theElement,
52 const XmlObjMgt_DOMString& theData,
53 const Standard_Boolean isClearText)
54{
55 XmlObjMgt_Document aDocument = theElement.getOwnerDocument();
56 LDOM_Text aText = aDocument.createTextNode (theData);
57 if (isClearText) aText.SetValueClear();
58 theElement.appendChild (aText);
59}
60
61//=======================================================================
62//function : GetStringValue
63//purpose : returns the first child text node
64//=======================================================================
65
66XmlObjMgt_DOMString XmlObjMgt::GetStringValue
67 (const XmlObjMgt_Element& theElement)
68{
69 XmlObjMgt_DOMString aString;
70 for (LDOM_Node aNode = theElement.getFirstChild();
71 aNode != NULL;
72 aNode = aNode.getNextSibling())
73 {
74 if (aNode.getNodeType() == LDOM_Node::TEXT_NODE) {
75 aString = ((const LDOM_Text&)aNode).getData();
76 break;
77 }
78 }
79 return aString;
80}
81
82//=======================================================================
83//function : SprintfExtStr
84//purpose : Converts theString to hex printable representation and put it
85// : to the out buffer
86//=======================================================================
87void SprintfExtStr(char * out, const TCollection_ExtendedString& theString) {
88 unsigned short * p = (unsigned short *)theString.ToExtString();
89 int len = theString.Length();
90 int i = 0;
91 unsigned short mask[4] = {0xf000,0x0f00,0x00f0,0x000f};
92 while (len) {
93 for(int j = 0,k=3; j<4; j++,k--) {
94 unsigned short v = *(p+i) & mask[j];//x000
95 v = v >> (4*k);
96 if(v < 10)
97 v |= 0x30;
98 else
99 v += 87;
100 out[4*i+j] = (char)v;
101 }
102 i++;len--;
103 }
104 out[4*theString.Length()] = 0x00;
105}
106//=======================================================================
107//function : SetExtendedString
108//purpose : Add text node to element and initialize it with string
109//=======================================================================
110
111Standard_Boolean XmlObjMgt::SetExtendedString
112 (XmlObjMgt_Element& theElement,
113 const TCollection_ExtendedString& theString)
114{
115 TCollection_AsciiString anAString;
116 if (theString.IsAscii()) {
117 anAString = TCollection_AsciiString (theString, '?');
118 SetStringValue (theElement, anAString.ToCString());
119 } else {
120 const Standard_Integer aLen = theString.Length();
121// const Standard_ExtCharacter * aString = theString.ToExtString();
122 char * buf0 = new char [4 * (aLen + 1) + 3];
91322f44 123 Sprintf (&buf0[0], "##%04x", 0xfeff); // set UNICODE header
7fd59977 124 char * buf = &buf0[6];
125// Standard_Integer i = 0;
126// while (i <= (aLen - 4)) {
91322f44 127// Sprintf (&buf[i*4], "%04x%04x%04x%04x", aString[i], aString[i+1],
7fd59977 128// aString[i+2], aString[i+3]);
129// i += 4;
130// }
131// while (i < aLen) {
91322f44 132// Sprintf (&buf[i*4], "%04x", aString[i]);
7fd59977 133// ++i;
134// }
135// buf[4*aLen] = '\0';
136
137 SprintfExtStr(buf, theString);
138 SetStringValue (theElement, buf0);
139 delete [] buf0;
140 }
141 return Standard_True;
142}
143
144//=======================================================================
145//function : GetExtendedString
146//purpose : Get the first text node in theElement and convert to ExtendedStr
147//=======================================================================
148
149Standard_Boolean XmlObjMgt::GetExtendedString
150 (const XmlObjMgt_Element& theElement,
151 TCollection_ExtendedString& theString)
152{
153 theString = GetStringValue (theElement);
154 return Standard_True;
155}
156
157//=======================================================================
158//function : GetTagEntryString
159//purpose : Convert XPath expression (DOMString) into TagEntry string
160// Returns False on error
161//=======================================================================
162
163Standard_Boolean XmlObjMgt::GetTagEntryString
164 (const XmlObjMgt_DOMString& theSource,
165 TCollection_AsciiString& theTagEntry)
166{
167 // Check the prefix
168 const size_t aPrefixSize = sizeof(aRefPrefix) - 1;
169 const char * aSource = theSource.GetString();
170 if (strncmp (aSource, aRefPrefix, aPrefixSize))
171 return Standard_False;
172
173 // Beging aTagEntry string
174 char * aTagEntry =
175 (char *) Standard::Allocate (strlen(aSource)/2); // quite enough to hold it
176 char * aTagEntryPtr = aTagEntry + 1;
177 * aTagEntry = '0';
178 aSource += aPrefixSize;
179
180 // Find all individual tags in a loop
181 const size_t anElem1Size = sizeof(aRefElem1) - 1;
182 const size_t anElem2Size = sizeof(aRefElem2) - 1;
183 while (aSource[0] != '\0') {
184 // Check the first part of individual tag: "/label[@tag="
185 if (strncmp (aSource, aRefElem1, anElem1Size))
186 return Standard_False;
187 aSource += anElem1Size;
188 const char aQuote = aSource[0];
189 if (aQuote != '\'' && aQuote != '\"')
190 return Standard_False;
191
192 // Check the integer value of the tag
193 errno = 0;
194 char * aPtr;
195 long aTagValue = strtol (&aSource[1], &aPtr, 10);
196 if (aTagValue <= 0 || aPtr[0] != aQuote ||
197 errno == ERANGE || errno == EINVAL)
198 return Standard_False;
7dc9e047 199 Standard_Integer aLen = (Standard_Integer)(aPtr - &aSource[1]);
7fd59977 200 aTagEntryPtr[0] = ':';
201 memcpy (&aTagEntryPtr[1], &aSource[1], aLen);
202 aTagEntryPtr += (aLen + 1);
203
204 // Check the final part of individual tag : "]"
205 if (strncmp (aPtr + 1, aRefElem2, anElem2Size))
206 return Standard_False;
207 aSource = aPtr + 1 + anElem2Size;
208 }
209 aTagEntryPtr[0] = '\0';
210 theTagEntry = aTagEntry;
211 Standard::Free ((Standard_Address&)aTagEntry);
212 return Standard_True;
213}
214
215//=======================================================================
216//function : SetTagEntryString
217//purpose : Form an XPath string corresponding to the input TagEntry
218//=======================================================================
219
220void XmlObjMgt::SetTagEntryString (XmlObjMgt_DOMString& theTarget,
221 const TCollection_AsciiString& theTagEntry)
222{
223 // Begin parsing theTagEntry
224 const char * aTagEntry = (const char*) theTagEntry.ToCString() + 1;
225 if (aTagEntry[-1] != '0')
226 return;
227
228 // Count the number of tags in the label entry string
229 const char * aPtr = aTagEntry;
230 Standard_Integer aTagCount = 0;
231 while (* aPtr) if (* aPtr++ == ':') aTagCount ++;
232
233 // Create a buffer to accumulate the XPath reference
234 const size_t anElem1Size = sizeof(aRefElem1) - 1;
235 const size_t anElem2Size = sizeof(aRefElem2) - 1;
236 char * aTarget =
237 (char *) Standard::Allocate (sizeof(aRefPrefix) + aTagCount *
238 (anElem1Size + anElem2Size + 12));
239 memcpy (aTarget, aRefPrefix, sizeof (aRefPrefix) - 1);
240 char * aTargetPtr = aTarget + (sizeof (aRefPrefix) - 1);
241
302f96fb 242 for(;;) {
7fd59977 243 // Check for the end-of-string; find the delimeter ':'
244 aPtr = strchr (aTagEntry, ':');
245 if (aPtr == NULL) break;
246 aTagEntry = aPtr + 1;
247
248 // Find the range of characters for an integer number
249 errno = 0;
250 char * ptr;
251 long aTagValue = strtol (aTagEntry, &ptr, 10);
252 if (aTagValue <= 0 || errno == ERANGE || errno == EINVAL)
253 return; // error
7dc9e047 254 Standard_Integer aTagSize = (Standard_Integer)(ptr - aTagEntry);
7fd59977 255
256 // Add one XPath level to the expression in aTarget
257 memcpy (&aTargetPtr[0], aRefElem1, anElem1Size);
258 aTargetPtr[anElem1Size] = '\"';
259 memcpy (&aTargetPtr[anElem1Size+1], aTagEntry, aTagSize);
260 aTargetPtr[anElem1Size+aTagSize+1] = '\"';
261 memcpy (&aTargetPtr[anElem1Size+aTagSize+2],aRefElem2, anElem2Size);
262 aTargetPtr += (anElem1Size + aTagSize + anElem2Size + 2);
263 }
264 * aTargetPtr = '\0';
265 theTarget = aTarget;
266 Standard::Free ((Standard_Address&)aTarget);
267}
268
269//=======================================================================
270//function : FindChildElement
271//purpose :
272//=======================================================================
273XmlObjMgt_Element XmlObjMgt::FindChildElement
274 (const XmlObjMgt_Element& theSource,
275 const Standard_Integer theId)
276{
277 LDOM_Node aNode = theSource.getFirstChild();
278 Standard_Integer anId;
279 while ( !aNode.isNull() )
280 {
281 if ( aNode.getNodeType() == LDOM_Node::ELEMENT_NODE )
282 {
283 LDOM_Element anElem = (LDOM_Element &) aNode;
284 if (anElem.getAttribute (IdString()).GetInteger(anId))
285 if (anId == theId) return anElem;
286 }
287 aNode = aNode.getNextSibling();
288 }
289
290 // find in all the document // to be done
291// LDOM_Document aDoc = theSource.getOwnerDocument();
292
293 return LDOM_Element();
294}
295
296//=======================================================================
297//function : FindChildByRef
298//purpose :
299//=======================================================================
300
301XmlObjMgt_Element XmlObjMgt::FindChildByRef
302 (const XmlObjMgt_Element& theSource,
303 const XmlObjMgt_DOMString& theRefName)
304{
305 Standard_Integer anID;
306 if (theSource.getAttribute (theRefName).GetInteger (anID))
307 return FindChildElement (theSource, anID);
308 return LDOM_Element();
309}
310
311
312//=======================================================================
313//function : FindChildByName
314//purpose :
315//=======================================================================
316XmlObjMgt_Element XmlObjMgt::FindChildByName
317 (const XmlObjMgt_Element& theSource,
318 const XmlObjMgt_DOMString& theName)
319{
320 return theSource.GetChildByTagName(theName);
321}
322
323//=======================================================================
324//function : GetInteger
325//purpose :
326//=======================================================================
327Standard_Boolean XmlObjMgt::GetInteger (Standard_CString& theString,
328 Standard_Integer& theValue)
329{
330 char * ptr;
331 errno = 0;
332 long aValue = strtol (theString, &ptr, 10);
333 if (ptr == theString || errno == ERANGE || errno == EINVAL)
334 return Standard_False;
335 theValue = Standard_Integer (aValue);
336 theString = ptr;
337 return Standard_True;
338}
339
340//=======================================================================
341//function : GetReal
342//purpose :
343//=======================================================================
344Standard_Boolean XmlObjMgt::GetReal (Standard_CString& theString,
345 Standard_Real& theValue)
346{
347 char * ptr;
348 errno = 0;
91322f44 349 double aValue = Strtod (theString, &ptr);
7fd59977 350 if (ptr == theString || errno == ERANGE || errno == EINVAL)
351 return Standard_False;
352 theValue = Standard_Real (aValue);
353 theString = ptr;
354 return Standard_True;
355}
356
357//=======================================================================
358//function : GetReal
359//purpose : Convert LDOMString to Real
360//=======================================================================
361Standard_Boolean XmlObjMgt::GetReal (const XmlObjMgt_DOMString& theString,
362 Standard_Real& theValue)
363{
364 switch (theString.Type()) {
365 case LDOMBasicString::LDOM_NULL:
366 return Standard_False;
367 case LDOMBasicString::LDOM_Integer:
368 {
369 Standard_Integer anIntValue;
370 theString.GetInteger(anIntValue);
371 theValue = Standard_Real(anIntValue);
372 break;
373 }
374 default: // LDOM_Ascii*
375 {
376 char * ptr;
377 const char * aString = theString.GetString();
378 errno = 0;
91322f44 379 double aValue = Strtod (aString, &ptr);
7fd59977 380 if (ptr == aString || errno == ERANGE || errno == EINVAL)
381 return Standard_False;
382 theValue = Standard_Real (aValue);
383 }
384 }
385 return Standard_True;
386}