0026229: Add the possibility in OCAF to open/save a document from/to a stream object
[occt.git] / src / LDOM / LDOMBasicString.cxx
1 // Created on: 2001-06-26
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2001-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <LDOMBasicString.hxx>
17 #include <LDOM_MemManager.hxx>
18 #include <TCollection_AsciiString.hxx>
19 #include <TCollection_ExtendedString.hxx>
20 #include <errno.h>
21
22 //=======================================================================
23 //function : LDOMString
24 //purpose  : Create a free string (not connected to any type of container)
25 //=======================================================================
26
27 LDOMBasicString::LDOMBasicString (const char * aValue)
28 {
29   if (aValue == NULL /*|| aValue[0] == '\0'*/) {
30     myType = LDOM_NULL;
31     myVal.ptr = NULL;
32   } else {
33     myType = LDOM_AsciiFree;
34     Standard_Size aLen = strlen (aValue) + 1;
35     myVal.ptr = new char [aLen];
36     memcpy (myVal.ptr, aValue, aLen);
37   }
38 }
39
40 //=======================================================================
41 //function : LDOMString
42 //purpose  : Create an Ascii string managed by LDOM_Document
43 //=======================================================================
44
45 LDOMBasicString::LDOMBasicString (const char                     * aValue,
46                                   const Handle(LDOM_MemManager)& aDoc)
47 {
48   if (aValue == NULL /*|| aValue[0] == '\0'*/) {
49     myType = LDOM_NULL;
50     myVal.ptr = NULL;
51   } else {
52     myType = LDOM_AsciiDoc;
53     Standard_Integer aLen = (Standard_Integer) strlen (aValue) + 1;
54     myVal.ptr = aDoc -> Allocate (aLen);
55     memcpy (myVal.ptr, aValue, aLen);
56   }
57 }
58   
59 //=======================================================================
60 //function : LDOMString
61 //purpose  : Create an Ascii string managed by LDOM_Document
62 //=======================================================================
63
64 LDOMBasicString::LDOMBasicString (const char                     * aValue,
65                                   const Standard_Integer         aLen,
66                                   const Handle(LDOM_MemManager)& aDoc)
67 {
68   if (aValue == NULL || aLen == 0) {
69     myType = LDOM_NULL;
70     myVal.ptr = NULL;
71   } else {
72     myType = LDOM_AsciiDoc;
73     myVal.ptr = aDoc -> Allocate (aLen + 1);
74     memcpy (myVal.ptr, aValue, aLen);
75     ((char *)myVal.ptr)[aLen] = '\0';
76   }
77 }
78   
79 //=======================================================================
80 //function : LDOMBasicString
81 //purpose  : Copy constructor
82 //=======================================================================
83
84 LDOMBasicString::LDOMBasicString (const LDOMBasicString& anOther)
85     : myType (anOther.Type())
86 {
87   switch (myType) {
88   case LDOM_AsciiFree:
89     if (anOther.myVal.ptr) {
90       Standard_Size aLen = strlen ((const char *)anOther.myVal.ptr) + 1;
91       myVal.ptr = new char [aLen];
92       memcpy (myVal.ptr, anOther.myVal.ptr, aLen);
93       break;
94     }
95   case LDOM_AsciiDoc:
96   case LDOM_AsciiDocClear:
97   case LDOM_AsciiHashed:
98     myVal.ptr = anOther.myVal.ptr;
99     break;
100   case LDOM_Integer:
101     myVal.i = anOther.myVal.i;
102   default: ;
103   }
104 }
105
106 //=======================================================================
107 //function : ~LDOMString()
108 //purpose  : Destructor
109 //=======================================================================
110
111 LDOMBasicString::~LDOMBasicString ()
112 {
113   if (myType == LDOM_AsciiFree) {
114     if (myVal.ptr)
115       delete [] (char *) myVal.ptr;
116   }
117 }
118
119 //=======================================================================
120 //function : operator =
121 //purpose  : Assignment to NULL
122 //=======================================================================
123
124 LDOMBasicString& LDOMBasicString::operator = (const LDOM_NullPtr *)
125 {
126   if (myType == LDOM_AsciiFree && myVal.ptr)
127     delete [] (char *) myVal.ptr;
128   myType    = LDOM_NULL;
129   myVal.ptr = NULL;
130   return * this;
131 }
132
133 //=======================================================================
134 //function : operator =
135 //purpose  : Assignment
136 //=======================================================================
137
138 LDOMBasicString& LDOMBasicString::operator = (const LDOMBasicString& anOther)
139 {
140   if (myType == LDOM_AsciiFree && myVal.ptr)
141     delete [] (char *) myVal.ptr;
142   myType    = anOther.Type();
143   switch (myType) {
144   case LDOM_AsciiFree:
145     if (anOther.myVal.ptr) {
146       Standard_Size aLen = strlen ((const char *)anOther.myVal.ptr) + 1;
147       myVal.ptr = new char [aLen];
148       memcpy (myVal.ptr, anOther.myVal.ptr, aLen);
149       break;
150     }
151   case LDOM_AsciiDoc:
152   case LDOM_AsciiDocClear:
153   case LDOM_AsciiHashed:
154     myVal.ptr = anOther.myVal.ptr;
155     break;
156   case LDOM_Integer:
157     myVal.i = anOther.myVal.i;
158   default: ;
159   }
160   return * this;
161 }
162
163 //=======================================================================
164 //function : equals
165 //purpose  : Compare two strings by content
166 //=======================================================================
167
168 Standard_Boolean LDOMBasicString::equals (const LDOMBasicString& anOther) const
169 {
170   Standard_Boolean aResult = Standard_False;
171   switch (myType)
172   {
173   case LDOM_NULL:
174     return (anOther == NULL);
175   case LDOM_Integer:
176     switch (anOther.Type())
177     {
178     case LDOM_Integer:
179       return (myVal.i == anOther.myVal.i);
180     case LDOM_AsciiFree:
181     case LDOM_AsciiDoc:
182     case LDOM_AsciiDocClear:
183     case LDOM_AsciiHashed:
184       {
185         long aLongOther = strtol ((const char *) anOther.myVal.ptr, NULL, 10);
186         return (errno == 0 && aLongOther == long(myVal.i));
187       }
188     case LDOM_NULL:
189     default:
190       ;
191     }
192     break;
193   default:
194     switch (anOther.Type())
195     {
196     case LDOM_Integer:
197       {
198         long aLong = strtol ((const char *) myVal.ptr, NULL, 10);
199         return (errno == 0 && aLong == long(anOther.myVal.i));
200       }
201     case LDOM_AsciiFree:
202     case LDOM_AsciiDoc:
203     case LDOM_AsciiDocClear:
204     case LDOM_AsciiHashed:
205       return (strcmp ((const char *) myVal.ptr,
206                       (const char *) anOther.myVal.ptr) == 0);
207     case LDOM_NULL:
208     default:
209       ;
210     }
211   }
212   return aResult;
213 }
214
215 //=======================================================================
216 //function : operator TCollection_AsciiString
217 //purpose  : 
218 //=======================================================================
219
220 LDOMBasicString::operator TCollection_AsciiString () const
221 {
222   switch (myType) {
223   case LDOM_Integer:
224     return TCollection_AsciiString (myVal.i);
225   case LDOM_AsciiFree:
226   case LDOM_AsciiDoc:
227   case LDOM_AsciiDocClear:
228   case LDOM_AsciiHashed:
229     return TCollection_AsciiString (Standard_CString(myVal.ptr));
230   default: ;
231   }
232   return TCollection_AsciiString ();
233 }
234
235 //=======================================================================
236 //function : operator TCollection_ExtendedString
237 //purpose  : 
238 //=======================================================================
239
240 LDOMBasicString::operator TCollection_ExtendedString () const
241 {
242   switch (myType) {
243   case LDOM_Integer:
244     return TCollection_ExtendedString (myVal.i);
245   case LDOM_AsciiFree:
246   case LDOM_AsciiDoc:
247   case LDOM_AsciiDocClear:
248   case LDOM_AsciiHashed:
249   {
250     char buf[6] = {'\0','\0','\0','\0','\0','\0'};
251     const long aUnicodeHeader = 0xfeff;
252     Standard_CString ptr = Standard_CString (myVal.ptr);
253     errno = 0;
254     // Check if ptr is ascii string
255     if (ptr[0] != '#' || ptr[1] != '#')
256       return TCollection_ExtendedString (ptr);
257     buf[0] = ptr[2];
258     buf[1] = ptr[3];
259     buf[2] = ptr[4];
260     buf[3] = ptr[5];
261     if (strtol (&buf[0], NULL, 16) != aUnicodeHeader)
262       return TCollection_ExtendedString (ptr);
263
264     // convert Unicode to Extended String
265     ptr += 2;
266     Standard_Size aLength = (strlen(ptr) / 4), j = 0;
267     Standard_ExtCharacter * aResult = new Standard_ExtCharacter[aLength--];
268     while (aLength--) {
269       ptr += 4;
270       buf[0] = ptr[0];
271       buf[1] = ptr[1];
272       buf[2] = ptr[2];
273       buf[3] = ptr[3];
274       aResult[j++] = Standard_ExtCharacter (strtol (&buf[0], NULL, 16));
275       if (errno) {
276         delete [] aResult;
277         return TCollection_ExtendedString();
278       }
279     }
280     aResult[j] = 0;
281     TCollection_ExtendedString aResultStr (aResult);
282     delete [] aResult;
283     return aResultStr;
284   }
285   default: ;
286   }
287   return TCollection_ExtendedString();
288 }
289
290 //=======================================================================
291 //function : GetInteger
292 //purpose  : Conversion to Integer
293 //=======================================================================
294
295 Standard_Boolean LDOMBasicString::GetInteger (Standard_Integer& aResult) const
296 {
297   switch (myType) {
298   case LDOM_Integer:
299     aResult = myVal.i;
300     break;
301   case LDOM_AsciiFree:
302   case LDOM_AsciiDoc:
303   case LDOM_AsciiDocClear:
304   case LDOM_AsciiHashed:
305     {
306       char * ptr;
307       long aValue = strtol ((const char *)myVal.ptr, &ptr, 10);
308       if (ptr == myVal.ptr || errno == ERANGE || errno == EINVAL)
309         return Standard_False;
310       aResult = Standard_Integer (aValue);
311       break;
312     }
313   default:
314     return Standard_False;
315   }
316   return Standard_True;
317 }
318
319 #ifdef OCCT_DEBUG
320 #ifndef _MSC_VER
321 //=======================================================================
322 // Debug Function for DBX: use "print -p <Variable> or pp <Variable>"
323 //=======================================================================
324 #include <LDOM_OSStream.hxx>
325 #define FLITERAL 0x10
326 char * db_pretty_print (const LDOMBasicString * aString, int fl, char *)
327 {
328   LDOM_OSStream out (128);
329   const char * str;
330   switch (aString -> myType) {
331   case LDOMBasicString::LDOM_Integer:
332     if ((fl & FLITERAL) == 0)  out << "LDOM_Integer: ";
333     out << '\"' << aString -> myVal.i << '\"'; goto finis;
334   case LDOMBasicString::LDOM_AsciiFree:
335     if ((fl & FLITERAL) == 0)  out << "LDOM_AsciiFree: ";
336     break;
337   case LDOMBasicString::LDOM_AsciiDoc:
338     if ((fl & FLITERAL) == 0)  out << "LDOM_AsciiDoc: ";
339     break;
340   case LDOMBasicString::LDOM_AsciiDocClear:
341     if ((fl & FLITERAL) == 0)  out << "LDOM_AsciiDocClear: ";
342     break;
343   case LDOMBasicString::LDOM_AsciiHashed:
344     if ((fl & FLITERAL) == 0)  out << "LDOM_AsciiHashed: ";
345     break;
346   default:
347     out << "Unknown type";
348   }
349   str = (const char *) aString -> myVal.ptr;
350   out << '\"';
351   if (strlen (str) > 512)
352     out.rdbuf() -> sputn (str, 512);
353   else
354     out << str;
355   out << '\"';
356  finis:
357   out << ends;
358   return (char *)out.str();
359 }
360 #endif
361 #endif