67b0bf657c5e9d84bd1e1ba7f62067b8bd36474d
[occt.git] / src / LDOM / LDOM_CharReference.cxx
1 // Created on: 2002-02-08
2 // Created by: Alexander GRIGORIEV
3 // Copyright (c) 2002-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 <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;
32 //const int ENTI_APOS = 5;
33
34 struct entityRef {
35   const char * name;
36   const int    length;
37   entityRef (const char * aName, const int aLen) : name(aName), length(aLen) {}
38   void operator= (const entityRef&);
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;
53   for(;;) {
54     char * aPtr = strchr (aSrcPtr, '&');
55     if (aPtr == NULL) {
56       //        End of the loop
57       aPtr = strchr (aSrcPtr, '\0');
58       if (anIncrCount == 0)
59         theLen = (Standard_Integer)(aPtr - theSrc);
60       else {
61         Standard_Integer aByteCount = (Standard_Integer)(aPtr - aSrcPtr);
62         memmove (aDstPtr, aSrcPtr, aByteCount + 1);
63         theLen = (Standard_Integer)(aDstPtr - theSrc) + aByteCount;
64       }
65       break;
66     }
67     Standard_Integer aByteCount = (Standard_Integer)(aPtr - aSrcPtr);
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;
83       anIncrCount += (Standard_Integer)(aNewPtr - aSrcPtr);
84       aSrcPtr = &aNewPtr[1];
85     }
86     else if (IS_EQUAL(aSrcPtr+1, "amp;")) {
87       aDstPtr = aSrcPtr - anIncrCount + 1;
88       aDstPtr[-1] = '&';
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("&amp;",  5),
141     entityRef("&lt;",   4),
142     entityRef("&gt;",   4),
143     entityRef("&quot;", 6),
144     entityRef("&apos;", 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
151   for(;;) {
152     const unsigned int iSrc = (unsigned int ) *(const unsigned char* )ptrSrc;
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)
164     theLen = (Standard_Integer)(endSrc - theSrc);
165   else {
166     char * ptrDest = new char [(endSrc - theSrc) + aCount * 5 + 1];
167     aDest = ptrDest;
168     for (ptrSrc = theSrc; ptrSrc < endSrc; ptrSrc++) {
169       const unsigned int iSrc = (unsigned int ) *(const unsigned char* )ptrSrc;
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     }
184     theLen = (Standard_Integer)(ptrDest - aDest);
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: [
284   NORMAL_C,     /* 05c: \       */
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 };