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 | |
29 | static const char aRefPrefix [] = "/document/label"; |
30 | static const char aRefElem1 [] = "/label[@tag="; |
31 | static const char aRefElem2 [] = "]"; |
32 | |
33 | //======================================================================= |
34 | //function : IdString |
35 | //purpose : return name of ID attribute to be used everywhere |
36 | //======================================================================= |
37 | |
38 | const 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 | |
51 | void 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 | |
66 | XmlObjMgt_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 | //======================================================================= |
87 | void 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 | |
111 | Standard_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 | |
149 | Standard_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 | |
163 | Standard_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; |
199 | Standard_Integer aLen = aPtr - &aSource[1]; |
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 | |
220 | void 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 |
254 | Standard_Integer aTagSize = ptr - aTagEntry; |
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 | //======================================================================= |
273 | XmlObjMgt_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 | |
301 | XmlObjMgt_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 | //======================================================================= |
316 | XmlObjMgt_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 | //======================================================================= |
327 | Standard_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 | //======================================================================= |
344 | Standard_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 | //======================================================================= |
361 | Standard_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 | } |