(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 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 venkat.puvvada 1.9         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 venkat.puvvada 1.9         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 venkat.puvvada 1.9         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