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

   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("&#0;")},
  67                {STRLIT_ARGS("&#1;")},
  68                {STRLIT_ARGS("&#2;")},
  69                {STRLIT_ARGS("&#3;")},
  70                {STRLIT_ARGS("&#4;")},
  71 kumpf  1.1     {STRLIT_ARGS("&#5;")},
  72                {STRLIT_ARGS("&#6;")},
  73                {STRLIT_ARGS("&#7;")},
  74                {STRLIT_ARGS("&#8;")},
  75                {STRLIT_ARGS("&#9;")},
  76                {STRLIT_ARGS("&#10;")},
  77                {STRLIT_ARGS("&#11;")},
  78                {STRLIT_ARGS("&#12;")},
  79                {STRLIT_ARGS("&#13;")},
  80                {STRLIT_ARGS("&#14;")},
  81                {STRLIT_ARGS("&#15;")},
  82                {STRLIT_ARGS("&#16;")},
  83                {STRLIT_ARGS("&#17;")},
  84                {STRLIT_ARGS("&#18;")},
  85                {STRLIT_ARGS("&#19;")},
  86                {STRLIT_ARGS("&#20;")},
  87                {STRLIT_ARGS("&#21;")},
  88                {STRLIT_ARGS("&#22;")},
  89                {STRLIT_ARGS("&#23;")},
  90                {STRLIT_ARGS("&#24;")},
  91                {STRLIT_ARGS("&#25;")},
  92 kumpf  1.1     {STRLIT_ARGS("&#26;")},
  93                {STRLIT_ARGS("&#27;")},
  94                {STRLIT_ARGS("&#28;")},
  95                {STRLIT_ARGS("&#29;")},
  96                {STRLIT_ARGS("&#30;")},
  97                {STRLIT_ARGS("&#31;")},
  98                {STRLIT_ARGS(" ")},
  99                {STRLIT_ARGS("!")},
 100                {STRLIT_ARGS("&quot;")},
 101                {STRLIT_ARGS("#")},
 102                {STRLIT_ARGS("$")},
 103                {STRLIT_ARGS("%")},
 104                {STRLIT_ARGS("&amp;")},
 105                {STRLIT_ARGS("&apos;")},
 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("&lt;")},
 127                {STRLIT_ARGS("=")},
 128                {STRLIT_ARGS("&gt;")},
 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("&#127;")},
 194            };
 195            
 196            // If _isSpecialChar7[ch] is true, then ch is a special character, which must
 197 marek  1.8 // 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.8 // 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.8 // 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 ashok.pathak 1.11 
 339                                                      
 340 dl.meetei    1.12 //Based on the platforms CHAR_MIN == -127 or CHAR_MIN == 0
 341                   //The above value is used to decide if the platform assumes
 342                   //char as signed char or unsigned char required to stop build
 343                   //btreaks for PPC under linux
 344 dl.meetei    1.13 static inline Boolean isSpecialChar(const char &c) 
 345 ashok.pathak 1.11 { 
 346 dl.meetei    1.12 #if CHAR_MIN < 0
 347 ashok.pathak 1.11     return (((c < 0x20) && (c >= 0)) || (c == 0x7f)); 
 348 dl.meetei    1.12 #else
 349                       return ((c < 0x20) || (c == 0x7f)); 
 350                   #endif
 351                   }
 352 ashok.pathak 1.11 
 353 kumpf        1.1  void XmlGenerator::_appendSpecialChar(PEGASUS_STD(ostream)& os, char c)
 354                   {
 355 dl.meetei    1.12     if(isSpecialChar(c))
 356 kumpf        1.1      {
 357                           char scratchBuffer[22];
 358                           Uint32 outputLength;
 359 kumpf        1.6          const char * output = Uint8ToString(scratchBuffer,
 360                                                               static_cast<Uint8>(c),
 361 kumpf        1.1                                              outputLength);
 362                           os << "&#" << output << ";";
 363                       }
 364                       else
 365                       {
 366                           switch (c)
 367                           {
 368                               case '&':
 369                                   os << "&amp;";
 370                                   break;
 371                   
 372                               case '<':
 373                                   os << "&lt;";
 374                                   break;
 375                   
 376                               case '>':
 377                                   os << "&gt;";
 378                                   break;
 379                   
 380                               case '"':
 381                                   os << "&quot;";
 382 kumpf        1.1                  break;
 383                   
 384                               case '\'':
 385                                   os << "&apos;";
 386                                   break;
 387                   
 388                               default:
 389                                   os << c;
 390                           }
 391                       }
 392                   }
 393                   
 394                   void XmlGenerator::_appendSurrogatePair(Buffer& out, Uint16 high, Uint16 low)
 395                   {
 396                       char str[6];
 397                       Uint8 charIN[5];
 398                       memset(str,0x00,sizeof(str));
 399                       memcpy(&charIN,&high,2);
 400                       memcpy(&charIN[2],&low,2);
 401                       const Uint16 *strsrc = (Uint16 *)charIN;
 402                       Uint16 *endsrc = (Uint16 *)&charIN[3];
 403 kumpf        1.1  
 404                       Uint8 *strtgt = (Uint8 *)str;
 405                       Uint8 *endtgt = (Uint8 *)&str[5];
 406                   
 407                       UTF16toUTF8(
 408                           &strsrc,
 409                           endsrc,
 410                           &strtgt,
 411                           endtgt);
 412                   
 413                       Uint32 number1 = UTF_8_COUNT_TRAIL_BYTES(str[0]) + 1;
 414                       out.append(str,number1);
 415                   }
 416                   
 417                   void XmlGenerator::_appendSpecial(PEGASUS_STD(ostream)& os, const char* str)
 418                   {
 419                       while (*str)
 420                           _appendSpecialChar(os, *str++);
 421                   }
 422                   
 423                   void XmlGenerator::append(Buffer& out, const Char16& x)
 424 kumpf        1.1  {
 425                       _appendChar(out, x);
 426                   }
 427                   
 428                   void XmlGenerator::append(Buffer& out, Boolean x)
 429                   {
 430                       if (x)
 431                           out.append(STRLIT_ARGS("TRUE"));
 432                       else
 433                           out.append(STRLIT_ARGS("FALSE"));
 434                   }
 435                   
 436                   void XmlGenerator::append(Buffer& out, Uint32 x)
 437                   {
 438                       Uint32 outputLength=0;
 439                       char buffer[22];
 440                       const char * output = Uint32ToString(buffer, x, outputLength);
 441                       out.append(output, outputLength);
 442                   }
 443                   
 444                   void XmlGenerator::append(Buffer& out, Sint32 x)
 445 kumpf        1.1  {
 446                       Uint32 outputLength=0;
 447                       char buffer[22];
 448                       const char * output = Sint32ToString(buffer, x, outputLength);
 449                       out.append(output, outputLength);
 450                   }
 451                   
 452                   void XmlGenerator::append(Buffer& out, Uint64 x)
 453                   {
 454                       Uint32 outputLength=0;
 455                       char buffer[22];
 456                       const char * output = Uint64ToString(buffer, x, outputLength);
 457                       out.append(output, outputLength);
 458                   }
 459                   
 460                   void XmlGenerator::append(Buffer& out, Sint64 x)
 461                   {
 462                       Uint32 outputLength=0;
 463                       char buffer[22];
 464                       const char * output = Sint64ToString(buffer, x, outputLength);
 465                       out.append(output, outputLength);
 466 kumpf        1.1  }
 467                   
 468                   void XmlGenerator::append(Buffer& out, Real32 x)
 469                   {
 470 thilo.boehm  1.7      Uint32 outputLength=0;
 471 kumpf        1.1      char buffer[128];
 472 thilo.boehm  1.7      const char * output = Real32ToString(buffer, x, outputLength);
 473                       out.append(output, outputLength);
 474 kumpf        1.1  }
 475                   
 476                   void XmlGenerator::append(Buffer& out, Real64 x)
 477                   {
 478 thilo.boehm  1.7      Uint32 outputLength=0;
 479 kumpf        1.1      char buffer[128];
 480 thilo.boehm  1.7      const char * output = Real64ToString(buffer, x, outputLength);
 481                       out.append(output, outputLength);
 482 kumpf        1.1  }
 483                   
 484                   void XmlGenerator::append(Buffer& out, const char* str)
 485                   {
 486                       size_t n = strlen(str);
 487                       out.append(str, n);
 488                   }
 489                   
 490                   void XmlGenerator::append(Buffer& out, const String& str)
 491                   {
 492                       const Uint16* p = (const Uint16*)str.getChar16Data();
 493                       size_t n = str.size();
 494                   
 495                       // Handle leading ASCII 7 characers in these next two loops (use unrolling).
 496                   
 497                       while (n >= 8 && ((p[0]|p[1]|p[2]|p[3]|p[4]|p[5]|p[6]|p[7]) & 0xFF80) == 0)
 498                       {
 499                           out.append(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
 500                           p += 8;
 501                           n -= 8;
 502                       }
 503 kumpf        1.1  
 504                       while (n >= 4 && ((p[0]|p[1]|p[2]|p[3]) & 0xFF80) == 0)
 505                       {
 506                           out.append(p[0], p[1], p[2], p[3]);
 507                           p += 4;
 508                           n -= 4;
 509                       }
 510                   
 511                       while (n--)
 512                       {
 513                           Uint16 c = *p++;
 514                   
 515                           // Special processing for UTF8 case:
 516                   
 517                           if (c < 128)
 518                           {
 519                               out.append(c);
 520                               continue;
 521                           }
 522                   
 523                           // Handle UTF8 case (if reached).
 524 kumpf        1.1  
 525                           if (((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
 526                               ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE)))
 527                           {
 528                               Char16 highSurrogate = p[-1];
 529                               Char16 lowSurrogate = p[0];
 530                               p++;
 531                               n--;
 532                   
 533                               _appendSurrogatePair(
 534                                   out, Uint16(highSurrogate),Uint16(lowSurrogate));
 535                           }
 536                           else
 537                           {
 538                               _appendChar(out, c);
 539                           }
 540                       }
 541                   }
 542                   
 543                   void XmlGenerator::appendSpecial(Buffer& out, const Char16& x)
 544                   {
 545 kumpf        1.1      _appendSpecialChar(out, x);
 546                   }
 547                   
 548                   void XmlGenerator::appendSpecial(Buffer& out, char x)
 549                   {
 550                       _appendSpecialChar7(out, x);
 551                   }
 552                   
 553                   void XmlGenerator::appendSpecial(Buffer& out, const char* str)
 554                   {
 555                       while (*str)
 556                           _appendSpecialChar7(out, *str++);
 557                   }
 558                   
 559                   void XmlGenerator::appendSpecial(Buffer& out, const String& str)
 560                   {
 561                       const Uint16* p = (const Uint16*)str.getChar16Data();
 562                       // prevCharIsSpace is true when the last character written to the Buffer
 563                       // is a space character (not a character reference).
 564                       Boolean prevCharIsSpace = false;
 565                   
 566 kumpf        1.1      // If the first character is a space, use a character reference to avoid
 567                       // space compression.
 568                       if (*p == ' ')
 569                       {
 570                           out.append(STRLIT_ARGS("&#32;"));
 571                           p++;
 572                       }
 573                   
 574                       Uint16 c;
 575                       while ((c = *p++) != 0)
 576                       {
 577                           if (c < 128)
 578                           {
 579                               if (_isSpecialChar7[c])
 580                               {
 581                                   // Write the character reference for the special character
 582                                   out.append(
 583                                       _specialChars[int(c)].str, _specialChars[int(c)].size);
 584                                   prevCharIsSpace = false;
 585                               }
 586                               else if (prevCharIsSpace && (c == ' '))
 587 kumpf        1.1              {
 588                                   // Write the character reference for the space character, to
 589                                   // avoid compression
 590                                   out.append(STRLIT_ARGS("&#32;"));
 591                                   prevCharIsSpace = false;
 592                               }
 593                               else
 594                               {
 595                                   out.append(c);
 596                                   prevCharIsSpace = (c == ' ');
 597                               }
 598                           }
 599                           else
 600                           {
 601                               // Handle UTF8 case
 602                   
 603                               if ((((c >= FIRST_HIGH_SURROGATE) && (c <= LAST_HIGH_SURROGATE)) ||
 604                                    ((c >= FIRST_LOW_SURROGATE) && (c <= LAST_LOW_SURROGATE))) &&
 605                                   *p)
 606                               {
 607                                   _appendSurrogatePair(out, c, *p++);
 608 kumpf        1.1              }
 609                               else
 610                               {
 611                                   _appendChar(out, c);
 612                               }
 613                   
 614                               prevCharIsSpace = false;
 615                           }
 616                       }
 617                   
 618                       // If the last character is a space, use a character reference to avoid
 619                       // space compression.
 620                       if (prevCharIsSpace)
 621                       {
 622                           out.remove(out.size() - 1);
 623                           out.append(STRLIT_ARGS("&#32;"));
 624                       }
 625                   }
 626                   
 627 thilo.boehm  1.7  // str has to be UTF-8 encoded
 628                   // that means the characters used cannot be larger than 7bit ASCII in value
 629                   // range
 630                   void XmlGenerator::appendSpecial(Buffer& out, const char* str, Uint32 size)
 631                   {
 632                       // employ loop unrolling and a less checking optimized Buffer access
 633                   
 634                       // Buffer cannot grow more than 6*size characters (ie. 4*size+2*size)
 635                       Uint32 newMaxSize = (size << 2) + (size << 1);
 636                       if (out.size() + newMaxSize >= out.capacity())
 637                       {
 638                           out.reserveCapacity(out.capacity() + newMaxSize);
 639                       }
 640                   
 641                       // Before using a loop unrolled algorithm to pick out the special chars
 642                       // we are going to assume there is no special char as this is the case most
 643                       // of the time anyway
 644                       Uint32 sizeStart=size;
 645                       const Uint8* p= (const Uint8*) str;
 646                   
 647                       while (size >= 4 &&
 648 thilo.boehm  1.7               (_isNormalChar7[p[0]] &
 649                                 _isNormalChar7[p[1]] &
 650                                 _isNormalChar7[p[2]] &
 651                                 _isNormalChar7[p[3]]))
 652                       {
 653                           size -= 4;
 654                           p += 4;
 655                       }
 656                       out.append_unchecked(str,sizeStart-size);
 657                       str=(const char*)p;
 658                   
 659                       while (size>=8)
 660                       {
 661 venkat.puvvada 1.9          register Uint8 c;
 662 thilo.boehm    1.7          c = str[0];
 663                             if (_isSpecialChar7[c])
 664                             {
 665                                 out.append_unchecked(
 666                                     _specialChars[c].str,
 667                                     _specialChars[c].size);
 668                             }
 669                             else
 670                             {
 671                                 out.append_unchecked(c);
 672                             }
 673                             c = str[1];
 674                             if (_isSpecialChar7[c])
 675                             {
 676                                 out.append_unchecked(
 677                                     _specialChars[c].str,
 678                                     _specialChars[c].size);
 679                             }
 680                             else
 681                             {
 682                                 out.append_unchecked(c);
 683 thilo.boehm    1.7          }
 684                             c = str[2];
 685                             if (_isSpecialChar7[c])
 686                             {
 687                                 out.append_unchecked(
 688                                     _specialChars[c].str,
 689                                     _specialChars[c].size);
 690                             }
 691                             else
 692                             {
 693                                 out.append_unchecked(c);
 694                             }
 695                             c = str[3];
 696                             if (_isSpecialChar7[c])
 697                             {
 698                                 out.append_unchecked(
 699                                     _specialChars[c].str,
 700                                     _specialChars[c].size);
 701                             }
 702                             else
 703                             {
 704 thilo.boehm    1.7              out.append_unchecked(c);
 705                             }
 706                             c = str[4];
 707                             if (_isSpecialChar7[c])
 708                             {
 709                                 out.append_unchecked(
 710                                     _specialChars[c].str,
 711                                     _specialChars[c].size);
 712                             }
 713                             else
 714                             {
 715                                 out.append_unchecked(c);
 716                             }
 717                             c = str[5];
 718                             if (_isSpecialChar7[c])
 719                             {
 720                                 out.append_unchecked(
 721                                     _specialChars[c].str,
 722                                     _specialChars[c].size);
 723                             }
 724                             else
 725 thilo.boehm    1.7          {
 726                                 out.append_unchecked(c);
 727                             }
 728                             c = str[6];
 729                             if (_isSpecialChar7[c])
 730                             {
 731                                 out.append_unchecked(
 732                                     _specialChars[c].str,
 733                                     _specialChars[c].size);
 734                             }
 735                             else
 736                             {
 737                                 out.append_unchecked(c);
 738                             }
 739                             c = str[7];
 740                             if (_isSpecialChar7[c])
 741                             {
 742                                 out.append_unchecked(
 743                                     _specialChars[c].str,
 744                                     _specialChars[c].size);
 745                             }
 746 thilo.boehm    1.7          else
 747                             {
 748                                 out.append_unchecked(c);
 749                             }
 750                             str+=8;
 751                             size-=8;
 752                         }
 753                     
 754                         while (size>=4)
 755                         {
 756 venkat.puvvada 1.9          register Uint8 c;
 757 thilo.boehm    1.7          c = str[0];
 758                             if (_isSpecialChar7[c])
 759                             {
 760                                 out.append_unchecked(
 761                                     _specialChars[c].str,
 762                                     _specialChars[c].size);
 763                             }
 764                             else
 765                             {
 766                                 out.append_unchecked(c);
 767                             }
 768                             c = str[1];
 769                             if (_isSpecialChar7[c])
 770                             {
 771                                 out.append_unchecked(
 772                                     _specialChars[c].str,
 773                                     _specialChars[c].size);
 774                             }
 775                             else
 776                             {
 777                                 out.append_unchecked(c);
 778 thilo.boehm    1.7          }
 779                             c = str[2];
 780                             if (_isSpecialChar7[c])
 781                             {
 782                                 out.append_unchecked(
 783                                     _specialChars[c].str,
 784                                     _specialChars[c].size);
 785                             }
 786                             else
 787                             {
 788                                 out.append_unchecked(c);
 789                             }
 790                             c = str[3];
 791                             if (_isSpecialChar7[c])
 792                             {
 793                                 out.append_unchecked(
 794                                     _specialChars[c].str,
 795                                     _specialChars[c].size);
 796                             }
 797                             else
 798                             {
 799 thilo.boehm    1.7              out.append_unchecked(c);
 800                             }
 801                             str+=4;
 802                             size-=4;
 803                         }
 804                     
 805                         while (size--)
 806                         {
 807 venkat.puvvada 1.9          register Uint8 c;
 808 thilo.boehm    1.7          c=*str;
 809                             if (_isSpecialChar7[c])
 810                             {
 811                                 out.append_unchecked(
 812                                     _specialChars[c].str,
 813                                     _specialChars[c].size);
 814                             }
 815                             else
 816                             {
 817                                 out.append_unchecked(c);
 818                             }
 819                             str++;
 820                         }
 821                     }
 822                     
 823                     
 824 kumpf          1.1  // See http://www.ietf.org/rfc/rfc2396.txt section 2
 825                     // Reserved characters = ';' '/' '?' ':' '@' '&' '=' '+' '$' ','
 826                     // Excluded characters:
 827                     //   Control characters = 0x00-0x1f, 0x7f
 828                     //   Space character = 0x20
 829                     //   Delimiters = '<' '>' '#' '%' '"'
 830                     //   Unwise = '{' '}' '|' '\\' '^' '[' ']' '`'
 831                     //
 832                     
 833                     static const char _is_uri[128] =
 834                     {
 835                         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,
 836                         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,
 837                         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,
 838                         0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,
 839                     };
 840                     
 841                     // Perform the necessary URI encoding of characters in HTTP header values.
 842                     // This is required by the HTTP/1.1 specification and the CIM/HTTP
 843                     // Specification (section 3.3.2).
 844                     void XmlGenerator::_encodeURIChar(String& outString, Sint8 char8)
 845 kumpf          1.1  {
 846                         Uint8 c = (Uint8)char8;
 847                         if (c > 127 || _is_uri[int(c)])
 848                         {
 849                             char hexencoding[4];
 850                             int n = sprintf(hexencoding, "%%%X%X", c/16, c%16);
 851                             outString.append(hexencoding, n);
 852                         }
 853                         else
 854                         {
 855                             outString.append((Uint16)c);
 856                         }
 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 kumpf          1.1      // First, convert to UTF-8 (include handling of surrogate pairs)
 867                         Buffer utf8;
 868                         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 kumpf          1.1      // Second, escape the non HTTP-safe chars
 888                         for (Uint32 i=0; i<utf8.size(); i++)
 889                         {
 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 kumpf          1.1      {
 909                             os << attributes[i].name << "=";
 910                     
 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 kumpf          1.1      Uint32 indentChars)
 930                     {
 931                         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 kumpf          1.1      XmlParser parser(tmp.get());
 951                         XmlEntry entry;
 952                         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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2