0024186: Eliminate remaining compiler warnings in MSVC++ 2010 64 bit with warning...
[occt.git] / src / XmlObjMgt / XmlObjMgt.cxx
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()
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];
123     Sprintf (&buf0[0], "##%04x", 0xfeff);          // set UNICODE header
124     char * buf = &buf0[6];
125 //     Standard_Integer i = 0;
126 //     while (i <= (aLen - 4)) {
127 //       Sprintf (&buf[i*4], "%04x%04x%04x%04x", aString[i], aString[i+1],
128 //                aString[i+2], aString[i+3]);
129 //         i += 4;
130 //     }
131 //     while (i < aLen) {
132 //       Sprintf (&buf[i*4], "%04x", aString[i]);
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 = (Standard_Integer)(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
242   for(;;) {
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 = (Standard_Integer)(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;
349   double aValue = Strtod (theString, &ptr);
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;
379       double aValue = Strtod (aString, &ptr);
380       if (ptr == aString || errno == ERANGE || errno == EINVAL)
381         return Standard_False;
382       theValue = Standard_Real (aValue);
383     }
384   }
385   return Standard_True;
386 }