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