(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 karl        1.8.2.2 
 339                                                        
 340                     //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                     static inline Boolean isSpecialChar(const char &c) 
 345                     { 
 346                     #if CHAR_MIN < 0
 347                         return (((c < 0x20) && (c >= 0)) || (c == 0x7f)); 
 348                     #else
 349                         return ((c < 0x20) || (c == 0x7f)); 
 350                     #endif
 351                     }
 352                     
 353 kumpf       1.1     void XmlGenerator::_appendSpecialChar(PEGASUS_STD(ostream)& os, char c)
 354                     {
 355 karl        1.8.2.2     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 karl        1.8.2.1         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 karl        1.8.2.1         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 karl        1.8.2.1         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