Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/tools/regression/detail/tiny_xml.cpp @ 29

Last change on this file since 29 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 3.9 KB
Line 
1//  tiny XML sub-set tools implementation  -----------------------------------//
2
3//  (C) Copyright Beman Dawes 2002.  Distributed under the Boost
4//  Software License, Version 1.0. (See accompanying file
5//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
7#include "tiny_xml.hpp"
8#include <cassert>
9#include <cstring>
10
11namespace
12{
13
14  void eat_whitespace( char & c, std::istream & in )
15  {
16    while ( c == ' ' || c == '\r' || c == '\n' || c == '\t' )
17      in.get( c );
18  }
19
20  std::string get_name( char & c, std::istream & in )
21  {
22    std::string result;
23    eat_whitespace( c, in );
24    while ( std::strchr(
25      "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-.", c )
26      != 0 )
27    {
28      result += c;
29      if(!in.get( c ))
30        throw std::string("xml: unexpected eof");
31    }
32    return result;
33  }
34
35  void eat_delim( char & c, std::istream & in,
36                  char delim, const std::string & msg )
37  {
38    eat_whitespace( c, in );
39    if ( c != delim )
40      throw std::string("xml syntax error, expected ") + delim
41       + " (" + msg + ")";
42    in.get( c );
43  }
44
45  std::string get_value( char & c, std::istream & in )
46  {
47    std::string result;
48    while ( c != '\"' )
49    {
50      result += c;
51      in.get( c );
52    }
53    in.get( c );
54    return result;
55  }
56
57}
58
59namespace boost
60{
61  namespace tiny_xml
62  {
63
64  //  parse  -----------------------------------------------------------------//
65
66    element_ptr parse( std::istream & in, const std::string & msg )
67    {
68      char c = 0;  // current character
69      element_ptr e( new element );
70
71      if(!in.get( c ))
72        throw std::string("xml: unexpected eof");
73      if ( c == '<' )
74        if(!in.get( c ))
75          throw std::string("xml: unexpected eof");
76
77      e->name = get_name( c, in );
78      eat_whitespace( c, in );
79
80      // attributes
81      while ( c != '>' )
82      {
83        attribute a;
84        a.name = get_name( c, in );
85
86        eat_delim( c, in, '=', msg );
87        eat_delim( c, in, '\"', msg );
88
89        a.value = get_value( c, in );
90
91        e->attributes.push_back( a );
92        eat_whitespace( c, in );
93      }
94      if(!in.get( c )) // next after '>'
95        throw std::string("xml: unexpected eof");
96
97      eat_whitespace( c, in );
98
99      // sub-elements
100      while ( c == '<' )
101      {
102        if ( in.peek() == '/' ) break;
103        e->elements.push_back( parse( in, msg ) );
104        in.get( c ); // next after '>'
105        eat_whitespace( c, in );
106      }
107
108      // content
109      if ( c != '<' )
110      {
111        e->content += '\n';
112        while ( c != '<' )
113        {
114          e->content += c;
115          if(!in.get( c ))
116            throw std::string("xml: unexpected eof");
117        }
118      }
119
120      assert( c == '<' );
121      if(!in.get( c )) // next after '<'
122        throw std::string("xml: unexpected eof");
123
124      eat_delim( c, in, '/', msg );
125      std::string end_name( get_name( c, in ) );
126      if ( e->name != end_name )
127        throw std::string("xml syntax error: beginning name ")
128          + e->name + " did not match end name " + end_name
129          + " (" + msg + ")";
130
131      eat_delim( c, in, '>', msg );
132      return e;
133    }
134
135    //  write  ---------------------------------------------------------------//
136
137    void write( const element & e, std::ostream & out )
138    {
139      out << "<" << e.name;
140      if ( !e.attributes.empty() )
141      {
142        for( attribute_list::const_iterator itr = e.attributes.begin();
143             itr != e.attributes.end(); ++itr )
144        {
145          out << " " << itr->name << "=\"" << itr->value << "\"";
146        }
147      }
148      out << ">";
149      if ( !e.elements.empty() )
150      {
151        out << "\n";
152        for( element_list::const_iterator itr = e.elements.begin();
153             itr != e.elements.end(); ++itr )
154        {
155          write( **itr, out );
156        }
157      }
158      if ( !e.content.empty() )
159      {
160        out << e.content;
161      }
162      out << "</" << e.name << ">\n";
163    }
164
165  } // namespace tiny_xml
166} // namespace boost
167
Note: See TracBrowser for help on using the repository browser.