~scottydelicious666/brewtarget/brewtarget

« back to all changes in this revision

Viewing changes to xml.cpp

  • Committer: Philip Greggory Lee
  • Date: 2009-08-23 16:53:43 UTC
  • Revision ID: git-v1:f8d1a25135bd92f06c46c562293800e4faa42c61
Made a src/ and ui/ directory and moved everything.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * xml.cpp is part of Brewtarget, and is Copyright Philip G. Lee
3
 
 * (rocketman768@gmail.com), 2009.
4
 
 *
5
 
 * Brewtarget is free software: you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation, either version 3 of the License, or
8
 
 * (at your option) any later version.
9
 
 
10
 
 * Brewtarget is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 
 */
18
 
 
19
 
#include <iostream>
20
 
#include <string>
21
 
#include <algorithm>
22
 
#include "xml.h"
23
 
 
24
 
using namespace std;
25
 
 
26
 
// Returns true if str1 begins with str2
27
 
bool beginsWith( const string &str1, const string &str2 )
28
 
{
29
 
   if( str1.size() < str2.size() )
30
 
      return false;
31
 
 
32
 
   return ( str1.compare( 0, str2.size(), str2 ) == 0 );
33
 
}
34
 
 
35
 
std::string replaceXmlCodes( const std::string &str )
36
 
{
37
 
   std::string::size_type ndx;
38
 
   std::string ret(str);
39
 
   
40
 
   // This iterative approach doesn't exactly conform to standards. During
41
 
   // processing, it may create other false XML codes which will get translated.
42
 
   while( true )
43
 
   {
44
 
      ndx = ret.find("&amp;");
45
 
      if( ndx >=  ret.size() || ndx == std::string::npos )
46
 
         break;
47
 
      ret.erase( ndx, 5 );
48
 
      ret.insert( ndx, "&" );
49
 
   }
50
 
   while( true )
51
 
   {
52
 
      ndx = ret.find("&lt;");
53
 
      if( ndx >=  ret.size() || ndx == std::string::npos )
54
 
         break;
55
 
      ret.erase( ndx, 4 );
56
 
      ret.insert( ndx, "<" );
57
 
   }
58
 
   while( true )
59
 
   {
60
 
      ndx = ret.find("&gt;");
61
 
      if( ndx >=  ret.size() || ndx == std::string::npos )
62
 
         break;
63
 
      ret.erase( ndx, 4 );
64
 
      ret.insert( ndx, ">" );
65
 
   }
66
 
   while( true )
67
 
   {
68
 
      ndx = ret.find("&quot;");
69
 
      if( ndx >=  ret.size() || ndx == std::string::npos )
70
 
         break;
71
 
      ret.erase( ndx, 6 );
72
 
      ret.insert( ndx, "\"" );
73
 
   }
74
 
   while( true )
75
 
   {
76
 
      ndx = ret.find("&apos;");
77
 
      if( ndx >=  ret.size() || ndx == std::string::npos )
78
 
         break;
79
 
      ret.erase( ndx, 6 );
80
 
      ret.insert( ndx, "\'" );
81
 
   }
82
 
   
83
 
   return ret;
84
 
}
85
 
 
86
 
std::string removeQuotes( const std::string &str )
87
 
{
88
 
   std::string::size_type quoteNdx, quot, apos;
89
 
   char c;
90
 
   std::string ret(str);
91
 
   
92
 
   quot = ret.find( "\"", 0 );
93
 
   apos = ret.find( "\'", 0 );
94
 
   quoteNdx = quot < apos? quot : apos; // Minimum
95
 
   
96
 
   if( quoteNdx == std::string::npos )
97
 
      return ret; // There were no quotes or apostrophes, so, don't process.
98
 
   
99
 
   c = ret.at(quoteNdx);
100
 
   
101
 
   ret.erase( 0, quoteNdx+1 );
102
 
   
103
 
   quoteNdx = ret.find(c);
104
 
   if( quoteNdx == std::string::npos )
105
 
      return ""; // There was a beginning quote or apostrophe, but no matching one...error.
106
 
   
107
 
   ret.erase( quoteNdx, ret.size() - quoteNdx );
108
 
   
109
 
   return ret;
110
 
}
111
 
 
112
 
