File: mxml_document.cpp

package info (click to toggle)
falconpl 0.9.6.9-git20120606-2
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 46,176 kB
  • sloc: cpp: 181,389; ansic: 109,025; yacc: 2,310; xml: 1,218; sh: 403; objc: 245; makefile: 82; sql: 20
file content (127 lines) | stat: -rw-r--r-- 2,595 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
   Mini XML lib PLUS for C++

   Document class

   Author: Giancarlo Niccolai <gc@falconpl.org>
*/


#include <mxml_document.h>

namespace MXML {

Document::Document( const Falcon::String &encoding, const int style )
   :Element(),
   m_encoding( encoding )
{
   m_style = style;
   m_root = new Node(Node::typeDocument);
   m_root->reserve();
}

Document::Document( Document &doc )
{
   m_style = doc.m_style;
   m_root = doc.m_root->clone();
   m_encoding = doc.m_encoding;
}

Document::Document( Falcon::Stream &in, const int style )
   throw( MalformedError )
{
   m_style = style;
   m_root = new Node( Node::typeDocument );
   m_root->reserve();
   read( in );
}

Document::~Document()
{
   if ( m_root->shell() == 0 )
      delete m_root;
   else
      m_root->unreserve();
}

Node *Document::main() const
{
   Node *ret = m_root->lastChild();
   while ( ret != 0 && ret->nodeType() != Node::typeTag )
      ret = ret->prev();
   return ret;
}

void Document::write( Falcon::Stream &stream, const int style ) const
{
   stream.writeString( "<?xml version=\"1.0\" encoding=\"" + m_encoding + "\"?>\n");
   m_root->write( stream, m_style );
}


void Document::read( Falcon::Stream &stream )
   throw( MalformedError )
{
   setPosition( 1, 1);
   if ( m_root->child() != 0 ) {
      m_root->dispose();
      m_root = new Node( Node::typeDocument );
      m_root->reserve();
   }

   // load the <?xml document declaration

   bool xmlDecl = false;

   while ( stream.good() && ! stream.eof() )
   {
      // ignore parameter style
      Node *child = new Node();
      try
      {
         child->read( stream, m_style, line(), character());
      }
      catch( MalformedError )
      {
         delete child;
         throw;
      }

      setPosition( child->line(), child->character() );
      if( child->nodeType() == Node::typeXMLDecl )
      {
         if ( xmlDecl )
         {
            MalformedError err( Error::errMultipleXmlDecl, child );
            delete child;
            throw err;
         }
         xmlDecl = true;

         // find the encoding parameter.
         if ( child->hasAttribute( "encoding" ) )
            m_encoding = child->getAttribute( "encoding" );
         else
            m_encoding = "C";

         delete child;
         continue;
      }

      if ( child->nodeType() == Node::typeData && child->data() == "" )
         delete child;
      else {
         m_root->addBelow( child );
      }
   }

   if ( stream.bad() )
   {
      throw IOError( Error::errIo, m_root );
   }
   //todo: validity checks
}

}

/* end of mxml_document.cpp */