1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include <precomp.h> 25 #include <udm/xml/xmlitem.hxx> 26 27 // NOT FULLY DECLARED SERVICES 28 #include <cosv/file.hxx> 29 30 31 namespace csi 32 { 33 namespace xml 34 { 35 36 char cReplacable[256] = 37 { 38 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0 - 49 39 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, // ", & 42 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43 44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50 - 99 45 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, // <, > 46 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 47 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49 50 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 100 - 149 51 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 52 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55 56 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 57 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 60 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 61 62 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 66 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67 68 0, 0, 0, 0, 0, 1 // 69 }; 70 71 72 class MultiItem : public Item 73 { 74 public: 75 MultiItem(); 76 ~MultiItem(); 77 78 void Add( 79 DYN Item * let_dpDatum ) 80 { csv_assert( let_dpDatum != 0 ); 81 aItems.push_back(let_dpDatum); } 82 void Erase() { aItems.erase_all(); } 83 84 private: 85 virtual void do_WriteOut( 86 csv::bostream & io_aFile ) const; 87 // DATA 88 ItemList aItems; 89 }; 90 91 92 void StreamOut( 93 Dyn< Item > & o_rContent, 94 DYN Item * let_dpItem ); 95 inline void 96 StreamOut( AttrList & o_rAttrs, 97 DYN Attribute * let_dpAttr ) 98 { 99 csv_assert( let_dpAttr != 0 ); 100 o_rAttrs.push_back( let_dpAttr ); 101 } 102 103 104 inline void 105 Impl_SetContent( Dyn< Item > & o_rContent, 106 DYN Item * let_dpItem ) 107 { 108 o_rContent = let_dpItem; 109 } 110 111 112 //********************* Attribute ****************************// 113 114 const String attrValueBegin("=\""); 115 const String attrValueEnd("\""); 116 117 void 118 Attribute::WriteOut( csv::bostream & io_aFile ) const 119 { 120 io_aFile.write( Name() ); 121 if ( Value().length() > 0 ) 122 { 123 io_aFile.write( attrValueBegin ); 124 io_aFile.write( Value() ); 125 io_aFile.write( attrValueEnd ); 126 } 127 } 128 129 130 131 //************************ Element ****************************// 132 133 const String newline("\n"); 134 const String space(" "); 135 const String beginTagBegin("<"); 136 const String endTagBegin("</"); 137 const String tagEnd(">"); 138 const String emptyTagEnd("/>"); 139 140 void 141 Element::do_WriteOut( csv::bostream & io_aFile ) const 142 { 143 io_aFile.write( beginTagBegin ); 144 io_aFile.write( inq_TagName() ); 145 146 const AttrList * pAttrs = inq_Attrs(); 147 if ( pAttrs != 0 ) 148 { 149 for ( AttrList::iterator it = pAttrs->begin(); 150 it != pAttrs->end(); 151 ++it ) 152 { 153 154 io_aFile.write( space ); 155 (*it)->WriteOut( io_aFile ); 156 } 157 } 158 159 const Item * pContent = inq_Content(); 160 if ( pContent != 0 ) 161 io_aFile.write( tagEnd ); 162 else 163 { 164 if (FinishEmptyTag_XmlStyle()) 165 io_aFile.write( emptyTagEnd ); 166 else 167 { 168 io_aFile.write( tagEnd ); 169 io_aFile.write( endTagBegin ); 170 io_aFile.write( inq_TagName() ); 171 io_aFile.write( tagEnd ); 172 } 173 } 174 if ( LineBreakAfterBeginTag() ) 175 io_aFile.write( newline ); 176 if ( pContent == 0 ) 177 return; 178 179 pContent->WriteOut( io_aFile ); 180 io_aFile.write( endTagBegin ); 181 io_aFile.write( inq_TagName() ); 182 io_aFile.write( tagEnd ); 183 if ( LineBreakAfterEndTag() ) 184 io_aFile.write( newline ); 185 } 186 187 bool 188 Element::FinishEmptyTag_XmlStyle() const 189 { 190 return true; 191 } 192 193 bool 194 Element::LineBreakAfterBeginTag() const 195 { 196 return false; 197 } 198 199 bool 200 Element::LineBreakAfterEndTag() const 201 { 202 return LineBreakAfterBeginTag(); 203 } 204 205 206 //************************ EmptyElement ****************************// 207 208 void 209 EmptyElement::op_streamout( DYN Item * ) 210 { 211 // Does nothing. 212 } 213 214 void 215 EmptyElement::op_streamout( DYN Attribute * let_dpAttr ) 216 { 217 StreamOut( inq_RefAttrs(), let_dpAttr ); 218 } 219 220 void 221 EmptyElement::do_SetContent( DYN Item * ) 222 { 223 // Does nothing. 224 } 225 226 const Item * 227 EmptyElement::inq_Content() const 228 { 229 return 0; 230 } 231 232 const AttrList * 233 EmptyElement::inq_Attrs() const 234 { 235 return & const_cast< EmptyElement* >(this)->inq_RefAttrs(); 236 } 237 238 239 //************************ PureElement ****************************// 240 241 void 242 PureElement::op_streamout( DYN Item * let_dpItem ) 243 { 244 StreamOut( inq_RefContent(), let_dpItem ); 245 } 246 247 void 248 PureElement::op_streamout( DYN Attribute * ) 249 { 250 // Does nothing. 251 } 252 253 void 254 PureElement::do_SetContent( DYN Item * let_dpItem ) 255 { 256 Impl_SetContent( inq_RefContent(), let_dpItem ); 257 } 258 259 const Item * 260 PureElement::inq_Content() const 261 { 262 return const_cast< PureElement* >(this)->inq_RefContent().Ptr(); 263 } 264 265 const AttrList * 266 PureElement::inq_Attrs() const 267 { 268 return 0; 269 } 270 271 272 //*************************** SglTag **************************// 273 274 void 275 SglTag::op_streamout( DYN Item * ) 276 { 277 // Does nothing. 278 } 279 280 void 281 SglTag::op_streamout( DYN Attribute * ) 282 { 283 // Does nothing. 284 } 285 286 void 287 SglTag::do_SetContent( DYN Item *) 288 { 289 // Does nothing. 290 } 291 292 const Item * 293 SglTag::inq_Content() const 294 { 295 return 0; 296 } 297 298 const AttrList * 299 SglTag::inq_Attrs() const 300 { 301 return 0; 302 } 303 304 305 //*************************** AnElement **************************// 306 307 AnElement::AnElement( const String & i_sTagName ) 308 : sTagName( i_sTagName ) 309 // pContent, 310 // aAttrs 311 { 312 } 313 314 AnElement::AnElement( const char * i_sTagName ) 315 : sTagName( i_sTagName ) 316 // pContent, 317 // aAttrs 318 { 319 } 320 321 AnElement::~AnElement() 322 { 323 } 324 325 void 326 AnElement::op_streamout( DYN Item * let_dpItem ) 327 { 328 StreamOut( pContent, let_dpItem ); 329 } 330 331 void 332 AnElement::op_streamout( DYN Attribute * let_dpAttr ) 333 { 334 StreamOut( aAttrs, let_dpAttr ); 335 } 336 337 void 338 AnElement::do_SetContent( DYN Item * let_dpItem ) 339 { 340 Impl_SetContent( pContent, let_dpItem ); 341 } 342 343 const String & 344 AnElement::inq_TagName() const 345 { 346 return sTagName; 347 } 348 349 const Item * 350 AnElement::inq_Content() const 351 { 352 return pContent.Ptr(); 353 } 354 355 const AttrList * 356 AnElement::inq_Attrs() const 357 { 358 return &aAttrs; 359 } 360 361 362 //*************************** AnEmptyElement **************************// 363 364 AnEmptyElement::AnEmptyElement( const String & i_sTagName ) 365 : sTagName( i_sTagName ) 366 // aAttrs 367 { 368 } 369 370 AnEmptyElement::AnEmptyElement( const char * i_sTagName ) 371 : sTagName( i_sTagName ) 372 // aAttrs 373 { 374 } 375 376 AnEmptyElement::~AnEmptyElement() 377 { 378 379 } 380 381 const String & 382 AnEmptyElement::inq_TagName() const 383 { 384 return sTagName; 385 } 386 387 AttrList & 388 AnEmptyElement::inq_RefAttrs() 389 { 390 return aAttrs; 391 } 392 393 394 //*************************** APureElement **************************// 395 396 APureElement::APureElement( const String & i_sTagName ) 397 : sTagName( i_sTagName ) 398 // pContent 399 { 400 } 401 402 APureElement::APureElement( const char * i_sTagName ) 403 : sTagName( i_sTagName ) 404 // pContent 405 { 406 } 407 408 APureElement::~APureElement() 409 { 410 } 411 412 const String & 413 APureElement::inq_TagName() const 414 { 415 return sTagName; 416 } 417 418 Dyn< Item > & 419 APureElement::inq_RefContent() 420 { 421 return pContent; 422 } 423 424 425 426 //*************************** ASglTag **************************// 427 428 ASglTag::ASglTag( const String & i_sTagName ) 429 : sTagName( i_sTagName ) 430 { 431 } 432 433 ASglTag::ASglTag( const char * i_sTagName ) 434 : sTagName( i_sTagName ) 435 { 436 } 437 438 ASglTag::~ASglTag() 439 { 440 } 441 442 const String & 443 ASglTag::inq_TagName() const 444 { 445 return sTagName; 446 } 447 448 449 //*************************** AnAttribute **************************// 450 AnAttribute::AnAttribute( const String & i_sName, 451 const String & i_sValue ) 452 : sName(i_sName), 453 sValue(i_sValue) 454 { 455 } 456 457 AnAttribute::AnAttribute( const char * i_sName, 458 const char * i_sValue ) 459 : sName(i_sName), 460 sValue(i_sValue) 461 { 462 } 463 464 AnAttribute::~AnAttribute() 465 { 466 } 467 468 const String & 469 AnAttribute::inq_Name() const 470 { 471 return sName; 472 } 473 474 const String & 475 AnAttribute::inq_Value() const 476 { 477 return sValue; 478 } 479 480 481 482 //*************************** Text **************************// 483 484 Text::Text( const String & i_sText ) 485 : sText(i_sText) 486 { 487 } 488 489 Text::Text( const char * i_sText ) 490 : sText(i_sText) 491 { 492 } 493 494 Text::~Text() 495 { 496 } 497 498 void 499 Text::do_WriteOut( csv::bostream & io_aFile ) const 500 { 501 const unsigned char * 502 pStart = reinterpret_cast< const unsigned char* >(sText.c_str()); 503 const unsigned char * 504 pOut = pStart; 505 506 for ( ; *pOut != '\0'; ++pOut ) 507 { 508 if ( cReplacable[*pOut] ) 509 { 510 if ( pOut != pStart ) 511 { 512 io_aFile.write( pStart, pOut-pStart ); 513 } 514 515 switch (*pOut) 516 { 517 case '<': io_aFile.write("<"); break; 518 case '>': io_aFile.write(">"); break; 519 case '"': io_aFile.write("""); break; 520 case '&': io_aFile.write("&"); break; 521 case 255: io_aFile.write(" "); break; 522 } 523 524 pStart = pOut+1; 525 } // endif (cReplacable[*pOut]) 526 } // end for 527 528 if ( pOut != pStart ) 529 { 530 io_aFile.write( pStart, pOut-pStart ); 531 } 532 } 533 534 535 //*************************** XmlCode **************************// 536 537 XmlCode::XmlCode( const String & i_sText ) 538 : sText(i_sText) 539 { 540 } 541 542 XmlCode::XmlCode( const char * i_sText ) 543 : sText(i_sText) 544 { 545 } 546 547 XmlCode::~XmlCode() 548 { 549 } 550 551 void 552 XmlCode::do_WriteOut( csv::bostream & io_aFile ) const 553 { 554 io_aFile.write(sText); 555 } 556 557 558 //*************************** MultiItem **************************// 559 560 MultiItem::MultiItem() 561 { 562 } 563 564 MultiItem::~MultiItem() 565 { 566 } 567 568 void 569 MultiItem::do_WriteOut( csv::bostream & io_aFile ) const 570 { 571 ItemList::iterator itEnd = aItems.end(); 572 573 for ( ItemList::iterator it = aItems.begin(); 574 it != itEnd; 575 ++it ) 576 { 577 (*it)->WriteOut( io_aFile ); 578 } 579 580 } 581 582 583 584 //*************************** Helpers **************************// 585 586 void 587 StreamOut( Dyn< Item > & o_rContent, 588 DYN Item * let_dpItem ) 589 { 590 MultiItem * pContent = 0; 591 if ( bool(o_rContent) ) 592 { 593 pContent = static_cast< MultiItem* >( o_rContent.MutablePtr() ); 594 csv_assert( dynamic_cast< MultiItem* >( o_rContent.MutablePtr() ) != 0 ); 595 } 596 else 597 { 598 pContent = new MultiItem; 599 o_rContent = pContent; 600 } 601 602 csv_assert( let_dpItem != 0 ); 603 pContent->Add( let_dpItem ); 604 } 605 606 607 608 609 } // namespace xml 610 } // namespace csi 611