Xml::Xml( istream &in )
113
 
{
114
 
   string tmp;
115
 
 
116
 
   while( getline( in, tmp ) )
117
 
      //xmlTextVec.push_back(tmp);
118
 
      xmlText += tmp;
119
 
 
120
 
   //iter = xmlTextVec.begin();
121
 
 
122
 
   // Transform everything to lowercase
123
 
   // so that comparing will be easier.
124
 
   transform( xmlText.begin(), xmlText.end(), xmlText.begin(), ToLower() );
125
 
 
126
 
   iter = xmlText.begin();
127
 
   end = xmlText.end();
128
 
}
129
 
 
130
 
void Xml::resetIter()
131
 
{
132
 
   iter = xmlText.begin();
133
 
}
134
 
 
135
 
string Xml::nextTag()
136
 
{
137
 
   string::const_iterator b, e;
138
 
   string ret;
139
 
 
140
 
   do
141
 
   {
142
 
      // Find next "<"
143
 
      while( *iter != '<' && iter != end )
144
 
         iter++;
145
 
 
146
 
      b = iter;
147
 
      b++;
148
 
 
149
 
      while( *iter != '>' && iter != end )
150
 
         iter++;
151
 
 
152
 
      e = iter;
153
 
      ret = string(b,e);
154
 
 
155
 
      // Leave the iterator on the character after
156
 
      // the ">".
157
 
      if( iter != end )
158
 
         ++iter;
159
 
   } while( beginsWith( ret, "!--" ) ); // This excludes comment lines.
160
 
 
161
 
   return trim(ret);
162
 
}
163
 
 
164
 
string Xml::nextNonTag()
165
 
{
166
 
   string::const_iterator b, e;
167
 
 
168
 
   b = iter;
169
 
   e = iter;
170
 
 
171
 
   while( *e != '<' && *e != '>' )
172
 
      ++e;
173
 
 
174
 
   iter = e;
175
 
 
176
 
   string ret(b,e);
177
 
   return trim(ret);
178
 
}
179
 
 
180
 
string Xml::getStringVal( const string &closeTag, bool &success, const string &errMsg )
181
 
{
182
 
   string ret = nextNonTag();
183
 
   if( ret.size() > 0 )
184
 
      success = true;
185
 
   else
186
 
      success = false;
187
 
 
188
 
   if( ! beginsWith( nextTag(), closeTag ) )
189
 
      cerr << errMsg << endl;
190
 
 
191
 
   return ret;
192
 
}
193
 
 
194
 
double Xml::getDoubleVal( const string &closeTag, bool &success, const string &errMsg )
195
 
{
196
 
   double ret;
197
 
   char *endptr;
198
 
   const char *txt = nextNonTag().c_str();
199
 
 
200
 
   ret = strtod( txt, &endptr );
201
 
 
202
 
   if( endptr == txt )
203
 
   {
204
 
      success = false;
205
 
      cerr << errMsg << endl;
206
 
   }
207
 
   else
208
 
      success = true;
209
 
 
210
 
   if( ! beginsWith( nextTag(), closeTag ) )
211
 
      cerr << errMsg << endl;
212
 
 
213
 
   return ret;
214
 
}
215
 
 
216
 
long int Xml::getLongVal( const string &closeTag, bool &success, const string &errMsg )
217
 
{
218
 
   long int ret;
219
 
   char *endptr;
220
 
   const char *txt = nextNonTag().c_str();
221
 
 
222
 
   ret = strtol( txt, &endptr, 10 );
223
 
 
224
 
   if( endptr == txt )
225
 
   {
226
 
      success = false;
227
 
      cerr << errMsg << endl;
228
 
   }
229
 
   else
230
 
      success = true;
231
 
 
232
 
   if( ! beginsWith( nextTag(), closeTag ) )
233
 
      cerr << errMsg << endl;
234
 
 
235
 
   return ret;
236
 
}
237
 
 
238
 
bool Xml::isAtEnd()
239
 
{
240
 
   return (iter == end);
241
 
}
242