0029151: GCC 7.1 warnings "this statement may fall through" [-Wimplicit-fallthrough=]
[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     Standard_FALLTHROUGH
96   case LDOM_AsciiDoc:
97   case LDOM_AsciiDocClear:
98   case LDOM_AsciiHashed:
99     myVal.ptr = anOther.myVal.ptr;
100     break;
101   case LDOM_Integer:
102     myVal.i = anOther.myVal.i;
103   default: ;
104   }
105 }
106
107 //=======================================================================
108 //function : ~LDOMString()
109 //purpose  : Destructor
110 //=======================================================================
111
112 LDOMBasicString::~LDOMBasicString ()
113 {
114   if (myType == LDOM_AsciiFree) {
115     if (myVal.ptr)
116       delete [] (char *) myVal.ptr;
117   }
118 }
119
120 //=======================================================================
121 //function : operator =
122 //purpose  : Assignment to NULL
123 //=======================================================================
124
125 LDOMBasicString& LDOMBasicString::operator = (const LDOM_NullPtr *)
126 {
127   if (myType == LDOM_AsciiFree && myVal.ptr)
128     delete [] (char *) myVal.ptr;
129   myType    = LDOM_NULL;
130   myVal.ptr = NULL;
131   return * this;
132 }
133
134 //=======================================================================
135 //function : operator =
136 //purpose  : Assignment
137 //=======================================================================
138
139 LDOMBasicString& LDOMBasicString::operator = (const LDOMBasicString& anOther)
140 {
141   if (myType == LDOM_AsciiFree && myVal.ptr)
142     delete [] (char *) myVal.ptr;
143   myType    = anOther.Type();
144   switch (myType) {
145   case LDOM_AsciiFree:
146     if (anOther.myVal.ptr) {
147       Standard_Size aLen = strlen ((const char *)anOther.myVal.ptr) + 1;
148       myVal.ptr = new char [aLen];
149       memcpy (myVal.ptr, anOther.myVal.ptr, aLen);
150       break;
151     }
152     Standard_FALLTHROUGH
153   case LDOM_AsciiDoc:
154   case LDOM_AsciiDocClear:
155   case LDOM_AsciiHashed:
156     myVal.ptr = anOther.myVal.ptr;
157     break;
158   case LDOM_Integer:
159     myVal.i = anOther.myVal.i;
160   default: ;
161   }
162   return * this;
163 }
164
165 //=======================================================================
166 //function : equals
167 //purpose  : Compare two strings by content
168 //=======================================================================
169
170 Standard_Boolean LDOMBasicString::equals (const LDOMBasicString& anOther) const
171 {
172   Standard_Boolean aResult = Standard_False;
173   switch (myType)
174   {
175   case LDOM_NULL:
176     return (anOther == NULL);
177   case LDOM_Integer:
178     switch (anOther.Type())
179     {
180     case LDOM_Integer:
181       return (myVal.i == anOther.myVal.i);
182     case LDOM_AsciiFree:
183     case LDOM_AsciiDoc:
184     case LDOM_AsciiDocClear:
185     case LDOM_AsciiHashed:
186       {
187         long aLongOther = strtol ((const char *) anOther.myVal.ptr, NULL, 10);
188         return (errno == 0 && aLongOther == long(myVal.i));
189       }
190     case LDOM_NULL:
191     default:
192       ;
193     }
194     break;
195   default:
196     switch (anOther.Type())
197     {
198     case LDOM_Integer:
199       {
200         long aLong = strtol ((const char *) myVal.ptr, NULL, 10);
201         return (errno == 0 && aLong == long(anOther.myVal.i));
202       }
203     case LDOM_AsciiFree:
204     case LDOM_AsciiDoc:
205     case LDOM_AsciiDocClear:
206     case LDOM_AsciiHashed:
207       return (strcmp ((const char *) myVal.ptr,
208                       (const char *) anOther.myVal.ptr) == 0);
209     case LDOM_NULL:
210     default:
211       ;
212     }
213   }
214   return aResult;
215 }
216
217 //=======================================================================
218 //function : operator TCollection_AsciiString
219 //purpose  : 
220 //=======================================================================
221
222 LDOMBasicString::operator TCollection_AsciiString () const
223 {
224   switch (myType) {
225   case LDOM_Integer:
226     return TCollection_AsciiString (myVal.i);
227   case LDOM_AsciiFree:
228   case LDOM_AsciiDoc:
229   case LDOM_AsciiDocClear:
230   case LDOM_AsciiHashed:
231     return TCollection_AsciiString (Standard_CString(myVal.ptr));
232   default: ;
233   }
234   return TCollection_AsciiString ();
235 }
236
237 //=======================================================================
238 //function : operator TCollection_ExtendedString
239 //purpose  : 
240 //=======================================================================
241
242 LDOMBasicString::operator TCollection_ExtendedString () const
243 {
244   switch (myType) {
245   case LDOM_Integer:
246     return TCollection_ExtendedString (myVal.i);
247   case LDOM_AsciiFree:
248   case LDOM_AsciiDoc:
249   case LDOM_AsciiDocClear:
250   case LDOM_AsciiHashed:
251   {
252     char buf[6] = {'\0','\0','\0','\0','\0','\0'};
253     const long aUnicodeHeader = 0xfeff;
254     Standard_CString ptr = Standard_CString (myVal.ptr);
255     errno = 0;
256     // Check if ptr is ascii string
257     if (ptr[0] != '#' || ptr[1] != '#')
258       return TCollection_ExtendedString (ptr);
259     buf[0] = ptr[2];
260     buf[1] = ptr[3];
261     buf[2] = ptr[4];
262     buf[3] = ptr[5];
263     if (strtol (&buf[0], NULL, 16) != aUnicodeHeader)
264       return TCollection_ExtendedString (ptr);
265
266     // convert Unicode to Extended String
267     ptr += 2;
268     Standard_Size aLength = (strlen(ptr) / 4), j = 0;
269     Standard_ExtCharacter * aResult = new Standard_ExtCharacter[aLength--];
270     while (aLength--) {
271       ptr += 4;
272       buf[0] = ptr[0];
273       buf[1] = ptr[1];
274       buf[2] = ptr[2];
275       buf[3] = ptr[3];
276       aResult[j++] = Standard_ExtCharacter (strtol (&buf[0], NULL, 16));
277       if (errno) {
278         delete [] aResult;
279         return TCollection_ExtendedString();
280       }
281     }
282     aResult[j] = 0;
283     TCollection_ExtendedString aResultStr (aResult);
284     delete [] aResult;
285     return aResultStr;
286   }
287   default: ;
288   }
289   return TCollection_ExtendedString();
290 }
291
292 //=======================================================================
293 //function : GetInteger
294 //purpose  : Conversion to Integer
295 //=======================================================================
296
297 Standard_Boolean LDOMBasicString::GetInteger (Standard_Integer& aResult) const
298 {
299   switch (myType) {
300   case LDOM_Integer:
301     aResult = myVal.i;
302     break;
303   case LDOM_AsciiFree:
304   case LDOM_AsciiDoc:
305   case LDOM_AsciiDocClear:
306   case LDOM_AsciiHashed:
307     {
308       char * ptr;
309       long aValue = strtol ((const char *)myVal.ptr, &ptr, 10);
310       if (ptr == myVal.ptr || errno == ERANGE || errno == EINVAL)
311         return Standard_False;
312       aResult = Standard_Integer (aValue);
313       break;
314     }
315   default:
316     return Standard_False;
317   }
318   return Standard_True;
319 }
320
321 #ifdef OCCT_DEBUG
322 #ifndef _MSC_VER
323 //=======================================================================
324 // Debug Function for DBX: use "print -p <Variable> or pp <Variable>"
325 //=======================================================================
326 #include <LDOM_OSStream.hxx>
327 #define FLITERAL 0x10
328 char * db_pretty_print (const LDOMBasicString * aString, int fl, char *)
329 {
330   LDOM_OSStream out (128);
331   const char * str;
332   switch (aString -> myType) {
333   case LDOMBasicString::LDOM_Integer:
334     if ((fl & FLITERAL) == 0)  out << "LDOM_Integer: ";
335     out << '\"' << aString -> myVal.i << '\"'; goto finis;
336   case LDOMBasicString::LDOM_AsciiFree:
337     if ((fl & FLITERAL) == 0)  out << "LDOM_AsciiFree: ";
338     break;
339   case LDOMBasicString::LDOM_AsciiDoc:
340     if ((fl & FLITERAL) == 0)  out << "LDOM_AsciiDoc: ";
341     break;
342   case LDOMBasicString::LDOM_AsciiDocClear:
343     if ((fl & FLITERAL) == 0)  out << "LDOM_AsciiDocClear: ";
344     break;
345   case LDOMBasicString::LDOM_AsciiHashed:
346     if ((fl & FLITERAL) == 0)  out << "LDOM_AsciiHashed: ";
347     break;
348   default:
349     out << "Unknown type";
350   }
351   str = (const char *) aString -> myVal.ptr;
352   out << '\"';
353   if (strlen (str) > 512)
354     out.rdbuf() -> sputn (str, 512);
355   else
356     out << str;
357   out << '\"';
358  finis:
359   out << ends;
360   return (char *)out.str();
361 }
362 #endif
363 #endif