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 kumpf 1.1 // have a special encoding in XML. But only use 7-bit ASCII characters to
198 // index this array.
199 static const int _isSpecialChar7[] =
200 {
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 marek 1.6.4.6 // If _isSpecialChar7[ch] is true, then ch is a special character, which must
208 // have a special encoding in XML. But only use 7-biat ASCII characters to
209 // index this array.
210 static const int _isNormalChar7[] =
211 {
212 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,
213 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,
214 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,
215 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
216 };
217
218
|
219 kumpf 1.1 ////////////////////////////////////////////////////////////////////////////////
220
221 Buffer& operator<<(Buffer& out, const Char16& x)
222 {
223 XmlGenerator::append(out, x);
224 return out;
225 }
226
227 Buffer& operator<<(Buffer& out, const String& x)
228 {
229 XmlGenerator::append(out, x);
230 return out;
231 }
232
233 Buffer& operator<<(Buffer& out, const Buffer& x)
234 {
235 out.append(x.getData(), x.size());
236 return out;
237 }
238
239 Buffer& operator<<(Buffer& out, Uint32 x)
240 kumpf 1.1 {
241 XmlGenerator::append(out, x);
242 return out;
243 }
244
245 Buffer& operator<<(Buffer& out, const CIMName& name)
246 {
247 XmlGenerator::append(out, name.getString ());
248 return out;
249 }
250
251 Buffer& operator<<(Buffer& out, const AcceptLanguageList& al)
252 {
253 XmlGenerator::append(out, LanguageParser::buildAcceptLanguageHeader(al));
254 return out;
255 }
256
257 Buffer& operator<<(Buffer& out, const ContentLanguageList& cl)
258 {
259 XmlGenerator::append(out, LanguageParser::buildContentLanguageHeader(cl));
260 return out;
261 kumpf 1.1 }
262
|
263 marek 1.6.4.2 const StrLit XmlGenerator::_XmlWriterTypeStrings[17] =
264 {
265 STRLIT("TYPE=\"boolean\""), STRLIT("TYPE=\"uint8\""),
266 STRLIT("TYPE=\"sint8\""), STRLIT("TYPE=\"uint16\""),
267 STRLIT("TYPE=\"sint16\""), STRLIT("TYPE=\"uint32\""),
268 STRLIT("TYPE=\"sint32\""), STRLIT("TYPE=\"uint64\""),
269 STRLIT("TYPE=\"sint64\""), STRLIT("TYPE=\"real32\""),
270 STRLIT("TYPE=\"real64\""), STRLIT("TYPE=\"char16\""),
271 STRLIT("TYPE=\"string\""), STRLIT("TYPE=\"datetime\""),
272 STRLIT("TYPE=\"reference\""), STRLIT("TYPE=\"object\""),
273 STRLIT("TYPE=\"instance\"")
274 };
275
|
276 marek 1.6.4.3 const StrLit XmlGenerator::_XmlWriterKeyTypeStrings[17] =
277 {
278 STRLIT("boolean"), STRLIT("numeric"),
279 STRLIT("numeric"), STRLIT("numeric"),
280 STRLIT("numeric"), STRLIT("numeric"),
281 STRLIT("numeric"), STRLIT("numeric"),
282 STRLIT("numeric"), STRLIT("numeric"),
283 STRLIT("numeric"), STRLIT("string"),
284 STRLIT("string"), STRLIT("string"),
285 /* The following are not valid values for a keytype, but left in here
286 so in case something is going wrong it can be easily concluded from the
287 generated XML */
288 STRLIT("reference"), STRLIT("object"),
289 STRLIT("instance")
290 };
291
|
292 kumpf 1.1 void XmlGenerator::_appendChar(Buffer& out, const Char16& c)
293 {
294 // We need to convert the Char16 to UTF8 then append the UTF8
295 // character into the array.
296 // NOTE: The UTF8 character could be several bytes long.
297 // WARNING: This function will put in replacement character for
298 // all characters that have surogate pairs.
299 char str[6];
300 memset(str,0x00,sizeof(str));
301 Uint8* charIN = (Uint8 *)&c;
302
303 const Uint16 *strsrc = (Uint16 *)charIN;
304 Uint16 *endsrc = (Uint16 *)&charIN[1];
305
306 Uint8 *strtgt = (Uint8 *)str;
307 Uint8 *endtgt = (Uint8 *)&str[5];
308
309 UTF16toUTF8(
310 &strsrc,
311 endsrc,
312 &strtgt,
313 kumpf 1.1 endtgt);
314
315 out.append(str, UTF_8_COUNT_TRAIL_BYTES(str[0]) + 1);
316 }
317
318 void XmlGenerator::_appendSpecialChar7(Buffer& out, char c)
319 {
320 if (_isSpecialChar7[int(c)])
321 out.append(_specialChars[int(c)].str, _specialChars[int(c)].size);
322 else
323 out.append(c);
324 }
325
326 void XmlGenerator::_appendSpecialChar(Buffer& out, const Char16& c)
327 {
328 if (c < 128)
329 _appendSpecialChar7(out, char(c));
330 else
331 _appendChar(out, c);
332 }
333
334 kumpf 1.1 void XmlGenerator::_appendSpecialChar(PEGASUS_STD(ostream)& os, char c)
335 {
336 if ( ((c < 0x20) && (c >= 0)) || (c == 0x7f) )
337 {
338 char scratchBuffer[22];
339 Uint32 outputLength;
|
340 kumpf 1.6 const char * output = Uint8ToString(scratchBuffer,
341 static_cast<Uint8>(c),
|
342 kumpf 1.1 outputLength);
343 os << "&#" << output << ";";
344 }
345 else
346 {
347 switch (c)
348 {
349 case '&':
350 os << "&";
351 break;
352
353 case '<':
354 os << "<";
355 break;
356
357 case '>':
358 os << ">";
359 break;
360
361 case '"':
362 os << """;
363 kumpf 1.1 break;
364
365 case '\'':
366 os << "'";
367 break;
368
369 default:
370 os << c;
371 }
372 }
373 }
374
375 void XmlGenerator::_appendSurrogatePair(Buffer& out, Uint16 high, Uint16 low)
376 {
377 char str[6];
378 Uint8 charIN[5];
379 memset(str,0x00,sizeof(str));
380 memcpy(&charIN,&high,2);
381 memcpy(&charIN[2],&low,2);
382 const Uint16 *strsrc = (Uint16 *)charIN;
383 Uint16 *endsrc = (Uint16 *)&charIN[3];
384 kumpf 1.1
385 Uint8 *strtgt = (Uint8 *)str;
386 Uint8 *endtgt = (Uint8 *)&str[5];
387
388 UTF16toUTF8(
389 &strsrc,
390 endsrc,
391 &strtgt,
392 endtgt);
393
394 Uint32 number1 = UTF_8_COUNT_TRAIL_BYTES(str[0]) + 1;
395 out.append(str,number1);
396 }
397
398 void XmlGenerator::_appendSpecial(PEGASUS_STD(ostream)& os, const char* str)
399 {
400 while (*str)
401 _appendSpecialChar(os, *str++);
402 }
403
404 void XmlGenerator::append(Buffer& out, const Char16& x)
405 kumpf 1.1 {
406 _appendChar(out, x);
407 }
408
409 void XmlGenerator::append(Buffer& out, Boolean x)
410 {
411 if (x)
412 out.append(STRLIT_ARGS("TRUE"));
413 else
414 out.append(STRLIT_ARGS("FALSE"));
415 }
416
417 void XmlGenerator::append(Buffer& out, Uint32 x)
418 {
419 Uint32 outputLength=0;
420 char buffer[22];
421 const char * output = Uint32ToString(buffer, x, outputLength);
422 out.append(output, outputLength);
423 }
424
425 void XmlGenerator::append(Buffer& out, Sint32 x)
426 kumpf 1.1 {
427 Uint32 outputLength=0;
428 char buffer[22];
429 const char * output = Sint32ToString(buffer, x, outputLength);
430 out.append(output, outputLength);
431 }
432
433 void XmlGenerator::append(Buffer& out, Uint64 x)
434 {
435 Uint32 outputLength=0;
436 char buffer[22];
437 const char * output = Uint64ToString(buffer, x, outputLength);
438 out.append(output, outputLength);
439 }
440
441 void XmlGenerator::append(Buffer& out, Sint64 x)
442 {
443 Uint32 outputLength=0;
444 char buffer[22];
445 const char * output = Sint64ToString(buffer, x, outputLength);
446 out.append(output, outputLength);
447 kumpf 1.1 }
448
449 void XmlGenerator::append(Buffer& out, Real32 x)
450 {
|
451 thilo.boehm 1.6.4.1 Uint32 outputLength=0;
|
452 kumpf 1.1 char buffer[128];
|
453 thilo.boehm 1.6.4.1 const char * output = Real32ToString(buffer, x, outputLength);
454 out.append(output, outputLength);
|
455 kumpf 1.1 }
456
457 void XmlGenerator::append(Buffer& out, Real64 x)
458 {
|
459 thilo.boehm 1.6.4.1 Uint32 outputLength=0;
|
460 kumpf 1.1 char buffer[128];
|
461 thilo.boehm 1.6.4.1 const char * output = Real64ToString(buffer, x, outputLength);
462 out.append(output, outputLength);
|
463 kumpf 1.1 }
464
465 void XmlGenerator::append(Buffer& out, const char* str)
466 {
467 size_t n = strlen(str);
468 out.append(str, n);
469 }
470
471 void XmlGenerator::append(Buffer& out, const String& str)
472 {
473 const Uint16* p = (const Uint16*)str.getChar16Data();
474 size_t n = str.size();
475
476 // Handle leading ASCII 7 characers in these next two loops (use unrolling).
477
478 while (n >= 8 && ((p[0]|p[1]|p[2]|p[3]|p[4]|p[5]|p[6]|p[7]) & 0xFF80) == 0)
479 {
480 out.append(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
481 p += 8;
482 n -= 8;
483 }
484 kumpf 1.1
485 while (n >= 4 && ((p[0]|p[1]|p[2]|p[3]) & 0xFF80) == 0)
486 {
487 out.append(p[0], p[1], p[2], p[3]);
488 p += 4;
489 n -= 4;
490 }
491
492 while (n--)
493 {
494 Uint16 c = *p++;
495
496 // Special processing for UTF8 case:
497
498 if (c < 128)
499 {
500 out.append(c);
501 continue;
502 }
503
504 // Handle UTF8 case (if reached).
505 kumpf 1.1
506 if (((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
507 ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE)))
508 {
509 Char16 highSurrogate = p[-1];
510 Char16 lowSurrogate = p[0];
511 p++;
512 n--;
513
514 _appendSurrogatePair(
515 out, Uint16(highSurrogate),Uint16(lowSurrogate));
516 }
517 else
518 {
519 _appendChar(out, c);
520 }
521 }
522 }
523
524 void XmlGenerator::appendSpecial(Buffer& out, const Char16& x)
525 {
526 kumpf 1.1 _appendSpecialChar(out, x);
527 }
528
529 void XmlGenerator::appendSpecial(Buffer& out, char x)
530 {
531 _appendSpecialChar7(out, x);
532 }
533
534 void XmlGenerator::appendSpecial(Buffer& out, const char* str)
535 {
536 while (*str)
537 _appendSpecialChar7(out, *str++);
538 }
539
540 void XmlGenerator::appendSpecial(Buffer& out, const String& str)
541 {
542 const Uint16* p = (const Uint16*)str.getChar16Data();
543 // prevCharIsSpace is true when the last character written to the Buffer
544 // is a space character (not a character reference).
545 Boolean prevCharIsSpace = false;
546
547 kumpf 1.1 // If the first character is a space, use a character reference to avoid
548 // space compression.
549 if (*p == ' ')
550 {
551 out.append(STRLIT_ARGS(" "));
552 p++;
553 }
554
555 Uint16 c;
556 while ((c = *p++) != 0)
557 {
558 if (c < 128)
559 {
560 if (_isSpecialChar7[c])
561 {
562 // Write the character reference for the special character
563 out.append(
564 _specialChars[int(c)].str, _specialChars[int(c)].size);
565 prevCharIsSpace = false;
566 }
567 else if (prevCharIsSpace && (c == ' '))
568 kumpf 1.1 {
569 // Write the character reference for the space character, to
570 // avoid compression
571 out.append(STRLIT_ARGS(" "));
572 prevCharIsSpace = false;
573 }
574 else
575 {
576 out.append(c);
577 prevCharIsSpace = (c == ' ');
578 }
579 }
580 else
581 {
582 // Handle UTF8 case
583
584 if ((((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
585 ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) &&
586 *p)
587 {
588 _appendSurrogatePair(out, c, *p++);
589 kumpf 1.1 }
590 else
591 {
592 _appendChar(out, c);
593 }
594
595 prevCharIsSpace = false;
596 }
597 }
598
599 // If the last character is a space, use a character reference to avoid
600 // space compression.
601 if (prevCharIsSpace)
602 {
603 out.remove(out.size() - 1);
604 out.append(STRLIT_ARGS(" "));
605 }
606 }
607
|
608 marek 1.6.4.6 // str has to be UTF-8 encoded
609 // that means the characters used cannot be larger than 7bit ASCII in value
610 // range
|
611 marek 1.6.4.2 void XmlGenerator::appendSpecial(Buffer& out, const char* str, Uint32 size)
612 {
613 // employ loop unrolling and a less checking optimized Buffer access
614
615 // Buffer cannot grow more than 6*size characters (ie. 4*size+2*size)
|
616 marek 1.6.4.4 Uint32 newMaxSize = (size << 2) + (size << 1);
|
617 r.kieninger 1.6.4.5 if (out.size() + newMaxSize >= out.capacity())
|
618 marek 1.6.4.4 {
619 out.reserveCapacity(out.capacity() + newMaxSize);
620 }
|
621 marek 1.6.4.2
|
622 marek 1.6.4.6 // Before using a loop unrolled algorithm to pick out the special chars
623 // we are going to assume there is no special char as this is the case most
624 // of the time anyway
625 Uint32 sizeStart=size;
626 const Uint8* p= (const Uint8*) str;
627
628 while (size >= 4 &&
|
629 r.kieninger 1.6.4.7 (_isNormalChar7[p[0]] &
630 _isNormalChar7[p[1]] &
631 _isNormalChar7[p[2]] &
|
632 marek 1.6.4.6 _isNormalChar7[p[3]]))
633 {
634 size -= 4;
635 p += 4;
636 }
637 out.append_unchecked(str,sizeStart-size);
638 str=(const char*)p;
639
|
640 marek 1.6.4.2 while (size>=8)
641 {
642 register int c;
643 c = str[0];
644 if (_isSpecialChar7[c])
645 {
646 out.append_unchecked(
647 _specialChars[c].str,
648 _specialChars[c].size);
649 }
650 else
651 {
652 out.append_unchecked(c);
653 }
654 c = str[1];
655 if (_isSpecialChar7[c])
656 {
657 out.append_unchecked(
658 _specialChars[c].str,
659 _specialChars[c].size);
660 }
661 marek 1.6.4.2 else
662 {
663 out.append_unchecked(c);
664 }
665 c = str[2];
666 if (_isSpecialChar7[c])
667 {
668 out.append_unchecked(
669 _specialChars[c].str,
670 _specialChars[c].size);
671 }
672 else
673 {
674 out.append_unchecked(c);
675 }
676 c = str[3];
677 if (_isSpecialChar7[c])
678 {
679 out.append_unchecked(
680 _specialChars[c].str,
681 _specialChars[c].size);
682 marek 1.6.4.2 }
683 else
684 {
685 out.append_unchecked(c);
686 }
687 c = str[4];
688 if (_isSpecialChar7[c])
689 {
690 out.append_unchecked(
691 _specialChars[c].str,
692 _specialChars[c].size);
693 }
694 else
695 {
696 out.append_unchecked(c);
697 }
698 c = str[5];
699 if (_isSpecialChar7[c])
700 {
701 out.append_unchecked(
702 _specialChars[c].str,
703 marek 1.6.4.2 _specialChars[c].size);
704 }
705 else
706 {
707 out.append_unchecked(c);
708 }
709 c = str[6];
710 if (_isSpecialChar7[c])
711 {
712 out.append_unchecked(
713 _specialChars[c].str,
714 _specialChars[c].size);
715 }
716 else
717 {
718 out.append_unchecked(c);
719 }
720 c = str[7];
721 if (_isSpecialChar7[c])
722 {
723 out.append_unchecked(
724 marek 1.6.4.2 _specialChars[c].str,
725 _specialChars[c].size);
726 }
727 else
728 {
729 out.append_unchecked(c);
730 }
731 str+=8;
732 size-=8;
733 }
734
735 while (size>=4)
736 {
737 register int c;
738 c = str[0];
739 if (_isSpecialChar7[c])
740 {
741 out.append_unchecked(
742 _specialChars[c].str,
743 _specialChars[c].size);
744 }
745 marek 1.6.4.2 else
746 {
747 out.append_unchecked(c);
748 }
749 c = str[1];
750 if (_isSpecialChar7[c])
751 {
752 out.append_unchecked(
753 _specialChars[c].str,
754 _specialChars[c].size);
755 }
756 else
757 {
758 out.append_unchecked(c);
759 }
760 c = str[2];
761 if (_isSpecialChar7[c])
762 {
763 out.append_unchecked(
764 _specialChars[c].str,
765 _specialChars[c].size);
766 marek 1.6.4.2 }
767 else
768 {
769 out.append_unchecked(c);
770 }
771 c = str[3];
772 if (_isSpecialChar7[c])
773 {
774 out.append_unchecked(
775 _specialChars[c].str,
776 _specialChars[c].size);
777 }
778 else
779 {
780 out.append_unchecked(c);
781 }
782 str+=4;
783 size-=4;
784 }
785
786 while (size--)
787 marek 1.6.4.2 {
788 register int c;
789 c=*str;
790 if (_isSpecialChar7[c])
791 {
792 out.append_unchecked(
793 _specialChars[c].str,
794 _specialChars[c].size);
795 }
796 else
797 {
798 out.append_unchecked(c);
799 }
800 str++;
801 }
802 }
803
804
|
805 kumpf 1.1 // See http://www.ietf.org/rfc/rfc2396.txt section 2
806 // Reserved characters = ';' '/' '?' ':' '@' '&' '=' '+' '$' ','
807 // Excluded characters:
808 // Control characters = 0x00-0x1f, 0x7f
809 // Space character = 0x20
810 // Delimiters = '<' '>' '#' '%' '"'
811 // Unwise = '{' '}' '|' '\\' '^' '[' ']' '`'
812 //
813
814 static const char _is_uri[128] =
815 {
816 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,
817 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,
818 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,
819 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,
820 };
821
822 // Perform the necessary URI encoding of characters in HTTP header values.
823 // This is required by the HTTP/1.1 specification and the CIM/HTTP
824 // Specification (section 3.3.2).
825 void XmlGenerator::_encodeURIChar(String& outString, Sint8 char8)
826 kumpf 1.1 {
827 Uint8 c = (Uint8)char8;
828
829 #ifndef PEGASUS_DO_NOT_IMPLEMENT_URI_ENCODING
830 if (c > 127 || _is_uri[int(c)])
831 {
832 char hexencoding[4];
833 int n = sprintf(hexencoding, "%%%X%X", c/16, c%16);
834 #ifdef PEGASUS_USE_STRING_EXTENSIONS
835 outString.append(hexencoding, n);
836 #else /* PEGASUS_USE_STRING_EXTENSIONS */
837 outString.append(hexencoding);
838 #endif /* PEGASUS_USE_STRING_EXTENSIONS */
839 }
840 else
841 #endif
842 {
843 outString.append((Uint16)c);
844 }
845 }
846
847 kumpf 1.1 String XmlGenerator::encodeURICharacters(const Buffer& uriString)
848 {
849 String encodedString;
850
851 for (Uint32 i=0; i<uriString.size(); i++)
852 {
853 _encodeURIChar(encodedString, uriString[i]);
854 }
855
856 return encodedString;
857 }
858
859 String XmlGenerator::encodeURICharacters(const String& uriString)
860 {
861 String encodedString;
862
863 // See the "CIM Operations over HTTP" spec, section 3.3.2 and
864 // 3.3.3, for the treatment of non US-ASCII (UTF-8) chars
865
866 // First, convert to UTF-8 (include handling of surrogate pairs)
867 Buffer utf8;
868 kumpf 1.1 for (Uint32 i = 0; i < uriString.size(); i++)
869 {
870 Uint16 c = uriString[i];
871
872 if (((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
873 ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE)))
874 {
875 Char16 highSurrogate = uriString[i];
876 Char16 lowSurrogate = uriString[++i];
877
878 _appendSurrogatePair(
879 utf8, Uint16(highSurrogate),Uint16(lowSurrogate));
880 }
881 else
882 {
883 _appendChar(utf8, uriString[i]);
884 }
885 }
886
887 // Second, escape the non HTTP-safe chars
888 for (Uint32 i=0; i<utf8.size(); i++)
889 kumpf 1.1 {
890 _encodeURIChar(encodedString, utf8[i]);
891 }
892
893 return encodedString;
894 }
895
896 //------------------------------------------------------------------------------
897 //
898 // _printAttributes()
899 //
900 //------------------------------------------------------------------------------
901
902 void XmlGenerator::_printAttributes(
903 PEGASUS_STD(ostream)& os,
904 const XmlAttribute* attributes,
905 Uint32 attributeCount)
906 {
907 for (Uint32 i = 0; i < attributeCount; i++)
908 {
909 os << attributes[i].name << "=";
910 kumpf 1.1
911 os << '"';
912 _appendSpecial(os, attributes[i].value);
913 os << '"';
914
915 if (i + 1 != attributeCount)
916 os << ' ';
917 }
918 }
919
920 //------------------------------------------------------------------------------
921 //
922 // _indent()
923 //
924 //------------------------------------------------------------------------------
925
926 void XmlGenerator::_indent(
927 PEGASUS_STD(ostream)& os,
928 Uint32 level,
929 Uint32 indentChars)
930 {
931 kumpf 1.1 Uint32 n = level * indentChars;
932
933 for (Uint32 i = 0; i < n; i++)
934 os << ' ';
935 }
936
937 //------------------------------------------------------------------------------
938 //
939 // indentedPrint()
940 //
941 //------------------------------------------------------------------------------
942
943 void XmlGenerator::indentedPrint(
944 PEGASUS_STD(ostream)& os,
945 const char* text,
946 Uint32 indentChars)
947 {
948 AutoArrayPtr<char> tmp(strcpy(new char[strlen(text) + 1], text));
949
950 XmlParser parser(tmp.get());
951 XmlEntry entry;
952 kumpf 1.1 Stack<const char*> stack;
953
954 while (parser.next(entry))
955 {
956 switch (entry.type)
957 {
958 case XmlEntry::XML_DECLARATION:
959 {
960 _indent(os, stack.size(), indentChars);
961
962 os << "<?" << entry.text << " ";
963 _printAttributes(
|
964 kumpf 1.3 os, entry.attributes.getData(), entry.attributes.size());
|
965 kumpf 1.1 os << "?>";
966 break;
967 }
968
969 case XmlEntry::START_TAG:
970 {
971 _indent(os, stack.size(), indentChars);
972
973 os << "<" << entry.text;
974
|
975 kumpf 1.3 if (entry.attributes.size())
|
976 kumpf 1.1 os << ' ';
977
978 _printAttributes(
|
979 kumpf 1.3 os, entry.attributes.getData(), entry.attributes.size());
|
980 kumpf 1.1 os << ">";
981 stack.push(entry.text);
982 break;
983 }
984
985 case XmlEntry::EMPTY_TAG:
986 {
987 _indent(os, stack.size(), indentChars);
988
989 os << "<" << entry.text << " ";
990 _printAttributes(
|
991 kumpf 1.3 os, entry.attributes.getData(), entry.attributes.size());
|
992 kumpf 1.1 os << "/>";
993 break;
994 }
995
996 case XmlEntry::END_TAG:
997 {
998 if (!stack.isEmpty() && strcmp(stack.top(), entry.text) == 0)
999 stack.pop();
1000
1001 _indent(os, stack.size(), indentChars);
1002
1003 os << "</" << entry.text << ">";
1004 break;
1005 }
1006
1007 case XmlEntry::COMMENT:
1008 {
1009 _indent(os, stack.size(), indentChars);
1010 os << "<!--";
1011 _appendSpecial(os, entry.text);
1012 os << "-->";
1013 kumpf 1.1 break;
1014 }
1015
1016 case XmlEntry::CONTENT:
1017 {
1018 _indent(os, stack.size(), indentChars);
1019 _appendSpecial(os, entry.text);
1020 break;
1021 }
1022
1023 case XmlEntry::CDATA:
1024 {
1025 _indent(os, stack.size(), indentChars);
1026 os << "<![CDATA[" << entry.text << "]]>";
1027 break;
1028 }
1029
1030 case XmlEntry::DOCTYPE:
1031 {
1032 _indent(os, stack.size(), indentChars);
1033 os << "<!DOCTYPE...>";
1034 kumpf 1.1 break;
1035 }
1036 }
1037
1038 os << PEGASUS_STD(endl);
1039 }
1040 }
1041
1042 PEGASUS_NAMESPACE_END
|