(file) Return to XmlGenerator.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 kumpf 1.1 //%2006////////////////////////////////////////////////////////////////////////
  2           //
  3           // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4           // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5           // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6           // IBM Corp.; EMC Corporation, The Open Group.
  7           // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8           // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9           // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10           // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11           // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12           // EMC Corporation; Symantec Corporation; The Open Group.
 13           //
 14           // Permission is hereby granted, free of charge, to any person obtaining a copy
 15           // of this software and associated documentation files (the "Software"), to
 16           // deal in the Software without restriction, including without limitation the
 17           // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18           // sell copies of the Software, and to permit persons to whom the Software is
 19           // furnished to do so, subject to the following conditions:
 20           // 
 21           // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22 kumpf 1.1 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23           // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24           // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25           // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26           // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27           // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28           // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29           //
 30           //==============================================================================
 31           //
 32           //%/////////////////////////////////////////////////////////////////////////////
 33           
 34           #include <cstdlib>
 35           #include <cstdio>
 36           
 37           #include <Pegasus/Common/Config.h>
 38           #include "XmlGenerator.h"
 39           #include "Constants.h"
 40           #include "StrLit.h"
 41           #include "CommonUTF.h"
 42           #include "StringConversion.h"
 43 kumpf 1.1 #include "LanguageParser.h"
 44           #include "AutoPtr.h"
 45           
 46           PEGASUS_NAMESPACE_BEGIN
 47           
 48           ////////////////////////////////////////////////////////////////////////////////
 49           //
 50           // SpecialChar and table.
 51           //
 52           ////////////////////////////////////////////////////////////////////////////////
 53           
 54           // Note: we cannot use StrLit here since it has a constructor (forbids
 55           // structure initialization).
 56           
 57           struct SpecialChar
 58           {
 59               const char* str;
 60               Uint32 size;
 61           };
 62           
 63           // Defines encodings of special characters. Just use a 7-bit ASCII character
 64 kumpf 1.1 // as an index into this array to retrieve its string encoding and encoding
 65           // length in bytes.
 66           static const SpecialChar _specialChars[] =
 67           {
 68               {STRLIT_ARGS("&#0;")},
 69               {STRLIT_ARGS("&#1;")},
 70               {STRLIT_ARGS("&#2;")},
 71               {STRLIT_ARGS("&#3;")},
 72               {STRLIT_ARGS("&#4;")},
 73               {STRLIT_ARGS("&#5;")},
 74               {STRLIT_ARGS("&#6;")},
 75               {STRLIT_ARGS("&#7;")},
 76               {STRLIT_ARGS("&#8;")},
 77               {STRLIT_ARGS("&#9;")},
 78               {STRLIT_ARGS("&#10;")},
 79               {STRLIT_ARGS("&#11;")},
 80               {STRLIT_ARGS("&#12;")},
 81               {STRLIT_ARGS("&#13;")},
 82               {STRLIT_ARGS("&#14;")},
 83               {STRLIT_ARGS("&#15;")},
 84               {STRLIT_ARGS("&#16;")},
 85 kumpf 1.1     {STRLIT_ARGS("&#17;")},
 86               {STRLIT_ARGS("&#18;")},
 87               {STRLIT_ARGS("&#19;")},
 88               {STRLIT_ARGS("&#20;")},
 89               {STRLIT_ARGS("&#21;")},
 90               {STRLIT_ARGS("&#22;")},
 91               {STRLIT_ARGS("&#23;")},
 92               {STRLIT_ARGS("&#24;")},
 93               {STRLIT_ARGS("&#25;")},
 94               {STRLIT_ARGS("&#26;")},
 95               {STRLIT_ARGS("&#27;")},
 96               {STRLIT_ARGS("&#28;")},
 97               {STRLIT_ARGS("&#29;")},
 98               {STRLIT_ARGS("&#30;")},
 99               {STRLIT_ARGS("&#31;")},
100               {STRLIT_ARGS(" ")},
101               {STRLIT_ARGS("!")},
102               {STRLIT_ARGS("&quot;")},
103               {STRLIT_ARGS("#")},
104               {STRLIT_ARGS("$")},
105               {STRLIT_ARGS("%")},
106 kumpf 1.1     {STRLIT_ARGS("&amp;")},
107               {STRLIT_ARGS("&apos;")},
108               {STRLIT_ARGS("(")},
109               {STRLIT_ARGS(")")},
110               {STRLIT_ARGS("*")},
111               {STRLIT_ARGS("+")},
112               {STRLIT_ARGS(",")},
113               {STRLIT_ARGS("-")},
114               {STRLIT_ARGS(".")},
115               {STRLIT_ARGS("/")},
116               {STRLIT_ARGS("0")},
117               {STRLIT_ARGS("1")},
118               {STRLIT_ARGS("2")},
119               {STRLIT_ARGS("3")},
120               {STRLIT_ARGS("4")},
121               {STRLIT_ARGS("5")},
122               {STRLIT_ARGS("6")},
123               {STRLIT_ARGS("7")},
124               {STRLIT_ARGS("8")},
125               {STRLIT_ARGS("9")},
126               {STRLIT_ARGS(":")},
127 kumpf 1.1     {STRLIT_ARGS(";")},
128               {STRLIT_ARGS("&lt;")},
129               {STRLIT_ARGS("=")},
130               {STRLIT_ARGS("&gt;")},
131               {STRLIT_ARGS("?")},
132               {STRLIT_ARGS("@")},
133               {STRLIT_ARGS("A")},
134               {STRLIT_ARGS("B")},
135               {STRLIT_ARGS("C")},
136               {STRLIT_ARGS("D")},
137               {STRLIT_ARGS("E")},
138               {STRLIT_ARGS("F")},
139               {STRLIT_ARGS("G")},
140               {STRLIT_ARGS("H")},
141               {STRLIT_ARGS("I")},
142               {STRLIT_ARGS("J")},
143               {STRLIT_ARGS("K")},
144               {STRLIT_ARGS("L")},
145               {STRLIT_ARGS("M")},
146               {STRLIT_ARGS("N")},
147               {STRLIT_ARGS("O")},
148 kumpf 1.1     {STRLIT_ARGS("P")},
149               {STRLIT_ARGS("Q")},
150               {STRLIT_ARGS("R")},
151               {STRLIT_ARGS("S")},
152               {STRLIT_ARGS("T")},
153               {STRLIT_ARGS("U")},
154               {STRLIT_ARGS("V")},
155               {STRLIT_ARGS("W")},
156               {STRLIT_ARGS("X")},
157               {STRLIT_ARGS("Y")},
158               {STRLIT_ARGS("Z")},
159               {STRLIT_ARGS("[")},
160               {STRLIT_ARGS("\\")},
161               {STRLIT_ARGS("]")},
162               {STRLIT_ARGS("^")},
163               {STRLIT_ARGS("_")},
164               {STRLIT_ARGS("`")},
165               {STRLIT_ARGS("a")},
166               {STRLIT_ARGS("b")},
167               {STRLIT_ARGS("c")},
168               {STRLIT_ARGS("d")},
169 kumpf 1.1     {STRLIT_ARGS("e")},
170               {STRLIT_ARGS("f")},
171               {STRLIT_ARGS("g")},
172               {STRLIT_ARGS("h")},
173               {STRLIT_ARGS("i")},
174               {STRLIT_ARGS("j")},
175               {STRLIT_ARGS("k")},
176               {STRLIT_ARGS("l")},
177               {STRLIT_ARGS("m")},
178               {STRLIT_ARGS("n")},
179               {STRLIT_ARGS("o")},
180               {STRLIT_ARGS("p")},
181               {STRLIT_ARGS("q")},
182               {STRLIT_ARGS("r")},
183               {STRLIT_ARGS("s")},
184               {STRLIT_ARGS("t")},
185               {STRLIT_ARGS("u")},
186               {STRLIT_ARGS("v")},
187               {STRLIT_ARGS("w")},
188               {STRLIT_ARGS("x")},
189               {STRLIT_ARGS("y")},
190 kumpf 1.1     {STRLIT_ARGS("z")},
191               {STRLIT_ARGS("{")},
192               {STRLIT_ARGS("|")},
193               {STRLIT_ARGS("}")},
194               {STRLIT_ARGS("~")},
195               {STRLIT_ARGS("&#127;")},
196           };
197           
198           // If _isSpecialChar7[ch] is true, then ch is a special character, which must
199           // have a special encoding in XML. But only use 7-bit ASCII characters to
200           // index this array.
201           static const int _isSpecialChar7[] =
202           {
203               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,
204               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,
205               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,
206               0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,
207           };
208           
209           ////////////////////////////////////////////////////////////////////////////////
210           
211 kumpf 1.1 Buffer& operator<<(Buffer& out, const Char16& x)
212           {
213               XmlGenerator::append(out, x);
214               return out;
215           }
216           
217           Buffer& operator<<(Buffer& out, const String& x)
218           {
219               XmlGenerator::append(out, x);
220               return out;
221           }
222           
223           Buffer& operator<<(Buffer& out, const Buffer& x)
224           {
225               out.append(x.getData(), x.size());
226               return out;
227           }
228           
229           Buffer& operator<<(Buffer& out, Uint32 x)
230           {
231               XmlGenerator::append(out, x);
232 kumpf 1.1     return out;
233           }
234           
235           Buffer& operator<<(Buffer& out, const CIMName& name)
236           {
237               XmlGenerator::append(out, name.getString ());
238               return out;
239           }
240           
241           Buffer& operator<<(Buffer& out, const AcceptLanguageList& al)
242           {
243               XmlGenerator::append(out, LanguageParser::buildAcceptLanguageHeader(al));
244               return out;
245           }
246           
247           Buffer& operator<<(Buffer& out, const ContentLanguageList& cl)
248           {
249               XmlGenerator::append(out, LanguageParser::buildContentLanguageHeader(cl));
250               return out;
251           }
252           
253 kumpf 1.1 void XmlGenerator::_appendChar(Buffer& out, const Char16& c)
254           {
255               // We need to convert the Char16 to UTF8 then append the UTF8
256               // character into the array.
257               // NOTE: The UTF8 character could be several bytes long.
258               // WARNING: This function will put in replacement character for
259               // all characters that have surogate pairs.
260               char str[6];
261               memset(str,0x00,sizeof(str));
262               Uint8* charIN = (Uint8 *)&c;
263           
264               const Uint16 *strsrc = (Uint16 *)charIN;
265               Uint16 *endsrc = (Uint16 *)&charIN[1];
266           
267               Uint8 *strtgt = (Uint8 *)str;
268               Uint8 *endtgt = (Uint8 *)&str[5];
269           
270               UTF16toUTF8(
271                   &strsrc,
272                   endsrc,
273                   &strtgt,
274 kumpf 1.1         endtgt);
275           
276               out.append(str, UTF_8_COUNT_TRAIL_BYTES(str[0]) + 1);
277           }
278           
279           void XmlGenerator::_appendSpecialChar7(Buffer& out, char c)
280           {
281               if (_isSpecialChar7[int(c)])
282                   out.append(_specialChars[int(c)].str, _specialChars[int(c)].size);
283               else
284                   out.append(c);
285           }
286           
287           void XmlGenerator::_appendSpecialChar(Buffer& out, const Char16& c)
288           {
289               if (c < 128)
290                   _appendSpecialChar7(out, char(c));
291               else
292                   _appendChar(out, c);
293           }
294           
295 kumpf 1.1 void XmlGenerator::_appendSpecialChar(PEGASUS_STD(ostream)& os, char c)
296           {
297               if ( ((c < 0x20) && (c >= 0)) || (c == 0x7f) )
298               {
299                   char scratchBuffer[22];
300                   Uint32 outputLength;
301                   const char * output = Uint8ToString(scratchBuffer, 
302                                                       static_cast<Uint8>(c), 
303                                                       outputLength);
304                   os << "&#" << output << ";";
305               }
306               else
307               {
308                   switch (c)
309                   {
310                       case '&':
311                           os << "&amp;";
312                           break;
313           
314                       case '<':
315                           os << "&lt;";
316 kumpf 1.1                 break;
317           
318                       case '>':
319                           os << "&gt;";
320                           break;
321           
322                       case '"':
323                           os << "&quot;";
324                           break;
325           
326                       case '\'':
327                           os << "&apos;";
328                           break;
329           
330                       default:
331                           os << c;
332                   }
333               }
334           }
335           
336           void XmlGenerator::_appendSurrogatePair(Buffer& out, Uint16 high, Uint16 low)
337 kumpf 1.1 {
338               char str[6];
339               Uint8 charIN[5];
340               memset(str,0x00,sizeof(str));
341               memcpy(&charIN,&high,2);
342               memcpy(&charIN[2],&low,2);
343               const Uint16 *strsrc = (Uint16 *)charIN;
344               Uint16 *endsrc = (Uint16 *)&charIN[3];
345           
346               Uint8 *strtgt = (Uint8 *)str;
347               Uint8 *endtgt = (Uint8 *)&str[5];
348           
349               UTF16toUTF8(
350                   &strsrc,
351                   endsrc,
352                   &strtgt,
353                   endtgt);
354           
355               Uint32 number1 = UTF_8_COUNT_TRAIL_BYTES(str[0]) + 1;
356               out.append(str,number1);
357           }
358 kumpf 1.1 
359           void XmlGenerator::_appendSpecial(PEGASUS_STD(ostream)& os, const char* str)
360           {
361               while (*str)
362                   _appendSpecialChar(os, *str++);
363           }
364           
365           // On windows sprintf outputs 3 digit precision exponent prepending
366           // zeros. Make it 2 digit precision if first digit is zero in the exponent.
367           #ifdef PEGASUS_OS_TYPE_WINDOWS
368           inline void _normalizeRealValueString(char *str)
369           {
370               // skip initial sign value...
371               if (*str == '-' || *str == '+')
372               {
373                   ++str;
374               }
375               while (*str && *str != '+' && *str != '-')
376               {
377                   ++str;
378               }
379 kumpf 1.1     if (*str && * ++str == '0')
380               {
381                   *str = *(str+1);
382                   *(str+1) = *(str+2);
383                   *(str+2) = 0;
384               }
385           }
386           #endif
387           
388           void XmlGenerator::append(Buffer& out, const Char16& x)
389           {
390               _appendChar(out, x);
391           }
392           
393           void XmlGenerator::append(Buffer& out, Boolean x)
394           {
395               if (x)
396                   out.append(STRLIT_ARGS("TRUE"));
397               else
398                   out.append(STRLIT_ARGS("FALSE"));
399           }
400 kumpf 1.1 
401           void XmlGenerator::append(Buffer& out, Uint32 x)
402           {
403               Uint32 outputLength=0;
404               char buffer[22];
405               const char * output = Uint32ToString(buffer, x, outputLength);
406               out.append(output, outputLength);
407           }
408           
409           void XmlGenerator::append(Buffer& out, Sint32 x)
410           {
411               Uint32 outputLength=0;
412               char buffer[22];
413               const char * output = Sint32ToString(buffer, x, outputLength);
414               out.append(output, outputLength);
415           }
416           
417           void XmlGenerator::append(Buffer& out, Uint64 x)
418           {
419               Uint32 outputLength=0;
420               char buffer[22];
421 kumpf 1.1     const char * output = Uint64ToString(buffer, x, outputLength);
422               out.append(output, outputLength);
423           }
424           
425           void XmlGenerator::append(Buffer& out, Sint64 x)
426           {
427               Uint32 outputLength=0;
428               char buffer[22];
429               const char * output = Sint64ToString(buffer, x, outputLength);
430               out.append(output, outputLength);
431           }
432           
433           void XmlGenerator::append(Buffer& out, Real32 x)
434           {
435               char buffer[128];
436               // %.7e gives '[-]m.ddddddde+/-xx', which seems compatible with the format
437               // given in the CIM/XML spec, and the precision required by the CIM 2.2 spec
438               // (4 byte IEEE floating point)
439               sprintf(buffer, "%.7e", x);
440           #ifdef PEGASUS_OS_TYPE_WINDOWS
441               _normalizeRealValueString(buffer);
442 kumpf 1.1 #endif
443               append(out, buffer);
444           }
445           
446           void XmlGenerator::append(Buffer& out, Real64 x)
447           {
448               char buffer[128];
449               // %.16e gives '[-]m.dddddddddddddddde+/-xx', which seems compatible
450               // with the format given in the CIM/XML spec, and the precision required
451               // by the CIM 2.2 spec (8 byte IEEE floating point)
452               sprintf(buffer, "%.16e", x);
453           #ifdef PEGASUS_OS_TYPE_WINDOWS
454               _normalizeRealValueString(buffer);
455           #endif
456               append(out, buffer);
457           }
458           
459           void XmlGenerator::append(Buffer& out, const char* str)
460           {
461               size_t n = strlen(str);
462               out.append(str, n);
463 kumpf 1.1 }
464           
465           void XmlGenerator::append(Buffer& out, const String& str)
466           {
467               const Uint16* p = (const Uint16*)str.getChar16Data();
468               size_t n = str.size();
469           
470               // Handle leading ASCII 7 characers in these next two loops (use unrolling).
471           
472               while (n >= 8 && ((p[0]|p[1]|p[2]|p[3]|p[4]|p[5]|p[6]|p[7]) & 0xFF80) == 0)
473               {
474                   out.append(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
475                   p += 8;
476                   n -= 8;
477               }
478           
479               while (n >= 4 && ((p[0]|p[1]|p[2]|p[3]) & 0xFF80) == 0)
480               {
481                   out.append(p[0], p[1], p[2], p[3]);
482                   p += 4;
483                   n -= 4;
484 kumpf 1.1     }
485           
486               while (n--)
487               {
488                   Uint16 c = *p++;
489           
490                   // Special processing for UTF8 case:
491           
492                   if (c < 128)
493                   {
494                       out.append(c);
495                       continue;
496                   }
497           
498                   // Handle UTF8 case (if reached).
499           
500                   if (((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
501                       ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE)))
502                   {
503                       Char16 highSurrogate = p[-1];
504                       Char16 lowSurrogate = p[0];
505 kumpf 1.1             p++;
506                       n--;
507           
508                       _appendSurrogatePair(
509                           out, Uint16(highSurrogate),Uint16(lowSurrogate));
510                   }
511                   else
512                   {
513                       _appendChar(out, c);
514                   }
515               }
516           }
517           
518           void XmlGenerator::appendSpecial(Buffer& out, const Char16& x)
519           {
520               _appendSpecialChar(out, x);
521           }
522           
523           void XmlGenerator::appendSpecial(Buffer& out, char x)
524           {
525               _appendSpecialChar7(out, x);
526 kumpf 1.1 }
527           
528           void XmlGenerator::appendSpecial(Buffer& out, const char* str)
529           {
530               while (*str)
531                   _appendSpecialChar7(out, *str++);
532           }
533           
534           void XmlGenerator::appendSpecial(Buffer& out, const String& str)
535           {
536               const Uint16* p = (const Uint16*)str.getChar16Data();
537               // prevCharIsSpace is true when the last character written to the Buffer
538               // is a space character (not a character reference).
539               Boolean prevCharIsSpace = false;
540           
541               // If the first character is a space, use a character reference to avoid
542               // space compression.
543               if (*p == ' ')
544               {
545                   out.append(STRLIT_ARGS("&#32;"));
546                   p++;
547 kumpf 1.1     }
548           
549               Uint16 c;
550               while ((c = *p++) != 0)
551               {
552                   if (c < 128)
553                   {
554                       if (_isSpecialChar7[c])
555                       {
556                           // Write the character reference for the special character
557                           out.append(
558                               _specialChars[int(c)].str, _specialChars[int(c)].size);
559                           prevCharIsSpace = false;
560                       }
561                       else if (prevCharIsSpace && (c == ' '))
562                       {
563                           // Write the character reference for the space character, to
564                           // avoid compression
565                           out.append(STRLIT_ARGS("&#32;"));
566                           prevCharIsSpace = false;
567                       }
568 kumpf 1.1             else
569                       {
570                           out.append(c);
571                           prevCharIsSpace = (c == ' ');
572                       }
573                   }
574                   else
575                   {
576                       // Handle UTF8 case
577           
578                       if ((((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
579                            ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) &&
580                           *p)
581                       {
582                           _appendSurrogatePair(out, c, *p++);
583                       }
584                       else
585                       {
586                           _appendChar(out, c);
587                       }
588           
589 kumpf 1.1             prevCharIsSpace = false;
590                   }
591               }
592           
593               // If the last character is a space, use a character reference to avoid
594               // space compression.
595               if (prevCharIsSpace)
596               {
597                   out.remove(out.size() - 1);
598                   out.append(STRLIT_ARGS("&#32;"));
599               }
600           }
601           
602           // See http://www.ietf.org/rfc/rfc2396.txt section 2
603           // Reserved characters = ';' '/' '?' ':' '@' '&' '=' '+' '$' ','
604           // Excluded characters:
605           //   Control characters = 0x00-0x1f, 0x7f
606           //   Space character = 0x20
607           //   Delimiters = '<' '>' '#' '%' '"'
608           //   Unwise = '{' '}' '|' '\\' '^' '[' ']' '`'
609           //
610 kumpf 1.1 
611           static const char _is_uri[128] =
612           {
613               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,
614               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,
615               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,
616               0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,
617           };
618           
619           // Perform the necessary URI encoding of characters in HTTP header values.
620           // This is required by the HTTP/1.1 specification and the CIM/HTTP
621           // Specification (section 3.3.2).
622           void XmlGenerator::_encodeURIChar(String& outString, Sint8 char8)
623           {
624               Uint8 c = (Uint8)char8;
625           
626           #ifndef PEGASUS_DO_NOT_IMPLEMENT_URI_ENCODING
627               if (c > 127 || _is_uri[int(c)])
628               {
629                   char hexencoding[4];
630                   int n = sprintf(hexencoding, "%%%X%X", c/16, c%16);
631 kumpf 1.1 #ifdef PEGASUS_USE_STRING_EXTENSIONS
632                   outString.append(hexencoding, n);
633           #else /* PEGASUS_USE_STRING_EXTENSIONS */
634                   outString.append(hexencoding);
635           #endif /* PEGASUS_USE_STRING_EXTENSIONS */
636               }
637               else
638           #endif
639               {
640                   outString.append((Uint16)c);
641               }
642           }
643           
644           String XmlGenerator::encodeURICharacters(const Buffer& uriString)
645           {
646               String encodedString;
647           
648               for (Uint32 i=0; i<uriString.size(); i++)
649               {
650                   _encodeURIChar(encodedString, uriString[i]);
651               }
652 kumpf 1.1 
653               return encodedString;
654           }
655           
656           String XmlGenerator::encodeURICharacters(const String& uriString)
657           {
658               String encodedString;
659           
660               // See the "CIM Operations over HTTP" spec, section 3.3.2 and
661               // 3.3.3, for the treatment of non US-ASCII (UTF-8) chars
662           
663               // First, convert to UTF-8 (include handling of surrogate pairs)
664               Buffer utf8;
665               for (Uint32 i = 0; i < uriString.size(); i++)
666               {
667                   Uint16 c = uriString[i];
668           
669                   if (((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
670                       ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE)))
671                   {
672                       Char16 highSurrogate = uriString[i];
673 kumpf 1.1             Char16 lowSurrogate = uriString[++i];
674           
675                       _appendSurrogatePair(
676                           utf8, Uint16(highSurrogate),Uint16(lowSurrogate));
677                   }
678                   else
679                   {
680                       _appendChar(utf8, uriString[i]);
681                   }
682               }
683           
684               // Second, escape the non HTTP-safe chars
685               for (Uint32 i=0; i<utf8.size(); i++)
686               {
687                   _encodeURIChar(encodedString, utf8[i]);
688               }
689           
690               return encodedString;
691           }
692           
693           //------------------------------------------------------------------------------
694 kumpf 1.1 //
695           // _printAttributes()
696           //
697           //------------------------------------------------------------------------------
698           
699           void XmlGenerator::_printAttributes(
700               PEGASUS_STD(ostream)& os,
701               const XmlAttribute* attributes,
702               Uint32 attributeCount)
703           {
704               for (Uint32 i = 0; i < attributeCount; i++)
705               {
706                   os << attributes[i].name << "=";
707           
708                   os << '"';
709                   _appendSpecial(os, attributes[i].value);
710                   os << '"';
711           
712                   if (i + 1 != attributeCount)
713                       os << ' ';
714               }
715 kumpf 1.1 }
716           
717           //------------------------------------------------------------------------------
718           //
719           // _indent()
720           //
721           //------------------------------------------------------------------------------
722           
723           void XmlGenerator::_indent(
724               PEGASUS_STD(ostream)& os,
725               Uint32 level,
726               Uint32 indentChars)
727           {
728               Uint32 n = level * indentChars;
729           
730               for (Uint32 i = 0; i < n; i++)
731                   os << ' ';
732           }
733           
734           //------------------------------------------------------------------------------
735           //
736 kumpf 1.1 // indentedPrint()
737           //
738           //------------------------------------------------------------------------------
739           
740           void XmlGenerator::indentedPrint(
741               PEGASUS_STD(ostream)& os,
742               const char* text,
743               Uint32 indentChars)
744           {
745               AutoArrayPtr<char> tmp(strcpy(new char[strlen(text) + 1], text));
746           
747               XmlParser parser(tmp.get());
748               XmlEntry entry;
749               Stack<const char*> stack;
750           
751               while (parser.next(entry))
752               {
753                   switch (entry.type)
754                   {
755                       case XmlEntry::XML_DECLARATION:
756                       {
757 kumpf 1.1                 _indent(os, stack.size(), indentChars);
758           
759                           os << "<?" << entry.text << " ";
760                           _printAttributes(
761                               os, entry.attributes, entry.attributeCount);
762                           os << "?>";
763                           break;
764                       }
765           
766                       case XmlEntry::START_TAG:
767                       {
768                           _indent(os, stack.size(), indentChars);
769           
770                           os << "<" << entry.text;
771           
772                           if (entry.attributeCount)
773                               os << ' ';
774           
775                           _printAttributes(
776                               os, entry.attributes, entry.attributeCount);
777                           os << ">";
778 kumpf 1.1                 stack.push(entry.text);
779                           break;
780                       }
781           
782                       case XmlEntry::EMPTY_TAG:
783                       {
784                           _indent(os, stack.size(), indentChars);
785           
786                           os << "<" << entry.text << " ";
787                           _printAttributes(
788                               os, entry.attributes, entry.attributeCount);
789                           os << "/>";
790                           break;
791                       }
792           
793                       case XmlEntry::END_TAG:
794                       {
795                           if (!stack.isEmpty() && strcmp(stack.top(), entry.text) == 0)
796                               stack.pop();
797           
798                           _indent(os, stack.size(), indentChars);
799 kumpf 1.1 
800                           os << "</" << entry.text << ">";
801                           break;
802                       }
803           
804                       case XmlEntry::COMMENT:
805                       {
806                           _indent(os, stack.size(), indentChars);
807                           os << "<!--";
808                           _appendSpecial(os, entry.text);
809                           os << "-->";
810                           break;
811                       }
812           
813                       case XmlEntry::CONTENT:
814                       {
815                           _indent(os, stack.size(), indentChars);
816                           _appendSpecial(os, entry.text);
817                           break;
818                       }
819           
820 kumpf 1.1             case XmlEntry::CDATA:
821                       {
822                           _indent(os, stack.size(), indentChars);
823                           os << "<![CDATA[" << entry.text << "]]>";
824                           break;
825                       }
826           
827                       case XmlEntry::DOCTYPE:
828                       {
829                           _indent(os, stack.size(), indentChars);
830                           os << "<!DOCTYPE...>";
831                           break;
832                       }
833                   }
834           
835                   os << PEGASUS_STD(endl);
836               }
837           }
838           
839           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2