aboutsummaryrefslogtreecommitdiff
path: root/c++-libbu++/src/object.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'c++-libbu++/src/object.cpp')
-rw-r--r--c++-libbu++/src/object.cpp339
1 files changed, 339 insertions, 0 deletions
diff --git a/c++-libbu++/src/object.cpp b/c++-libbu++/src/object.cpp
new file mode 100644
index 0000000..15d7cb5
--- /dev/null
+++ b/c++-libbu++/src/object.cpp
@@ -0,0 +1,339 @@
1#include "gats/object.h"
2
3#include "gats/integer.h"
4#include "gats/float.h"
5#include "gats/boolean.h"
6#include "gats/string.h"
7#include "gats/list.h"
8#include "gats/dictionary.h"
9#include "gats/null.h"
10
11#include <stdlib.h>
12
13#include <bu/formatter.h>
14#include <bu/stream.h>
15
16#include <bu/sio.h>
17using namespace Bu;
18
19Gats::Object::Object()
20{
21}
22
23Gats::Object::~Object()
24{
25}
26
27Gats::Object *Gats::Object::read( Bu::Stream &rIn )
28{
29 char buf;
30 rIn.read( &buf, 1 );
31 Object *pObj = NULL;
32 switch( buf )
33 {
34 case 'i':
35 pObj = new Gats::Integer();
36 break;
37
38 case 's':
39 pObj = new Gats::String();
40 break;
41
42 case '0':
43 case '1':
44 pObj = new Gats::Boolean();
45 break;
46
47 case 'l':
48 pObj = new Gats::List();
49 break;
50
51 case 'd':
52 pObj = new Gats::Dictionary();
53 break;
54
55 case 'f': // Normal floats
56 case 'F': // Special float values
57 pObj = new Gats::Float();
58 break;
59
60 case 'n':
61 pObj = new Gats::Null();
62 break;
63
64 case 'e':
65 return NULL;
66
67 default:
68 throw Bu::ExceptionBase("Invalid Gats type discovered: %c.", buf );
69 }
70
71 pObj->read( rIn, buf );
72
73 return pObj;
74}
75
76void Gats::Object::skipWs( Bu::String::const_iterator &i )
77{
78 for(; *i == ' ' || *i == '\t' || *i == '\r' || *i == '\n'; i++ ) { }
79}
80
81Bu::String Gats::Object::token( Bu::String::const_iterator &i )
82{
83 Bu::String sRet;
84 if( *i == '\"' )
85 {
86 for( i++; i && *i != '\"' ; i++ )
87 {
88 if( *i == '\\' )
89 i++;
90 sRet += i;
91 }
92 i++;
93 }
94 else
95 {
96 for(; i && *i != ' ' && *i != '\t' && *i != '\r' && *i != '\n' &&
97 *i != ',' && *i != ']' && *i != '}' && *i != '[' &&
98 *i != '{'; i++ )
99 {
100 sRet += i;
101 }
102 }
103
104 return sRet;
105}
106
107Gats::Object *Gats::Object::strToGats( Bu::String::const_iterator &i )
108{
109 skipWs( i );
110
111 switch( *i )
112 {
113 case '[':
114 {
115 Gats::List *pLst = new Gats::List();
116 i++;
117 for(;;)
118 {
119 skipWs( i );
120 if( *i == ']' )
121 {
122 i++;
123 return pLst;
124 }
125 Gats::Object *pObj = strToGats( i );
126 if( !pObj )
127 break;
128 pLst->append( pObj );
129 skipWs( i );
130 switch( *i )
131 {
132 case ',':
133 i++;
134 break;
135
136 case ']':
137 i++;
138 return pLst;
139
140 default:
141 throw Bu::ExceptionBase("Invalid character found.");
142 }
143 }
144 }
145 break;
146
147 case '{':
148 {
149 Gats::Dictionary *pDict = new Gats::Dictionary();
150 i++;
151 for(;;)
152 {
153 skipWs( i );
154 if( *i == '}' )
155 {
156 i++;
157 return pDict;
158 }
159 if( *i != '\"' )
160 throw Bu::ExceptionBase("Keys must be quoted strings.");
161 Bu::String sKey = token( i );
162 skipWs( i );
163 if( *i != ':' )
164 throw Bu::ExceptionBase("Keys and values must be "
165 "seperated with colons.");
166 i++;
167 Gats::Object *pObj = strToGats( i );
168 if( !pObj )
169 throw Bu::ExceptionBase("No value object found.");
170 pDict->insert( sKey, pObj );
171 skipWs( i );
172 switch( *i )
173 {
174 case ',':
175 i++;
176 break;
177
178 case '}':
179 i++;
180 return pDict;
181
182 default:
183 throw Bu::ExceptionBase("Invalid character found.");
184 }
185 }
186 }
187 break;
188
189 case '\"':
190 return new Gats::String( token( i ) );
191 break;
192
193 case '0':
194 case '1':
195 case '2':
196 case '3':
197 case '4':
198 case '5':
199 case '6':
200 case '7':
201 case '8':
202 case '9':
203 case '.':
204 case '+':
205 case '-':
206 {
207 Bu::String s = token( i );
208 int iSize = s.getSize();
209 if( s[iSize-1] == 'i' )
210 {
211 return new Gats::Integer(
212 strtoll( s.getStr(), NULL, 10 )
213 );
214 }
215 else if( s[iSize-1] == 'f' )
216 {
217 return new Gats::Float(
218 strtod( s.getStr(), NULL )
219 );
220 }
221 else
222 {
223 for( Bu::String::iterator i = s.begin(); i; i++ )
224 {
225 if( *i == '.' )
226 return new Gats::Float(
227 strtod( s.getStr(), NULL )
228 );
229 }
230 return new Gats::Integer(
231 strtoll( s.getStr(), NULL, 10 )
232 );
233 }
234 }
235 break;
236
237 default:
238 {
239 Bu::String s = token( i );
240 int iSize = s.getSize();
241 // Test for explicit types first
242 if( iSize > 2 )
243 {
244 if( (s[0] >= '0' && s[0] <= '9') || s[0] == '+' || s[0] == '-' )
245 {
246 }
247 else
248 {
249 Bu::String st = s.toLower();
250 if( st == "true" )
251 {
252 return new Gats::Boolean( true );
253 }
254 else if( st == "false" )
255 {
256 return new Gats::Boolean( false );
257 }
258 else if( st == "null" )
259 {
260 return new Gats::Null();
261 }
262 }
263 }
264 }
265 break;
266 }
267
268 return NULL;
269}
270
271Gats::Object *Gats::Object::strToGats( const Bu::String &sStr )
272{
273 Bu::String::const_iterator i = sStr.begin();
274
275 return strToGats( i );
276}
277
278Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Object &obj )
279{
280 switch( obj.getType() )
281 {
282 case Gats::typeDictionary:
283 return f << dynamic_cast<const Gats::Dictionary &>(obj);
284
285 case Gats::typeList:
286 return f << dynamic_cast<const Gats::List &>(obj);
287
288 case Gats::typeString:
289 return f << dynamic_cast<const Gats::String &>(obj);
290
291 case Gats::typeInteger:
292 return f << dynamic_cast<const Gats::Integer &>(obj);
293
294 case Gats::typeFloat:
295 return f << dynamic_cast<const Gats::Float &>(obj);
296
297 case Gats::typeBoolean:
298 return f << dynamic_cast<const Gats::Boolean &>(obj);
299
300 case Gats::typeNull:
301 return f << dynamic_cast<const Gats::Null &>(obj);
302
303 default:
304 return f << "***ERROR: Bad Gats type***";
305 }
306}
307
308Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Type &t )
309{
310 switch( t )
311 {
312 case Gats::typeDictionary: return f << "dictionary";
313 case Gats::typeList: return f << "list";
314 case Gats::typeString: return f << "string";
315 case Gats::typeInteger: return f << "integer";
316 case Gats::typeFloat: return f << "float";
317 case Gats::typeBoolean: return f << "boolean";
318 case Gats::typeNull: return f << "null";
319 }
320
321 return f << "***unknown***";
322}
323
324const char *Gats::typeToStr( Gats::Type t )
325{
326 switch( t )
327 {
328 case Gats::typeDictionary: return "dictionary";
329 case Gats::typeList: return "list";
330 case Gats::typeString: return "string";
331 case Gats::typeInteger: return "integer";
332 case Gats::typeFloat: return "float";
333 case Gats::typeBoolean: return "boolean";
334 case Gats::typeNull: return "null";
335 }
336
337 return "***unknown***";
338}
339