b311480e |
1 | // Created on: 2002-02-08 |
2 | // Created by: Alexander GRIGORIEV |
973c2be1 |
3 | // Copyright (c) 2002-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 <LDOM_CharReference.hxx> |
17 | #include <stdio.h> |
18 | #include <stdlib.h> |
19 | #include <string.h> |
20 | |
21 | // Uncomment this line if you want that your XML files contain codes 0xc0-0xff |
22 | // as defined in Latin-1 code set. Otherwise these codes are written |
23 | // numerically as &#x..; |
24 | //#define LDOM_ALLOW_LATIN_1 |
25 | |
26 | const int NORMAL_C = 0; |
27 | const int CHAR_REF = -1; |
28 | const int ENTI_AMP = 1; |
29 | const int ENTI_LT = 2; |
30 | const int ENTI_GT = 3; |
31 | const int ENTI_QUOT = 4; |
f24125b9 |
32 | //const int ENTI_APOS = 5; |
7fd59977 |
33 | |
34 | struct entityRef { |
35 | const char * name; |
36 | const int length; |
37 | entityRef (const char * aName, const int aLen) : name(aName), length(aLen) {} |
d390b166 |
38 | void operator= (const entityRef&); |
7fd59977 |
39 | }; |
40 | |
41 | //======================================================================= |
42 | //function : Decode |
43 | //purpose : Convertes entity and character references on input |
44 | // Always returns the same string (shortened after replacements) |
45 | //======================================================================= |
46 | |
47 | char * LDOM_CharReference::Decode (char * theSrc, Standard_Integer& theLen) |
48 | { |
49 | #define IS_EQUAL(_ptr,_string) (!memcmp(_ptr, _string, sizeof(_string)-1)) |
50 | |
51 | char * aSrcPtr = theSrc, * aDstPtr = theSrc; |
52 | Standard_Integer anIncrCount = 0; |
302f96fb |
53 | for(;;) { |
7fd59977 |
54 | char * aPtr = strchr (aSrcPtr, '&'); |
55 | if (aPtr == NULL) { |
56 | // End of the loop |
57 | aPtr = strchr (aSrcPtr, '\0'); |
58 | if (anIncrCount == 0) |
7dc9e047 |
59 | theLen = (Standard_Integer)(aPtr - theSrc); |
7fd59977 |
60 | else { |
7dc9e047 |
61 | Standard_Integer aByteCount = (Standard_Integer)(aPtr - aSrcPtr); |
7fd59977 |
62 | memmove (aDstPtr, aSrcPtr, aByteCount + 1); |
7dc9e047 |
63 | theLen = (Standard_Integer)(aDstPtr - theSrc) + aByteCount; |
7fd59977 |
64 | } |
65 | break; |
66 | } |
7dc9e047 |
67 | Standard_Integer aByteCount = (Standard_Integer)(aPtr - aSrcPtr); |
7fd59977 |
68 | if (aByteCount > 0 && aDstPtr != aSrcPtr) |
69 | memmove (aDstPtr, aSrcPtr, aByteCount); |
70 | aSrcPtr = aPtr; |
71 | if (aSrcPtr[1] == '#') { |
72 | unsigned long aChar; |
73 | char * aNewPtr; |
74 | aDstPtr = aSrcPtr - anIncrCount + 1; |
75 | if (aSrcPtr[2] == 'x') |
76 | aChar = strtoul (&aSrcPtr[3], &aNewPtr, 16); // hex encoding |
77 | else |
78 | aChar = strtoul (&aSrcPtr[2], &aNewPtr, 10); // decimal encoding |
79 | if (aNewPtr[0] != ';' || aChar == 0 || aChar > 255UL) |
80 | // Error reading an XML string |
81 | return NULL; |
82 | aDstPtr[-1] = (char) aChar; |
7dc9e047 |
83 | anIncrCount += (Standard_Integer)(aNewPtr - aSrcPtr); |
7fd59977 |
84 | aSrcPtr = &aNewPtr[1]; |
85 | } |
86 | else if (IS_EQUAL(aSrcPtr+1, "amp;")) { |
87 | aDstPtr = aSrcPtr - anIncrCount + 1; |
80cd454f |
88 | aDstPtr[-1] = '&'; |
7fd59977 |
89 | anIncrCount += 4; |
90 | aSrcPtr += 5; |
91 | } |
92 | else if (IS_EQUAL(aSrcPtr+1, "lt;")) { |
93 | aDstPtr = aSrcPtr - anIncrCount + 1; |
94 | aDstPtr[-1] = '<'; |
95 | anIncrCount += 3; |
96 | aSrcPtr += 4; |
97 | } |
98 | else if (IS_EQUAL(aSrcPtr+1, "gt;")) { |
99 | aDstPtr = aSrcPtr - anIncrCount + 1; |
100 | aDstPtr[-1] = '>'; |
101 | anIncrCount += 3; |
102 | aSrcPtr += 4; |
103 | } |
104 | else if (IS_EQUAL(aSrcPtr+1, "quot;")) { |
105 | aDstPtr = aSrcPtr - anIncrCount + 1; |
106 | aDstPtr[-1] = '\"'; |
107 | anIncrCount += 5; |
108 | aSrcPtr += 6; |
109 | } |
110 | else if (IS_EQUAL(aSrcPtr+1, "apos;")) { |
111 | aDstPtr = aSrcPtr - anIncrCount + 1; |
112 | aDstPtr[-1] = '\''; |
113 | anIncrCount += 5; |
114 | aSrcPtr += 6; |
115 | } |
116 | else { |
117 | aDstPtr = aSrcPtr - anIncrCount; |
118 | * aDstPtr++ = * aSrcPtr++; |
119 | continue; |
120 | } |
121 | } |
122 | return theSrc; |
123 | } |
124 | |
125 | //======================================================================= |
126 | //function : Encode |
127 | //purpose : This method takes the input string theSrc and returns: |
128 | // - the pointer equal to theSrc if there are no replacements, or |
129 | // - the pointer to a newly allocated string with replacements |
130 | // The output parameter theLen is assigned to the length of |
131 | // the returned string (whatever the case) |
132 | //======================================================================= |
133 | |
134 | char * LDOM_CharReference::Encode (const char* theSrc, Standard_Integer& theLen, |
135 | const Standard_Boolean isAttribute) |
136 | { |
137 | // Initialising the constants |
138 | static const struct entityRef entity_ref[6] = { |
139 | entityRef(NULL, 0), |
140 | entityRef("&", 5), |
141 | entityRef("<", 4), |
142 | entityRef(">", 4), |
143 | entityRef(""", 6), |
144 | entityRef("'", 6) |
145 | }; |
146 | |
147 | const char * endSrc, * ptrSrc = theSrc; |
148 | char * aDest = (char *) theSrc; |
149 | Standard_Integer aCount = 0; |
150 | // Analyse if there is a non-standard character in the string |
302f96fb |
151 | for(;;) { |
a738b534 |
152 | const unsigned int iSrc = (unsigned int ) *(const unsigned char* )ptrSrc; |
7fd59977 |
153 | if (iSrc == 0) { |
154 | endSrc = ptrSrc; |
155 | break; |
156 | } |
157 | if (myTab[iSrc] != NORMAL_C) |
158 | if (isAttribute || myTab[iSrc] != ENTI_QUOT) |
159 | aCount++; |
160 | ptrSrc++; |
161 | } |
162 | // If there are such, copy the string with replacements |
163 | if (!aCount) |
7dc9e047 |
164 | theLen = (Standard_Integer)(endSrc - theSrc); |
7fd59977 |
165 | else { |
166 | char * ptrDest = new char [(endSrc - theSrc) + aCount * 5 + 1]; |
167 | aDest = ptrDest; |
168 | for (ptrSrc = theSrc; ptrSrc < endSrc; ptrSrc++) { |
a738b534 |
169 | const unsigned int iSrc = (unsigned int ) *(const unsigned char* )ptrSrc; |
7fd59977 |
170 | const int aCode = myTab[iSrc]; |
171 | if (aCode == NORMAL_C) // normal (regular) character |
172 | * ptrDest++ = * ptrSrc; |
173 | else if (aCode == CHAR_REF) { // character reference |
174 | sprintf (ptrDest, "&#x%02x;", iSrc); |
175 | ptrDest += 6; |
176 | } else // predefined entity reference |
177 | if (isAttribute == Standard_False && aCode == ENTI_QUOT) |
178 | * ptrDest++ = * ptrSrc; |
179 | else { |
180 | memcpy (ptrDest, entity_ref[aCode].name, entity_ref[aCode].length+1); |
181 | ptrDest += entity_ref[aCode].length; |
182 | } |
183 | } |
7dc9e047 |
184 | theLen = (Standard_Integer)(ptrDest - aDest); |
7fd59977 |
185 | * ptrDest = '\0'; |
186 | } |
187 | return aDest; |
188 | } |
189 | |
190 | int LDOM_CharReference::myTab [256] = { |
191 | NORMAL_C, // 000 |
192 | CHAR_REF, // 001 |
193 | CHAR_REF, // 002 |
194 | CHAR_REF, // 003 |
195 | CHAR_REF, // 004 |
196 | CHAR_REF, // 005 |
197 | CHAR_REF, // 006 |
198 | CHAR_REF, // 007 |
199 | CHAR_REF, // 008 |
200 | NORMAL_C, // 009 TAB |
201 | NORMAL_C, // 00a LF |
202 | CHAR_REF, // 00b |
203 | CHAR_REF, // 00c |
204 | NORMAL_C, // 00d CR |
205 | CHAR_REF, // 00e |
206 | CHAR_REF, // 00f |
207 | CHAR_REF, // 010 |
208 | CHAR_REF, // 011 |
209 | CHAR_REF, // 012 |
210 | CHAR_REF, // 013 |
211 | CHAR_REF, // 014 |
212 | CHAR_REF, // 015 |
213 | CHAR_REF, // 016 |
214 | CHAR_REF, // 017 |
215 | CHAR_REF, // 018 |
216 | CHAR_REF, // 019 |
217 | CHAR_REF, // 01a |
218 | CHAR_REF, // 01b |
219 | CHAR_REF, // 01c |
220 | CHAR_REF, // 01d |
221 | CHAR_REF, // 01e |
222 | CHAR_REF, // 01f |
223 | NORMAL_C, // 020: |
224 | NORMAL_C, // 021: ! |
225 | ENTI_QUOT, // 022: " |
226 | NORMAL_C, // 023: # |
227 | NORMAL_C, // 024: $ |
228 | NORMAL_C, // 025: % |
229 | ENTI_AMP, // 026: & |
230 | // ENTI_APOS, // 027: ' Here we do never use apostrophe as delimiter |
231 | NORMAL_C, // 027: ' |
232 | NORMAL_C, // 028: ( |
233 | NORMAL_C, // 029: ) |
234 | NORMAL_C, // 02a: * |
235 | NORMAL_C, // 02b: + |
236 | NORMAL_C, // 02c: , |
237 | NORMAL_C, // 02d: - |
238 | NORMAL_C, // 02e: . |
239 | NORMAL_C, // 02f: / |
240 | NORMAL_C, // 030: 0 |
241 | NORMAL_C, // 031: 1 |
242 | NORMAL_C, // 032: 2 |
243 | NORMAL_C, // 033: 3 |
244 | NORMAL_C, // 034: 4 |
245 | NORMAL_C, // 035: 5 |
246 | NORMAL_C, // 036: 6 |
247 | NORMAL_C, // 037: 7 |
248 | NORMAL_C, // 038: 8 |
249 | NORMAL_C, // 039: 9 |
250 | NORMAL_C, // 03a: : |
251 | NORMAL_C, // 03b: ; |
252 | ENTI_LT, // 03c: < |
253 | NORMAL_C, // 03d: = |
254 | ENTI_GT, // 03e: > |
255 | NORMAL_C, // 03f: ? |
256 | NORMAL_C, // 040: @ |
257 | NORMAL_C, // 041: A |
258 | NORMAL_C, // 042: B |
259 | NORMAL_C, // 043: C |
260 | NORMAL_C, // 044: D |
261 | NORMAL_C, // 045: E |
262 | NORMAL_C, // 046: F |
263 | NORMAL_C, // 047: G |
264 | NORMAL_C, // 048: H |
265 | NORMAL_C, // 049: I |
266 | NORMAL_C, // 04a: J |
267 | NORMAL_C, // 04b: K |
268 | NORMAL_C, // 04c: L |
269 | NORMAL_C, // 04d: M |
270 | NORMAL_C, // 04e: N |
271 | NORMAL_C, // 04f: O |
272 | NORMAL_C, // 050: P |
273 | NORMAL_C, // 051: Q |
274 | NORMAL_C, // 052: R |
275 | NORMAL_C, // 053: S |
276 | NORMAL_C, // 054: T |
277 | NORMAL_C, // 055: U |
278 | NORMAL_C, // 056: V |
279 | NORMAL_C, // 057: W |
280 | NORMAL_C, // 058: X |
281 | NORMAL_C, // 059: Y |
282 | NORMAL_C, // 05a: Z |
283 | NORMAL_C, // 05b: [ |
012d92b6 |
284 | NORMAL_C, /* 05c: \ */ |
7fd59977 |
285 | NORMAL_C, // 05d: ] |
286 | NORMAL_C, // 05e: ^ |
287 | NORMAL_C, // 05f: _ |
288 | NORMAL_C, // 060: ` |
289 | NORMAL_C, // 061: a |
290 | NORMAL_C, // 062: b |
291 | NORMAL_C, // 063: c |
292 | NORMAL_C, // 064: d |
293 | NORMAL_C, // 065: e |
294 | NORMAL_C, // 066: f |
295 | NORMAL_C, // 067: g |
296 | NORMAL_C, // 068: h |
297 | NORMAL_C, // 069: i |
298 | NORMAL_C, // 06a: j |
299 | NORMAL_C, // 06b: k |
300 | NORMAL_C, // 06c: l |
301 | NORMAL_C, // 06d: m |
302 | NORMAL_C, // 06e: n |
303 | NORMAL_C, // 06f: o |
304 | NORMAL_C, // 070: p |
305 | NORMAL_C, // 071: q |
306 | NORMAL_C, // 072: r |
307 | NORMAL_C, // 073: s |
308 | NORMAL_C, // 074: t |
309 | NORMAL_C, // 075: u |
310 | NORMAL_C, // 076: v |
311 | NORMAL_C, // 077: w |
312 | NORMAL_C, // 078: x |
313 | NORMAL_C, // 079: y |
314 | NORMAL_C, // 07a: z |
315 | NORMAL_C, // 07b: { |
316 | NORMAL_C, // 07c: | |
317 | NORMAL_C, // 07d: } |
318 | NORMAL_C, // 07e: ~ |
319 | NORMAL_C, // 07f: \7f |
320 | CHAR_REF, // 080 |
321 | CHAR_REF, // 081 |
322 | CHAR_REF, // 082 |
323 | CHAR_REF, // 083 |
324 | CHAR_REF, // 084 |
325 | CHAR_REF, // 085 |
326 | CHAR_REF, // 086 |
327 | CHAR_REF, // 087 |
328 | CHAR_REF, // 088 |
329 | CHAR_REF, // 089 |
330 | CHAR_REF, // 08a |
331 | CHAR_REF, // 08b |
332 | CHAR_REF, // 08c |
333 | CHAR_REF, // 08d |
334 | CHAR_REF, // 08e |
335 | CHAR_REF, // 08f |
336 | CHAR_REF, // 090 |
337 | CHAR_REF, // 091 |
338 | CHAR_REF, // 092 |
339 | CHAR_REF, // 093 |
340 | CHAR_REF, // 094 |
341 | CHAR_REF, // 095 |
342 | CHAR_REF, // 096 |
343 | CHAR_REF, // 097 |
344 | CHAR_REF, // 098 |
345 | CHAR_REF, // 099 |
346 | CHAR_REF, // 09a |
347 | CHAR_REF, // 09b |
348 | CHAR_REF, // 09c |
349 | CHAR_REF, // 09d |
350 | CHAR_REF, // 09e |
351 | CHAR_REF, // 09f |
352 | CHAR_REF, // 0a0 |
353 | CHAR_REF, // 0a1 |
354 | CHAR_REF, // 0a2 |
355 | CHAR_REF, // 0a3 |
356 | CHAR_REF, // 0a4 |
357 | CHAR_REF, // 0a5 |
358 | CHAR_REF, // 0a6 |
359 | CHAR_REF, // 0a7 |
360 | CHAR_REF, // 0a8 |
361 | CHAR_REF, // 0a9 |
362 | CHAR_REF, // 0aa |
363 | CHAR_REF, // 0ab |
364 | CHAR_REF, // 0ac |
365 | CHAR_REF, // 0ad |
366 | CHAR_REF, // 0ae |
367 | CHAR_REF, // 0af |
368 | CHAR_REF, // 0b0 |
369 | CHAR_REF, // 0b1 |
370 | CHAR_REF, // 0b2 |
371 | CHAR_REF, // 0b3 |
372 | CHAR_REF, // 0b4 |
373 | CHAR_REF, // 0b5 |
374 | CHAR_REF, // 0b6 |
375 | CHAR_REF, // 0b7 |
376 | CHAR_REF, // 0b8 |
377 | CHAR_REF, // 0b9 |
378 | CHAR_REF, // 0ba |
379 | CHAR_REF, // 0bb |
380 | CHAR_REF, // 0bc |
381 | CHAR_REF, // 0bd |
382 | CHAR_REF, // 0be |
383 | CHAR_REF, // 0bf |
384 | #ifdef LDOM_ALLOW_LATIN_1 |
385 | NORMAL_C, // 0c0 |
386 | NORMAL_C, // 0c1 |
387 | NORMAL_C, // 0c2 |
388 | NORMAL_C, // 0c3 |
389 | NORMAL_C, // 0c4 |
390 | NORMAL_C, // 0c5 |
391 | NORMAL_C, // 0c6 |
392 | NORMAL_C, // 0c7 |
393 | NORMAL_C, // 0c8 |
394 | NORMAL_C, // 0c9 |
395 | NORMAL_C, // 0ca |
396 | NORMAL_C, // 0cb |
397 | NORMAL_C, // 0cc |
398 | NORMAL_C, // 0cd |
399 | NORMAL_C, // 0ce |
400 | NORMAL_C, // 0cf |
401 | NORMAL_C, // 0d0 |
402 | NORMAL_C, // 0d1 |
403 | NORMAL_C, // 0d2 |
404 | NORMAL_C, // 0d3 |
405 | NORMAL_C, // 0d4 |
406 | NORMAL_C, // 0d5 |
407 | NORMAL_C, // 0d6 |
408 | // CHAR_REF, // 0d7 |
409 | NORMAL_C, // 0d7 |
410 | NORMAL_C, // 0d8 |
411 | NORMAL_C, // 0d9 |
412 | NORMAL_C, // 0da |
413 | NORMAL_C, // 0db |
414 | NORMAL_C, // 0dc |
415 | NORMAL_C, // 0dd |
416 | NORMAL_C, // 0de |
417 | NORMAL_C, // 0df |
418 | NORMAL_C, // 0e0 |
419 | NORMAL_C, // 0e1 |
420 | NORMAL_C, // 0e2 |
421 | NORMAL_C, // 0e3 |
422 | NORMAL_C, // 0e4 |
423 | NORMAL_C, // 0e5 |
424 | NORMAL_C, // 0e6 |
425 | NORMAL_C, // 0e7 |
426 | NORMAL_C, // 0e8 |
427 | NORMAL_C, // 0e9 |
428 | NORMAL_C, // 0ea |
429 | NORMAL_C, // 0eb |
430 | NORMAL_C, // 0ec |
431 | NORMAL_C, // 0ed |
432 | NORMAL_C, // 0ee |
433 | NORMAL_C, // 0ef |
434 | NORMAL_C, // 0f0 |
435 | NORMAL_C, // 0f1 |
436 | NORMAL_C, // 0f2 |
437 | NORMAL_C, // 0f3 |
438 | NORMAL_C, // 0f4 |
439 | NORMAL_C, // 0f5 |
440 | NORMAL_C, // 0f6 |
441 | // CHAR_REF, // 0f7 |
442 | NORMAL_C, // 0f7 |
443 | NORMAL_C, // 0f8 |
444 | NORMAL_C, // 0f9 |
445 | NORMAL_C, // 0fa |
446 | NORMAL_C, // 0fb |
447 | NORMAL_C, // 0fc |
448 | NORMAL_C, // 0fd |
449 | NORMAL_C, // 0fe |
450 | NORMAL_C // 0ff |
451 | #else |
452 | CHAR_REF, // 0c0 |
453 | CHAR_REF, // 0c1 |
454 | CHAR_REF, // 0c2 |
455 | CHAR_REF, // 0c3 |
456 | CHAR_REF, // 0c4 |
457 | CHAR_REF, // 0c5 |
458 | CHAR_REF, // 0c6 |
459 | CHAR_REF, // 0c7 |
460 | CHAR_REF, // 0c8 |
461 | CHAR_REF, // 0c9 |
462 | CHAR_REF, // 0ca |
463 | CHAR_REF, // 0cb |
464 | CHAR_REF, // 0cc |
465 | CHAR_REF, // 0cd |
466 | CHAR_REF, // 0ce |
467 | CHAR_REF, // 0cf |
468 | CHAR_REF, // 0d0 |
469 | CHAR_REF, // 0d1 |
470 | CHAR_REF, // 0d2 |
471 | CHAR_REF, // 0d3 |
472 | CHAR_REF, // 0d4 |
473 | CHAR_REF, // 0d5 |
474 | CHAR_REF, // 0d6 |
475 | CHAR_REF, // 0d7 |
476 | CHAR_REF, // 0d8 |
477 | CHAR_REF, // 0d9 |
478 | CHAR_REF, // 0da |
479 | CHAR_REF, // 0db |
480 | CHAR_REF, // 0dc |
481 | CHAR_REF, // 0dd |
482 | CHAR_REF, // 0de |
483 | CHAR_REF, // 0df |
484 | CHAR_REF, // 0e0 |
485 | CHAR_REF, // 0e1 |
486 | CHAR_REF, // 0e2 |
487 | CHAR_REF, // 0e3 |
488 | CHAR_REF, // 0e4 |
489 | CHAR_REF, // 0e5 |
490 | CHAR_REF, // 0e6 |
491 | CHAR_REF, // 0e7 |
492 | CHAR_REF, // 0e8 |
493 | CHAR_REF, // 0e9 |
494 | CHAR_REF, // 0ea |
495 | CHAR_REF, // 0eb |
496 | CHAR_REF, // 0ec |
497 | CHAR_REF, // 0ed |
498 | CHAR_REF, // 0ee |
499 | CHAR_REF, // 0ef |
500 | CHAR_REF, // 0f0 |
501 | CHAR_REF, // 0f1 |
502 | CHAR_REF, // 0f2 |
503 | CHAR_REF, // 0f3 |
504 | CHAR_REF, // 0f4 |
505 | CHAR_REF, // 0f5 |
506 | CHAR_REF, // 0f6 |
507 | CHAR_REF, // 0f7 |
508 | CHAR_REF, // 0f8 |
509 | CHAR_REF, // 0f9 |
510 | CHAR_REF, // 0fa |
511 | CHAR_REF, // 0fb |
512 | CHAR_REF, // 0fc |
513 | CHAR_REF, // 0fd |
514 | CHAR_REF, // 0fe |
515 | CHAR_REF // 0ff |
516 | #endif // LDOM_ALLOW_LATIN_1 |
517 | }; |