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
Add(DYN Item * let_dpDatum)78 void Add(
79 DYN Item * let_dpDatum )
80 { csv_assert( let_dpDatum != 0 );
81 aItems.push_back(let_dpDatum); }
Erase()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
StreamOut(AttrList & o_rAttrs,DYN Attribute * let_dpAttr)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
Impl_SetContent(Dyn<Item> & o_rContent,DYN Item * let_dpItem)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
WriteOut(csv::bostream & io_aFile) const118 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
do_WriteOut(csv::bostream & io_aFile) const141 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
FinishEmptyTag_XmlStyle() const188 Element::FinishEmptyTag_XmlStyle() const
189 {
190 return true;
191 }
192
193 bool
LineBreakAfterBeginTag() const194 Element::LineBreakAfterBeginTag() const
195 {
196 return false;
197 }
198
199 bool
LineBreakAfterEndTag() const200 Element::LineBreakAfterEndTag() const
201 {
202 return LineBreakAfterBeginTag();
203 }
204
205
206 //************************ EmptyElement ****************************//
207
208 void
op_streamout(DYN Item *)209 EmptyElement::op_streamout( DYN Item * )
210 {
211 // Does nothing.
212 }
213
214 void
op_streamout(DYN Attribute * let_dpAttr)215 EmptyElement::op_streamout( DYN Attribute * let_dpAttr )
216 {
217 StreamOut( inq_RefAttrs(), let_dpAttr );
218 }
219
220 void
do_SetContent(DYN Item *)221 EmptyElement::do_SetContent( DYN Item * )
222 {
223 // Does nothing.
224 }
225
226 const Item *
inq_Content() const227 EmptyElement::inq_Content() const
228 {
229 return 0;
230 }
231
232 const AttrList *
inq_Attrs() const233 EmptyElement::inq_Attrs() const
234 {
235 return & const_cast< EmptyElement* >(this)->inq_RefAttrs();
236 }
237
238
239 //************************ PureElement ****************************//
240
241 void
op_streamout(DYN Item * let_dpItem)242 PureElement::op_streamout( DYN Item * let_dpItem )
243 {
244 StreamOut( inq_RefContent(), let_dpItem );
245 }
246
247 void
op_streamout(DYN Attribute *)248 PureElement::op_streamout( DYN Attribute * )
249 {
250 // Does nothing.
251 }
252
253 void
do_SetContent(DYN Item * let_dpItem)254 PureElement::do_SetContent( DYN Item * let_dpItem )
255 {
256 Impl_SetContent( inq_RefContent(), let_dpItem );
257 }
258
259 const Item *
inq_Content() const260 PureElement::inq_Content() const
261 {
262 return const_cast< PureElement* >(this)->inq_RefContent().Ptr();
263 }
264
265 const AttrList *
inq_Attrs() const266 PureElement::inq_Attrs() const
267 {
268 return 0;
269 }
270
271
272 //*************************** SglTag **************************//
273
274 void
op_streamout(DYN Item *)275 SglTag::op_streamout( DYN Item * )
276 {
277 // Does nothing.
278 }
279
280 void
op_streamout(DYN Attribute *)281 SglTag::op_streamout( DYN Attribute * )
282 {
283 // Does nothing.
284 }
285
286 void
do_SetContent(DYN Item *)287 SglTag::do_SetContent( DYN Item *)
288 {
289 // Does nothing.
290 }
291
292 const Item *
inq_Content() const293 SglTag::inq_Content() const
294 {
295 return 0;
296 }
297
298 const AttrList *
inq_Attrs() const299 SglTag::inq_Attrs() const
300 {
301 return 0;
302 }
303
304
305 //*************************** AnElement **************************//
306
AnElement(const String & i_sTagName)307 AnElement::AnElement( const String & i_sTagName )
308 : sTagName( i_sTagName )
309 // pContent,
310 // aAttrs
311 {
312 }
313
AnElement(const char * i_sTagName)314 AnElement::AnElement( const char * i_sTagName )
315 : sTagName( i_sTagName )
316 // pContent,
317 // aAttrs
318 {
319 }
320
~AnElement()321 AnElement::~AnElement()
322 {
323 }
324
325 void
op_streamout(DYN Item * let_dpItem)326 AnElement::op_streamout( DYN Item * let_dpItem )
327 {
328 StreamOut( pContent, let_dpItem );
329 }
330
331 void
op_streamout(DYN Attribute * let_dpAttr)332 AnElement::op_streamout( DYN Attribute * let_dpAttr )
333 {
334 StreamOut( aAttrs, let_dpAttr );
335 }
336
337 void
do_SetContent(DYN Item * let_dpItem)338 AnElement::do_SetContent( DYN Item * let_dpItem )
339 {
340 Impl_SetContent( pContent, let_dpItem );
341 }
342
343 const String &
inq_TagName() const344 AnElement::inq_TagName() const
345 {
346 return sTagName;
347 }
348
349 const Item *
inq_Content() const350 AnElement::inq_Content() const
351 {
352 return pContent.Ptr();
353 }
354
355 const AttrList *
inq_Attrs() const356 AnElement::inq_Attrs() const
357 {
358 return &aAttrs;
359 }
360
361
362 //*************************** AnEmptyElement **************************//
363
AnEmptyElement(const String & i_sTagName)364 AnEmptyElement::AnEmptyElement( const String & i_sTagName )
365 : sTagName( i_sTagName )
366 // aAttrs
367 {
368 }
369
AnEmptyElement(const char * i_sTagName)370 AnEmptyElement::AnEmptyElement( const char * i_sTagName )
371 : sTagName( i_sTagName )
372 // aAttrs
373 {
374 }
375
~AnEmptyElement()376 AnEmptyElement::~AnEmptyElement()
377 {
378
379 }
380
381 const String &
inq_TagName() const382 AnEmptyElement::inq_TagName() const
383 {
384 return sTagName;
385 }
386
387 AttrList &
inq_RefAttrs()388 AnEmptyElement::inq_RefAttrs()
389 {
390 return aAttrs;
391 }
392
393
394 //*************************** APureElement **************************//
395
APureElement(const String & i_sTagName)396 APureElement::APureElement( const String & i_sTagName )
397 : sTagName( i_sTagName )
398 // pContent
399 {
400 }
401
APureElement(const char * i_sTagName)402 APureElement::APureElement( const char * i_sTagName )
403 : sTagName( i_sTagName )
404 // pContent
405 {
406 }
407
~APureElement()408 APureElement::~APureElement()
409 {
410 }
411
412 const String &
inq_TagName() const413 APureElement::inq_TagName() const
414 {
415 return sTagName;
416 }
417
418 Dyn< Item > &
inq_RefContent()419 APureElement::inq_RefContent()
420 {
421 return pContent;
422 }
423
424
425
426 //*************************** ASglTag **************************//
427
ASglTag(const String & i_sTagName)428 ASglTag::ASglTag( const String & i_sTagName )
429 : sTagName( i_sTagName )
430 {
431 }
432
ASglTag(const char * i_sTagName)433 ASglTag::ASglTag( const char * i_sTagName )
434 : sTagName( i_sTagName )
435 {
436 }
437
~ASglTag()438 ASglTag::~ASglTag()
439 {
440 }
441
442 const String &
inq_TagName() const443 ASglTag::inq_TagName() const
444 {
445 return sTagName;
446 }
447
448
449 //*************************** AnAttribute **************************//
AnAttribute(const String & i_sName,const String & i_sValue)450 AnAttribute::AnAttribute( const String & i_sName,
451 const String & i_sValue )
452 : sName(i_sName),
453 sValue(i_sValue)
454 {
455 }
456
AnAttribute(const char * i_sName,const char * i_sValue)457 AnAttribute::AnAttribute( const char * i_sName,
458 const char * i_sValue )
459 : sName(i_sName),
460 sValue(i_sValue)
461 {
462 }
463
~AnAttribute()464 AnAttribute::~AnAttribute()
465 {
466 }
467
468 const String &
inq_Name() const469 AnAttribute::inq_Name() const
470 {
471 return sName;
472 }
473
474 const String &
inq_Value() const475 AnAttribute::inq_Value() const
476 {
477 return sValue;
478 }
479
480
481
482 //*************************** Text **************************//
483
Text(const String & i_sText)484 Text::Text( const String & i_sText )
485 : sText(i_sText)
486 {
487 }
488
Text(const char * i_sText)489 Text::Text( const char * i_sText )
490 : sText(i_sText)
491 {
492 }
493
~Text()494 Text::~Text()
495 {
496 }
497
498 void
do_WriteOut(csv::bostream & io_aFile) const499 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
XmlCode(const String & i_sText)537 XmlCode::XmlCode( const String & i_sText )
538 : sText(i_sText)
539 {
540 }
541
XmlCode(const char * i_sText)542 XmlCode::XmlCode( const char * i_sText )
543 : sText(i_sText)
544 {
545 }
546
~XmlCode()547 XmlCode::~XmlCode()
548 {
549 }
550
551 void
do_WriteOut(csv::bostream & io_aFile) const552 XmlCode::do_WriteOut( csv::bostream & io_aFile ) const
553 {
554 io_aFile.write(sText);
555 }
556
557
558 //*************************** MultiItem **************************//
559
MultiItem()560 MultiItem::MultiItem()
561 {
562 }
563
~MultiItem()564 MultiItem::~MultiItem()
565 {
566 }
567
568 void
do_WriteOut(csv::bostream & io_aFile) const569 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
StreamOut(Dyn<Item> & o_rContent,DYN Item * let_dpItem)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