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