wxArt2D
genxmlpars.cpp
Go to the documentation of this file.
1 /*! \file xmlparse/src/genxmlpars.cpp
2  \brief a2dDocument - XML reader via Expat
3  \author Klaas Holwerda
4 
5  Copyright: 2001-2004 (C) Klaas Holwerda
6 
7  Licence: wxWidgets licence
8 
9  RCS-ID: $Id: genxmlpars.cpp,v 1.46 2009/07/15 21:23:43 titato Exp $
10 */
11 
12 #include "wxartbaseprec.h"
13 
14 #ifdef __BORLANDC__
15 #pragma hdrstop
16 #endif
17 
18 #ifndef WX_PRECOMP
19 #include "wx/wx.h"
20 #endif
21 
22 #include "wxartbaseprivate.h"
23 
24 #if wxART2D_USE_XMLPARSE
25 
26 const size_t XMLBUFSIZE = 1024;
27 
28 #include "wx/wfstream.h"
29 #include "wx/intl.h"
30 #include "wx/log.h"
31 #include "wx/strconv.h"
32 #include <wx/tokenzr.h>
33 
34 #include "wx/xmlparse/genxmlpars.h"
35 #include "wx/xmlparse/xmlencode.h"
36 
37 //----------------------------------------------------------------------------
38 // a2dIOHandlerXML
39 //----------------------------------------------------------------------------
40 
42 {
43  m_parser = NULL;
44  m_buffer = NULL;
45  m_done = false;
46 }
47 
49 {
51 
52  assert( m_buffer == NULL );
53  assert( m_parser == NULL );
54 
55  m_parser = XML_ParserCreate( NULL );
56  m_buffer = NULL;
57 
58  m_done = false;
59 
60  //the C++ parser object itself as userdata
61  XML_SetUserData( m_parser, ( void* ) this );
62 
63  XML_SetElementHandler( m_parser, BaseStartElementHnd, BaseEndElementHnd );
64  XML_SetCharacterDataHandler( m_parser, BaseCharacterDataHnd );
65  XML_SetCommentHandler( m_parser, BaseCommentHnd );
66  XML_SetDefaultHandler( m_parser, BaseDefaultHnd );
67 }
68 
70 {
72 
73  if ( m_parser )
74  {
75  XML_ParserFree( m_parser );
76  m_parser = NULL;
77  }
78  m_buffer = NULL;
79 }
80 
82 {
83  if ( m_parser )
84  XML_ParserFree( m_parser );
85 }
86 
88 {
89  if ( m_parser )
90  return XML_GetCurrentColumnNumber( m_parser );
91  return 0;
92 }
93 
95 {
96  if ( m_parser )
97  return XML_GetCurrentLineNumber( m_parser );
98  return 0;
99 }
100 
102 {
103  if ( m_parser )
104  return XmlDecodeStringToString( XML_ErrorString( XML_GetErrorCode( m_parser ) ) );
105  return wxT( "" );
106 }
107 
108 void a2dIOHandlerXML::BaseStartElementHnd( void* userData, const char* name, const char** atts )
109 {
110  a2dIOHandlerXML* parser = ( a2dIOHandlerXML* ) userData;
111 
112  a2dXMLTag* tag = new a2dXMLTag( START_TAG, XmlDecodeStringToString( name ) );
113 
114  int i = 0;
115  while ( atts[i] )
116  {
117  tag->SetAttribute( XmlDecodeStringToString( atts[i] ), XmlDecodeStringToString( atts[i + 1] ) );
118  i += 2;
119  }
120 
121  parser->StartElementHnd( tag );
122 
123 }
124 
125 void a2dIOHandlerXML::BaseEndElementHnd( void* userData, const char* name )
126 {
127  a2dIOHandlerXML* parser = ( a2dIOHandlerXML* ) userData;
128 
129  parser->EndElementHnd( XmlDecodeStringToString( name ) );
130 }
131 
132 void a2dIOHandlerXML::BaseCharacterDataHnd( void* userData, const char* s, int len )
133 {
134  a2dIOHandlerXML* parser = ( a2dIOHandlerXML* ) userData;
135 
136  char* buf = new char[len + 1];
137 
138  buf[len] = wxT( '\0' );
139  memcpy( buf, s, ( size_t )len );
140 
141  parser->CharacterDataHnd( XmlDecodeStringToString( buf ) );
142 
143  delete buf;
144 }
145 
146 void a2dIOHandlerXML::BaseCommentHnd( void* userData, const char* data )
147 {
148  a2dIOHandlerXML* parser = ( a2dIOHandlerXML* ) userData;
149 
150  parser->CommentHnd( XmlDecodeStringToString( data ) );
151 }
152 
153 void a2dIOHandlerXML::BaseDefaultHnd( void* userData, const char* s, int len )
154 {
155  a2dIOHandlerXML* parser = ( a2dIOHandlerXML* ) userData;
156 
157  wxString buf = XmlDecodeStringToString( s, ( size_t )len );
158 
159  // XML header:
160  if ( len > 6 && memcmp( s, "<?xml ", 6 ) == 0 )
161  {
162  wxString buf = XmlDecodeStringToString( s, ( size_t )len );
163  int pos;
164  pos = buf.Find( wxT( "encoding=" ) );
165  if ( pos != wxNOT_FOUND )
166  m_encoding = buf.Mid( pos + 10 ).BeforeFirst( buf[( size_t )pos + 9] );
167  pos = buf.Find( wxT( "version=" ) );
168  if ( pos != wxNOT_FOUND )
169  m_version = buf.Mid( pos + 9 ).BeforeFirst( buf[( size_t )pos + 8] );
170  }
171 
172  parser->DefaultHnd( buf );
173 }
174 
175 double a2dIOHandlerXML::ParseDouble( const wxString& buffer, unsigned int& position )
176 {
177  const wxChar* start = buffer.c_str() + ( long ) position;
178  wxChar* end;
179  double val = wxStrtod( start, &end );
180  position = end - buffer.c_str();
181 
182  if ( start == end )
183  throw a2dIOHandlerXMLException( wxT( "not a number near: " ), GetCurrentLineNumber(), GetCurrentColumnNumber() + position );
184 
185  return val;
186 }
187 
188 void a2dIOHandlerXML::SkipCommaSpaces( const wxString& buffer, unsigned int& position )
189 {
190  char current;
191  for( ;; )
192  {
193  current = buffer[position];
194  switch ( current )
195  {
196  default:
197  return;
198  case wxT( ',' ): case 0x20: case 0x09: case 0x0D: case 0x0A:
199  position++;
200  break;
201  }
202  }
203 }
204 
205 void a2dIOHandlerXML::SkipSpaces( const wxString& buffer, unsigned int& position )
206 {
207  char current;
208  for( ;; )
209  {
210  current = buffer[position];
211  switch ( current )
212  {
213  default:
214  return;
215  case 0x20: case 0x09: case 0x0D: case 0x0A:
216  position++;
217  break;
218  }
219  }
220 }
221 
222 //----------------------------------------------------------------------------
223 // a2dXMLTag
224 //----------------------------------------------------------------------------
225 
226 a2dXMLTag::a2dXMLTag( XMLeventType type, wxString tagname )
227 {
228  m_tag = tagname;
229  m_type = type;
230  m_line = 0;
231  m_column = 0;
232  m_hasContent = false;
233  m_hasattributes = false;
234 }
235 
237 {
238  m_tag = other.m_tag;
239  m_type = other.m_type;
240  m_hasContent = false;
241  m_hasattributes = false;
242  m_attributes = other.m_attributes;
243  m_line = 0;
244  m_column = 0;
245 }
246 
248 {
249 }
250 
251 a2dObject* a2dXMLTag::Clone( CloneOptions WXUNUSED( options ) ) const
252 {
253  return new a2dXMLTag( *this );
254 }
255 
256 bool a2dXMLTag::SetAttribute( const wxString& attributeName, const wxString& Value )
257 {
258  a2dAttributeHash::iterator iter = m_attributes.find( attributeName );
259  m_attributes[ attributeName ] = Value;
260  return iter != m_attributes.end();
261 }
262 
263 wxString* a2dXMLTag::GetAttribute( const wxString& attributeName )
264 {
265  a2dAttributeHash::iterator iter = m_attributes.find( attributeName );
266  if( iter == m_attributes.end() )
267  return NULL;// error, alias does not exist
268 
269  return &iter->second;
270 }
271 
272 #if wxART2D_USE_CVGIO
273 
274 void a2dXMLTag::DoSave( wxObject* WXUNUSED( parent ), a2dIOHandlerXmlSerOut& WXUNUSED( out ), a2dXmlSer_flag WXUNUSED( xmlparts ), a2dObjectList* WXUNUSED( towrite ) )
275 {
276  wxASSERT( 0 );
277 }
278 
279 #endif //wxART2D_USE_CVGIO
280 
281 #if wxART2D_USE_CVGIO
282 
283 void a2dXMLTag::DoLoad( wxObject* WXUNUSED( parent ), a2dIOHandlerXmlSerIn& WXUNUSED( parser ), a2dXmlSer_flag WXUNUSED( xmlparts ) )
284 {
285  wxASSERT( 0 );
286 }
287 
288 #endif //wxART2D_USE_CVGIO
289 
290 wxString GetTypeString( const XMLeventType& type )
291 {
292  switch ( type )
293  {
294  case START_DOCUMENT: { return wxT( "START_DOCUMENT" ); break; }
295  case END_DOCUMENT: { return wxT( "END_DOCUMENT" ); break; }
296  case START_TAG: { return wxT( "START_TAG" ); break; }
297  case END_TAG: { return wxT( "END_TAG" ); break; }
298  case CONTENT: { return wxT( "CONTENT" ); break; }
299  default: break;
300  }
301  return wxT( "" );
302 }
303 
304 //----------------------------------------------------------------------------
305 // a2dIOHandlerXMLPull
306 //----------------------------------------------------------------------------
307 
308 wxString a2dIOHandlerXML::m_encoding = wxT( "UTF-8" );
309 
310 wxString a2dIOHandlerXML::m_version = wxT( "1.0" );
311 
313 {
314  m_depth = 0;
315  m_current = 0 ;
316  m_startdoc = new a2dXMLTag( START_DOCUMENT, wxT( "startdocument" ) );
317  m_enddoc = new a2dXMLTag( END_DOCUMENT, wxT( "enddocument" ) );
318  m_scale = 1;
319 }
320 
322 {
323  delete m_startdoc;
324  delete m_enddoc;
325 }
326 
328 {
329  m_depth = 0;
330  m_current = m_startdoc;
332 }
333 
335 {
336  m_elements.clear();
337  m_current = 0;
338 
340 }
341 
343 {
344  if ( m_current )
345  return m_current->m_column;
346  return -1;
347 }
348 
350 {
351  if ( m_current )
352  return m_current->m_line;
353  return -1;
354 }
355 
356 void a2dIOHandlerXMLPull::StartElementHnd( a2dXMLTag* tag )
357 {
358  tag->m_line = XML_GetCurrentLineNumber( m_parser );
359  tag->m_column = XML_GetCurrentColumnNumber( m_parser );
360  m_elements.push_back( tag );
361 }
362 
363 void a2dIOHandlerXMLPull::EndElementHnd( const wxString& name )
364 {
365  a2dXMLTag* tag = new a2dXMLTag( END_TAG, name );
366  m_elements.push_back( tag );
367  tag->m_line = XML_GetCurrentLineNumber( m_parser );
368  tag->m_column = XML_GetCurrentColumnNumber( m_parser );
369 }
370 
371 void a2dIOHandlerXMLPull::CharacterDataHnd( const wxString& text )
372 {
373  //TODO like this no mixed content
374  //either search last open tag ( without a matching endtag )
375  //or create a a2dXMLTag with only content and of type CONTENT
376  //of which there may be several in a row or concatenate.
377 
378  if ( !m_elements.empty() )
379  m_elements.back()->m_text += text;
380 }
381 
382 void a2dIOHandlerXMLPull::CommentHnd( const wxString& WXUNUSED( comment ) )
383 {
384 }
385 
386 void a2dIOHandlerXMLPull::DefaultHnd( const wxString& WXUNUSED( def ) )
387 {
388 }
389 
390 void a2dIOHandlerXMLPull::Require( const XMLeventType& type, wxString name )
391 {
392  if ( !m_elements.empty() )
393  {
394  if ( m_current->m_type != type || m_current->m_tag != name )
395  {
396 
397  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "expected: %s '%s'\ngot %s '%s' at line %d" ), GetTypeString( type ).c_str(), name.c_str(),
399  throw a2dIOHandlerXMLException( wxT( "expected:" ) + name , GetCurrentLineNumber(), GetCurrentColumnNumber() );
400  }
401  return;
402  }
403  else
404  {
405  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "XML end of file reached at line %d" ), GetCurrentLineNumber() );
406  throw a2dIOHandlerXMLException( wxT( "XML end of file reached" ), GetCurrentLineNumber(), GetCurrentColumnNumber() );
407  }
408 }
409 
410 
412 {
413  XMLeventType eventType = Next();
414 
415  if ( eventType != START_TAG && eventType != END_TAG )
416  {
417  throw a2dIOHandlerXMLException( wxT( "expected start or end tag" ) , GetCurrentLineNumber(), GetCurrentColumnNumber() );
418  }
419  return eventType;
420 }
421 
423 {
424  if ( !m_elements.empty() )
425  {
426  m_elements.pop_front();
427  m_depth--;
428 
429  if ( !m_elements.empty() )
430  {
431  m_depth++;
432  m_current = m_elements.front();
433  return m_current->m_type;
434  }
435  }
436 
437  FillQueue();
438 
439  if ( !m_elements.empty() )
440  {
441  m_depth++;
442  m_current = m_elements.front();
443  return m_current->m_type;
444  }
445 
446  m_current = m_enddoc;
447  return END_DOCUMENT;
448 }
449 
450 wxString a2dIOHandlerXMLPull::GetAttributeValue( const wxString& attrib, const wxString& defaultv )
451 {
452  if ( m_current->m_type != START_TAG )
453  throw a2dIOHandlerXMLException( wxT( "GetAttributeValue on non starttag" ) , GetCurrentLineNumber(), GetCurrentColumnNumber() );
454 
455  wxString* val = m_current->GetAttribute( attrib );
456  if ( m_current->GetAttribute( attrib ) )
457  return *val;
458  return defaultv;
459 }
460 
461 wxString a2dIOHandlerXMLPull::RequireAttributeValue( const wxString& attrib )
462 {
463  if ( m_current->m_type != START_TAG )
464  throw a2dIOHandlerXMLException( wxT( "GetAttributeValue on non starttag" ) , GetCurrentLineNumber(), GetCurrentColumnNumber() );
465 
466  wxString* val = m_current->GetAttribute( attrib );
467  if ( val )
468  return *val;
469 
470  throw a2dIOHandlerXMLException( wxT( "No such attribute: " ) + attrib , GetCurrentLineNumber(), GetCurrentColumnNumber() );
471  return *val;
472 }
473 
474 double a2dIOHandlerXMLPull::GetAttributeValueDouble( const wxString& attrib, double defaultv )
475 {
476  wxString s = GetAttributeValue( attrib );
477  if ( !s.IsEmpty() )
478  {
479  double num;
480  s.ToDouble( &num );
481  return num;
482  }
483 
484  return defaultv;
485 }
486 
487 double a2dIOHandlerXMLPull::RequireAttributeValueDouble( const wxString& attrib )
488 {
489  wxString s = RequireAttributeValue( attrib );
490  double num;
491  s.ToDouble( &num );
492  return num;
493 }
494 
495 int a2dIOHandlerXMLPull::GetAttributeValueInt( const wxString& attrib, int defaultv )
496 {
497  wxString s = GetAttributeValue( attrib );
498  if ( !s.IsEmpty() )
499  {
500  long num;
501  s.ToLong( &num );
502  return num;
503  }
504 
505  return defaultv;
506 }
507 
509 {
510  wxString s = RequireAttributeValue( attrib );
511  long num;
512  s.ToLong( &num );
513  return num;
514 }
515 
516 long a2dIOHandlerXMLPull::GetAttributeValueLong( const wxString& attrib, long defaultv )
517 {
518  wxString s = GetAttributeValue( attrib );
519  if ( !s.IsEmpty() )
520  {
521  long num;
522  s.ToLong( &num );
523  return num;
524  }
525 
526  return defaultv;
527 }
528 
530 {
531  wxString s = RequireAttributeValue( attrib );
532  long num;
533  s.ToLong( &num );
534  return num;
535 }
536 
537 bool a2dIOHandlerXMLPull::GetAttributeValueBool( const wxString& attrib, bool defaultv )
538 {
539  wxString s = GetAttributeValue( attrib );
540  if ( !s.IsEmpty() )
541  {
542  if ( s.MakeLower() == wxT( "true" ) )
543  return true;
544  else
545  return false;
546  }
547 
548  return defaultv;
549 }
550 
552 {
553  wxString s = RequireAttributeValue( attrib );
554  if ( s.MakeLower() == wxT( "true" ) )
555  return true;
556  else
557  return false;
558 }
559 
560 bool a2dIOHandlerXMLPull::HasAttribute( const wxString& attrib )
561 {
562  return m_current->GetAttribute( attrib ) != NULL;
563 }
564 
566 {
567  return m_current->m_tag;
568 }
569 
571 {
572  // it is possible that a content text is just overlapping
573  // one buffer read to the other. Therefore is at the moment of wanting the content
574  // the number of elements is 1 or less, start parsing the next part of the file.
575  // In case of large content it will all be concatenated.
576 
577  while( m_elements.size() <= 1 && !m_done )
578  {
579  //read/parse some more
580 
581  size_t bytes_read;
582  m_buffer = ( char* ) XML_GetBuffer( m_parser, XMLBUFSIZE );
583  if ( m_buffer == NULL )
584  {
585  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "XML couldnot allocate buffer" ) );
587  }
588  bytes_read = Read( m_buffer, XMLBUFSIZE );
589  if ( bytes_read < 0 )
590  {
591  /* handle error */
592  }
593 
594  m_done = ( bytes_read < XMLBUFSIZE );
595 
596  if ( !XML_ParseBuffer( m_parser, bytes_read, m_done ) )
597  {
598  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "XML parsing error: '%s' at line %d" ), a2dIOHandlerXML::GetErrorString().c_str(), a2dIOHandlerXML::GetCurrentLineNumber() );
600  }
601  }
602 
603  return m_current->m_text;
604 }
605 
607 {
608  return m_current->m_type;
609 }
610 
612 {
613  //queue might be empty, need to read more.
614 
615  while( m_elements.empty() && !m_done )
616  {
617  //read/parse some more
618 
619  size_t bytes_read;
620  m_buffer = ( char* ) XML_GetBuffer( m_parser, XMLBUFSIZE );
621  if ( m_buffer == NULL )
622  {
623  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "XML couldnot allocate buffer" ) );
625  }
626  /*
627  #if wxUSE_UNICODE
628  wxChar* buf = new wxChar[XMLBUFSIZE];
629 
630  bytes_read = Read( buf, XMLBUFSIZE);
631  m_buffer = (char*) wxString(buf).mb_str().data();
632  delete buf;
633  #else
634  */
635  bytes_read = Read( m_buffer, XMLBUFSIZE );
636 //#endif // wxUSE_UNICODE
637  if ( bytes_read < 0 )
638  {
639  /* handle error */
640  }
641 
642  m_done = ( bytes_read < XMLBUFSIZE );
643 
644  if ( !XML_ParseBuffer( m_parser, bytes_read, m_done ) )
645  {
646  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "XML parsing error: '%s' at line %d" ), a2dIOHandlerXML::GetErrorString().c_str(), a2dIOHandlerXML::GetCurrentLineNumber() );
648  }
649  }
650 }
651 
653 {
654  int sublevel = 1;
655 
656  while( sublevel > 0 )
657  {
658  XMLeventType type = Next();
659  switch( type )
660  {
661  case START_TAG:
662  ++sublevel;
663  break;
664  case END_TAG:
665  --sublevel;
666  break;
667  default:
668  break;
669  }
670  }
671 }
672 
673 //----------------------------------------------------------------------------
674 // a2dIOHandlerXMLWrite
675 //----------------------------------------------------------------------------
676 
678 {
679  m_format = wxT( "%g" );
680  m_indentSize = 4;
681  m_scale = 1;
682  m_indent = 0;
683  m_depth = 0;
684  m_current = 0 ;
685  m_startdoc = new a2dXMLTag( START_DOCUMENT, wxT( "startdocument" ) );
686  m_enddoc = new a2dXMLTag( END_DOCUMENT, wxT( "enddocument" ) );
687 }
688 
690 {
691  delete m_startdoc;
692  delete m_enddoc;
693 }
694 
696 {
697  m_indent = 0;
698  m_depth = 0;
699  m_current = m_startdoc;
701 }
702 
704 {
706 
707  m_current = 0;
708 }
709 
710 int a2dIOHandlerXMLWrite::GetCurrentColumnNumber()
711 {
712  return m_current->m_column;
713 }
714 
715 int a2dIOHandlerXMLWrite::GetCurrentLineNumber()
716 {
717  return m_current->m_line;
718 }
719 
720 //output
721 
722 
723 void a2dIOHandlerXMLWrite::WriteStartDocument( const wxString& version, const wxString& encoding, bool standalone )
724 {
725  m_depth = 0;
726  *this << wxT( "<?xml version=\"" ) << version << wxT( "\" encoding=\"" ) << encoding << wxT( "\"" );
727  *this << wxT( " standalone=\"" ) << ( standalone ? wxT( "yes" ) : wxT( "no" ) ) << wxT( "\"?>\n" );
728 }
729 
731 {
732  wxASSERT_MSG( m_elements.empty(), wxT( "not end of document, still elements open" ) );
733  wxASSERT_MSG( m_current == m_enddoc, wxT( "unBalanced" ) );
734 }
735 
736 
737 
738 void a2dIOHandlerXMLWrite::WriteStartElement( const wxString& name, bool newLine )
739 {
740  //the current that is the parent of this tag to write, has content
741  m_current->m_hasContent = true;
742 
743  if ( newLine )
744  WriteNewLine();
745 
746  m_current = new a2dXMLTag( START_TAG, name );
747  m_elements.push_front( m_current );
748 
749 
750  m_depth++;
751  m_indent = m_depth;
752 
753  *this << wxT( "<" ) << name << wxT( ">" );
754 }
755 
756 
757 void a2dIOHandlerXMLWrite::WriteStartElementAttributes( const wxString& name, bool newLine )
758 {
759  //the current that is the parent of this tag to write, has content
760  m_current->m_hasContent = true;
761 
762  if ( newLine )
763  WriteNewLine();
764 
765  m_current = new a2dXMLTag( START_TAG, name );
766  m_current->m_hasattributes = true;
767  m_elements.push_front( m_current );
768 
769 
770  m_depth++;
771  m_indent = m_depth;
772  *this << wxT( "<" ) << name;
773 }
774 
775 
776 void a2dIOHandlerXMLWrite::WriteStartElement( const a2dXMLTag& tag, bool newLine )
777 {
778  //the current that is the parent of this tag to write, has content
779  m_current->m_hasContent = true;
780 
781  if ( newLine )
782  WriteNewLine();
783 
784  m_current = new a2dXMLTag( tag );
785  m_elements.push_front( m_current );
786 
787  m_current->m_hasattributes = m_current->m_attributes.size() != 0;
788 
789  m_depth++;
790  m_indent = m_depth;
791  *this << wxT( "<" ) << m_current->m_tag << wxT( ">" );
792 }
793 
794 void a2dIOHandlerXMLWrite::WriteElement( const wxString& name, const wxString& content, bool newLine )
795 {
796  if ( newLine )
797  WriteNewLine();
798 
799  *this << wxT( "<" ) << name << wxT( ">" );
800  WriteStringEnt( content );
801  *this << wxT( "</" ) << name << wxT( ">" );
802 
803  m_indent = m_depth;
804 }
805 
806 void a2dIOHandlerXMLWrite::WriteAttribute( const wxString& name, bool value, bool onlyIfTrue )
807 {
808  wxString error = wxT( "Wrong start tag" ) + m_current->m_tag;
809  wxASSERT_MSG( m_current->m_hasattributes , error );
810  if ( ( onlyIfTrue && value ) || !onlyIfTrue )
811  {
812  if ( value == true )
813  *this << wxT( " " ) << name << wxT( "=\"true\"" );
814  else
815  *this << wxT( " " ) << name << wxT( "=\"false\"" );
816  }
817 }
818 
819 void a2dIOHandlerXMLWrite::WriteAttribute( const a2dNamedProperty& attribute )
820 {
821  wxString error = wxT( "Wrong start tag" ) + m_current->m_tag;
822  wxASSERT_MSG( m_current->m_hasattributes , error );
823 
824  *this << wxT( " " ) << attribute.GetName() << wxT( "=\"" ) << attribute.StringValueRepresentation();
825 }
826 
827 void a2dIOHandlerXMLWrite::WriteAttributeEnt( const wxString& name, const wxString& value )
828 {
829  wxString error = wxT( "Wrong start tag" ) + this->m_current->m_tag;
830  wxASSERT_MSG( this->m_current->m_hasattributes , error );
831 
832  *this << wxT( " " ) << name << wxT( "=\"" );
833  WriteStringEnt( value );
834  *this << wxT( "\"" );
835 }
836 
838 {
839  wxString error = wxT( "Wrong start tag" ) + m_current->m_tag;
840  wxASSERT_MSG( m_current->m_hasattributes , error );
841  m_current->m_hasattributes = false;
842 
843  if ( close )
844  {
845  m_depth--;
846 
847  *this << wxT( "/>" );
848 
849  m_elements.pop_front();
850  if ( !m_elements.empty() )
851  m_current = m_elements.front();
852  else
853  m_current = m_enddoc;
854  }
855  else
856  *this << wxT( ">" );
857 
858  m_indent = m_depth; //at begin of starttag
859 }
860 
861 
863 {
864  wxString error = wxT( "Wrong start tag or attributes not written" ) + m_current->m_tag;
865  wxASSERT_MSG( !m_current->m_hasattributes , wxT( "Wrong start tag or attributes not written" ) );
866 
867  m_depth--;
868  m_indent = m_depth;
869 
870  if ( newLine )
871  WriteNewLine();
872 
873  m_current = m_elements.front();
874 
875  *this << wxT( "</" ) << m_current->m_tag << wxT( ">" );
876 
877  m_elements.pop_front();
878  if ( !m_elements.empty() )
879  m_current = m_elements.front();
880  else
881  m_current = m_enddoc;
882 }
883 
884 void a2dIOHandlerXMLWrite::WriteContent( const wxString& content )
885 {
886  m_indent = m_depth;
887  *this << content;
888 }
889 
891 {
892  WriteIndent();
893 }
894 
895 
896 void a2dIOHandlerXMLWrite::WriteIndent()
897 {
898  wxString str = wxT( "\n" );
899  if ( m_indentSize )
900  {
901  str += wxString ( ' ', m_indent * m_indentSize );
902  }
903  if ( str.IsEmpty() ) return;
904 
905  WriteString( str );
906 }
907 
908 void a2dIOHandlerXMLWrite::EndlWriteString( const wxString& string )
909 {
910  WriteNewLine();
911  WriteString( string );
912 }
913 
914 void a2dIOHandlerXMLWrite::WriteStringEnt( const wxString& string )
915 {
916  wxString buf;
917  size_t i, last, len;
918  wxChar c;
919 
920  len = string.Len();
921  last = 0;
922  for ( i = 0; i < len; i++ )
923  {
924  c = string.GetChar( i );
925  if ( c == wxT( '<' ) || c == wxT( '>' ) ||
926  ( c == wxT( '&' ) && string.Mid( i + 1, 4 ) != wxT( "amp;" ) ) ||
927  ( c == wxT( '"' ) ) )
928  {
929  a2dIOHandlerStrOut::WriteString( string.Mid( last, i - last ) );
930  switch ( c )
931  {
932  case wxT( '<' ):
933  a2dIOHandlerStrOut::WriteString( wxT( "&lt;" ) );
934  break;
935  case wxT( '>' ):
936  a2dIOHandlerStrOut::WriteString( wxT( "&gt;" ) );
937  break;
938  case wxT( '&' ):
939  a2dIOHandlerStrOut::WriteString( wxT( "&amp;" ) );
940  break;
941  case wxT( '"' ):
942  a2dIOHandlerStrOut::WriteString( wxT( "&quot;" ) );
943  break;
944  default:
945  break;
946  }
947  last = i + 1;
948  }
949  }
950  a2dIOHandlerStrOut::WriteString( string.Mid( last, i - last ) );
951 }
952 
953 void a2dIOHandlerXMLWrite::XmlEncodeStringToStream(
954  const wxChar* string,
955  size_t len
956 )
957 {
958 #if wxUSE_UNICODE
959 
960  for( const wxChar* pos = string; *pos; pos++ )
961  {
962  if( *pos >= 32 && *pos <= 126 && *pos != wxChar( '<' ) && *pos != wxChar( '>' )
963  && *pos != wxChar( '&' ) && *pos != wxChar( '\"' ) )
964  *this << ( char ) *pos;
965  else
966  *this << wxT( "&#" ) << ( unsigned int )( wxUChar )( *pos ) << wxT( ";" );
967  }
968 
969 #else
970  size_t nLen = ( len != wxStringBase::npos )
971  ? len
972  : wxConvLocal.MB2WC( ( wchar_t* ) NULL, string, 0 );
973 
974  if( nLen == ( size_t ) - 1 )
975  {
976  // Some error occured, write the string as is
977  unsigned i = 0;
978 
979  for( const wxChar* pos = string; *pos && i < nLen; pos++, i++ )
980  {
981  if( *pos >= 32 && *pos <= 126 && *pos != '<' && *pos != '>' && *pos != '&' && *pos != '\"' )
982  *this << ( char ) *pos;
983  else
984  *this << "&#" << ( unsigned int )( wchar_t )( *pos ) << ";";
985  }
986  }
987 
988  wchar_t* buf = new wchar_t[nLen + 1];
989  wxConvLocal.MB2WC( buf, string, nLen );
990  buf[nLen] = 0;
991 
992  for( const wchar_t* pos = buf; *pos; pos++ )
993  {
994  if( *pos >= 32 && *pos <= 126 && *pos != '<' && *pos != '>' && *pos != '&' && *pos != '\"' )
995  *this << ( char ) *pos;
996  else
997  *this << wxT( "&#" ) << ( unsigned int )( wchar_t )( *pos ) << wxT( ";" );
998  }
999 
1000  delete[] buf;
1001 #endif
1002 
1003 }
1004 
1005 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const wxChar* string )
1006 {
1007  WriteString( wxString( string ) );
1008  return *this;
1009 }
1010 
1011 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const wxString& string )
1012 {
1013  WriteString( string );
1014  return *this;
1015 }
1016 
1017 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( char c )
1018 {
1019  WriteString( wxString::FromAscii( c ) );
1020 
1021  return *this;
1022 }
1023 
1024 #if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
1025 
1026 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( wchar_t wc )
1027 {
1028  WriteString( wxString( &wc, m_conv, 1 ) );
1029 
1030  return *this;
1031 }
1032 
1033 #endif // wxUSE_UNICODE
1034 
1035 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const wxInt16& c )
1036 {
1037  wxString str;
1038  str.Printf( wxT( "%d" ), ( signed int )c );
1039  WriteString( str );
1040 
1041  return *this;
1042 }
1043 
1044 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const wxInt32& c )
1045 {
1046  wxString str;
1047  str.Printf( wxT( "%ld" ), ( signed long )c );
1048  WriteString( str );
1049 
1050  return *this;
1051 }
1052 
1053 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const wxInt64& c )
1054 {
1055  wxString str;
1056  str.Printf( wxT( "%lld" ), ( unsigned long long ) c );
1057  WriteString( str );
1058 
1059  return *this;
1060 }
1061 
1062 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const wxUint16& c )
1063 {
1064  wxString str;
1065  str.Printf( wxT( "%u" ), ( unsigned int )c );
1066  WriteString( str );
1067 
1068  return *this;
1069 }
1070 
1071 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const wxUint32& c )
1072 {
1073  wxString str;
1074  str.Printf( wxT( "%lu" ), ( unsigned long )c );
1075  WriteString( str );
1076 
1077  return *this;
1078 }
1079 
1080 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const wxUint64& c )
1081 {
1082  wxString str;
1083  str.Printf( wxT( "%llu" ), ( unsigned long long )c );
1084  WriteString( str );
1085 
1086  return *this;
1087 }
1088 
1089 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const double& f )
1090 {
1091  WriteDouble( f );
1092  return *this;
1093 }
1094 
1095 a2dIOHandlerXMLWrite& a2dIOHandlerXMLWrite::operator<<( const float& f )
1096 {
1097  WriteDouble( ( double )f );
1098  return *this;
1099 }
1100 
1101 #if wxART2D_USE_CVGIO
1102 
1103 //----------------------------------------------------------------------------
1104 // a2dIOHandlerXmlSerIn
1105 //----------------------------------------------------------------------------
1106 
1108 {
1109  m_doc = NULL;
1110  m_formatVersion = wxEmptyString;
1111 }
1112 
1113 
1115 {
1116 }
1117 
1118 bool a2dIOHandlerXmlSerIn::CanLoad( a2dDocumentInputStream& stream, const wxObject* obj, wxClassInfo* docClassInfo )
1119 {
1120  SeekI( 0 );
1121  char cheader[7];
1122  cheader[6] = 0;
1123  Read( cheader, 6 );
1124  SeekI( 0 );
1125 
1126  // A check for a XML header should be enough,
1127  // encoding etc. is set by a2dIOHandlerXML::BaseDefaultHnd
1128  return ( memcmp( cheader, "<?xml ", 6 ) == 0 );
1129 }
1130 
1132 {
1133  m_streami = &stream;
1134  m_doc = doc;
1135 
1136  InitializeLoad();
1137 
1138  bool oke = true;
1139 
1140  try
1141  {
1142  ( ( a2dObject* )m_doc )->Load( NULL, *this );
1143 
1144  //now resolve references on id.
1145  //CVG links on Id's
1146  LinkReferences();
1147 
1148  }
1149  catch ( const a2dIOHandlerXMLException& e )
1150  {
1151  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "CVG parsing error: %s at line %d column %d" ),
1152  e.getMessage().c_str(), e.getLineNumber(), e.getColumnNumber() );
1153  oke = false;
1154  }
1155 
1156  ResetLoad();
1157 
1158  return oke;
1159 }
1160 
1162 {
1163  if ( GetTagName() == wxT( "o" ) )
1164  {
1165  Require( START_TAG, wxT( "o" ) );
1166 
1167  wxString classname = GetAttributeValue( wxT( "classname" ) );
1168  a2dObject* o = wxStaticCast( CreateObject( classname ), a2dObject );
1169  if ( !o )
1170  {
1171  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "could not create a2dObject %s, will be skipped line %d" ),
1172  classname.c_str(), GetCurrentLineNumber() );
1173  SkipSubTree();
1174  Require( END_TAG, wxT( "o" ) );
1175  Next();
1176  }
1177  else
1178  o->Load( parent, *this );
1179  return o;
1180  }
1181  return NULL;
1182 }
1183 
1184 //----------------------------------------------------------------------------
1185 // a2dIOHandlerXmlSerOut
1186 //----------------------------------------------------------------------------
1187 
1189 {
1190 }
1191 
1192 
1194 {
1195 }
1196 
1197 bool a2dIOHandlerXmlSerOut::Save( a2dDocumentOutputStream& stream, const wxObject* doc )
1198 {
1199  m_doc = ( wxObject* ) doc;
1200  m_streamo = &stream;
1201 
1202  if ( !IsOk() )
1203  {
1204  a2dGeneralGlobals->ReportErrorF( a2dError_FileCouldNotOpen, _( "Sorry, could not open stream for saving" ) );
1205  return false;
1206  }
1207 
1208  InitializeSave();
1209 
1210  ( ( a2dObject* )m_doc )->Save( NULL, *this, NULL );
1211 
1212  ResetSave();
1213 
1214  return true;
1215 }
1216 #endif //wxART2D_USE_CVGIO
1217 
1218 
1219 //----------------------------------------------------------------------------
1220 // a2dXmlString
1221 //----------------------------------------------------------------------------
1222 
1223 a2dXmlString::a2dXmlString( const wxString& str )
1224 {
1225  m_streamo = &m_strstream;
1226  InitializeSave();
1227  WriteString( str );
1228 }
1229 
1230 
1232 {
1233  ResetSave();
1234 }
1235 
1236 void a2dXmlString::Reset()
1237 {
1238  //m_streamo->SeekO(0);
1239 }
1240 
1241 void a2dXmlString::WriteCommand( const wxString& name, bool close )
1242 {
1243  WriteStartElementAttributes( _T( "command" ), false );
1244  WriteAttribute( _T( "name" ), name );
1245  if ( close )
1246  WriteEndAttributes( true );
1247 }
1248 
1249 
1250 
1251 #endif /* wxART2D_USE_XMLPARSE */
virtual void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
Load settings.
Definition: genxmlpars.cpp:283
bool GetAttributeValueBool(const wxString &attrib, bool defaultv=false)
Returns the boolean value of an attribute.
Definition: genxmlpars.cpp:537
For exceptions thrown while parsing XML files.
Definition: genxmlpars.h:36
(In) Visible property that can be added to Docview Objects.
Definition: gen.h:1785
void WriteContent(const wxString &content)
Writes content between start and end tag.
Definition: genxmlpars.cpp:884
a2dObject * LoadOneObject(wxObject *parent)
load one object from a CVG file.
void WriteElement(const wxString &name, const wxString &content=wxT(""), bool newLine=true)
Writes start and end tag.
Definition: genxmlpars.cpp:794
bool HasAttribute(const wxString &attrib)
Does the current tag have this attribute?
Definition: genxmlpars.cpp:560
virtual void InitializeLoad()
Inits the handler for reading.
Definition: gen.cpp:4971
wxString GetTypeString(const XMLeventType &type)
translate XMLeventType to a string
Definition: genxmlpars.cpp:290
wxString m_tag
tag name
Definition: genxmlpars.h:147
XMLeventType Next()
Walks to next element and returns event type.
Definition: genxmlpars.cpp:422
bool RequireAttributeValueBool(const wxString &attrib)
Forces an attribute and returns its boolean value.
Definition: genxmlpars.cpp:551
Input handler for the XML format.
Definition: genxmlpars.h:197
void WriteCommand(const wxString &name, bool close=true)
write a command string
virtual bool Load(a2dDocumentInputStream &stream, wxObject *doc)
load a complete document
virtual void InitializeSave()
Inits the handler for writing.
Definition: gen.cpp:5095
wxObject * m_doc
the document to store/load the data found into
Definition: genxmlpars.h:880
virtual void ResetSave()
Reset the object after saving.
Definition: gen.cpp:5101
void WriteStartElementAttributes(const wxString &name, bool newLine=true)
Writes start tag which has attributes.
Definition: genxmlpars.cpp:757
a2dIOHandlerXmlSerOut()
Constructor.
virtual int GetCurrentLineNumber()
Returns the current line no.
Definition: genxmlpars.cpp:94
Ref Counted base object.
Definition: gen.h:1045
a2dXMLTag * m_current
current XML tag
Definition: genxmlpars.h:569
virtual a2dObject * Clone(CloneOptions options) const
create an exact copy of this property
Definition: genxmlpars.cpp:251
wxOutputStream a2dDocumentOutputStream
output stream based wxStreams
Definition: gen.h:3458
a2dSmrtPtrList< a2dXMLTag > m_elements
queue of begin and end elements tags not yet processed
Definition: genxmlpars.h:805
~a2dIOHandlerXML()
Destructor.
Definition: genxmlpars.cpp:81
virtual int GetCurrentLineNumber()
where in the input was line the current tag
Definition: genxmlpars.cpp:349
a2dDocumentInputStream * m_streami
file or other string stream containing the format to parse.
Definition: gen.h:3734
int GetAttributeValueInt(const wxString &attrib, int defaultv=0)
Returns the integer value of an attribute.
Definition: genxmlpars.cpp:495
const a2dError a2dError_FileCouldNotOpen
virtual int GetCurrentColumnNumber()
where in the input was column the current tag
Definition: genxmlpars.cpp:342
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:819
a2dIOHandlerXMLWrite()
Constructor.
Definition: genxmlpars.cpp:677
long RequireAttributeValueLong(const wxString &attrib)
Forces an attribute and returns its long integer value.
Definition: genxmlpars.cpp:529
~a2dXMLTag()
Destructor.
Definition: genxmlpars.cpp:247
wxString GetName() const
Get the name of the a2dPropertyId object.
Definition: gen.h:1864
bool m_hasContent
flag to trigger if content was written
Definition: genxmlpars.h:160
wxString GetContent()
Returns the current content.
Definition: genxmlpars.cpp:570
virtual int GetCurrentColumnNumber()
Returns the current column no.
Definition: genxmlpars.cpp:87
a2dIOHandlerXMLPull()
Constructor.
Definition: genxmlpars.cpp:312
virtual wxObject * CreateObject(const wxString &symbolicName)
Creates an specific object by name.
Definition: gen.cpp:4937
used in XML parsing to hold one tag and its atributes
Definition: genxmlpars.h:111
void WriteEndElement(bool newLine=true)
Writes correspondending end tag for the current start tag.
Definition: genxmlpars.cpp:862
virtual void ResetLoad()
Reset the object after loading.
Definition: genxmlpars.cpp:334
void WriteStartDocument(const wxString &version, const wxString &encoding, bool standalone)
Writes the XML header declaration.
Definition: genxmlpars.cpp:723
virtual void DoSave(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList *towrite)
Save settings.
Definition: genxmlpars.cpp:274
XML I/O classes which is Pull parser based for reading XML files.
long GetAttributeValueLong(const wxString &attrib, long defaultv=0)
Returns the long value of an attribute.
Definition: genxmlpars.cpp:516
a2dIOHandlerStrIn & SeekI(wxFileOffset pos)
set stream at a position
Definition: gen.cpp:5021
void WriteNewLine()
Writes a new line and takes care of indentation.
Definition: genxmlpars.cpp:890
XML_Parser m_parser
expat parser
Definition: genxmlpars.h:280
a2dIOHandlerXML()
Constructor.
Definition: genxmlpars.cpp:41
~a2dXmlString()
Destructor.
wxObject * m_doc
the document to store/load the data found into
Definition: genxmlpars.h:854
bool m_hasattributes
does the current XMLTag have attributes?
Definition: genxmlpars.h:163
~a2dIOHandlerXmlSerIn()
Destructor.
void SkipSubTree()
Skips all child elements / tags of current element / tag.
Definition: genxmlpars.cpp:652
XMLeventType
Types of XML events when reading files.
Definition: genxmlpars.h:80
bool m_done
true if reached end of document
Definition: genxmlpars.h:286
virtual void ResetLoad()
Reset the object after loading.
Definition: genxmlpars.cpp:69
const a2dError a2dError_XMLparse
virtual void InitializeSave()
Inits the IO handler for writing.
Definition: genxmlpars.cpp:695
void FillQueue()
Reads next piece of document into buffer.
Definition: genxmlpars.cpp:611
virtual void InitializeLoad()
Inits the handler for reading.
Definition: genxmlpars.cpp:48
a2dIOHandlerXmlSerIn()
Constructor.
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
Definition: gen.h:123
virtual void ResetSave()
Reset the object after saving.
Definition: genxmlpars.cpp:703
A2DGENERALDLLEXP a2dSmrtPtr< a2dGeneralGlobal > a2dGeneralGlobals
a global pointer to get to global instance of important classes.
Definition: comevt.cpp:1148
virtual void InitializeLoad()
Inits the IO handler for reading.
Definition: genxmlpars.cpp:327
a2dSmrtPtrList< a2dXMLTag > m_elements
queue of begin and end elements tags not yet processed
Definition: genxmlpars.h:559
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:862
bool CanLoad(a2dDocumentInputStream &stream, const wxObject *obj, wxClassInfo *docClassInfo=NULL)
test header of the file to see if its CVG format
bool IsOk() const
is the stream Oke to write
Definition: gen.cpp:5207
wxString RequireAttributeValue(const wxString &attrib)
Forces an attribute and returns its string value.
Definition: genxmlpars.cpp:461
void WriteEndAttributes(bool close=false)
&quot;Closes&quot; the start tag after writing all attributes (writes the &quot;&gt;&quot; or &quot;/&gt;&quot; bracket).
Definition: genxmlpars.cpp:837
functions for encoding characters in xml
wxString GetErrorString()
Returns last error as string.
Definition: genxmlpars.cpp:101
using a file stream for output, stream a a2dDocument or other wxObject into a stream.
Definition: gen.h:3751
double GetAttributeValueDouble(const wxString &attrib, double defaultv=0)
Returns the double value of an attribute.
Definition: genxmlpars.cpp:474
a2dXMLTag * m_current
current XML tag
Definition: genxmlpars.h:811
wxInputStream a2dDocumentInputStream
input stream based wxStreams
Definition: gen.h:3456
~a2dIOHandlerXmlSerOut()
Destructor.
virtual void Load(wxObject *parent, a2dIOHandlerXmlSerIn &parser)
load object from CVG file
Definition: gen.cpp:1396
wxString GetAttributeValue(const wxString &attrib, const wxString &defaultv=wxT(""))
Returns the value of an attribute.
Definition: genxmlpars.cpp:450
int RequireAttributeValueInt(const wxString &attrib)
Forces an attribute and returns its integer value.
Definition: genxmlpars.cpp:508
char * m_buffer
buffer used for passing part of the input stream
Definition: genxmlpars.h:283
XMLeventType m_type
event type
Definition: genxmlpars.h:153
void WriteEndDocument()
Checks if all open tags are closed.
Definition: genxmlpars.cpp:730
XMLeventType GetEventType()
Returns the type of current event.
Definition: genxmlpars.cpp:606
void Require(const XMLeventType &type, wxString name)
Forces a special tag.
Definition: genxmlpars.cpp:390
virtual bool Save(a2dDocumentOutputStream &stream, const wxObject *doc)
save a2dCanvasDocument as CVG
wxString GetTagName()
Returns name of the current XML tag.
Definition: genxmlpars.cpp:565
XMLeventType NextTag()
Walks to next tag.
Definition: genxmlpars.cpp:411
virtual wxString StringValueRepresentation() const
Definition: gen.h:1905
for writing XML files.
Definition: genxmlpars.h:576
~a2dIOHandlerXMLWrite()
Destructor.
Definition: genxmlpars.cpp:689
void EndlWriteString(const wxString &string)
Writes a userdefined string into document.
Definition: genxmlpars.cpp:908
virtual void WriteDouble(double d)
write a double number.
Definition: genxmlpars.h:754
double RequireAttributeValueDouble(const wxString &attrib)
Forces an attribute and returns its double value.
Definition: genxmlpars.cpp:487
wxMBConv & m_conv
unicode conversion
Definition: gen.h:3822
a2dXmlString(const wxString &str=wxT(""))
Constructor.
a2dXMLTag(XMLeventType type, wxString tagname=wxT(""))
Constructor.
Definition: genxmlpars.cpp:226
list of a2dObject&#39;s
Definition: gen.h:3157
virtual bool LinkReferences(bool ignoreNonResolved=false)
link references to their destination
Definition: gen.cpp:4862
wxString m_text
Content of the tag.
Definition: genxmlpars.h:150
a2dDocumentOutputStream * m_streamo
file or other string stream containing the format to output to.
Definition: gen.h:3825
virtual void WriteString(const wxString &string)
write a string
Definition: gen.cpp:5107
CloneOptions
options for cloning
Definition: gen.h:1200
virtual void ResetLoad()
Reset the handler after loading.
Definition: gen.cpp:4977
~a2dIOHandlerXMLPull()
Destructor.
Definition: genxmlpars.cpp:321
void WriteStartElement(const wxString &name, bool newLine=true)
Writes start tag which has no attributes.
Definition: genxmlpars.cpp:738
genxmlpars.cpp Source File -- Sun Oct 12 2014 17:04:20 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation