1 martin 1.4 //%LICENSE////////////////////////////////////////////////////////////////
|
2 martin 1.5 //
|
3 martin 1.4 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
|
9 martin 1.5 //
|
10 martin 1.4 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
|
16 martin 1.5 //
|
17 martin 1.4 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
|
19 martin 1.5 //
|
20 martin 1.4 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
21 martin 1.5 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
22 martin 1.4 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 martin 1.5 //
|
28 martin 1.4 //////////////////////////////////////////////////////////////////////////
|
29 kumpf 1.1 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include <cstdlib>
33 #include <cstdio>
34
35 #include <Pegasus/Common/Config.h>
36 #include "XmlGenerator.h"
37 #include "Constants.h"
38 #include "StrLit.h"
39 #include "CommonUTF.h"
40 #include "StringConversion.h"
41 #include "LanguageParser.h"
42 #include "AutoPtr.h"
43
44 PEGASUS_NAMESPACE_BEGIN
45
46 ////////////////////////////////////////////////////////////////////////////////
47 //
48 // SpecialChar and table.
49 //
50 kumpf 1.1 ////////////////////////////////////////////////////////////////////////////////
51
52 // Note: we cannot use StrLit here since it has a constructor (forbids
53 // structure initialization).
54
55 struct SpecialChar
56 {
57 const char* str;
58 Uint32 size;
59 };
60
61 // Defines encodings of special characters. Just use a 7-bit ASCII character
62 // as an index into this array to retrieve its string encoding and encoding
63 // length in bytes.
64 static const SpecialChar _specialChars[] =
65 {
66 {STRLIT_ARGS("�")},
67 {STRLIT_ARGS("")},
68 {STRLIT_ARGS("")},
69 {STRLIT_ARGS("")},
70 {STRLIT_ARGS("")},
71 kumpf 1.1 {STRLIT_ARGS("")},
72 {STRLIT_ARGS("")},
73 {STRLIT_ARGS("")},
74 {STRLIT_ARGS("")},
75 {STRLIT_ARGS("	")},
76 {STRLIT_ARGS(" ")},
77 {STRLIT_ARGS("")},
78 {STRLIT_ARGS("")},
79 {STRLIT_ARGS(" ")},
80 {STRLIT_ARGS("")},
81 {STRLIT_ARGS("")},
82 {STRLIT_ARGS("")},
83 {STRLIT_ARGS("")},
84 {STRLIT_ARGS("")},
85 {STRLIT_ARGS("")},
86 {STRLIT_ARGS("")},
87 {STRLIT_ARGS("")},
88 {STRLIT_ARGS("")},
89 {STRLIT_ARGS("")},
90 {STRLIT_ARGS("")},
91 {STRLIT_ARGS("")},
92 kumpf 1.1 {STRLIT_ARGS("")},
93 {STRLIT_ARGS("")},
94 {STRLIT_ARGS("")},
95 {STRLIT_ARGS("")},
96 {STRLIT_ARGS("")},
97 {STRLIT_ARGS("")},
98 {STRLIT_ARGS(" ")},
99 {STRLIT_ARGS("!")},
100 {STRLIT_ARGS(""")},
101 {STRLIT_ARGS("#")},
102 {STRLIT_ARGS("$")},
103 {STRLIT_ARGS("%")},
104 {STRLIT_ARGS("&")},
105 {STRLIT_ARGS("'")},
106 {STRLIT_ARGS("(")},
107 {STRLIT_ARGS(")")},
108 {STRLIT_ARGS("*")},
109 {STRLIT_ARGS("+")},
110 {STRLIT_ARGS(",")},
111 {STRLIT_ARGS("-")},
112 {STRLIT_ARGS(".")},
113 kumpf 1.1 {STRLIT_ARGS("/")},
114 {STRLIT_ARGS("0")},
115 {STRLIT_ARGS("1")},
116 {STRLIT_ARGS("2")},
117 {STRLIT_ARGS("3")},
118 {STRLIT_ARGS("4")},
119 {STRLIT_ARGS("5")},
120 {STRLIT_ARGS("6")},
121 {STRLIT_ARGS("7")},
122 {STRLIT_ARGS("8")},
123 {STRLIT_ARGS("9")},
124 {STRLIT_ARGS(":")},
125 {STRLIT_ARGS(";")},
126 {STRLIT_ARGS("<")},
127 {STRLIT_ARGS("=")},
128 {STRLIT_ARGS(">")},
129 {STRLIT_ARGS("?")},
130 {STRLIT_ARGS("@")},
131 {STRLIT_ARGS("A")},
132 {STRLIT_ARGS("B")},
133 {STRLIT_ARGS("C")},
134 kumpf 1.1 {STRLIT_ARGS("D")},
135 {STRLIT_ARGS("E")},
136 {STRLIT_ARGS("F")},
137 {STRLIT_ARGS("G")},
138 {STRLIT_ARGS("H")},
139 {STRLIT_ARGS("I")},
140 {STRLIT_ARGS("J")},
141 {STRLIT_ARGS("K")},
142 {STRLIT_ARGS("L")},
143 {STRLIT_ARGS("M")},
144 {STRLIT_ARGS("N")},
145 {STRLIT_ARGS("O")},
146 {STRLIT_ARGS("P")},
147 {STRLIT_ARGS("Q")},
148 {STRLIT_ARGS("R")},
149 {STRLIT_ARGS("S")},
150 {STRLIT_ARGS("T")},
151 {STRLIT_ARGS("U")},
152 {STRLIT_ARGS("V")},
153 {STRLIT_ARGS("W")},
154 {STRLIT_ARGS("X")},
155 kumpf 1.1 {STRLIT_ARGS("Y")},
156 {STRLIT_ARGS("Z")},
157 {STRLIT_ARGS("[")},
158 {STRLIT_ARGS("\\")},
159 {STRLIT_ARGS("]")},
160 {STRLIT_ARGS("^")},
161 {STRLIT_ARGS("_")},
162 {STRLIT_ARGS("`")},
163 {STRLIT_ARGS("a")},
164 {STRLIT_ARGS("b")},
165 {STRLIT_ARGS("c")},
166 {STRLIT_ARGS("d")},
167 {STRLIT_ARGS("e")},
168 {STRLIT_ARGS("f")},
169 {STRLIT_ARGS("g")},
170 {STRLIT_ARGS("h")},
171 {STRLIT_ARGS("i")},
172 {STRLIT_ARGS("j")},
173 {STRLIT_ARGS("k")},
174 {STRLIT_ARGS("l")},
175 {STRLIT_ARGS("m")},
176 kumpf 1.1 {STRLIT_ARGS("n")},
177 {STRLIT_ARGS("o")},
178 {STRLIT_ARGS("p")},
179 {STRLIT_ARGS("q")},
180 {STRLIT_ARGS("r")},
181 {STRLIT_ARGS("s")},
182 {STRLIT_ARGS("t")},
183 {STRLIT_ARGS("u")},
184 {STRLIT_ARGS("v")},
185 {STRLIT_ARGS("w")},
186 {STRLIT_ARGS("x")},
187 {STRLIT_ARGS("y")},
188 {STRLIT_ARGS("z")},
189 {STRLIT_ARGS("{")},
190 {STRLIT_ARGS("|")},
191 {STRLIT_ARGS("}")},
192 {STRLIT_ARGS("~")},
193 {STRLIT_ARGS("")},
194 };
195
196 // If _isSpecialChar7[ch] is true, then ch is a special character, which must
|
197 marek 1.7.2.1 // have a special encoding in XML.
198 // Remaining 128 values are automatically initialised to 0 by compiler.
199 static const int _isSpecialChar7[256] =
|
200 kumpf 1.1 {
201 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0,0,
202 0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,
203 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
204 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
205 };
206
|
207 thilo.boehm 1.7 // If _isSpecialChar7[ch] is true, then ch is a special character, which must
|
208 marek 1.7.2.1 // have a special encoding in XML.
|
209 thilo.boehm 1.7 static const int _isNormalChar7[] =
210 {
211 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,1,1,
212 1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,
213 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
214 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
|
215 marek 1.7.2.1 // remaining 128 values are used on multi-byte UTF-8 and should not be escaped
216 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
217 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
218 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
219 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
|
220 thilo.boehm 1.7 };
221
222
|
223 kumpf 1.1 ////////////////////////////////////////////////////////////////////////////////
224
225 Buffer& operator<<(Buffer& out, const Char16& x)
226 {
227 XmlGenerator::append(out, x);
228 return out;
229 }
230
231 Buffer& operator<<(Buffer& out, const String& x)
232 {
233 XmlGenerator::append(out, x);
234 return out;
235 }
236
237 Buffer& operator<<(Buffer& out, const Buffer& x)
238 {
239 out.append(x.getData(), x.size());
240 return out;
241 }
242
243 Buffer& operator<<(Buffer& out, Uint32 x)
244 kumpf 1.1 {
245 XmlGenerator::append(out, x);
246 return out;
247 }
248
249 Buffer& operator<<(Buffer& out, const CIMName& name)
250 {
251 XmlGenerator::append(out, name.getString ());
252 return out;
253 }
254
255 Buffer& operator<<(Buffer& out, const AcceptLanguageList& al)
256 {
257 XmlGenerator::append(out, LanguageParser::buildAcceptLanguageHeader(al));
258 return out;
259 }
260
261 Buffer& operator<<(Buffer& out, const ContentLanguageList& cl)
262 {
263 XmlGenerator::append(out, LanguageParser::buildContentLanguageHeader(cl));
264 return out;
265 kumpf 1.1 }
266
|
267 thilo.boehm 1.7 const StrLit XmlGenerator::_XmlWriterTypeStrings[17] =
268 {
269 STRLIT("TYPE=\"boolean\""), STRLIT("TYPE=\"uint8\""),
270 STRLIT("TYPE=\"sint8\""), STRLIT("TYPE=\"uint16\""),
271 STRLIT("TYPE=\"sint16\""), STRLIT("TYPE=\"uint32\""),
272 STRLIT("TYPE=\"sint32\""), STRLIT("TYPE=\"uint64\""),
273 STRLIT("TYPE=\"sint64\""), STRLIT("TYPE=\"real32\""),
274 STRLIT("TYPE=\"real64\""), STRLIT("TYPE=\"char16\""),
275 STRLIT("TYPE=\"string\""), STRLIT("TYPE=\"datetime\""),
276 STRLIT("TYPE=\"reference\""), STRLIT("TYPE=\"object\""),
277 STRLIT("TYPE=\"instance\"")
278 };
279
280 const StrLit XmlGenerator::_XmlWriterKeyTypeStrings[17] =
281 {
282 STRLIT("boolean"), STRLIT("numeric"),
283 STRLIT("numeric"), STRLIT("numeric"),
284 STRLIT("numeric"), STRLIT("numeric"),
285 STRLIT("numeric"), STRLIT("numeric"),
286 STRLIT("numeric"), STRLIT("numeric"),
287 STRLIT("numeric"), STRLIT("string"),
288 thilo.boehm 1.7 STRLIT("string"), STRLIT("string"),
289 /* The following are not valid values for a keytype, but left in here
290 so in case something is going wrong it can be easily concluded from the
291 generated XML */
292 STRLIT("reference"), STRLIT("object"),
293 STRLIT("instance")
294 };
295
|
296 kumpf 1.1 void XmlGenerator::_appendChar(Buffer& out, const Char16& c)
297 {
298 // We need to convert the Char16 to UTF8 then append the UTF8
299 // character into the array.
300 // NOTE: The UTF8 character could be several bytes long.
301 // WARNING: This function will put in replacement character for
302 // all characters that have surogate pairs.
303 char str[6];
304 memset(str,0x00,sizeof(str));
305 Uint8* charIN = (Uint8 *)&c;
306
307 const Uint16 *strsrc = (Uint16 *)charIN;
308 Uint16 *endsrc = (Uint16 *)&charIN[1];
309
310 Uint8 *strtgt = (Uint8 *)str;
311 Uint8 *endtgt = (Uint8 *)&str[5];
312
313 UTF16toUTF8(
314 &strsrc,
315 endsrc,
316 &strtgt,
317 kumpf 1.1 endtgt);
318
319 out.append(str, UTF_8_COUNT_TRAIL_BYTES(str[0]) + 1);
320 }
321
322 void XmlGenerator::_appendSpecialChar7(Buffer& out, char c)
323 {
324 if (_isSpecialChar7[int(c)])
325 out.append(_specialChars[int(c)].str, _specialChars[int(c)].size);
326 else
327 out.append(c);
328 }
329
330 void XmlGenerator::_appendSpecialChar(Buffer& out, const Char16& c)
331 {
332 if (c < 128)
333 _appendSpecialChar7(out, char(c));
334 else
335 _appendChar(out, c);
336 }
337
338 kumpf 1.1 void XmlGenerator::_appendSpecialChar(PEGASUS_STD(ostream)& os, char c)
339 {
340 if ( ((c < 0x20) && (c >= 0)) || (c == 0x7f) )
341 {
342 char scratchBuffer[22];
343 Uint32 outputLength;
|
344 kumpf 1.6 const char * output = Uint8ToString(scratchBuffer,
345 static_cast<Uint8>(c),
|
346 kumpf 1.1 outputLength);
347 os << "&#" << output << ";";
348 }
349 else
350 {
351 switch (c)
352 {
353 case '&':
354 os << "&";
355 break;
356
357 case '<':
358 os << "<";
359 break;
360
361 case '>':
362 os << ">";
363 break;
364
365 case '"':
366 os << """;
367 kumpf 1.1 break;
368
369 case '\'':
370 os << "'";
371 break;
372
373 default:
374 os << c;
375 }
376 }
377 }
378
379 void XmlGenerator::_appendSurrogatePair(Buffer& out, Uint16 high, Uint16 low)
380 {
381 char str[6];
382 Uint8 charIN[5];
383 memset(str,0x00,sizeof(str));
384 memcpy(&charIN,&high,2);
385 memcpy(&charIN[2],&low,2);
386 const Uint16 *strsrc = (Uint16 *)charIN;
387 Uint16 *endsrc = (Uint16 *)&charIN[3];
388 kumpf 1.1
389 Uint8 *strtgt = (Uint8 *)str;
390 Uint8 *endtgt = (Uint8 *)&str[5];
391
392 UTF16toUTF8(
393 &strsrc,
394 endsrc,
395 &strtgt,
396 endtgt);
397
398 Uint32 number1 = UTF_8_COUNT_TRAIL_BYTES(str[0]) + 1;
399 out.append(str,number1);
400 }
401
402 void XmlGenerator::_appendSpecial(PEGASUS_STD(ostream)& os, const char* str)
403 {
404 while (*str)
405 _appendSpecialChar(os, *str++);
406 }
407
408 void XmlGenerator::append(Buffer& out, const Char16& x)
409 kumpf 1.1 {
410 _appendChar(out, x);
411 }
412
413 void XmlGenerator::append(Buffer& out, Boolean x)
414 {
415 if (x)
416 out.append(STRLIT_ARGS("TRUE"));
417 else
418 out.append(STRLIT_ARGS("FALSE"));
419 }
420
421 void XmlGenerator::append(Buffer& out, Uint32 x)
422 {
423 Uint32 outputLength=0;
424 char buffer[22];
425 const char * output = Uint32ToString(buffer, x, outputLength);
426 out.append(output, outputLength);
427 }
428
429 void XmlGenerator::append(Buffer& out, Sint32 x)
430 kumpf 1.1 {
431 Uint32 outputLength=0;
432 char buffer[22];
433 const char * output = Sint32ToString(buffer, x, outputLength);
434 out.append(output, outputLength);
435 }
436
437 void XmlGenerator::append(Buffer& out, Uint64 x)
438 {
439 Uint32 outputLength=0;
440 char buffer[22];
441 const char * output = Uint64ToString(buffer, x, outputLength);
442 out.append(output, outputLength);
443 }
444
445 void XmlGenerator::append(Buffer& out, Sint64 x)
446 {
447 Uint32 outputLength=0;
448 char buffer[22];
449 const char * output = Sint64ToString(buffer, x, outputLength);
450 out.append(output, outputLength);
451 kumpf 1.1 }
452
453 void XmlGenerator::append(Buffer& out, Real32 x)
454 {
|
455 thilo.boehm 1.7 Uint32 outputLength=0;
|
456 kumpf 1.1 char buffer[128];
|
457 thilo.boehm 1.7 const char * output = Real32ToString(buffer, x, outputLength);
458 out.append(output, outputLength);
|
459 kumpf 1.1 }
460
461 void XmlGenerator::append(Buffer& out, Real64 x)
462 {
|
463 thilo.boehm 1.7 Uint32 outputLength=0;
|
464 kumpf 1.1 char buffer[128];
|
465 thilo.boehm 1.7 const char * output = Real64ToString(buffer, x, outputLength);
466 out.append(output, outputLength);
|
467 kumpf 1.1 }
468
469 void XmlGenerator::append(Buffer& out, const char* str)
470 {
471 size_t n = strlen(str);
472 out.append(str, n);
473 }
474
475 void XmlGenerator::append(Buffer& out, const String& str)
476 {
477 const Uint16* p = (const Uint16*)str.getChar16Data();
478 size_t n = str.size();
479
480 // Handle leading ASCII 7 characers in these next two loops (use unrolling).
481
482 while (n >= 8 && ((p[0]|p[1]|p[2]|p[3]|p[4]|p[5]|p[6]|p[7]) & 0xFF80) == 0)
483 {
484 out.append(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
485 p += 8;
486 n -= 8;
487 }
488 kumpf 1.1
489 while (n >= 4 && ((p[0]|p[1]|p[2]|p[3]) & 0xFF80) == 0)
490 {
491 out.append(p[0], p[1], p[2], p[3]);
492 p += 4;
493 n -= 4;
494 }
495
496 while (n--)
497 {
498 Uint16 c = *p++;
499
500 // Special processing for UTF8 case:
501
502 if (c < 128)
503 {
504 out.append(c);
505 continue;
506 }
507
508 // Handle UTF8 case (if reached).
509 kumpf 1.1
510 if (((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
511 ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE)))
512 {
513 Char16 highSurrogate = p[-1];
514 Char16 lowSurrogate = p[0];
515 p++;
516 n--;
517
518 _appendSurrogatePair(
519 out, Uint16(highSurrogate),Uint16(lowSurrogate));
520 }
521 else
522 {
523 _appendChar(out, c);
524 }
525 }
526 }
527
528 void XmlGenerator::appendSpecial(Buffer& out, const Char16& x)
529 {
530 kumpf 1.1 _appendSpecialChar(out, x);
531 }
532
533 void XmlGenerator::appendSpecial(Buffer& out, char x)
534 {
535 _appendSpecialChar7(out, x);
536 }
537
538 void XmlGenerator::appendSpecial(Buffer& out, const char* str)
539 {
540 while (*str)
541 _appendSpecialChar7(out, *str++);
542 }
543
544 void XmlGenerator::appendSpecial(Buffer& out, const String& str)
545 {
546 const Uint16* p = (const Uint16*)str.getChar16Data();
547 // prevCharIsSpace is true when the last character written to the Buffer
548 // is a space character (not a character reference).
549 Boolean prevCharIsSpace = false;
550
551 kumpf 1.1 // If the first character is a space, use a character reference to avoid
552 // space compression.
553 if (*p == ' ')
554 {
555 out.append(STRLIT_ARGS(" "));
556 p++;
557 }
558
559 Uint16 c;
560 while ((c = *p++) != 0)
561 {
562 if (c < 128)
563 {
564 if (_isSpecialChar7[c])
565 {
566 // Write the character reference for the special character
567 out.append(
568 _specialChars[int(c)].str, _specialChars[int(c)].size);
569 prevCharIsSpace = false;
570 }
571 else if (prevCharIsSpace && (c == ' '))
572 kumpf 1.1 {
573 // Write the character reference for the space character, to
574 // avoid compression
575 out.append(STRLIT_ARGS(" "));
576 prevCharIsSpace = false;
577 }
578 else
579 {
580 out.append(c);
581 prevCharIsSpace = (c == ' ');
582 }
583 }
584 else
585 {
586 // Handle UTF8 case
587
588 if ((((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
589 ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) &&
590 *p)
591 {
592 _appendSurrogatePair(out, c, *p++);
593 kumpf 1.1 }
594 else
595 {
596 _appendChar(out, c);
597 }
598
599 prevCharIsSpace = false;
600 }
601 }
602
603 // If the last character is a space, use a character reference to avoid
604 // space compression.
605 if (prevCharIsSpace)
606 {
607 out.remove(out.size() - 1);
608 out.append(STRLIT_ARGS(" "));
609 }
610 }
611
|
612 thilo.boehm 1.7 // str has to be UTF-8 encoded
613 // that means the characters used cannot be larger than 7bit ASCII in value
614 // range
615 void XmlGenerator::appendSpecial(Buffer& out, const char* str, Uint32 size)
616 {
617 // employ loop unrolling and a less checking optimized Buffer access
618
619 // Buffer cannot grow more than 6*size characters (ie. 4*size+2*size)
620 Uint32 newMaxSize = (size << 2) + (size << 1);
621 if (out.size() + newMaxSize >= out.capacity())
622 {
623 out.reserveCapacity(out.capacity() + newMaxSize);
624 }
625
626 // Before using a loop unrolled algorithm to pick out the special chars
627 // we are going to assume there is no special char as this is the case most
628 // of the time anyway
629 Uint32 sizeStart=size;
630 const Uint8* p= (const Uint8*) str;
631
632 while (size >= 4 &&
633 thilo.boehm 1.7 (_isNormalChar7[p[0]] &
634 _isNormalChar7[p[1]] &
635 _isNormalChar7[p[2]] &
636 _isNormalChar7[p[3]]))
637 {
638 size -= 4;
639 p += 4;
640 }
641 out.append_unchecked(str,sizeStart-size);
642 str=(const char*)p;
643
644 while (size>=8)
645 {
|
646 marek 1.7.2.2 register Uint8 c;
|
647 thilo.boehm 1.7 c = str[0];
648 if (_isSpecialChar7[c])
649 {
650 out.append_unchecked(
651 _specialChars[c].str,
652 _specialChars[c].size);
653 }
654 else
655 {
656 out.append_unchecked(c);
657 }
658 c = str[1];
659 if (_isSpecialChar7[c])
660 {
661 out.append_unchecked(
662 _specialChars[c].str,
663 _specialChars[c].size);
664 }
665 else
666 {
667 out.append_unchecked(c);
668 thilo.boehm 1.7 }
669 c = str[2];
670 if (_isSpecialChar7[c])
671 {
672 out.append_unchecked(
673 _specialChars[c].str,
674 _specialChars[c].size);
675 }
676 else
677 {
678 out.append_unchecked(c);
679 }
680 c = str[3];
681 if (_isSpecialChar7[c])
682 {
683 out.append_unchecked(
684 _specialChars[c].str,
685 _specialChars[c].size);
686 }
687 else
688 {
689 thilo.boehm 1.7 out.append_unchecked(c);
690 }
691 c = str[4];
692 if (_isSpecialChar7[c])
693 {
694 out.append_unchecked(
695 _specialChars[c].str,
696 _specialChars[c].size);
697 }
698 else
699 {
700 out.append_unchecked(c);
701 }
702 c = str[5];
703 if (_isSpecialChar7[c])
704 {
705 out.append_unchecked(
706 _specialChars[c].str,
707 _specialChars[c].size);
708 }
709 else
710 thilo.boehm 1.7 {
711 out.append_unchecked(c);
712 }
713 c = str[6];
714 if (_isSpecialChar7[c])
715 {
716 out.append_unchecked(
717 _specialChars[c].str,
718 _specialChars[c].size);
719 }
720 else
721 {
722 out.append_unchecked(c);
723 }
724 c = str[7];
725 if (_isSpecialChar7[c])
726 {
727 out.append_unchecked(
728 _specialChars[c].str,
729 _specialChars[c].size);
730 }
731 thilo.boehm 1.7 else
732 {
733 out.append_unchecked(c);
734 }
735 str+=8;
736 size-=8;
737 }
738
739 while (size>=4)
740 {
|
741 marek 1.7.2.2 register Uint8 c;
|
742 thilo.boehm 1.7 c = str[0];
743 if (_isSpecialChar7[c])
744 {
745 out.append_unchecked(
746 _specialChars[c].str,
747 _specialChars[c].size);
748 }
749 else
750 {
751 out.append_unchecked(c);
752 }
753 c = str[1];
754 if (_isSpecialChar7[c])
755 {
756 out.append_unchecked(
757 _specialChars[c].str,
758 _specialChars[c].size);
759 }
760 else
761 {
762 out.append_unchecked(c);
763 thilo.boehm 1.7 }
764 c = str[2];
765 if (_isSpecialChar7[c])
766 {
767 out.append_unchecked(
768 _specialChars[c].str,
769 _specialChars[c].size);
770 }
771 else
772 {
773 out.append_unchecked(c);
774 }
775 c = str[3];
776 if (_isSpecialChar7[c])
777 {
778 out.append_unchecked(
779 _specialChars[c].str,
780 _specialChars[c].size);
781 }
782 else
783 {
784 thilo.boehm 1.7 out.append_unchecked(c);
785 }
786 str+=4;
787 size-=4;
788 }
789
790 while (size--)
791 {
|
792 marek 1.7.2.2 register Uint8 c;
|
793 thilo.boehm 1.7 c=*str;
794 if (_isSpecialChar7[c])
795 {
796 out.append_unchecked(
797 _specialChars[c].str,
798 _specialChars[c].size);
799 }
800 else
801 {
802 out.append_unchecked(c);
803 }
804 str++;
805 }
806 }
807
808
|
809 kumpf 1.1 // See http://www.ietf.org/rfc/rfc2396.txt section 2
810 // Reserved characters = ';' '/' '?' ':' '@' '&' '=' '+' '$' ','
811 // Excluded characters:
812 // Control characters = 0x00-0x1f, 0x7f
813 // Space character = 0x20
814 // Delimiters = '<' '>' '#' '%' '"'
815 // Unwise = '{' '}' '|' '\\' '^' '[' ']' '`'
816 //
817
818 static const char _is_uri[128] =
819 {
820 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,
821 1,1,0,0,0,0,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
822 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
823 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,
824 };
825
826 // Perform the necessary URI encoding of characters in HTTP header values.
827 // This is required by the HTTP/1.1 specification and the CIM/HTTP
828 // Specification (section 3.3.2).
829 void XmlGenerator::_encodeURIChar(String& outString, Sint8 char8)
830 kumpf 1.1 {
831 Uint8 c = (Uint8)char8;
832
833 #ifndef PEGASUS_DO_NOT_IMPLEMENT_URI_ENCODING
834 if (c > 127 || _is_uri[int(c)])
835 {
836 char hexencoding[4];
837 int n = sprintf(hexencoding, "%%%X%X", c/16, c%16);
838 #ifdef PEGASUS_USE_STRING_EXTENSIONS
839 outString.append(hexencoding, n);
840 #else /* PEGASUS_USE_STRING_EXTENSIONS */
841 outString.append(hexencoding);
842 #endif /* PEGASUS_USE_STRING_EXTENSIONS */
843 }
844 else
845 #endif
846 {
847 outString.append((Uint16)c);
848 }
849 }
850
851 kumpf 1.1 String XmlGenerator::encodeURICharacters(const Buffer& uriString)
852 {
853 String encodedString;
854
855 for (Uint32 i=0; i<uriString.size(); i++)
856 {
857 _encodeURIChar(encodedString, uriString[i]);
858 }
859
860 return encodedString;
861 }
862
863 String XmlGenerator::encodeURICharacters(const String& uriString)
864 {
865 String encodedString;
866
867 // See the "CIM Operations over HTTP" spec, section 3.3.2 and
868 // 3.3.3, for the treatment of non US-ASCII (UTF-8) chars
869
870 // First, convert to UTF-8 (include handling of surrogate pairs)
871 Buffer utf8;
872 kumpf 1.1 for (Uint32 i = 0; i < uriString.size(); i++)
873 {
874 Uint16 c = uriString[i];
875
876 if (((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
877 ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE)))
878 {
879 Char16 highSurrogate = uriString[i];
880 Char16 lowSurrogate = uriString[++i];
881
882 _appendSurrogatePair(
883 utf8, Uint16(highSurrogate),Uint16(lowSurrogate));
884 }
885 else
886 {
887 _appendChar(utf8, uriString[i]);
888 }
889 }
890
891 // Second, escape the non HTTP-safe chars
892 for (Uint32 i=0; i<utf8.size(); i++)
893 kumpf 1.1 {
894 _encodeURIChar(encodedString, utf8[i]);
895 }
896
897 return encodedString;
898 }
899
900 //------------------------------------------------------------------------------
901 //
902 // _printAttributes()
903 //
904 //------------------------------------------------------------------------------
905
906 void XmlGenerator::_printAttributes(
907 PEGASUS_STD(ostream)& os,
908 const XmlAttribute* attributes,
909 Uint32 attributeCount)
910 {
911 for (Uint32 i = 0; i < attributeCount; i++)
912 {
913 os << attributes[i].name << "=";
914 kumpf 1.1
915 os << '"';
916 _appendSpecial(os, attributes[i].value);
917 os << '"';
918
919 if (i + 1 != attributeCount)
920 os << ' ';
921 }
922 }
923
924 //------------------------------------------------------------------------------
925 //
926 // _indent()
927 //
928 //------------------------------------------------------------------------------
929
930 void XmlGenerator::_indent(
931 PEGASUS_STD(ostream)& os,
932 Uint32 level,
933 Uint32 indentChars)
934 {
935 kumpf 1.1 Uint32 n = level * indentChars;
936
937 for (Uint32 i = 0; i < n; i++)
938 os << ' ';
939 }
940
941 //------------------------------------------------------------------------------
942 //
943 // indentedPrint()
944 //
945 //------------------------------------------------------------------------------
946
947 void XmlGenerator::indentedPrint(
948 PEGASUS_STD(ostream)& os,
949 const char* text,
950 Uint32 indentChars)
951 {
952 AutoArrayPtr<char> tmp(strcpy(new char[strlen(text) + 1], text));
953
954 XmlParser parser(tmp.get());
955 XmlEntry entry;
956 kumpf 1.1 Stack<const char*> stack;
957
958 while (parser.next(entry))
959 {
960 switch (entry.type)
961 {
962 case XmlEntry::XML_DECLARATION:
963 {
964 _indent(os, stack.size(), indentChars);
965
966 os << "<?" << entry.text << " ";
967 _printAttributes(
|
968 kumpf 1.3 os, entry.attributes.getData(), entry.attributes.size());
|
969 kumpf 1.1 os << "?>";
970 break;
971 }
972
973 case XmlEntry::START_TAG:
974 {
975 _indent(os, stack.size(), indentChars);
976
977 os << "<" << entry.text;
978
|
979 kumpf 1.3 if (entry.attributes.size())
|
980 kumpf 1.1 os << ' ';
981
982 _printAttributes(
|
983 kumpf 1.3 os, entry.attributes.getData(), entry.attributes.size());
|
984 kumpf 1.1 os << ">";
985 stack.push(entry.text);
986 break;
987 }
988
989 case XmlEntry::EMPTY_TAG:
990 {
991 _indent(os, stack.size(), indentChars);
992
993 os << "<" << entry.text << " ";
994 _printAttributes(
|
995 kumpf 1.3 os, entry.attributes.getData(), entry.attributes.size());
|
996 kumpf 1.1 os << "/>";
997 break;
998 }
999
1000 case XmlEntry::END_TAG:
1001 {
1002 if (!stack.isEmpty() && strcmp(stack.top(), entry.text) == 0)
1003 stack.pop();
1004
1005 _indent(os, stack.size(), indentChars);
1006
1007 os << "</" << entry.text << ">";
1008 break;
1009 }
1010
1011 case XmlEntry::COMMENT:
1012 {
1013 _indent(os, stack.size(), indentChars);
1014 os << "<!--";
1015 _appendSpecial(os, entry.text);
1016 os << "-->";
1017 kumpf 1.1 break;
1018 }
1019
1020 case XmlEntry::CONTENT:
1021 {
1022 _indent(os, stack.size(), indentChars);
1023 _appendSpecial(os, entry.text);
1024 break;
1025 }
1026
1027 case XmlEntry::CDATA:
1028 {
1029 _indent(os, stack.size(), indentChars);
1030 os << "<![CDATA[" << entry.text << "]]>";
1031 break;
1032 }
1033
1034 case XmlEntry::DOCTYPE:
1035 {
1036 _indent(os, stack.size(), indentChars);
1037 os << "<!DOCTYPE...>";
1038 kumpf 1.1 break;
1039 }
1040 }
1041
1042 os << PEGASUS_STD(endl);
1043 }
1044 }
1045
1046 PEGASUS_NAMESPACE_END
|