root/win32/xsd-3.1.0-i686/libxsd/xsd/cxx/xml/string.txx @ 111

Revision 111, 10.4 kB (checked in by mido, 16 years ago)

pridana knihovna XSD (a jeji chlebodarkyne XERCES), v ramci Win32 zprovoznen priklad tests/test_xsd_hello.cxx

Line 
1// file      : xsd/cxx/xml/string.txx
2// author    : Boris Kolpackov <boris@codesynthesis.com>
3// copyright : Copyright (c) 2005-2008 Code Synthesis Tools CC
4// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file
5
6#ifndef XSD_CXX_XML_STRING_TXX
7#define XSD_CXX_XML_STRING_TXX
8
9#ifndef XSD_USE_LCP
10namespace xsd
11{
12  namespace cxx
13  {
14    namespace xml
15    {
16      namespace bits
17      {
18        template <typename C>
19        const unsigned char char_transcoder<C>::first_byte_mask_[5] =
20        {
21          0x00, 0x00, 0xC0, 0xE0, 0xF0
22        };
23
24        template <typename C>
25        std::basic_string<C> char_transcoder<C>::
26        to (const XMLCh* s, std::size_t len)
27        {
28          const XMLCh* end (s + len);
29
30          // Find what the resulting buffer size will be.
31          //
32          std::size_t rl (0);
33          unsigned int u (0); // Four byte UCS-4 char.
34
35          bool valid (true);
36          const XMLCh* p (s);
37
38          for (; p < end; ++p)
39          {
40            XMLCh x (*p);
41
42            if (x < 0xD800 || x > 0xDBFF)
43              u = x;
44            else
45            {
46              // Make sure we have one more char and it has a valid
47              // value for the second char in a surrogate pair.
48              //
49              if (++p == end || !((*p >= 0xDC00) && (*p <= 0xDFFF)))
50              {
51                valid = false;
52                break;
53              }
54
55              u = ((x - 0xD800) << 10) + (*p - 0xDC00) + 0x10000;
56            }
57
58            if (u < 0x80)
59              rl++;
60            else if (u < 0x800)
61              rl += 2;
62            else if (u < 0x10000)
63              rl += 3;
64            else if (u < 0x110000)
65              rl += 4;
66            else
67            {
68              valid = false;
69              break;
70            }
71          }
72
73          if (!valid)
74            throw invalid_utf16_string ();
75
76          std::basic_string<C> r;
77          r.reserve (rl + 1);
78          r.resize (rl);
79          C* rs (const_cast<C*> (r.c_str ()));
80
81          std::size_t i (0);
82          unsigned int count (0);
83
84          p = s;
85
86          // Tight first loop for the common case.
87          //
88          for (; p < end && *p < 0x80; ++p)
89            rs[i++] = C (*p);
90
91          for (; p < end; ++p)
92          {
93            XMLCh x (*p);
94
95            if ((x >= 0xD800) && (x <= 0xDBFF))
96            {
97              u = ((x - 0xD800) << 10) + (*++p - 0xDC00) + 0x10000;
98            }
99            else
100              u = x;
101
102            if (u < 0x80)
103              count = 1;
104            else if (u < 0x800)
105              count = 2;
106            else if (u < 0x10000)
107              count = 3;
108            else if (u < 0x110000)
109              count = 4;
110
111            switch(count)
112            {
113            case 4:
114              {
115                rs[i + 3] = C ((u | 0x80UL) & 0xBFUL);
116                u >>= 6;
117              }
118            case 3:
119              {
120                rs[i + 2] = C ((u | 0x80UL) & 0xBFUL);
121                u >>= 6;
122              }
123            case 2:
124              {
125                rs[i + 1] = C ((u | 0x80UL) & 0xBFUL);
126                u >>= 6;
127              }
128            case 1:
129              {
130                rs[i] = C (u | first_byte_mask_[count]);
131              }
132            }
133
134            i += count;
135          }
136
137          return r;
138        }
139
140        template <typename C>
141        XMLCh* char_transcoder<C>::
142        from (const C* s, std::size_t len)
143        {
144          bool valid (true);
145          const C* end (s + len);
146
147          // Find what the resulting buffer size will be.
148          //
149          std::size_t rl (0);
150          unsigned int count (0);
151
152          for (const C* p (s); p < end; ++p)
153          {
154            unsigned char c (*p);
155
156            if (c < 0x80)
157            {
158              // Fast path.
159              //
160              rl += 1;
161              continue;
162            }
163            else if ((c >> 5) == 0x06)
164              count = 2;
165            else if ((c >> 4) == 0x0E)
166              count = 3;
167            else if ((c >> 3) == 0x1E)
168              count = 4;
169            else
170            {
171              valid = false;
172              break;
173            }
174
175            p += count - 1; // One will be added in the for loop
176
177            if (p + 1 > end)
178            {
179              valid = false;
180              break;
181            }
182
183            // BMP is represented by up to 3 code points in UTF-8.
184            //
185            rl += count > 3 ? 2 : 1;
186          }
187
188          if (!valid)
189            throw invalid_utf8_string ();
190
191          auto_array<XMLCh> r (new XMLCh[rl + 1]);
192          XMLCh* ir (r.get ());
193
194          unsigned int u (0); // Four byte UCS-4 char.
195
196          for (const C* p (s); p < end; ++p)
197          {
198            unsigned char c (*p);
199
200            if (c < 0x80)
201            {
202              // Fast path.
203              //
204              *ir++ = static_cast<XMLCh> (c);
205              continue;
206            }
207            else if ((c >> 5) == 0x06)
208            {
209              // UTF-8:   110yyyyy 10zzzzzz
210              // Unicode: 00000yyy yyzzzzzz
211              //
212              u = (c & 0x1F) << 6;
213
214              c = *++p;
215              if ((c >> 6) != 2)
216              {
217                valid = false;
218                break;
219              }
220              u |= c & 0x3F;
221            }
222            else if ((c >> 4) == 0x0E)
223            {
224              // UTF-8:   1110xxxx 10yyyyyy 10zzzzzz
225              // Unicode: xxxxyyyy yyzzzzzz
226              //
227              u = (c & 0x0F) << 6;
228
229              c = *++p;
230              if ((c >> 6) != 2)
231              {
232                valid = false;
233                break;
234              }
235              u = (u | (c & 0x3F)) << 6;
236
237              c = *++p;
238              if ((c >> 6) != 2)
239              {
240                valid = false;
241                break;
242              }
243              u |= c & 0x3F;
244            }
245            else if ((c >> 3) == 0x1E)
246            {
247              // UTF-8:   000wwwxx xxxxyyyy yyzzzzzz
248              // Unicode: 11110www 10xxxxxx 10yyyyyy 10zzzzzz
249              //
250              u = (c & 0x07) << 6;
251
252              c = *++p;
253              if ((c >> 6) != 2)
254              {
255                valid = false;
256                break;
257              }
258              u = (u | (c & 0x3F)) << 6;
259
260              c = *++p;
261              if ((c >> 6) != 2)
262              {
263                valid = false;
264                break;
265              }
266              u = (u | (c & 0x3F)) << 6;
267
268              c = *++p;
269              if ((c >> 6) != 2)
270              {
271                valid = false;
272                break;
273              }
274              u |= c & 0x3F;
275            }
276
277            if (u & 0xFFFF0000)
278            {
279              // Surrogate pair.
280              //
281              *ir++ = static_cast<XMLCh> (((u - 0x10000) >> 10) + 0xD800);
282              *ir++ = static_cast<XMLCh> ((u & 0x3FF) + 0xDC00);
283            }
284            else
285              *ir++ = static_cast<XMLCh> (u);
286          }
287
288          if (!valid)
289            throw invalid_utf8_string ();
290
291          *ir = XMLCh (0);
292
293          return r.release ();
294        }
295      }
296    }
297  }
298}
299
300#endif // XSD_USE_LCP
301#endif // XSD_CXX_XML_STRING_TXX
302
303
304#if defined(XSD_USE_WCHAR) || !defined(XSD_USE_CHAR)
305
306#ifndef XSD_CXX_XML_STRING_TXX_WCHAR
307#define XSD_CXX_XML_STRING_TXX_WCHAR
308
309namespace xsd
310{
311  namespace cxx
312  {
313    namespace xml
314    {
315      namespace bits
316      {
317        // wchar_transcoder (specialization for 2-byte wchar_t)
318        //
319        template <typename W>
320        std::basic_string<W> wchar_transcoder<W, 2>::
321        to (const XMLCh* s, std::size_t length)
322        {
323          std::basic_string<W> r;
324          r.reserve (length + 1);
325          r.resize (length);
326          W* rs (const_cast<W*> (r.c_str ()));
327
328          for (std::size_t i (0); i < length; ++s, ++i)
329          {
330            rs[i] = *s;
331          }
332
333          return r;
334        }
335
336        template <typename W>
337        XMLCh* wchar_transcoder<W, 2>::
338        from (const W* s, std::size_t length)
339        {
340          auto_array<XMLCh> r (new XMLCh[length + 1]);
341          XMLCh* ir (r.get ());
342
343          for (std::size_t i (0); i < length; ++ir, ++i)
344          {
345            *ir = static_cast<XMLCh> (s[i]);
346          }
347
348          *ir = XMLCh (0);
349
350          return r.release ();
351        }
352
353
354        // wchar_transcoder (specialization for 4-byte wchar_t)
355        //
356        template <typename W>
357        std::basic_string<W> wchar_transcoder<W, 4>::
358        to (const XMLCh* s, std::size_t length)
359        {
360          const XMLCh* end (s + length);
361
362          // Find what the resulting buffer size will be.
363          //
364          std::size_t rl (0);
365
366          for (const XMLCh* p (s); p < end; ++p)
367          {
368            rl++;
369
370            if ((*p >= 0xD800) && (*p <= 0xDBFF))
371            {
372              // Make sure we have one more char and it has a valid
373              // value for the second char in a surrogate pair.
374              //
375              if (++p == end || !((*p >= 0xDC00) && (*p <= 0xDFFF)))
376                throw invalid_utf16_string ();
377            }
378          }
379
380          std::basic_string<W> r;
381          r.reserve (rl + 1);
382          r.resize (rl);
383          W* rs (const_cast<W*> (r.c_str ()));
384
385          std::size_t i (0);
386
387          for (const XMLCh* p (s); p < end; ++p)
388          {
389            XMLCh x (*p);
390
391            if (x < 0xD800 || x > 0xDBFF)
392              rs[i++] = W (x);
393            else
394              rs[i++] = ((x - 0xD800) << 10) + (*++p - 0xDC00) + 0x10000;
395          }
396
397          return r;
398        }
399
400        template <typename W>
401        XMLCh* wchar_transcoder<W, 4>::
402        from (const W* s, std::size_t length)
403        {
404          // Find what the resulting buffer size will be.
405          //
406          std::size_t rl (0);
407
408          for (const W* p (s); p < s + length; ++p)
409          {
410            rl += (*p & 0xFFFF0000) ? 2 : 1;
411          }
412
413          auto_array<XMLCh> r (new XMLCh[rl + 1]);
414          XMLCh* ir (r.get ());
415
416          for (const W* p (s); p < s + length; ++p)
417          {
418            W w (*p);
419
420            if (w & 0xFFFF0000)
421            {
422              // Surrogate pair.
423              //
424              *ir++ = static_cast<XMLCh> (((w - 0x10000) >> 10) + 0xD800);
425              *ir++ = static_cast<XMLCh> ((w & 0x3FF) + 0xDC00);
426            }
427            else
428              *ir++ = static_cast<XMLCh> (w);
429          }
430
431          *ir = XMLCh (0);
432
433          return r.release ();
434        }
435      }
436    }
437  }
438}
439
440#endif // XSD_CXX_XML_STRING_TXX_WCHAR
441#endif // XSD_USE_WCHAR
Note: See TracBrowser for help on using the browser.