(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 karl        1.8.2.1         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 karl        1.8.2.1         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 karl        1.8.2.1         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