0031340: LDOM fails to read XML file starting with BOM
[occt.git] / src / LDOM / LDOMBasicString.cxx
CommitLineData
b311480e 1// Created on: 2001-06-26
2// Created by: Alexander GRIGORIEV
973c2be1 3// Copyright (c) 2001-2014 OPEN CASCADE SAS
b311480e 4//
973c2be1 5// This file is part of Open CASCADE Technology software library.
b311480e 6//
d5f74e42 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
973c2be1 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.
b311480e 12//
973c2be1 13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
7fd59977 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
27LDOMBasicString::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;
60be1f9b 34 Standard_Size aLen = strlen (aValue) + 1;
7fd59977 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
45LDOMBasicString::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;
60be1f9b 53 Standard_Integer aLen = (Standard_Integer) strlen (aValue) + 1;
7fd59977 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
64LDOMBasicString::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
84LDOMBasicString::LDOMBasicString (const LDOMBasicString& anOther)
85 : myType (anOther.Type())
86{
87 switch (myType) {
88 case LDOM_AsciiFree:
89 if (anOther.myVal.ptr) {
60be1f9b 90 Standard_Size aLen = strlen ((const char *)anOther.myVal.ptr) + 1;
7fd59977 91 myVal.ptr = new char [aLen];
92 memcpy (myVal.ptr, anOther.myVal.ptr, aLen);
93 break;
94 }
b1811c1d 95 Standard_FALLTHROUGH
7fd59977 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
112LDOMBasicString::~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
125LDOMBasicString& 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
139LDOMBasicString& 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) {
60be1f9b 147 Standard_Size aLen = strlen ((const char *)anOther.myVal.ptr) + 1;
7fd59977 148 myVal.ptr = new char [aLen];
149 memcpy (myVal.ptr, anOther.myVal.ptr, aLen);
150 break;
151 }
b1811c1d 152 Standard_FALLTHROUGH
7fd59977 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
170Standard_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
222LDOMBasicString::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
242LDOMBasicString::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;
60be1f9b 268 Standard_Size aLength = (strlen(ptr) / 4), j = 0;
7fd59977 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
297Standard_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
0797d9d3 321#ifdef OCCT_DEBUG
57c28b61 322#ifndef _MSC_VER
7fd59977 323//=======================================================================
324// Debug Function for DBX: use "print -p <Variable> or pp <Variable>"
325//=======================================================================
326#include <LDOM_OSStream.hxx>
327#define FLITERAL 0x10
328char * 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:
04232180 359 out << std::ends;
7fd59977 360 return (char *)out.str();
361}
362#endif
363#endif