12 #include "wxartbaseprec.h"
22 #include "wxartbaseprivate.h"
24 #if wxART2D_USE_XMLPARSE
26 const size_t XMLBUFSIZE = 1024;
28 #include "wx/wfstream.h"
31 #include "wx/strconv.h"
32 #include <wx/tokenzr.h>
61 XML_SetUserData(
m_parser, (
void* )
this );
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 );
90 return XML_GetCurrentColumnNumber(
m_parser );
97 return XML_GetCurrentLineNumber(
m_parser );
104 return XmlDecodeStringToString( XML_ErrorString( XML_GetErrorCode(
m_parser ) ) );
108 void a2dIOHandlerXML::BaseStartElementHnd(
void* userData,
const char* name,
const char** atts )
117 tag->SetAttribute( XmlDecodeStringToString( atts[i] ), XmlDecodeStringToString( atts[i + 1] ) );
121 parser->StartElementHnd( tag );
125 void a2dIOHandlerXML::BaseEndElementHnd(
void* userData,
const char* name )
129 parser->EndElementHnd( XmlDecodeStringToString( name ) );
132 void a2dIOHandlerXML::BaseCharacterDataHnd(
void* userData,
const char* s,
int len )
136 char* buf =
new char[len + 1];
138 buf[len] = wxT(
'\0' );
139 memcpy( buf, s, (
size_t )len );
141 parser->CharacterDataHnd( XmlDecodeStringToString( buf ) );
146 void a2dIOHandlerXML::BaseCommentHnd(
void* userData,
const char* data )
150 parser->CommentHnd( XmlDecodeStringToString( data ) );
153 void a2dIOHandlerXML::BaseDefaultHnd(
void* userData,
const char* s,
int len )
157 wxString buf = XmlDecodeStringToString( s, (
size_t )len );
160 if ( len > 6 && memcmp( s,
"<?xml ", 6 ) == 0 )
162 wxString buf = XmlDecodeStringToString( s, (
size_t )len );
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] );
172 parser->DefaultHnd( buf );
175 double a2dIOHandlerXML::ParseDouble(
const wxString& buffer,
unsigned int& position )
177 const wxChar* start = buffer.c_str() + ( long ) position;
179 double val = wxStrtod( start, &end );
180 position = end - buffer.c_str();
188 void a2dIOHandlerXML::SkipCommaSpaces(
const wxString& buffer,
unsigned int& position )
193 current = buffer[position];
198 case wxT(
',' ): case 0x20: case 0x09: case 0x0D: case 0x0A:
205 void a2dIOHandlerXML::SkipSpaces(
const wxString& buffer,
unsigned int& position )
210 current = buffer[position];
215 case 0x20:
case 0x09:
case 0x0D:
case 0x0A:
242 m_attributes = other.m_attributes;
256 bool a2dXMLTag::SetAttribute(
const wxString& attributeName,
const wxString& Value )
258 a2dAttributeHash::iterator iter = m_attributes.find( attributeName );
259 m_attributes[ attributeName ] = Value;
260 return iter != m_attributes.end();
263 wxString* a2dXMLTag::GetAttribute(
const wxString& attributeName )
265 a2dAttributeHash::iterator iter = m_attributes.find( attributeName );
266 if( iter == m_attributes.end() )
269 return &iter->second;
272 #if wxART2D_USE_CVGIO
279 #endif //wxART2D_USE_CVGIO
281 #if wxART2D_USE_CVGIO
288 #endif //wxART2D_USE_CVGIO
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; }
308 wxString a2dIOHandlerXML::m_encoding = wxT(
"UTF-8" );
310 wxString a2dIOHandlerXML::m_version = wxT(
"1.0" );
356 void a2dIOHandlerXMLPull::StartElementHnd(
a2dXMLTag* tag )
358 tag->m_line = XML_GetCurrentLineNumber(
m_parser );
359 tag->m_column = XML_GetCurrentColumnNumber(
m_parser );
363 void a2dIOHandlerXMLPull::EndElementHnd(
const wxString& name )
367 tag->m_line = XML_GetCurrentLineNumber(
m_parser );
368 tag->m_column = XML_GetCurrentColumnNumber(
m_parser );
371 void a2dIOHandlerXMLPull::CharacterDataHnd(
const wxString& text )
382 void a2dIOHandlerXMLPull::CommentHnd(
const wxString& WXUNUSED( comment ) )
386 void a2dIOHandlerXMLPull::DefaultHnd(
const wxString& WXUNUSED( def ) )
455 wxString* val =
m_current->GetAttribute( attrib );
466 wxString* val =
m_current->GetAttribute( attrib );
542 if ( s.MakeLower() == wxT(
"true" ) )
554 if ( s.MakeLower() == wxT(
"true" ) )
562 return m_current->GetAttribute( attrib ) != NULL;
588 bytes_read = Read(
m_buffer, XMLBUFSIZE );
589 if ( bytes_read < 0 )
594 m_done = ( bytes_read < XMLBUFSIZE );
635 bytes_read = Read(
m_buffer, XMLBUFSIZE );
637 if ( bytes_read < 0 )
642 m_done = ( bytes_read < XMLBUFSIZE );
656 while( sublevel > 0 )
679 m_format = wxT(
"%g" );
710 int a2dIOHandlerXMLWrite::GetCurrentColumnNumber()
715 int a2dIOHandlerXMLWrite::GetCurrentLineNumber()
726 *
this << wxT(
"<?xml version=\"" ) << version << wxT(
"\" encoding=\"" ) << encoding << wxT(
"\"" );
727 *
this << wxT(
" standalone=\"" ) << ( standalone ? wxT(
"yes" ) : wxT(
"no" ) ) << wxT(
"\"?>\n" );
732 wxASSERT_MSG(
m_elements.empty(), wxT(
"not end of document, still elements open" ) );
733 wxASSERT_MSG(
m_current == m_enddoc, wxT(
"unBalanced" ) );
753 *
this << wxT(
"<" ) << name << wxT(
">" );
772 *
this << wxT(
"<" ) << name;
799 *
this << wxT(
"<" ) << name << wxT(
">" );
800 WriteStringEnt( content );
801 *
this << wxT(
"</" ) << name << wxT(
">" );
806 void a2dIOHandlerXMLWrite::WriteAttribute(
const wxString& name,
bool value,
bool onlyIfTrue )
810 if ( ( onlyIfTrue && value ) || !onlyIfTrue )
813 *
this << wxT(
" " ) << name << wxT(
"=\"true\"" );
815 *
this << wxT(
" " ) << name << wxT(
"=\"false\"" );
827 void a2dIOHandlerXMLWrite::WriteAttributeEnt(
const wxString& name,
const wxString& value )
829 wxString error = wxT(
"Wrong start tag" ) + this->
m_current->
m_tag;
832 *
this << wxT(
" " ) << name << wxT(
"=\"" );
833 WriteStringEnt( value );
834 *
this << wxT(
"\"" );
847 *
this << wxT(
"/>" );
864 wxString error = wxT(
"Wrong start tag or attributes not written" ) +
m_current->
m_tag;
896 void a2dIOHandlerXMLWrite::WriteIndent()
898 wxString str = wxT(
"\n" );
901 str += wxString (
' ', m_indent * m_indentSize );
903 if ( str.IsEmpty() )
return;
914 void a2dIOHandlerXMLWrite::WriteStringEnt(
const wxString&
string )
922 for ( i = 0; i < len; i++ )
924 c =
string.GetChar( i );
925 if ( c == wxT(
'<' ) || c == wxT(
'>' ) ||
926 ( c == wxT(
'&' ) &&
string.Mid( i + 1, 4 ) != wxT(
"amp;" ) ) ||
927 ( c == wxT(
'"' ) ) )
953 void a2dIOHandlerXMLWrite::XmlEncodeStringToStream(
954 const wxChar*
string,
960 for(
const wxChar* pos =
string; *pos; pos++ )
962 if( *pos >= 32 && *pos <= 126 && *pos != wxChar(
'<' ) && *pos != wxChar(
'>' )
963 && *pos != wxChar(
'&' ) && *pos != wxChar(
'\"' ) )
964 *
this << ( char ) *pos;
966 *
this << wxT(
"&#" ) << (
unsigned int )( wxUChar )( *pos ) << wxT(
";" );
970 size_t nLen = ( len != wxStringBase::npos )
972 : wxConvLocal.MB2WC( (
wchar_t* ) NULL,
string, 0 );
974 if( nLen == (
size_t ) - 1 )
979 for(
const wxChar* pos =
string; *pos && i < nLen; pos++, i++ )
981 if( *pos >= 32 && *pos <= 126 && *pos !=
'<' && *pos !=
'>' && *pos !=
'&' && *pos !=
'\"' )
982 *
this << ( char ) *pos;
984 *
this <<
"&#" << (
unsigned int )(
wchar_t )( *pos ) <<
";";
988 wchar_t* buf =
new wchar_t[nLen + 1];
989 wxConvLocal.MB2WC( buf,
string, nLen );
992 for(
const wchar_t* pos = buf; *pos; pos++ )
994 if( *pos >= 32 && *pos <= 126 && *pos !=
'<' && *pos !=
'>' && *pos !=
'&' && *pos !=
'\"' )
995 *
this << ( char ) *pos;
997 *
this << wxT(
"&#" ) << (
unsigned int )(
wchar_t )( *pos ) << wxT(
";" );
1024 #if wxUSE_UNICODE && wxWCHAR_T_IS_REAL_TYPE
1033 #endif // wxUSE_UNICODE
1038 str.Printf( wxT(
"%d" ), (
signed int )c );
1047 str.Printf( wxT(
"%ld" ), (
signed long )c );
1056 str.Printf( wxT(
"%lld" ), (
unsigned long long ) c );
1065 str.Printf( wxT(
"%u" ), (
unsigned int )c );
1074 str.Printf( wxT(
"%lu" ), (
unsigned long )c );
1083 str.Printf( wxT(
"%llu" ), (
unsigned long long )c );
1101 #if wxART2D_USE_CVGIO
1110 m_formatVersion = wxEmptyString;
1128 return ( memcmp( cheader,
"<?xml ", 6 ) == 0 );
1152 e.getMessage().c_str(), e.getLineNumber(), e.getColumnNumber() );
1178 o->
Load( parent, *
this );
1199 m_doc = ( wxObject* ) doc;
1216 #endif //wxART2D_USE_CVGIO
1236 void a2dXmlString::Reset()
1244 WriteAttribute( _T(
"name" ), name );
virtual void DoLoad(wxObject *parent, a2dIOHandlerXmlSerIn &parser, a2dXmlSer_flag xmlparts)
Load settings.
bool GetAttributeValueBool(const wxString &attrib, bool defaultv=false)
Returns the boolean value of an attribute.
For exceptions thrown while parsing XML files.
(In) Visible property that can be added to Docview Objects.
void WriteContent(const wxString &content)
Writes content between start and end tag.
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.
bool HasAttribute(const wxString &attrib)
Does the current tag have this attribute?
virtual void InitializeLoad()
Inits the handler for reading.
wxString GetTypeString(const XMLeventType &type)
translate XMLeventType to a string
XMLeventType Next()
Walks to next element and returns event type.
bool RequireAttributeValueBool(const wxString &attrib)
Forces an attribute and returns its boolean value.
Input handler for the XML format.
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.
wxObject * m_doc
the document to store/load the data found into
virtual void ResetSave()
Reset the object after saving.
void WriteStartElementAttributes(const wxString &name, bool newLine=true)
Writes start tag which has attributes.
a2dIOHandlerXmlSerOut()
Constructor.
virtual int GetCurrentLineNumber()
Returns the current line no.
a2dXMLTag * m_current
current XML tag
virtual a2dObject * Clone(CloneOptions options) const
create an exact copy of this property
wxOutputStream a2dDocumentOutputStream
output stream based wxStreams
a2dSmrtPtrList< a2dXMLTag > m_elements
queue of begin and end elements tags not yet processed
~a2dIOHandlerXML()
Destructor.
virtual int GetCurrentLineNumber()
where in the input was line the current tag
a2dDocumentInputStream * m_streami
file or other string stream containing the format to parse.
int GetAttributeValueInt(const wxString &attrib, int defaultv=0)
Returns the integer value of an attribute.
const a2dError a2dError_FileCouldNotOpen
virtual int GetCurrentColumnNumber()
where in the input was column the current tag
Input and output handler for the XmlSer format.
a2dIOHandlerXMLWrite()
Constructor.
long RequireAttributeValueLong(const wxString &attrib)
Forces an attribute and returns its long integer value.
wxString GetName() const
Get the name of the a2dPropertyId object.
bool m_hasContent
flag to trigger if content was written
wxString GetContent()
Returns the current content.
virtual int GetCurrentColumnNumber()
Returns the current column no.
a2dIOHandlerXMLPull()
Constructor.
virtual wxObject * CreateObject(const wxString &symbolicName)
Creates an specific object by name.
used in XML parsing to hold one tag and its atributes
void WriteEndElement(bool newLine=true)
Writes correspondending end tag for the current start tag.
virtual void ResetLoad()
Reset the object after loading.
void WriteStartDocument(const wxString &version, const wxString &encoding, bool standalone)
Writes the XML header declaration.
virtual void DoSave(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts, a2dObjectList *towrite)
Save settings.
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.
a2dIOHandlerStrIn & SeekI(wxFileOffset pos)
set stream at a position
void WriteNewLine()
Writes a new line and takes care of indentation.
XML_Parser m_parser
expat parser
a2dIOHandlerXML()
Constructor.
~a2dXmlString()
Destructor.
wxObject * m_doc
the document to store/load the data found into
bool m_hasattributes
does the current XMLTag have attributes?
~a2dIOHandlerXmlSerIn()
Destructor.
void SkipSubTree()
Skips all child elements / tags of current element / tag.
XMLeventType
Types of XML events when reading files.
bool m_done
true if reached end of document
virtual void ResetLoad()
Reset the object after loading.
const a2dError a2dError_XMLparse
virtual void InitializeSave()
Inits the IO handler for writing.
void FillQueue()
Reads next piece of document into buffer.
virtual void InitializeLoad()
Inits the handler for reading.
a2dIOHandlerXmlSerIn()
Constructor.
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
virtual void ResetSave()
Reset the object after saving.
A2DGENERALDLLEXP a2dSmrtPtr< a2dGeneralGlobal > a2dGeneralGlobals
a global pointer to get to global instance of important classes.
virtual void InitializeLoad()
Inits the IO handler for reading.
a2dSmrtPtrList< a2dXMLTag > m_elements
queue of begin and end elements tags not yet processed
Input and output handler for the XmlSer format.
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
wxString RequireAttributeValue(const wxString &attrib)
Forces an attribute and returns its string value.
void WriteEndAttributes(bool close=false)
"Closes" the start tag after writing all attributes (writes the ">" or "/>" bracket).
functions for encoding characters in xml
wxString GetErrorString()
Returns last error as string.
using a file stream for output, stream a a2dDocument or other wxObject into a stream.
double GetAttributeValueDouble(const wxString &attrib, double defaultv=0)
Returns the double value of an attribute.
a2dXMLTag * m_current
current XML tag
wxInputStream a2dDocumentInputStream
input stream based wxStreams
~a2dIOHandlerXmlSerOut()
Destructor.
virtual void Load(wxObject *parent, a2dIOHandlerXmlSerIn &parser)
load object from CVG file
wxString GetAttributeValue(const wxString &attrib, const wxString &defaultv=wxT(""))
Returns the value of an attribute.
int RequireAttributeValueInt(const wxString &attrib)
Forces an attribute and returns its integer value.
char * m_buffer
buffer used for passing part of the input stream
XMLeventType m_type
event type
void WriteEndDocument()
Checks if all open tags are closed.
XMLeventType GetEventType()
Returns the type of current event.
void Require(const XMLeventType &type, wxString name)
Forces a special tag.
virtual bool Save(a2dDocumentOutputStream &stream, const wxObject *doc)
save a2dCanvasDocument as CVG
wxString GetTagName()
Returns name of the current XML tag.
XMLeventType NextTag()
Walks to next tag.
virtual wxString StringValueRepresentation() const
~a2dIOHandlerXMLWrite()
Destructor.
void EndlWriteString(const wxString &string)
Writes a userdefined string into document.
virtual void WriteDouble(double d)
write a double number.
double RequireAttributeValueDouble(const wxString &attrib)
Forces an attribute and returns its double value.
wxMBConv & m_conv
unicode conversion
a2dXmlString(const wxString &str=wxT(""))
Constructor.
a2dXMLTag(XMLeventType type, wxString tagname=wxT(""))
Constructor.
virtual bool LinkReferences(bool ignoreNonResolved=false)
link references to their destination
wxString m_text
Content of the tag.
a2dDocumentOutputStream * m_streamo
file or other string stream containing the format to output to.
virtual void WriteString(const wxString &string)
write a string
CloneOptions
options for cloning
virtual void ResetLoad()
Reset the handler after loading.
~a2dIOHandlerXMLPull()
Destructor.
void WriteStartElement(const wxString &name, bool newLine=true)
Writes start tag which has no attributes.