00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <spl/text/StringBuffer.h>
00026 #include <spl/io/TextStream.h>
00027 #include <spl/xml/XmlDocument.h>
00028 #include <spl/xml/XmlElement.h>
00029
00030 int XmlDocument::m_tabsize;
00031 bool XmlDocument::m_condenseWhiteSpace = true;
00032
00033 XmlDocument::XmlDocument()
00034 : XmlNode( XmlNode::DOCUMENT ),
00035 m_useMicrosoftBOM(false)
00036 {
00037 m_tabsize = 4;
00038 m_useMicrosoftBOM = false;
00039 }
00040
00041 XmlDocument::XmlDocument( const XmlDocument& copy )
00042 : XmlNode( XmlNode::DOCUMENT ),
00043 m_useMicrosoftBOM(false)
00044 {
00045 copy.CopyTo( *this );
00046 }
00047
00048 XmlDocument::~XmlDocument()
00049 {
00050 }
00051
00052 void XmlDocument::operator=( const XmlDocument& copy )
00053 {
00054 Clear();
00055 copy.CopyTo( *this );
00056 }
00057
00058 XmlElementPtr XmlDocument::RootElement()
00059 {
00060 return FirstChildElement();
00061 }
00062
00063 String XmlDocument::Name() const
00064 {
00065 return String("#document");
00066 }
00067
00069 void XmlDocument::Write( TextWriter& xmlout ) const
00070 {
00071 if ( m_useMicrosoftBOM )
00072 {
00073 const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
00074 const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
00075 const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
00076
00077 xmlout.Write( (byte)TIXML_UTF_LEAD_0 );
00078 xmlout.Write( (byte)TIXML_UTF_LEAD_1 );
00079 xmlout.Write( (byte)TIXML_UTF_LEAD_2 );
00080 }
00081 WriteTo( xmlout );
00082 }
00083
00085 XmlDocumentPtr XmlDocument::Parse( TextReader& xmlin, XmlParsingData* args, XmlEncoding encoding )
00086 {
00087 if ( !xmlin.CanRead() )
00088 {
00089 throw new XmlException("Stream is not readable", -1, -1);
00090 }
00091
00092
00093 long length = xmlin.Length();
00094
00095
00096 if ( length <= 0 )
00097 {
00098 throw new XmlException( "Stream is empty", -1, -1 );
00099 }
00100
00101
00102
00103 StringBuffer data( length+1 );
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126 const int buflen = 256;
00127 Array<byte> buf(buflen);
00128 int readlen;
00129
00130 while ( (readlen = xmlin.ReadBlock(buf, 0, buflen)) > 0 )
00131 {
00132 int crpos = spl::IndexofchfromWithLen((const char *)buf.Data(), 0xD, 0, readlen);
00133 if ( crpos < 0 )
00134 {
00135 data.Append(buf, readlen);
00136 continue;
00137 }
00138 for ( int x = 0; x < readlen; x++ )
00139 {
00140 char ch = buf[x];
00141 if ( ch != 0xD )
00142 {
00143 data.Append(ch);
00144 }
00145 else if ( x < readlen )
00146 {
00147 if ( x == readlen-1 || buf[x+1] != 0xA )
00148 {
00149 data.Append((char)0xA);
00150 }
00151 }
00152 }
00153 }
00154
00155 XmlDocumentPtr doc(new XmlDocument());
00156 XmlNodePtr xdoc = (XmlNodePtr)doc;
00157 doc->m_self = xdoc;
00158
00159 doc->_Parse( data.GetChars(), args, encoding );
00160
00161 return doc;
00162 }
00163
00164 void XmlDocument::CopyTo( XmlDocument& target ) const
00165 {
00166 XmlNode::CopyTo( target );
00167
00168 target.m_tabsize = m_tabsize;
00169 target.m_useMicrosoftBOM = m_useMicrosoftBOM;
00170
00171 if (m_firstChild.IsNotNull())
00172 {
00173 XmlNodePtr node;
00174 for ( node = m_firstChild; node.IsNotNull(); node = node->NextSibling() )
00175 {
00176 node.ValidateMem();
00177 target.AppendChild( node->Clone() );
00178 }
00179 }
00180 }
00181
00182 XmlNodePtr XmlDocument::Clone() const
00183 {
00184 XmlDocumentPtr clone = XmlDocumentPtr(new XmlDocument());
00185 XmlNodePtr xclone = (XmlNodePtr)clone;
00186 clone->m_self = xclone;
00187 CopyTo( *clone );
00188 return clone;
00189 }
00190
00191 void XmlDocument::WriteTo( TextWriter& writer ) const
00192 {
00193 for ( XmlNodePtr node = FirstChild(); node.IsNotNull(); node = node->NextSibling() )
00194 {
00195 node->WriteTo( writer );
00196 }
00197 }
00198
00199 StringPtr XmlDocument::InnerXml() const
00200 {
00201 return ToString();
00202 }
00203
00204 StringPtr XmlDocument::ToString() const
00205 {
00206 MemoryStreamPtr ms(new MemoryStream());
00207 TextWriter writer(ms);
00208 WriteTo(writer);
00209 return ms->ToString();
00210 }
00211
00212 XmlDocumentPtr XmlDocument::ToDocument() const
00213 {
00214 return (XmlNodePtr)m_self;
00215 }
00216
00217 #ifdef DEBUG
00218 void XmlDocument::ValidateMem() const
00219 {
00220 XmlNode::ValidateMem();
00221 }
00222
00223 void XmlDocument::CheckMem() const
00224 {
00225 XmlNode::CheckMem();
00226 }
00227 #endif