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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2