aboutsummaryrefslogtreecommitdiff
path: root/c++-libbu++/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2012-11-09 16:25:22 +0000
committerMike Buland <eichlan@xagasoft.com>2012-11-09 16:25:22 +0000
commit74dd68ad611d15abf16a65c36a7cfd3f4492930a (patch)
tree843fed9ba6bb03253a01314afc3b1dfbb2dfd26c /c++-libbu++/src
parentd9b407475ae3ebe434b29d9eabdd7d4416e17881 (diff)
downloadlibgats-74dd68ad611d15abf16a65c36a7cfd3f4492930a.tar.gz
libgats-74dd68ad611d15abf16a65c36a7cfd3f4492930a.tar.bz2
libgats-74dd68ad611d15abf16a65c36a7cfd3f4492930a.tar.xz
libgats-74dd68ad611d15abf16a65c36a7cfd3f4492930a.zip
Made the repo less libbu++-centric.
Diffstat (limited to 'c++-libbu++/src')
-rw-r--r--c++-libbu++/src/boolean.cpp53
-rw-r--r--c++-libbu++/src/boolean.h30
-rw-r--r--c++-libbu++/src/dictionary.cpp380
-rw-r--r--c++-libbu++/src/dictionary.h74
-rw-r--r--c++-libbu++/src/float.cpp130
-rw-r--r--c++-libbu++/src/float.h33
-rw-r--r--c++-libbu++/src/gatsc/main.cpp73
-rw-r--r--c++-libbu++/src/gatscon/clientthread.cpp38
-rw-r--r--c++-libbu++/src/gatscon/clientthread.h37
-rw-r--r--c++-libbu++/src/gatscon/clientwidget.cpp82
-rw-r--r--c++-libbu++/src/gatscon/clientwidget.h30
-rw-r--r--c++-libbu++/src/gatscon/clientwidget.ui87
-rw-r--r--c++-libbu++/src/gatscon/connectdlg.cpp22
-rw-r--r--c++-libbu++/src/gatscon/connectdlg.h17
-rw-r--r--c++-libbu++/src/gatscon/connectdlg.ui99
-rw-r--r--c++-libbu++/src/gatscon/filewidget.cpp72
-rw-r--r--c++-libbu++/src/gatscon/filewidget.h29
-rw-r--r--c++-libbu++/src/gatscon/filewidget.ui95
-rw-r--r--c++-libbu++/src/gatscon/gatstotree.cpp91
-rw-r--r--c++-libbu++/src/gatscon/gatstotree.h28
-rw-r--r--c++-libbu++/src/gatscon/iobase.cpp1
-rw-r--r--c++-libbu++/src/gatscon/iobase.h10
-rw-r--r--c++-libbu++/src/gatscon/main.cpp13
-rw-r--r--c++-libbu++/src/gatscon/mainwnd.cpp119
-rw-r--r--c++-libbu++/src/gatscon/mainwnd.h26
-rw-r--r--c++-libbu++/src/gatscon/mainwnd.ui207
-rw-r--r--c++-libbu++/src/gatscon/proxythread.cpp108
-rw-r--r--c++-libbu++/src/gatscon/proxythread.h60
-rw-r--r--c++-libbu++/src/gatscon/proxywidget.cpp131
-rw-r--r--c++-libbu++/src/gatscon/proxywidget.h33
-rw-r--r--c++-libbu++/src/gatscon/proxywidget.ui181
-rw-r--r--c++-libbu++/src/gatscon/setupproxydlg.cpp27
-rw-r--r--c++-libbu++/src/gatscon/setupproxydlg.h18
-rw-r--r--c++-libbu++/src/gatscon/setupproxydlg.ui112
-rw-r--r--c++-libbu++/src/gatscon/treetogats.cpp52
-rw-r--r--c++-libbu++/src/gatscon/treetogats.h13
-rw-r--r--c++-libbu++/src/gatsstream.cpp108
-rw-r--r--c++-libbu++/src/gatsstream.h56
-rw-r--r--c++-libbu++/src/integer.cpp39
-rw-r--r--c++-libbu++/src/integer.h86
-rw-r--r--c++-libbu++/src/list.cpp205
-rw-r--r--c++-libbu++/src/list.h58
-rw-r--r--c++-libbu++/src/null.cpp33
-rw-r--r--c++-libbu++/src/null.h24
-rw-r--r--c++-libbu++/src/object.cpp339
-rw-r--r--c++-libbu++/src/object.h55
-rw-r--r--c++-libbu++/src/protocolgats.cpp56
-rw-r--r--c++-libbu++/src/protocolgats.h30
-rw-r--r--c++-libbu++/src/string.cpp70
-rw-r--r--c++-libbu++/src/string.h32
-rw-r--r--c++-libbu++/src/tests/clone.cpp22
-rw-r--r--c++-libbu++/src/tests/dump.cpp30
-rw-r--r--c++-libbu++/src/tests/int.cpp47
-rw-r--r--c++-libbu++/src/types.h8
-rw-r--r--c++-libbu++/src/unit/basic.unit191
-rw-r--r--c++-libbu++/src/unit/float.unit84
-rw-r--r--c++-libbu++/src/unit/io.unit128
57 files changed, 4312 insertions, 0 deletions
diff --git a/c++-libbu++/src/boolean.cpp b/c++-libbu++/src/boolean.cpp
new file mode 100644
index 0000000..729e644
--- /dev/null
+++ b/c++-libbu++/src/boolean.cpp
@@ -0,0 +1,53 @@
1#include "gats/boolean.h"
2
3#include <bu/formatter.h>
4#include <bu/stream.h>
5
6Gats::Boolean::Boolean() :
7 bVal( false )
8{
9}
10
11Gats::Boolean::Boolean( bool bVal ) :
12 bVal( bVal )
13{
14}
15
16Gats::Boolean::~Boolean()
17{
18}
19
20Gats::Object *Gats::Boolean::clone() const
21{
22 return new Gats::Boolean( bVal );
23}
24
25void Gats::Boolean::write( Bu::Stream &rOut ) const
26{
27 if( bVal )
28 {
29 rOut.write("1", 1 );
30 }
31 else
32 {
33 rOut.write("0", 1 );
34 }
35}
36
37void Gats::Boolean::read( Bu::Stream &rIn, char cType )
38{
39 if( cType == '1' )
40 {
41 bVal = true;
42 }
43 else
44 {
45 bVal = false;
46 }
47}
48
49Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Boolean &b )
50{
51 return f << "(bool) " << b.getValue();
52}
53
diff --git a/c++-libbu++/src/boolean.h b/c++-libbu++/src/boolean.h
new file mode 100644
index 0000000..6b256c5
--- /dev/null
+++ b/c++-libbu++/src/boolean.h
@@ -0,0 +1,30 @@
1#ifndef GATS_BOOLEAN_H
2#define GATS_BOOLEAN_H
3
4#include "gats/object.h"
5
6namespace Gats
7{
8 class Boolean : public Gats::Object
9 {
10 public:
11 Boolean();
12 Boolean( bool bVal );
13 virtual ~Boolean();
14
15 virtual Type getType() const { return typeBoolean; }
16 bool getValue() const { return bVal; }
17 void setValue( bool b ) { bVal = b; }
18 virtual Object *clone() const;
19
20 virtual void write( Bu::Stream &rOut ) const;
21 virtual void read( Bu::Stream &rIn, char cType );
22
23 private:
24 bool bVal;
25 };
26};
27
28Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Boolean &b );
29
30#endif
diff --git a/c++-libbu++/src/dictionary.cpp b/c++-libbu++/src/dictionary.cpp
new file mode 100644
index 0000000..b59d652
--- /dev/null
+++ b/c++-libbu++/src/dictionary.cpp
@@ -0,0 +1,380 @@
1#include "gats/dictionary.h"
2
3#include "gats/boolean.h"
4#include "gats/integer.h"
5#include "gats/float.h"
6#include "gats/string.h"
7#include "gats/list.h"
8
9#include <bu/formatter.h>
10
11template<>
12uint32_t Bu::__calcHashCode<Gats::String>( const Gats::String &s )
13{
14 return __calcHashCode( dynamic_cast<const Bu::String &>(s) );
15}
16
17Gats::Dictionary::Dictionary()
18{
19}
20
21Gats::Dictionary::~Dictionary()
22{
23 for( iterator i = begin(); i; i++ )
24 {
25 delete *i;
26 }
27}
28
29Gats::Object *Gats::Dictionary::clone() const
30{
31 Gats::Dictionary *pClone = new Gats::Dictionary;
32 for( const_iterator i = begin(); i; i++ )
33 {
34 Bu::String s(i.getKey());
35 pClone->insert( s.clone(), (*i)->clone() );
36 }
37
38 return pClone;
39}
40
41void Gats::Dictionary::write( Bu::Stream &rOut ) const
42{
43 rOut.write("d", 1 );
44 for( const_iterator i= begin(); i; i++ )
45 {
46 i.getKey().write( rOut );
47 (*i)->write( rOut );
48 }
49 rOut.write("e", 1 );
50}
51
52void Gats::Dictionary::read( Bu::Stream &rIn, char cType )
53{
54 for(;;)
55 {
56 char cNext;
57 rIn.read( &cNext, 1 );
58 if( cNext == 'e' )
59 break;
60 if( cNext != 's' )
61 throw Bu::ExceptionBase("You can only use strings as keys.");
62 Gats::String sKey;
63 sKey.read( rIn, cNext );
64
65 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
66 sKey, Gats::Object::read( rIn )
67 );
68 }
69}
70
71void Gats::Dictionary::insert( const Bu::String &sKey, char i )
72{
73 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
74 sKey, new Gats::Integer( i )
75 );
76}
77
78void Gats::Dictionary::insert( const Bu::String &sKey, unsigned char i )
79{
80 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
81 sKey, new Gats::Integer( i )
82 );
83}
84
85void Gats::Dictionary::insert( const Bu::String &sKey, signed char i )
86{
87 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
88 sKey, new Gats::Integer( i )
89 );
90}
91
92void Gats::Dictionary::insert( const Bu::String &sKey, unsigned short i )
93{
94 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
95 sKey, new Gats::Integer( i )
96 );
97}
98
99void Gats::Dictionary::insert( const Bu::String &sKey, signed short i )
100{
101 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
102 sKey, new Gats::Integer( i )
103 );
104}
105
106void Gats::Dictionary::insert( const Bu::String &sKey, unsigned int i )
107{
108 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
109 sKey, new Gats::Integer( i )
110 );
111}
112
113void Gats::Dictionary::insert( const Bu::String &sKey, signed int i )
114{
115 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
116 sKey, new Gats::Integer( i )
117 );
118}
119
120void Gats::Dictionary::insert( const Bu::String &sKey, unsigned long i )
121{
122 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
123 sKey, new Gats::Integer( i )
124 );
125}
126
127void Gats::Dictionary::insert( const Bu::String &sKey, signed long i )
128{
129 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
130 sKey, new Gats::Integer( i )
131 );
132}
133
134void Gats::Dictionary::insert( const Bu::String &sKey, unsigned long long i )
135{
136 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
137 sKey, new Gats::Integer( i )
138 );
139}
140
141void Gats::Dictionary::insert( const Bu::String &sKey, signed long long i )
142{
143 ((Bu::Hash<Gats::String, Gats::Object *> *)this)->insert(
144 sKey, new Gats::Integer( i )
145 );
146}
147/*
148void Gats::Dictionary::insert( const Bu::String &sKey, bool b )
149{
150 Bu::Hash<Gats::String, Gats::Object *>::insert(
151 sKey, new Gats::Boolean( b )
152 );
153}*/
154
155void Gats::Dictionary::insert( const Bu::String &sKey, float d )
156{
157 Bu::Hash<Gats::String, Gats::Object *>::insert(
158 sKey, new Gats::Float( d )
159 );
160}
161
162void Gats::Dictionary::insert( const Bu::String &sKey, double d )
163{
164 Bu::Hash<Gats::String, Gats::Object *>::insert(
165 sKey, new Gats::Float( d )
166 );
167}
168
169void Gats::Dictionary::insert( const Bu::String &sKey, const char *s )
170{
171 Bu::Hash<Gats::String, Gats::Object *>::insert(
172 sKey, new Gats::String( s )
173 );
174}
175
176void Gats::Dictionary::insert( const Bu::String &sKey, const Bu::String &s )
177{
178 Bu::Hash<Gats::String, Gats::Object *>::insert(
179 sKey, new Gats::String( s )
180 );
181}
182
183void Gats::Dictionary::insertBool( const Bu::String &sKey, bool b )
184{
185 Bu::Hash<Gats::String, Gats::Object *>::insert(
186 sKey, new Gats::Boolean( b )
187 );
188}
189
190void Gats::Dictionary::insertInt( const Bu::String &sKey, int64_t i )
191{
192 Bu::Hash<Gats::String, Gats::Object *>::insert(
193 sKey, new Gats::Integer( i )
194 );
195}
196
197void Gats::Dictionary::insertFloat( const Bu::String &sKey, double d )
198{
199 Bu::Hash<Gats::String, Gats::Object *>::insert(
200 sKey, new Gats::Float( d )
201 );
202}
203
204void Gats::Dictionary::insertStr( const Bu::String &sKey, const Bu::String &s )
205{
206 Bu::Hash<Gats::String, Gats::Object *>::insert(
207 sKey, new Gats::String( s )
208 );
209}
210
211void Gats::Dictionary::insertList( const Bu::String &sKey, Gats::List *pL )
212{
213 Bu::Hash<Gats::String, Gats::Object *>::insert(
214 sKey, pL
215 );
216}
217
218void Gats::Dictionary::insertDict( const Bu::String &sKey,
219 Gats::Dictionary *pD )
220{
221 Bu::Hash<Gats::String, Gats::Object *>::insert(
222 sKey, pD
223 );
224}
225
226Gats::List *Gats::Dictionary::insertList( const Bu::String &sKey )
227{
228 Gats::List *pLst = new Gats::List();
229 insertList( sKey, pLst );
230 return pLst;
231}
232
233Gats::Dictionary *Gats::Dictionary::insertDict( const Bu::String &sKey )
234{
235 Gats::Dictionary *pDict = new Gats::Dictionary();
236 insertDict( sKey, pDict );
237 return pDict;
238}
239
240bool Gats::Dictionary::getBool( const Bu::String &sKey )
241{
242 Gats::Boolean *pOb = dynamic_cast<Gats::Boolean *>( get( sKey ) );
243 if( !pOb )
244 throw Bu::ExceptionBase("Cannot use %s item '%s' as bool.",
245 typeToStr( get( sKey )->getType() ), sKey.getStr() );
246
247 return pOb->getValue();
248}
249
250int64_t Gats::Dictionary::getInt( const Bu::String &sKey )
251{
252 Gats::Integer *pOb = dynamic_cast<Gats::Integer *>( get( sKey ) );
253 if( !pOb )
254 throw Bu::ExceptionBase("Cannot use %s item '%s' as int.",
255 typeToStr( get( sKey )->getType() ), sKey.getStr() );
256
257 return pOb->getValue();
258}
259
260double Gats::Dictionary::getFloat( const Bu::String &sKey )
261{
262 Gats::Float *pOb = dynamic_cast<Gats::Float *>( get( sKey ) );
263 if( !pOb )
264 throw Bu::ExceptionBase("Cannot use %s item '%s' as float.",
265 typeToStr( get( sKey )->getType() ), sKey.getStr() );
266
267 return pOb->getValue();
268}
269
270Bu::String Gats::Dictionary::getStr( const Bu::String &sKey )
271{
272 Gats::String *pOb = dynamic_cast<Gats::String *>( get( sKey ) );
273 if( !pOb )
274 throw Bu::ExceptionBase("Cannot use %s item '%s' as string.",
275 typeToStr( get( sKey )->getType() ), sKey.getStr() );
276
277 return *pOb;
278}
279
280Gats::List *Gats::Dictionary::getList( const Bu::String &sKey )
281{
282 Gats::List *pOb = dynamic_cast<Gats::List *>( get( sKey ) );
283 if( !pOb )
284 throw Bu::ExceptionBase("Cannot use %s item '%s' as list.",
285 typeToStr( get( sKey )->getType() ), sKey.getStr() );
286
287 return pOb;
288}
289
290Gats::Dictionary *Gats::Dictionary::getDict( const Bu::String &sKey )
291{
292 Gats::Dictionary *pOb = dynamic_cast<Gats::Dictionary *>( get( sKey ) );
293 if( !pOb )
294 throw Bu::ExceptionBase("Cannot use %s item '%s' as dictionary.",
295 typeToStr( get( sKey )->getType() ), sKey.getStr() );
296
297 return pOb;
298}
299
300bool Gats::Dictionary::getBool( const Bu::String &sKey ) const
301{
302 Gats::Boolean *pOb = dynamic_cast<Gats::Boolean *>( get( sKey ) );
303 if( !pOb )
304 throw Bu::ExceptionBase("Cannot use %s item '%s' as bool.",
305 typeToStr( get( sKey )->getType() ), sKey.getStr() );
306
307 return pOb->getValue();
308}
309
310int64_t Gats::Dictionary::getInt( const Bu::String &sKey ) const
311{
312 Gats::Integer *pOb = dynamic_cast<Gats::Integer *>( get( sKey ) );
313 if( !pOb )
314 throw Bu::ExceptionBase("Cannot use %s item '%s' as int.",
315 typeToStr( get( sKey )->getType() ), sKey.getStr() );
316
317 return pOb->getValue();
318}
319
320double Gats::Dictionary::getFloat( const Bu::String &sKey ) const
321{
322 Gats::Float *pOb = dynamic_cast<Gats::Float *>( get( sKey ) );
323 if( !pOb )
324 throw Bu::ExceptionBase("Cannot use %s item '%s' as float.",
325 typeToStr( get( sKey )->getType() ), sKey.getStr() );
326
327 return pOb->getValue();
328}
329
330Bu::String Gats::Dictionary::getStr( const Bu::String &sKey ) const
331{
332 Gats::String *pOb = dynamic_cast<Gats::String *>( get( sKey ) );
333 if( !pOb )
334 throw Bu::ExceptionBase("Cannot use %s item '%s' as string.",
335 typeToStr( get( sKey )->getType() ), sKey.getStr() );
336
337 return *pOb;
338}
339
340Gats::List *Gats::Dictionary::getList( const Bu::String &sKey ) const
341{
342 Gats::List *pOb = dynamic_cast<Gats::List *>( get( sKey ) );
343 if( !pOb )
344 throw Bu::ExceptionBase("Cannot use %s item '%s' as list.",
345 typeToStr( get( sKey )->getType() ), sKey.getStr() );
346
347 return pOb;
348}
349
350Gats::Dictionary *Gats::Dictionary::getDict( const Bu::String &sKey ) const
351{
352 Gats::Dictionary *pOb = dynamic_cast<Gats::Dictionary *>( get( sKey ) );
353 if( !pOb )
354 throw Bu::ExceptionBase("Cannot use %s item '%s' as dictionary.",
355 typeToStr( get( sKey )->getType() ), sKey.getStr() );
356
357 return pOb;
358}
359
360Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Dictionary &d )
361{
362 f << "(dict) {";
363 f.incIndent();
364 int iMax = 0;
365 for( Gats::Dictionary::const_iterator i = d.begin(); i; i++ )
366 {
367 if( i.getKey().getSize() > iMax )
368 iMax = i.getKey().getSize();
369 }
370 iMax += 2;
371 for( Gats::Dictionary::const_iterator i = d.begin(); i; i++ )
372 {
373 f << f.nl << Bu::Fmt( iMax ) << i.getKey() + ": " << *i.getValue();
374 }
375 f.decIndent();
376 f << f.nl << "}";
377
378 return f;
379}
380
diff --git a/c++-libbu++/src/dictionary.h b/c++-libbu++/src/dictionary.h
new file mode 100644
index 0000000..3dd1000
--- /dev/null
+++ b/c++-libbu++/src/dictionary.h
@@ -0,0 +1,74 @@
1#ifndef GATS_DICTIONARY_H
2#define GATS_DICTIONARY_H
3
4#include "gats/object.h"
5#include "gats/string.h"
6#include <bu/hash.h>
7
8namespace Gats
9{
10 class List;
11
12 class Dictionary : public Gats::Object,
13 public Bu::Hash<Gats::String, Gats::Object *>
14 {
15 public:
16 Dictionary();
17 virtual ~Dictionary();
18
19 virtual Type getType() const { return typeDictionary; }
20 virtual Object *clone() const;
21 virtual void write( Bu::Stream &rOut ) const;
22 virtual void read( Bu::Stream &rIn, char cType );
23
24 void insert( const Bu::String &sKey, const char *s );
25 void insert( const Bu::String &sKey, const Bu::String &s );
26 void insert( const Bu::String &sKey, char i );
27 void insert( const Bu::String &sKey, unsigned char i );
28 void insert( const Bu::String &sKey, signed char i );
29 void insert( const Bu::String &sKey, unsigned short i );
30 void insert( const Bu::String &sKey, signed short i );
31 void insert( const Bu::String &sKey, unsigned int i );
32 void insert( const Bu::String &sKey, signed int i );
33 void insert( const Bu::String &sKey, unsigned long i );
34 void insert( const Bu::String &sKey, signed long i );
35 void insert( const Bu::String &sKey, unsigned long long i );
36 void insert( const Bu::String &sKey, signed long long i );
37 //void insert( const Bu::String &sKey, bool b );
38 void insert( const Bu::String &sKey, float d );
39 void insert( const Bu::String &sKey, double d );
40 using Bu::Hash<Gats::String, Gats::Object *>::insert;
41 void insertBool( const Bu::String &sKey, bool b );
42 void insertInt( const Bu::String &sKey, int64_t i );
43 void insertFloat( const Bu::String &sKey, double d );
44 void insertStr( const Bu::String &sKey, const Bu::String &s );
45 void insertList( const Bu::String &sKey, Gats::List *pL );
46 void insertDict( const Bu::String &sKey, Gats::Dictionary *pD );
47 Gats::List *insertList( const Bu::String &sKey );
48 Gats::Dictionary *insertDict( const Bu::String &sKey );
49
50 bool getBool( const Bu::String &sKey );
51 int64_t getInt( const Bu::String &sKey );
52 double getFloat( const Bu::String &sKey );
53 Bu::String getStr( const Bu::String &sKey );
54 Gats::List *getList( const Bu::String &sKey );
55 Gats::Dictionary *getDict( const Bu::String &sKey );
56
57 bool getBool( const Bu::String &sKey ) const;
58 int64_t getInt( const Bu::String &sKey ) const;
59 double getFloat( const Bu::String &sKey ) const;
60 Bu::String getStr( const Bu::String &sKey ) const;
61 Gats::List *getList( const Bu::String &sKey ) const;
62 Gats::Dictionary *getDict( const Bu::String &sKey ) const;
63 };
64};
65
66namespace Bu
67{
68template<>
69uint32_t __calcHashCode<Gats::String>( const Gats::String &s );
70};
71
72Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Dictionary &d );
73
74#endif
diff --git a/c++-libbu++/src/float.cpp b/c++-libbu++/src/float.cpp
new file mode 100644
index 0000000..c01d824
--- /dev/null
+++ b/c++-libbu++/src/float.cpp
@@ -0,0 +1,130 @@
1#include "gats/float.h"
2#include "gats/integer.h"
3
4#include <bu/formatter.h>
5#include <math.h>
6
7#include <bu/sio.h>
8using namespace Bu;
9Gats::Float::Float() :
10 fVal( 0.0 )
11{
12}
13
14Gats::Float::Float( double f ) :
15 fVal( f )
16{
17}
18
19Gats::Float::~Float()
20{
21}
22
23Gats::Object *Gats::Float::clone() const
24{
25 return new Gats::Float( fVal );
26}
27
28void Gats::Float::write( Bu::Stream &rOut ) const
29{
30 if( fVal == 0.0 )
31 {
32 if( signbit( fVal ) )
33 rOut.write("FZ", 2 );
34 else
35 rOut.write("Fz", 2 );
36 }
37 else if( !isfinite( fVal ) )
38 {
39 if( isnan( fVal ) )
40 {
41 if( signbit( fVal ) )
42 rOut.write("FN", 2 );
43 else
44 rOut.write("Fn", 2 );
45 }
46 else
47 {
48 if( signbit( fVal ) )
49 rOut.write("FI", 2 );
50 else
51 rOut.write("Fi", 2 );
52 }
53 }
54 else
55 {
56 rOut.write("f", 1 );
57 double d = fVal;
58 bool bNeg = false;
59 int64_t iScale=0;
60 if( signbit( d ) )
61 {
62 bNeg = true;
63 d = -d;
64 }
65
66 iScale = log( d ) / 0x1.62e42fefa39efp+2; // log( 256.0 )
67 if( iScale < 0 ) iScale--;
68 d /= pow( 256.0, iScale );
69
70 Bu::String s;
71 s += (uint8_t)(d);
72 d -= (int)d;
73 for( int j = 0; j < 150 && d; j++ )
74 {
75 d = d*256.0;
76 s += (uint8_t)d;
77 d -= (int)d;
78 }
79 Gats::Integer::writePackedInt( rOut, bNeg?-s.getSize():s.getSize() );
80 rOut.write( s.getStr(), s.getSize() );
81 Gats::Integer::writePackedInt( rOut, iScale );
82 }
83}
84
85void Gats::Float::read( Bu::Stream &rIn, char cType )
86{
87 if( cType == 'F' )
88 {
89 char buf;
90 rIn.read( &buf, 1 );
91 switch( buf )
92 {
93 case 'N': fVal = -NAN; break;
94 case 'n': fVal = NAN; break;
95 case 'I': fVal = -INFINITY; break;
96 case 'i': fVal = INFINITY; break;
97 case 'Z': fVal = -0.0; break;
98 case 'z': fVal = 0.0; break;
99 }
100 }
101 else if( cType == 'f' )
102 {
103 int64_t iStr;
104 Gats::Integer::readPackedInt( rIn, iStr );
105 bool bNeg = false;
106 if( iStr < 0 )
107 {
108 bNeg = true;
109 iStr = -iStr;
110 }
111 Bu::String s( iStr );
112 rIn.read( s.getStr(), iStr );
113 fVal = 0.0;
114 for( int j = iStr-1; j > 0; j-- )
115 {
116 fVal = (fVal+(uint8_t)s[j])*0x1p-8;
117 }
118 fVal += (uint8_t)s[0];
119 int64_t iScale;
120 Gats::Integer::readPackedInt( rIn, iScale );
121 fVal *= pow( 256.0, iScale );
122 if( bNeg ) fVal = -fVal;
123 }
124}
125
126Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt )
127{
128 return f << "(float) " << flt.getValue();
129}
130
diff --git a/c++-libbu++/src/float.h b/c++-libbu++/src/float.h
new file mode 100644
index 0000000..ba38d6c
--- /dev/null
+++ b/c++-libbu++/src/float.h
@@ -0,0 +1,33 @@
1#ifndef GATS_FLOAT_H
2#define GATS_FLOAT_H
3
4#include "gats/object.h"
5
6#include <bu/string.h>
7
8namespace Gats
9{
10 class Float : public Gats::Object
11 {
12 public:
13 Float();
14 Float( double f );
15 virtual ~Float();
16
17 virtual Object *clone() const;
18
19 virtual Type getType() const { return typeFloat; }
20 double getValue() const { return fVal; }
21
22 virtual void write( Bu::Stream &rOut ) const;
23 virtual void read( Bu::Stream &rIn, char cType );
24
25 private:
26 double fVal;
27 mutable Bu::String sWriteCache;
28 };
29}
30
31Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Float &flt );
32
33#endif
diff --git a/c++-libbu++/src/gatsc/main.cpp b/c++-libbu++/src/gatsc/main.cpp
new file mode 100644
index 0000000..2bac3fd
--- /dev/null
+++ b/c++-libbu++/src/gatsc/main.cpp
@@ -0,0 +1,73 @@
1#include <bu/optparser.h>
2#include <bu/string.h>
3#include <bu/file.h>
4#include <bu/sio.h>
5
6#include "gats/types.h"
7#include "gats/gatsstream.h"
8
9using namespace Bu;
10
11class Options : public OptParser
12{
13public:
14 Options( int argc, char *argv[] ) :
15 bCompile( true )
16 {
17 addHelpBanner("Gats Compiler\nUsage: gatsc [options] [input]\n");
18
19 addOption( sInput, 'i', "input", "Specify input file.");
20 addOption( sOutput, 'o', "output", "Specify output file.");
21
22 addOption( bCompile, 'd', "decompile",
23 "Convert binary gats to text gats.");
24
25 addHelpOption('h', "help", "This Help");
26
27 setNonOption( slot( this, &Options::setInput ) );
28
29 setOverride("decompile", false );
30
31 parse( argc, argv );
32 }
33
34 int setInput( StrArray aParam )
35 {
36 sInput = aParam[0];
37 return 0;
38 }
39
40 bool bCompile;
41 String sInput;
42 String sOutput;
43};
44
45int main( int argc, char *argv[] )
46{
47 Options opt( argc, argv );
48
49 if( opt.sInput.isEmpty() )
50 {
51 sio << "You must specify an input." << sio.nl << sio.nl;
52 return 1;
53 }
54
55 if( opt.sOutput.isEmpty() )
56 {
57 opt.sOutput.set( opt.sInput.begin(), opt.sInput.find('.') );
58 opt.sOutput += ".gats";
59 }
60
61 if( opt.bCompile )
62 {
63 File fIn( opt.sInput, File::Read );
64 File fOut( opt.sOutput, File::WriteNew );
65 Gats::GatsStream gs( fOut );
66 Gats::Object *pObj = Gats::Object::strToGats( fIn.readAll() );
67 gs.writeObject( pObj );
68 delete pObj;
69 }
70
71 return 0;
72}
73
diff --git a/c++-libbu++/src/gatscon/clientthread.cpp b/c++-libbu++/src/gatscon/clientthread.cpp
new file mode 100644
index 0000000..4c7b72a
--- /dev/null
+++ b/c++-libbu++/src/gatscon/clientthread.cpp
@@ -0,0 +1,38 @@
1#include "clientthread.h"
2
3#include <bu/tcpsocket.h>
4
5ClientThread::ClientThread( QObject *pParent, const QByteArray &baHost,
6 int iPort ) :
7 QThread( pParent ),
8 baHost( baHost ),
9 iPort( iPort ),
10 gsCli( ssCli )
11{
12}
13
14ClientThread::~ClientThread()
15{
16}
17
18void ClientThread::send( Gats::Object *pObj )
19{
20 gsCli.writeObject( pObj );
21}
22
23void ClientThread::run()
24{
25 ssCli.setStream(
26 new Bu::TcpSocket( baHost.constData(), iPort )
27 );
28
29 while( !ssCli.isEos() )
30 {
31 Gats::Object *pObj = gsCli.readObject();
32 if( pObj == NULL )
33 continue;
34
35 emit recv( pObj );
36 }
37}
38
diff --git a/c++-libbu++/src/gatscon/clientthread.h b/c++-libbu++/src/gatscon/clientthread.h
new file mode 100644
index 0000000..3182d37
--- /dev/null
+++ b/c++-libbu++/src/gatscon/clientthread.h
@@ -0,0 +1,37 @@
1#ifndef CLIENT_THREAD_H
2#define CLIENT_THREAD_H
3
4#include <QThread>
5#include <QByteArray>
6
7#include <bu/streamstack.h>
8#include <gats/gatsstream.h>
9
10namespace Gats
11{
12 class Object;
13};
14
15class ClientThread : public QThread
16{
17 Q_OBJECT;
18public:
19 ClientThread( QObject *pParent, const QByteArray &baHost, int iPort );
20 virtual ~ClientThread();
21
22 void send( Gats::Object *pObj );
23
24signals:
25 void recv( Gats::Object *pObj );
26
27protected:
28 virtual void run();
29
30private:
31 QByteArray baHost;
32 int iPort;
33 Bu::StreamStack ssCli;
34 Gats::GatsStream gsCli;
35};
36
37#endif
diff --git a/c++-libbu++/src/gatscon/clientwidget.cpp b/c++-libbu++/src/gatscon/clientwidget.cpp
new file mode 100644
index 0000000..941d9fa
--- /dev/null
+++ b/c++-libbu++/src/gatscon/clientwidget.cpp
@@ -0,0 +1,82 @@
1#include "clientwidget.h"
2#include "clientthread.h"
3
4#include "gatstotree.h"
5#include "treetogats.h"
6
7#include <QMessageBox>
8
9#include <gats/gatsstream.h>
10#include <bu/tcpsocket.h>
11#include <bu/sio.h>
12#include <bu/file.h>
13
14using namespace Bu;
15
16ClientWidget::ClientWidget( QWidget *pParent, const QByteArray &baHost,
17 int iPort ) :
18 QWidget( pParent )
19{
20 setupUi( this );
21
22 pCli = new ClientThread( this, baHost, iPort );
23 connect( pCli, SIGNAL(recv( Gats::Object *)),
24 this, SLOT(recv(Gats::Object *)), Qt::QueuedConnection );
25
26 pCli->start();
27}
28
29ClientWidget::~ClientWidget()
30{
31}
32
33void ClientWidget::saveTo( const QString &sFile )
34{
35 File fOut( sFile.toAscii().constData(), File::WriteNew );
36 Gats::GatsStream gsOut( fOut );
37 QTreeWidgetItem *pRoot = twHistory->invisibleRootItem();
38 for( int j = 0; j < pRoot->childCount(); j++ )
39 {
40 Gats::Object *pObj = treeToGats( pRoot->child( j ) );
41 gsOut.writeObject( pObj );
42 delete pObj;
43 }
44}
45
46void ClientWidget::send()
47{
48 try
49 {
50 Gats::Object *pObj = Gats::Object::strToGats(
51 leGats->text().toAscii().constData()
52 );
53 sio << "Send: " << *pObj << sio.nl;
54 QTreeWidgetItem *pIt = new QTreeWidgetItem(
55 twHistory->invisibleRootItem()
56 );
57 pIt->setText( 0, "send" );
58 gatsToTree( pIt, pObj );
59 pCli->send( pObj );
60 delete pObj;
61
62 leGats->setText("");
63 leGats->setFocus();
64 }
65 catch( Bu::ExceptionBase &e )
66 {
67 QMessageBox::critical( this, "Gats Console - Error", e.what() );
68 }
69}
70
71void ClientWidget::recv( Gats::Object *pObj )
72{
73 sio << "Recv: " << *pObj << sio.nl;
74
75 QTreeWidgetItem *pIt = new QTreeWidgetItem(
76 twHistory->invisibleRootItem()
77 );
78 pIt->setText( 0, "recv" );
79 gatsToTree( pIt, pObj );
80 delete pObj;
81}
82
diff --git a/c++-libbu++/src/gatscon/clientwidget.h b/c++-libbu++/src/gatscon/clientwidget.h
new file mode 100644
index 0000000..06c154d
--- /dev/null
+++ b/c++-libbu++/src/gatscon/clientwidget.h
@@ -0,0 +1,30 @@
1#ifndef CLIENT_WIDGET_H
2#define CLIENT_WIDGET_H
3
4#include <QObject>
5#include "ui_clientwidget.h"
6#include "iobase.h"
7
8namespace Gats
9{
10 class Object;
11};
12
13class ClientWidget : public QWidget, protected Ui::ClientWidget, public IoBase
14{
15 Q_OBJECT;
16public:
17 ClientWidget( QWidget *pParent, const QByteArray &baHost, int iPort );
18 virtual ~ClientWidget();
19
20 virtual void saveTo( const QString &sFile );
21
22public slots:
23 void send();
24 void recv( Gats::Object *pObj );
25
26private:
27 class ClientThread *pCli;
28};
29
30#endif
diff --git a/c++-libbu++/src/gatscon/clientwidget.ui b/c++-libbu++/src/gatscon/clientwidget.ui
new file mode 100644
index 0000000..a0cb997
--- /dev/null
+++ b/c++-libbu++/src/gatscon/clientwidget.ui
@@ -0,0 +1,87 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ClientWidget</class>
4 <widget class="QWidget" name="ClientWidget">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>363</width>
10 <height>291</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout">
17 <item>
18 <widget class="QTreeWidget" name="twHistory">
19 <column>
20 <property name="text">
21 <string>Name</string>
22 </property>
23 </column>
24 <column>
25 <property name="text">
26 <string>Type</string>
27 </property>
28 </column>
29 <column>
30 <property name="text">
31 <string>Value</string>
32 </property>
33 </column>
34 </widget>
35 </item>
36 <item>
37 <layout class="QHBoxLayout" name="horizontalLayout">
38 <item>
39 <widget class="QLabel" name="label">
40 <property name="text">
41 <string>Gats:</string>
42 </property>
43 </widget>
44 </item>
45 <item>
46 <widget class="QLineEdit" name="leGats"/>
47 </item>
48 <item>
49 <widget class="QPushButton" name="pushButton">
50 <property name="text">
51 <string>Send</string>
52 </property>
53 <property name="autoDefault">
54 <bool>true</bool>
55 </property>
56 <property name="default">
57 <bool>true</bool>
58 </property>
59 </widget>
60 </item>
61 </layout>
62 </item>
63 </layout>
64 </widget>
65 <resources/>
66 <connections>
67 <connection>
68 <sender>pushButton</sender>
69 <signal>clicked()</signal>
70 <receiver>ClientWidget</receiver>
71 <slot>send()</slot>
72 <hints>
73 <hint type="sourcelabel">
74 <x>332</x>
75 <y>276</y>
76 </hint>
77 <hint type="destinationlabel">
78 <x>322</x>
79 <y>367</y>
80 </hint>
81 </hints>
82 </connection>
83 </connections>
84 <slots>
85 <slot>send()</slot>
86 </slots>
87</ui>
diff --git a/c++-libbu++/src/gatscon/connectdlg.cpp b/c++-libbu++/src/gatscon/connectdlg.cpp
new file mode 100644
index 0000000..589ae97
--- /dev/null
+++ b/c++-libbu++/src/gatscon/connectdlg.cpp
@@ -0,0 +1,22 @@
1#include "connectdlg.h"
2
3ConnectDlg::ConnectDlg( QWidget *pParent ) :
4 QDialog( pParent )
5{
6 setupUi( this );
7}
8
9ConnectDlg::~ConnectDlg()
10{
11}
12
13QByteArray ConnectDlg::getHostname() const
14{
15 return leHost->text().toAscii();
16}
17
18int ConnectDlg::getPort() const
19{
20 return sbPort->value();
21}
22
diff --git a/c++-libbu++/src/gatscon/connectdlg.h b/c++-libbu++/src/gatscon/connectdlg.h
new file mode 100644
index 0000000..57ea6cd
--- /dev/null
+++ b/c++-libbu++/src/gatscon/connectdlg.h
@@ -0,0 +1,17 @@
1#ifndef CONNECT_DLG_H
2#define CONNECT_DLG_H
3
4#include "ui_connectdlg.h"
5
6class ConnectDlg : public QDialog, protected Ui::ConnectDlg
7{
8 Q_OBJECT;
9public:
10 ConnectDlg( QWidget *pParent );
11 virtual ~ConnectDlg();
12
13 QByteArray getHostname() const;
14 int getPort() const;
15};
16
17#endif
diff --git a/c++-libbu++/src/gatscon/connectdlg.ui b/c++-libbu++/src/gatscon/connectdlg.ui
new file mode 100644
index 0000000..6875e27
--- /dev/null
+++ b/c++-libbu++/src/gatscon/connectdlg.ui
@@ -0,0 +1,99 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ConnectDlg</class>
4 <widget class="QDialog" name="ConnectDlg">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>300</width>
10 <height>93</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Gats Console - Connect</string>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout">
17 <item>
18 <layout class="QFormLayout" name="formLayout">
19 <item row="0" column="0">
20 <widget class="QLabel" name="label">
21 <property name="text">
22 <string>Hostname:</string>
23 </property>
24 </widget>
25 </item>
26 <item row="1" column="0">
27 <widget class="QLabel" name="label_2">
28 <property name="text">
29 <string>Port:</string>
30 </property>
31 </widget>
32 </item>
33 <item row="0" column="1">
34 <widget class="QLineEdit" name="leHost">
35 <property name="text">
36 <string>localhost</string>
37 </property>
38 </widget>
39 </item>
40 <item row="1" column="1">
41 <widget class="QSpinBox" name="sbPort">
42 <property name="minimum">
43 <number>1</number>
44 </property>
45 <property name="maximum">
46 <number>32767</number>
47 </property>
48 </widget>
49 </item>
50 </layout>
51 </item>
52 <item>
53 <widget class="QDialogButtonBox" name="buttonBox">
54 <property name="orientation">
55 <enum>Qt::Horizontal</enum>
56 </property>
57 <property name="standardButtons">
58 <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
59 </property>
60 </widget>
61 </item>
62 </layout>
63 </widget>
64 <resources/>
65 <connections>
66 <connection>
67 <sender>buttonBox</sender>
68 <signal>accepted()</signal>
69 <receiver>ConnectDlg</receiver>
70 <slot>accept()</slot>
71 <hints>
72 <hint type="sourcelabel">
73 <x>248</x>
74 <y>254</y>
75 </hint>
76 <hint type="destinationlabel">
77 <x>157</x>
78 <y>274</y>
79 </hint>
80 </hints>
81 </connection>
82 <connection>
83 <sender>buttonBox</sender>
84 <signal>rejected()</signal>
85 <receiver>ConnectDlg</receiver>
86 <slot>reject()</slot>
87 <hints>
88 <hint type="sourcelabel">
89 <x>316</x>
90 <y>260</y>
91 </hint>
92 <hint type="destinationlabel">
93 <x>286</x>
94 <y>274</y>
95 </hint>
96 </hints>
97 </connection>
98 </connections>
99</ui>
diff --git a/c++-libbu++/src/gatscon/filewidget.cpp b/c++-libbu++/src/gatscon/filewidget.cpp
new file mode 100644
index 0000000..dbd70fd
--- /dev/null
+++ b/c++-libbu++/src/gatscon/filewidget.cpp
@@ -0,0 +1,72 @@
1#include "filewidget.h"
2
3#include "gatstotree.h"
4#include "treetogats.h"
5
6#include <gats/types.h>
7#include <gats/gatsstream.h>
8#include <bu/file.h>
9
10#include <QInputDialog>
11
12using namespace Bu;
13
14FileWidget::FileWidget( QWidget *pParent ) :
15 QWidget( pParent )
16{
17 setupUi( this );
18}
19
20FileWidget::FileWidget( QWidget *pParent, QString sFile ) :
21 QWidget( pParent )
22{
23 setupUi( this );
24
25 File fIn( sFile.toAscii().constData(), File::Read );
26 Gats::GatsStream gsIn( fIn );
27 Gats::Object *pObj;
28 while( (pObj = gsIn.readObject()) )
29 {
30 QTreeWidgetItem *pNew = new QTreeWidgetItem(
31 twGats->invisibleRootItem()
32 );
33 pNew->setText( 0, "<root>" );
34 gatsToTree( pNew, pObj );
35 delete pObj;
36 }
37}
38
39FileWidget::~FileWidget()
40{
41}
42
43void FileWidget::saveTo( const QString &sFile )
44{
45 File fOut( sFile.toAscii().constData(), File::WriteNew );
46 Gats::GatsStream gsOut( fOut );
47 QTreeWidgetItem *pRoot = twGats->invisibleRootItem();
48 for( int j = 0; j < pRoot->childCount(); j++ )
49 {
50 Gats::Object *pObj = treeToGats( pRoot->child( j ) );
51 gsOut.writeObject( pObj );
52 delete pObj;
53 }
54}
55
56void FileWidget::addRootItem()
57{
58 QString sText = QInputDialog::getText( this, "Gats Console - Add Root Item",
59 "Gats:");
60 Gats::Object *pObj = Gats::Object::strToGats( sText.toAscii().constData() );
61 QTreeWidgetItem *pNew = new QTreeWidgetItem(
62 twGats->invisibleRootItem()
63 );
64 pNew->setText( 0, "<root>" );
65 gatsToTree( pNew, pObj );
66 delete pObj;
67}
68
69void FileWidget::delRootItem()
70{
71}
72
diff --git a/c++-libbu++/src/gatscon/filewidget.h b/c++-libbu++/src/gatscon/filewidget.h
new file mode 100644
index 0000000..9993bfe
--- /dev/null
+++ b/c++-libbu++/src/gatscon/filewidget.h
@@ -0,0 +1,29 @@
1#ifndef FILE_WIDGET_H
2#define FILE_WIDGET_H
3
4#include "ui_filewidget.h"
5#include "iobase.h"
6
7namespace Gats
8{
9 class Object;
10};
11
12class FileWidget : public QWidget, protected Ui::FileWidget, public IoBase
13{
14 Q_OBJECT;
15public:
16 FileWidget( QWidget *pParent=NULL );
17 FileWidget( QWidget *pParent, QString sFile );
18 virtual ~FileWidget();
19
20 virtual void saveTo( const QString &sFile );
21
22public slots:
23 void addRootItem();
24 void delRootItem();
25
26private:
27};
28
29#endif
diff --git a/c++-libbu++/src/gatscon/filewidget.ui b/c++-libbu++/src/gatscon/filewidget.ui
new file mode 100644
index 0000000..d0e6ec3
--- /dev/null
+++ b/c++-libbu++/src/gatscon/filewidget.ui
@@ -0,0 +1,95 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>FileWidget</class>
4 <widget class="QWidget" name="FileWidget">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>316</width>
10 <height>300</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout">
17 <item>
18 <widget class="QTreeWidget" name="twGats">
19 <column>
20 <property name="text">
21 <string>Name</string>
22 </property>
23 </column>
24 <column>
25 <property name="text">
26 <string>Type</string>
27 </property>
28 </column>
29 <column>
30 <property name="text">
31 <string>Value</string>
32 </property>
33 </column>
34 </widget>
35 </item>
36 <item>
37 <layout class="QHBoxLayout" name="horizontalLayout_2">
38 <item>
39 <widget class="QPushButton" name="pushButton_2">
40 <property name="text">
41 <string>Add Root Item</string>
42 </property>
43 </widget>
44 </item>
45 <item>
46 <widget class="QPushButton" name="pushButton">
47 <property name="text">
48 <string>Del Root Item</string>
49 </property>
50 </widget>
51 </item>
52 </layout>
53 </item>
54 </layout>
55 </widget>
56 <resources/>
57 <connections>
58 <connection>
59 <sender>pushButton_2</sender>
60 <signal>clicked()</signal>
61 <receiver>FileWidget</receiver>
62 <slot>addRootItem()</slot>
63 <hints>
64 <hint type="sourcelabel">
65 <x>60</x>
66 <y>283</y>
67 </hint>
68 <hint type="destinationlabel">
69 <x>10</x>
70 <y>343</y>
71 </hint>
72 </hints>
73 </connection>
74 <connection>
75 <sender>pushButton</sender>
76 <signal>clicked()</signal>
77 <receiver>FileWidget</receiver>
78 <slot>delRootItem()</slot>
79 <hints>
80 <hint type="sourcelabel">
81 <x>252</x>
82 <y>283</y>
83 </hint>
84 <hint type="destinationlabel">
85 <x>258</x>
86 <y>324</y>
87 </hint>
88 </hints>
89 </connection>
90 </connections>
91 <slots>
92 <slot>addRootItem()</slot>
93 <slot>delRootItem()</slot>
94 </slots>
95</ui>
diff --git a/c++-libbu++/src/gatscon/gatstotree.cpp b/c++-libbu++/src/gatscon/gatstotree.cpp
new file mode 100644
index 0000000..e388d5e
--- /dev/null
+++ b/c++-libbu++/src/gatscon/gatstotree.cpp
@@ -0,0 +1,91 @@
1#include "gatstotree.h"
2
3#include <gats/types.h>
4
5#include <QTreeWidgetItem>
6
7void gatsToTree( QTreeWidgetItem *p, Gats::Object *pObj )
8{
9 switch( pObj->getType() )
10 {
11 case Gats::typeInteger:
12 gatsToTree( p, dynamic_cast<Gats::Integer *>( pObj ) );
13 break;
14
15 case Gats::typeString:
16 gatsToTree( p, dynamic_cast<Gats::String *>( pObj ) );
17 break;
18
19 case Gats::typeFloat:
20 gatsToTree( p, dynamic_cast<Gats::Float *>( pObj ) );
21 break;
22
23 case Gats::typeBoolean:
24 gatsToTree( p, dynamic_cast<Gats::Boolean *>( pObj ) );
25 break;
26
27 case Gats::typeList:
28 gatsToTree( p, dynamic_cast<Gats::List *>( pObj ) );
29 break;
30
31 case Gats::typeDictionary:
32 gatsToTree( p, dynamic_cast<Gats::Dictionary *>( pObj ) );
33 break;
34
35 case Gats::typeNull:
36 gatsToTree( p, dynamic_cast<Gats::Null *>( pObj ) );
37 break;
38 }
39}
40
41void gatsToTree( QTreeWidgetItem *p, Gats::Integer *pObj )
42{
43 p->setText( 1, "int");
44 p->setText( 2, QString("%1").arg( pObj->getValue() ) );
45}
46
47void gatsToTree( QTreeWidgetItem *p, Gats::String *pObj )
48{
49 p->setText( 1, "str");
50 p->setText( 2, QString("%1").arg( pObj->getStr() ) );
51}
52
53void gatsToTree( QTreeWidgetItem *p, Gats::Float *pObj )
54{
55 p->setText( 1, "float");
56 p->setText( 2, QString("%1").arg( pObj->getValue() ) );
57}
58
59void gatsToTree( QTreeWidgetItem *p, Gats::Boolean *pObj )
60{
61 p->setText( 1, "bool");
62 p->setText( 2, pObj->getValue()?"true":"false" );
63}
64
65void gatsToTree( QTreeWidgetItem *p, Gats::List *pObj )
66{
67 p->setText( 1, "list");
68 int j = 0;
69 for( Gats::List::iterator i = pObj->begin(); i; i++ )
70 {
71 QTreeWidgetItem *pIt = new QTreeWidgetItem( p );
72 pIt->setText( 0, QString("%1").arg( j++ ) );
73 gatsToTree( pIt, *i );
74 }
75}
76
77void gatsToTree( QTreeWidgetItem *p, Gats::Dictionary *pObj )
78{
79 p->setText( 1, "dict");
80 for( Gats::Dictionary::iterator i = pObj->begin(); i; i++ )
81 {
82 QTreeWidgetItem *pIt = new QTreeWidgetItem( p );
83 pIt->setText( 0, QString( i.getKey().getStr() ) );
84 gatsToTree( pIt, *i );
85 }
86}
87
88void gatsToTree( QTreeWidgetItem *p, Gats::Null *pObj )
89{
90 p->setText( 1, "null");
91}
diff --git a/c++-libbu++/src/gatscon/gatstotree.h b/c++-libbu++/src/gatscon/gatstotree.h
new file mode 100644
index 0000000..a803017
--- /dev/null
+++ b/c++-libbu++/src/gatscon/gatstotree.h
@@ -0,0 +1,28 @@
1#ifndef GATS_TO_TREE_H
2#define GATS_TO_TREE_H
3
4class QTreeWidgetItem;
5
6namespace Gats
7{
8 class Integer;
9 class String;
10 class Float;
11 class Boolean;
12 class List;
13 class Dictionary;
14 class Object;
15};
16
17#include <gats/types.h>
18
19void gatsToTree( QTreeWidgetItem *p, Gats::Object *pObj );
20void gatsToTree( QTreeWidgetItem *p, Gats::Integer *pObj );
21void gatsToTree( QTreeWidgetItem *p, Gats::String *pObj );
22void gatsToTree( QTreeWidgetItem *p, Gats::Float *pObj );
23void gatsToTree( QTreeWidgetItem *p, Gats::Boolean *pObj );
24void gatsToTree( QTreeWidgetItem *p, Gats::List *pObj );
25void gatsToTree( QTreeWidgetItem *p, Gats::Dictionary *pObj );
26void gatsToTree( QTreeWidgetItem *p, Gats::Null *pObj );
27
28#endif
diff --git a/c++-libbu++/src/gatscon/iobase.cpp b/c++-libbu++/src/gatscon/iobase.cpp
new file mode 100644
index 0000000..309444c
--- /dev/null
+++ b/c++-libbu++/src/gatscon/iobase.cpp
@@ -0,0 +1 @@
#include "iobase.h"
diff --git a/c++-libbu++/src/gatscon/iobase.h b/c++-libbu++/src/gatscon/iobase.h
new file mode 100644
index 0000000..5bd3843
--- /dev/null
+++ b/c++-libbu++/src/gatscon/iobase.h
@@ -0,0 +1,10 @@
1#ifndef IO_BASE_H
2#define IO_BASE_H
3
4class IoBase
5{
6public:
7 virtual void saveTo( const class QString &sFile )=0;
8};
9
10#endif
diff --git a/c++-libbu++/src/gatscon/main.cpp b/c++-libbu++/src/gatscon/main.cpp
new file mode 100644
index 0000000..b9b2327
--- /dev/null
+++ b/c++-libbu++/src/gatscon/main.cpp
@@ -0,0 +1,13 @@
1#include "mainwnd.h"
2#include <QApplication>
3
4int main( int argc, char *argv[] )
5{
6 QApplication app( argc, argv );
7
8 MainWnd wnd;
9 wnd.show();
10
11 return app.exec();
12}
13
diff --git a/c++-libbu++/src/gatscon/mainwnd.cpp b/c++-libbu++/src/gatscon/mainwnd.cpp
new file mode 100644
index 0000000..5d31019
--- /dev/null
+++ b/c++-libbu++/src/gatscon/mainwnd.cpp
@@ -0,0 +1,119 @@
1#include "mainwnd.h"
2
3#include "clientwidget.h"
4#include "proxywidget.h"
5#include "filewidget.h"
6
7#include "connectdlg.h"
8#include "setupproxydlg.h"
9
10#include <QLabel>
11#include <QFileDialog>
12
13MainWnd::MainWnd()
14{
15 setupUi( this );
16
17 pMode = new QLabel( "Idle", this );
18 statusBar()->addPermanentWidget( pMode );
19}
20
21MainWnd::~MainWnd()
22{
23}
24
25void MainWnd::connect()
26{
27 ConnectDlg dlg( this );
28 if( dlg.exec() == QDialog::Accepted )
29 {
30 sCurFile.clear();
31 setCentralWidget(
32 new ClientWidget(
33 this, dlg.getHostname(), dlg.getPort()
34 )
35 );
36 pMode->setText(
37 QString("Client Mode: %1:%2").arg( QString(dlg.getHostname()) ).
38 arg( dlg.getPort() )
39 );
40 }
41}
42
43void MainWnd::proxy()
44{
45 SetupProxyDlg dlg( this );
46
47 if( dlg.exec() == QDialog::Accepted )
48 {
49 sCurFile.clear();
50 setCentralWidget(
51 new ProxyWidget(
52 this, dlg.getPortIn(), dlg.getHostOut(), dlg.getPortOut()
53 )
54 );
55 pMode->setText(
56 QString("Proxy Mode: :%1 -> %2:%3").arg( dlg.getPortIn() ).
57 arg( QString(dlg.getHostOut()) ).
58 arg( dlg.getPortOut() )
59 );
60 }
61}
62
63void MainWnd::open()
64{
65 QString sFile = QFileDialog::getOpenFileName(
66 this, "Gats Console - open gats file"
67 );
68 if( sFile.isEmpty() )
69 return;
70
71 sCurFile = sFile;
72 setCentralWidget(
73 new FileWidget( this, sFile )
74 );
75 pMode->setText( QString("File mode: %1").arg( sCurFile ) );
76}
77
78void MainWnd::newFile()
79{
80 sCurFile.clear();
81 setCentralWidget(
82 new FileWidget( this )
83 );
84 pMode->setText( QString("File mode: <untitled>") );
85}
86
87void MainWnd::save()
88{
89 if( sCurFile.isEmpty() )
90 {
91 saveAs();
92 }
93 else
94 {
95 IoBase *pIo = dynamic_cast<IoBase *>(centralWidget());
96 if( !pIo )
97 return;
98
99 pIo->saveTo( sCurFile );
100 }
101}
102
103void MainWnd::saveAs()
104{
105 IoBase *pIo = dynamic_cast<IoBase *>(centralWidget());
106 if( !pIo )
107 return;
108
109 QString sFile = QFileDialog::getSaveFileName(
110 this, "Gats Console - save gats file"
111 );
112 if( sFile.isEmpty() )
113 return;
114
115 pIo->saveTo( sFile );
116
117 sCurFile = sFile;
118}
119
diff --git a/c++-libbu++/src/gatscon/mainwnd.h b/c++-libbu++/src/gatscon/mainwnd.h
new file mode 100644
index 0000000..d1ae080
--- /dev/null
+++ b/c++-libbu++/src/gatscon/mainwnd.h
@@ -0,0 +1,26 @@
1#ifndef MAIN_WND_H
2#define MAIN_WND_H
3
4#include "ui_mainwnd.h"
5
6class MainWnd : public QMainWindow, protected Ui::MainWnd
7{
8 Q_OBJECT;
9public:
10 MainWnd();
11 virtual ~MainWnd();
12
13public slots:
14 void connect();
15 void proxy();
16 void open();
17 void newFile();
18 void save();
19 void saveAs();
20
21private:
22 QString sCurFile;
23 class QLabel *pMode;
24};
25
26#endif
diff --git a/c++-libbu++/src/gatscon/mainwnd.ui b/c++-libbu++/src/gatscon/mainwnd.ui
new file mode 100644
index 0000000..01f534a
--- /dev/null
+++ b/c++-libbu++/src/gatscon/mainwnd.ui
@@ -0,0 +1,207 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>MainWnd</class>
4 <widget class="QMainWindow" name="MainWnd">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>431</width>
10 <height>319</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Gats Console</string>
15 </property>
16 <widget class="QWidget" name="centralwidget"/>
17 <widget class="QMenuBar" name="menubar">
18 <property name="geometry">
19 <rect>
20 <x>0</x>
21 <y>0</y>
22 <width>431</width>
23 <height>21</height>
24 </rect>
25 </property>
26 <widget class="QMenu" name="menu_File">
27 <property name="title">
28 <string>&amp;File</string>
29 </property>
30 <addaction name="action_Open_gats_file"/>
31 <addaction name="action_New_Gats_File"/>
32 <addaction name="action_Save"/>
33 <addaction name="action_Save_As"/>
34 <addaction name="separator"/>
35 <addaction name="actionE_xit"/>
36 </widget>
37 <widget class="QMenu" name="menu_Network">
38 <property name="title">
39 <string>&amp;Network</string>
40 </property>
41 <addaction name="action_Open_connection"/>
42 <addaction name="action_Open_proxy_connection"/>
43 </widget>
44 <addaction name="menu_File"/>
45 <addaction name="menu_Network"/>
46 </widget>
47 <widget class="QStatusBar" name="statusbar"/>
48 <action name="action_Open_connection">
49 <property name="text">
50 <string>&amp;Open connection...</string>
51 </property>
52 </action>
53 <action name="action_Open_proxy_connection">
54 <property name="text">
55 <string>&amp;Start proxy...</string>
56 </property>
57 </action>
58 <action name="action_Open_gats_file">
59 <property name="text">
60 <string>&amp;Open Gats File...</string>
61 </property>
62 </action>
63 <action name="action_New_Gats_File">
64 <property name="text">
65 <string>&amp;New Gats File</string>
66 </property>
67 </action>
68 <action name="action_Save">
69 <property name="text">
70 <string>&amp;Save</string>
71 </property>
72 </action>
73 <action name="action_Save_As">
74 <property name="text">
75 <string>&amp;Save As...</string>
76 </property>
77 </action>
78 <action name="actionE_xit">
79 <property name="text">
80 <string>E&amp;xit</string>
81 </property>
82 </action>
83 </widget>
84 <resources/>
85 <connections>
86 <connection>
87 <sender>action_Open_connection</sender>
88 <signal>triggered()</signal>
89 <receiver>MainWnd</receiver>
90 <slot>connect()</slot>
91 <hints>
92 <hint type="sourcelabel">
93 <x>-1</x>
94 <y>-1</y>
95 </hint>
96 <hint type="destinationlabel">
97 <x>215</x>
98 <y>159</y>
99 </hint>
100 </hints>
101 </connection>
102 <connection>
103 <sender>action_Open_proxy_connection</sender>
104 <signal>triggered()</signal>
105 <receiver>MainWnd</receiver>
106 <slot>proxy()</slot>
107 <hints>
108 <hint type="sourcelabel">
109 <x>-1</x>
110 <y>-1</y>
111 </hint>
112 <hint type="destinationlabel">
113 <x>215</x>
114 <y>159</y>
115 </hint>
116 </hints>
117 </connection>
118 <connection>
119 <sender>action_Open_gats_file</sender>
120 <signal>triggered()</signal>
121 <receiver>MainWnd</receiver>
122 <slot>open()</slot>
123 <hints>
124 <hint type="sourcelabel">
125 <x>-1</x>
126 <y>-1</y>
127 </hint>
128 <hint type="destinationlabel">
129 <x>215</x>
130 <y>159</y>
131 </hint>
132 </hints>
133 </connection>
134 <connection>
135 <sender>actionE_xit</sender>
136 <signal>triggered()</signal>
137 <receiver>MainWnd</receiver>
138 <slot>close()</slot>
139 <hints>
140 <hint type="sourcelabel">
141 <x>-1</x>
142 <y>-1</y>
143 </hint>
144 <hint type="destinationlabel">
145 <x>215</x>
146 <y>159</y>
147 </hint>
148 </hints>
149 </connection>
150 <connection>
151 <sender>action_New_Gats_File</sender>
152 <signal>triggered()</signal>
153 <receiver>MainWnd</receiver>
154 <slot>newFile()</slot>
155 <hints>
156 <hint type="sourcelabel">
157 <x>-1</x>
158 <y>-1</y>
159 </hint>
160 <hint type="destinationlabel">
161 <x>215</x>
162 <y>159</y>
163 </hint>
164 </hints>
165 </connection>
166 <connection>
167 <sender>action_Save</sender>
168 <signal>triggered()</signal>
169 <receiver>MainWnd</receiver>
170 <slot>save()</slot>
171 <hints>
172 <hint type="sourcelabel">
173 <x>-1</x>
174 <y>-1</y>
175 </hint>
176 <hint type="destinationlabel">
177 <x>215</x>
178 <y>159</y>
179 </hint>
180 </hints>
181 </connection>
182 <connection>
183 <sender>action_Save_As</sender>
184 <signal>triggered()</signal>
185 <receiver>MainWnd</receiver>
186 <slot>saveAs()</slot>
187 <hints>
188 <hint type="sourcelabel">
189 <x>-1</x>
190 <y>-1</y>
191 </hint>
192 <hint type="destinationlabel">
193 <x>215</x>
194 <y>159</y>
195 </hint>
196 </hints>
197 </connection>
198 </connections>
199 <slots>
200 <slot>connect()</slot>
201 <slot>proxy()</slot>
202 <slot>open()</slot>
203 <slot>save()</slot>
204 <slot>saveAs()</slot>
205 <slot>newFile()</slot>
206 </slots>
207</ui>
diff --git a/c++-libbu++/src/gatscon/proxythread.cpp b/c++-libbu++/src/gatscon/proxythread.cpp
new file mode 100644
index 0000000..574b56b
--- /dev/null
+++ b/c++-libbu++/src/gatscon/proxythread.cpp
@@ -0,0 +1,108 @@
1#include "proxythread.h"
2
3#include <gats/types.h>
4
5#include <bu/tcpsocket.h>
6#include <bu/tcpserversocket.h>
7#include <bu/sio.h>
8#include <bu/membuf.h>
9
10using namespace Bu;
11
12ProxyThread::ProxyThread( QObject *pParent, int iPortIn,
13 const QByteArray &baHostOut, int iPortOut ) :
14 QThread( pParent ),
15 pHost( NULL ),
16 iPortIn( iPortIn ),
17 baHostOut( baHostOut ),
18 iPortOut( iPortOut ),
19 gsCli( ssCli )
20{
21 pHost = new ProxyHostThread( pParent, this );
22}
23
24ProxyThread::~ProxyThread()
25{
26}
27
28void ProxyThread::send( Gats::Object *pObj )
29{
30 MemBuf bg;
31 Gats::GatsStream gs( bg );
32 gs.writeObject( pObj );
33 ssCli.write( bg.getString().getStr(), bg.getString().getSize() );
34}
35
36void ProxyThread::run()
37{
38 int iSockIn;
39
40 {
41 TcpServerSocket tsIn( iPortIn );
42 do
43 {
44 iSockIn = tsIn.accept( 5 );
45 } while( iSockIn < 0 );
46 }
47
48 emit gotConnection();
49
50 ssCli.setStream( new TcpSocket( iSockIn ) );
51 ssCli.setBlocking( true );
52
53 pHost->setStream(
54 new TcpSocket( baHostOut.constData(), iPortOut )
55 );
56
57 pHost->start();
58
59 while( !ssCli.isEos() )
60 {
61 Gats::Object *pObj = gsCli.readObject();
62 if( pObj == NULL )
63 continue;
64
65 pHost->send( pObj );
66 emit recv( pObj );
67 }
68
69}
70
71ProxyHostThread::ProxyHostThread( QObject *pParent, ProxyThread *pClient ) :
72 QThread( pParent ),
73 pClient( pClient ),
74 ssHst(),
75 gsHst( ssHst )
76{
77}
78
79ProxyHostThread::~ProxyHostThread()
80{
81}
82
83void ProxyHostThread::send( Gats::Object *pObj )
84{
85 MemBuf bg;
86 Gats::GatsStream gs( bg );
87 gs.writeObject( pObj );
88 ssHst.write( bg.getString().getStr(), bg.getString().getSize() );
89}
90
91void ProxyHostThread::setStream( Bu::Stream *pStr )
92{
93 ssHst.setStream( pStr );
94}
95
96void ProxyHostThread::run()
97{
98 while( !ssHst.isEos() )
99 {
100 Gats::Object *pObj = gsHst.readObject();
101 if( pObj == NULL )
102 continue;
103
104 pClient->send( pObj );
105 emit recv( pObj );
106 }
107}
108
diff --git a/c++-libbu++/src/gatscon/proxythread.h b/c++-libbu++/src/gatscon/proxythread.h
new file mode 100644
index 0000000..df75046
--- /dev/null
+++ b/c++-libbu++/src/gatscon/proxythread.h
@@ -0,0 +1,60 @@
1#ifndef PROXY_THREAD_H
2#define PROXY_THREAD_H
3
4#include <QThread>
5
6#include <bu/streamstack.h>
7#include <gats/gatsstream.h>
8
9class ProxyThread : public QThread
10{
11 Q_OBJECT;
12public:
13 ProxyThread( QObject *pParent, int iPortIn, const QByteArray &baHostOut,
14 int iPortOut );
15 virtual ~ProxyThread();
16
17 class ProxyHostThread *pHost;
18
19 void send( Gats::Object *pObj );
20
21signals:
22 void recv( Gats::Object *pObj );
23 void gotConnection();
24
25protected:
26 virtual void run();
27
28private:
29 int iPortIn;
30 QByteArray baHostOut;
31 int iPortOut;
32
33 Bu::StreamStack ssCli;
34 Gats::GatsStream gsCli;
35};
36
37class ProxyHostThread : public QThread
38{
39 Q_OBJECT;
40public:
41 ProxyHostThread( QObject *pParent, ProxyThread *pClient );
42 virtual ~ProxyHostThread();
43
44 void send( Gats::Object *pObj );
45
46 void setStream( Bu::Stream *pStr );
47
48signals:
49 void recv( Gats::Object *pObj );
50
51protected:
52 virtual void run();
53
54private:
55 ProxyThread *pClient;
56 Bu::StreamStack ssHst;
57 Gats::GatsStream gsHst;
58};
59
60#endif
diff --git a/c++-libbu++/src/gatscon/proxywidget.cpp b/c++-libbu++/src/gatscon/proxywidget.cpp
new file mode 100644
index 0000000..215f95f
--- /dev/null
+++ b/c++-libbu++/src/gatscon/proxywidget.cpp
@@ -0,0 +1,131 @@
1#include "proxywidget.h"
2#include "proxythread.h"
3
4#include "gatstotree.h"
5#include "treetogats.h"
6
7#include <QMessageBox>
8
9#include <gats/gatsstream.h>
10#include <gats/types.h>
11#include <bu/sio.h>
12#include <bu/file.h>
13
14using namespace Bu;
15
16ProxyWidget::ProxyWidget( QWidget *pParent, int iPortIn,
17 const QByteArray baHost, int iPortOut ) :
18 QWidget( pParent ),
19 pPrx( NULL )
20{
21 setupUi( this );
22
23 pPrx = new ProxyThread( this, iPortIn, baHost, iPortOut );
24
25 connect( pPrx, SIGNAL(gotConnection()),
26 this, SLOT(gotConnection()), Qt::QueuedConnection );
27 connect( pPrx, SIGNAL(recv( Gats::Object *)),
28 this, SLOT(clientRecv(Gats::Object *)), Qt::QueuedConnection );
29 connect( pPrx->pHost, SIGNAL(recv( Gats::Object *)),
30 this, SLOT(hostRecv(Gats::Object *)), Qt::QueuedConnection );
31
32 pPrx->start();
33}
34
35ProxyWidget::~ProxyWidget()
36{
37}
38
39void ProxyWidget::saveTo( const QString &sFile )
40{
41 File fOut( sFile.toAscii().constData(), File::WriteNew );
42 Gats::GatsStream gsOut( fOut );
43 QTreeWidgetItem *pRoot = twHistory->invisibleRootItem();
44 for( int j = 0; j < pRoot->childCount(); j++ )
45 {
46 Gats::Object *pObj = treeToGats( pRoot->child( j ) );
47 gsOut.writeObject( pObj );
48 delete pObj;
49 }
50}
51
52void ProxyWidget::sendToClient()
53{
54 try
55 {
56 Gats::Object *pObj = Gats::Object::strToGats(
57 leGats->text().toAscii().constData()
58 );
59 sio << "Send: " << *pObj << sio.nl;
60 QTreeWidgetItem *pIt = new QTreeWidgetItem(
61 twHistory->invisibleRootItem()
62 );
63 pIt->setText( 0, "proxy -> client" );
64 gatsToTree( pIt, pObj );
65 pPrx->send( pObj );
66 delete pObj;
67
68 leGats->setText("");
69 leGats->setFocus();
70 }
71 catch( Bu::ExceptionBase &e )
72 {
73 QMessageBox::critical( this, "Gats Console - Error", e.what() );
74 }
75}
76
77void ProxyWidget::sendToServer()
78{
79 try
80 {
81 Gats::Object *pObj = Gats::Object::strToGats(
82 leGats->text().toAscii().constData()
83 );
84 sio << "Send: " << *pObj << sio.nl;
85 QTreeWidgetItem *pIt = new QTreeWidgetItem(
86 twHistory->invisibleRootItem()
87 );
88 pIt->setText( 0, "proxy -> host" );
89 gatsToTree( pIt, pObj );
90 pPrx->pHost->send( pObj );
91 delete pObj;
92
93 leGats->setText("");
94 leGats->setFocus();
95 }
96 catch( Bu::ExceptionBase &e )
97 {
98 QMessageBox::critical( this, "Gats Console - Error", e.what() );
99 }
100}
101
102void ProxyWidget::clientRecv( Gats::Object *pObj )
103{
104 sio << "Recv: " << *pObj << sio.nl;
105
106 QTreeWidgetItem *pIt = new QTreeWidgetItem(
107 twHistory->invisibleRootItem()
108 );
109 pIt->setText( 0, "client -> host" );
110 gatsToTree( pIt, pObj );
111 delete pObj;
112}
113
114void ProxyWidget::hostRecv( Gats::Object *pObj )
115{
116 sio << "Recv: " << *pObj << sio.nl;
117
118 QTreeWidgetItem *pIt = new QTreeWidgetItem(
119 twHistory->invisibleRootItem()
120 );
121 pIt->setText( 0, "host -> client" );
122 gatsToTree( pIt, pObj );
123 delete pObj;
124}
125
126void ProxyWidget::gotConnection()
127{
128 lwConnect->stop();
129 swRoot->setCurrentIndex( 1 );
130}
131
diff --git a/c++-libbu++/src/gatscon/proxywidget.h b/c++-libbu++/src/gatscon/proxywidget.h
new file mode 100644
index 0000000..d6ebf4d
--- /dev/null
+++ b/c++-libbu++/src/gatscon/proxywidget.h
@@ -0,0 +1,33 @@
1#ifndef PROXY_WIDGET_H
2#define PROXY_WIDGET_H
3
4#include "ui_proxywidget.h"
5#include "iobase.h"
6
7namespace Gats
8{
9 class Object;
10};
11
12class ProxyWidget : public QWidget, protected Ui::ProxyWidget, public IoBase
13{
14 Q_OBJECT;
15public:
16 ProxyWidget( QWidget *pParent, int iPortIn, const QByteArray baHost,
17 int iPortOut );
18 virtual ~ProxyWidget();
19
20 virtual void saveTo( const QString &sFile );
21
22public slots:
23 void sendToClient();
24 void sendToServer();
25 void clientRecv( Gats::Object *pObj );
26 void hostRecv( Gats::Object *pObj );
27 void gotConnection();
28
29private:
30 class ProxyThread *pPrx;
31};
32
33#endif
diff --git a/c++-libbu++/src/gatscon/proxywidget.ui b/c++-libbu++/src/gatscon/proxywidget.ui
new file mode 100644
index 0000000..995fc73
--- /dev/null
+++ b/c++-libbu++/src/gatscon/proxywidget.ui
@@ -0,0 +1,181 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>ProxyWidget</class>
4 <widget class="QWidget" name="ProxyWidget">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>338</width>
10 <height>300</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout_2">
17 <property name="margin">
18 <number>0</number>
19 </property>
20 <item>
21 <widget class="QStackedWidget" name="swRoot">
22 <property name="currentIndex">
23 <number>0</number>
24 </property>
25 <widget class="QWidget" name="page">
26 <layout class="QVBoxLayout" name="verticalLayout_4">
27 <item>
28 <spacer name="verticalSpacer">
29 <property name="orientation">
30 <enum>Qt::Vertical</enum>
31 </property>
32 <property name="sizeHint" stdset="0">
33 <size>
34 <width>20</width>
35 <height>40</height>
36 </size>
37 </property>
38 </spacer>
39 </item>
40 <item>
41 <widget class="QLabel" name="label_2">
42 <property name="text">
43 <string>Listening for connections...</string>
44 </property>
45 <property name="alignment">
46 <set>Qt::AlignCenter</set>
47 </property>
48 </widget>
49 </item>
50 <item>
51 <widget class="LoadingWidget" name="lwConnect" native="true">
52 <property name="minimumSize">
53 <size>
54 <width>0</width>
55 <height>50</height>
56 </size>
57 </property>
58 </widget>
59 </item>
60 <item>
61 <spacer name="verticalSpacer_2">
62 <property name="orientation">
63 <enum>Qt::Vertical</enum>
64 </property>
65 <property name="sizeHint" stdset="0">
66 <size>
67 <width>20</width>
68 <height>40</height>
69 </size>
70 </property>
71 </spacer>
72 </item>
73 </layout>
74 </widget>
75 <widget class="QWidget" name="page_2">
76 <layout class="QVBoxLayout" name="verticalLayout_3">
77 <item>
78 <widget class="QTreeWidget" name="twHistory">
79 <column>
80 <property name="text">
81 <string>Name</string>
82 </property>
83 </column>
84 <column>
85 <property name="text">
86 <string>Type</string>
87 </property>
88 </column>
89 <column>
90 <property name="text">
91 <string>Value</string>
92 </property>
93 </column>
94 </widget>
95 </item>
96 <item>
97 <layout class="QHBoxLayout" name="horizontalLayout">
98 <item>
99 <widget class="QLabel" name="label">
100 <property name="text">
101 <string>Gats:</string>
102 </property>
103 </widget>
104 </item>
105 <item>
106 <widget class="QLineEdit" name="leGats"/>
107 </item>
108 <item>
109 <layout class="QVBoxLayout" name="verticalLayout">
110 <item>
111 <widget class="QPushButton" name="pushButton">
112 <property name="text">
113 <string>Send to Client</string>
114 </property>
115 </widget>
116 </item>
117 <item>
118 <widget class="QPushButton" name="pushButton_2">
119 <property name="text">
120 <string>Send to Server</string>
121 </property>
122 </widget>
123 </item>
124 </layout>
125 </item>
126 </layout>
127 </item>
128 </layout>
129 </widget>
130 </widget>
131 </item>
132 </layout>
133 </widget>
134 <customwidgets>
135 <customwidget>
136 <class>LoadingWidget</class>
137 <extends>QWidget</extends>
138 <header>loadingwidget.h</header>
139 <container>1</container>
140 </customwidget>
141 </customwidgets>
142 <resources/>
143 <connections>
144 <connection>
145 <sender>pushButton</sender>
146 <signal>clicked()</signal>
147 <receiver>ProxyWidget</receiver>
148 <slot>sendToClient()</slot>
149 <hints>
150 <hint type="sourcelabel">
151 <x>280</x>
152 <y>258</y>
153 </hint>
154 <hint type="destinationlabel">
155 <x>392</x>
156 <y>223</y>
157 </hint>
158 </hints>
159 </connection>
160 <connection>
161 <sender>pushButton_2</sender>
162 <signal>clicked()</signal>
163 <receiver>ProxyWidget</receiver>
164 <slot>sendToServer()</slot>
165 <hints>
166 <hint type="sourcelabel">
167 <x>306</x>
168 <y>284</y>
169 </hint>
170 <hint type="destinationlabel">
171 <x>199</x>
172 <y>340</y>
173 </hint>
174 </hints>
175 </connection>
176 </connections>
177 <slots>
178 <slot>sendToClient()</slot>
179 <slot>sendToServer()</slot>
180 </slots>
181</ui>
diff --git a/c++-libbu++/src/gatscon/setupproxydlg.cpp b/c++-libbu++/src/gatscon/setupproxydlg.cpp
new file mode 100644
index 0000000..7c7a873
--- /dev/null
+++ b/c++-libbu++/src/gatscon/setupproxydlg.cpp
@@ -0,0 +1,27 @@
1#include "setupproxydlg.h"
2
3SetupProxyDlg::SetupProxyDlg( QWidget *pParent ) :
4 QDialog( pParent )
5{
6 setupUi( this );
7}
8
9SetupProxyDlg::~SetupProxyDlg()
10{
11}
12
13int SetupProxyDlg::getPortIn() const
14{
15 return sbPortIn->value();
16}
17
18QByteArray SetupProxyDlg::getHostOut() const
19{
20 return leHostOut->text().toAscii();
21}
22
23int SetupProxyDlg::getPortOut() const
24{
25 return sbPortOut->value();
26}
27
diff --git a/c++-libbu++/src/gatscon/setupproxydlg.h b/c++-libbu++/src/gatscon/setupproxydlg.h
new file mode 100644
index 0000000..6cc31bd
--- /dev/null
+++ b/c++-libbu++/src/gatscon/setupproxydlg.h
@@ -0,0 +1,18 @@
1#ifndef SETUP_PROXY_DLG_H
2#define SETUP_PROXY_DLG_H
3
4#include "ui_setupproxydlg.h"
5
6class SetupProxyDlg : public QDialog, protected Ui::SetupProxyDlg
7{
8 Q_OBJECT;
9public:
10 SetupProxyDlg( QWidget *pParent=NULL );
11 virtual ~SetupProxyDlg();
12
13 int getPortIn() const;
14 QByteArray getHostOut() const;
15 int getPortOut() const;
16};
17
18#endif
diff --git a/c++-libbu++/src/gatscon/setupproxydlg.ui b/c++-libbu++/src/gatscon/setupproxydlg.ui
new file mode 100644
index 0000000..c713baf
--- /dev/null
+++ b/c++-libbu++/src/gatscon/setupproxydlg.ui
@@ -0,0 +1,112 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>SetupProxyDlg</class>
4 <widget class="QDialog" name="SetupProxyDlg">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>359</width>
10 <height>122</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Gats Console - Setup Proxy</string>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout">
17 <item>
18 <layout class="QFormLayout" name="formLayout">
19 <item row="0" column="0">
20 <widget class="QLabel" name="label_2">
21 <property name="text">
22 <string>Listening port:</string>
23 </property>
24 </widget>
25 </item>
26 <item row="0" column="1">
27 <widget class="QSpinBox" name="sbPortIn">
28 <property name="minimum">
29 <number>1</number>
30 </property>
31 <property name="maximum">
32 <number>32767</number>
33 </property>
34 </widget>
35 </item>
36 <item row="1" column="0">
37 <widget class="QLabel" name="label_3">
38 <property name="text">
39 <string>Target host:</string>
40 </property>
41 </widget>
42 </item>
43 <item row="1" column="1">
44 <widget class="QLineEdit" name="leHostOut"/>
45 </item>
46 <item row="2" column="0">
47 <widget class="QLabel" name="label_4">
48 <property name="text">
49 <string>Target port:</string>
50 </property>
51 </widget>
52 </item>
53 <item row="2" column="1">
54 <widget class="QSpinBox" name="sbPortOut">
55 <property name="minimum">
56 <number>1</number>
57 </property>
58 <property name="maximum">
59 <number>32767</number>
60 </property>
61 </widget>
62 </item>
63 </layout>
64 </item>
65 <item>
66 <widget class="QDialogButtonBox" name="buttonBox">
67 <property name="orientation">
68 <enum>Qt::Horizontal</enum>
69 </property>
70 <property name="standardButtons">
71 <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
72 </property>
73 </widget>
74 </item>
75 </layout>
76 </widget>
77 <resources/>
78 <connections>
79 <connection>
80 <sender>buttonBox</sender>
81 <signal>accepted()</signal>
82 <receiver>SetupProxyDlg</receiver>
83 <slot>accept()</slot>
84 <hints>
85 <hint type="sourcelabel">
86 <x>248</x>
87 <y>254</y>
88 </hint>
89 <hint type="destinationlabel">
90 <x>157</x>
91 <y>274</y>
92 </hint>
93 </hints>
94 </connection>
95 <connection>
96 <sender>buttonBox</sender>
97 <signal>rejected()</signal>
98 <receiver>SetupProxyDlg</receiver>
99 <slot>reject()</slot>
100 <hints>
101 <hint type="sourcelabel">
102 <x>316</x>
103 <y>260</y>
104 </hint>
105 <hint type="destinationlabel">
106 <x>286</x>
107 <y>274</y>
108 </hint>
109 </hints>
110 </connection>
111 </connections>
112</ui>
diff --git a/c++-libbu++/src/gatscon/treetogats.cpp b/c++-libbu++/src/gatscon/treetogats.cpp
new file mode 100644
index 0000000..a1571d1
--- /dev/null
+++ b/c++-libbu++/src/gatscon/treetogats.cpp
@@ -0,0 +1,52 @@
1#include "treetogats.h"
2
3#include <QTreeWidgetItem>
4
5#include <gats/types.h>
6
7Gats::Object *treeToGats( QTreeWidgetItem *pRoot )
8{
9 QString sType = pRoot->text( 1 );
10 QByteArray baDat = pRoot->text( 2 ).toAscii();
11 if( sType == "int" )
12 {
13 return new Gats::Integer( strtoll( baDat.constData(), NULL, 10 ) );
14 }
15 else if( sType == "str" )
16 {
17 return new Gats::String( baDat.constData(), baDat.size() );
18 }
19 else if( sType == "float" )
20 {
21 return new Gats::Float( strtod( baDat.constData(), NULL ) );
22 }
23 else if( sType == "bool" )
24 {
25 return new Gats::Boolean( baDat == "true" );
26 }
27 else if( sType == "list" )
28 {
29 Gats::List *pRet = new Gats::List();
30 for( int j = 0; j < pRoot->childCount(); j++ )
31 {
32 pRet->append( treeToGats( pRoot->child( j ) ) );
33 }
34 return pRet;
35 }
36 else if( sType == "dict" )
37 {
38 Gats::Dictionary *pRet = new Gats::Dictionary();
39 for( int j = 0; j < pRoot->childCount(); j++ )
40 {
41 QTreeWidgetItem *pChild = pRoot->child( j );
42 pRet->insert(
43 pChild->text( 0 ).toAscii().constData(),
44 treeToGats( pChild )
45 );
46 }
47 return pRet;
48 }
49
50 throw Bu::ExceptionBase("Unhandled type found.");
51}
52
diff --git a/c++-libbu++/src/gatscon/treetogats.h b/c++-libbu++/src/gatscon/treetogats.h
new file mode 100644
index 0000000..931623d
--- /dev/null
+++ b/c++-libbu++/src/gatscon/treetogats.h
@@ -0,0 +1,13 @@
1#ifndef TREE_TO_GATS_H
2#define TREE_TO_GATS_H
3
4class QTreeWidgetItem;
5
6namespace Gats
7{
8 class Object;
9};
10
11Gats::Object *treeToGats( QTreeWidgetItem *pRoot );
12
13#endif
diff --git a/c++-libbu++/src/gatsstream.cpp b/c++-libbu++/src/gatsstream.cpp
new file mode 100644
index 0000000..d5e3f82
--- /dev/null
+++ b/c++-libbu++/src/gatsstream.cpp
@@ -0,0 +1,108 @@
1#include "gats/gatsstream.h"
2#include "gats/object.h"
3
4// #include <bu/sio.h>
5#include <bu/nullstream.h>
6// using namespace Bu;
7
8Gats::GatsStream::GatsStream( Bu::Stream &rStream ) :
9 rStream( rStream )
10{
11}
12
13Gats::GatsStream::~GatsStream()
14{
15}
16
17Gats::Object *Gats::GatsStream::readObject()
18{
19 char buf[1500];
20
21 // sio << "Gats::GatsStream::readObject(): Scanning for object header." << sio.nl;
22 do
23 {
24 if( qbRead.getSize() < 5 )
25 {
26 // sio << "Gats::GatsStream::readObject(): reading header data, need 5b, have " << qbRead.getSize() << "b." << sio.nl;
27 int iRead = rStream.read( buf, 5-qbRead.getSize() );
28 qbRead.write( buf, iRead );
29
30 if( qbRead.getSize() < 5 )
31 return NULL;
32 }
33 } while( !skipReadNulls() );
34
35 uint8_t uVer;
36 qbRead.peek( &uVer, 1 );
37 // sio << "Gats::GatsStream::readObject(): Packet version: " << (int)uVer << sio.nl;
38
39 int32_t iSize;
40 qbRead.peek( &iSize, 4, 1 );
41 iSize = be32toh( iSize );
42 // sio << "Gats::GatsStream::readObject(): Header read, looking for " << iSize << "b, we have " << qbRead.getSize() << "b." << sio.nl;
43 while( qbRead.getSize() < iSize )
44 {
45 int32_t iRead = iSize - qbRead.getSize();
46 if( iRead > 1500 )
47 iRead = 1500;
48 // sio << "Gats::GatsStream::readObject(): Attempting to read " << iRead << "b." << sio.nl;
49 int32_t iReal = rStream.read( buf, iRead );
50 // sio << "Gats::GatsStream::readObject(): Read " << iReal << "b." << sio.nl;
51 qbRead.write( buf, iReal );
52 if( iReal < iRead )
53 {
54 // sio << "Gats::GatsStream::readObject(): Insufficient data read in block, bailing on read." << sio.nl;
55 return NULL;
56 }
57 }
58
59 if( qbRead.getSize() < iSize )
60 {
61 // sio << "Gats::GatsStream::readObject(): Somehow, we still don't have enough data, bailing." << sio.nl;
62 return NULL;
63 }
64
65 // sio << "Gats::GatsStream::readObject(): We have " << qbRead.getSize() << "b of " << iSize << "b, time to read the object." << sio.nl;
66
67 qbRead.seek( 5 );
68 Gats::Object *pObj = Gats::Object::read( qbRead );
69
70 // sio << "Gats::GatsStream::readObject(): Read completed, there are " << qbRead.getSize() << "b left in the buffer." << sio.nl;
71 return pObj;
72}
73
74void Gats::GatsStream::writeObject( Gats::Object *pObject )
75{
76 Bu::NullStream ns;
77 pObject->write( ns );
78
79 uint8_t uBuf = 1;
80 int32_t iSize = htobe32( ns.tell()+5 );
81 rStream.write( &uBuf, 1 );
82 rStream.write( &iSize, 4 );
83 pObject->write( rStream );
84
85 // sio << "Object consumed " << ns.tell() << "b." << sio.nl;
86}
87
88bool Gats::GatsStream::skipReadNulls()
89{
90 char buf;
91
92 // sio << "Gats::GatsStream::skipReadNulls(): Scanning for nulls, " << qbRead.getSize() << "b." << sio.nl;
93 bool bHaveSeeked = false;
94 for(;;)
95 {
96 if( qbRead.peek( &buf, 1 ) == 0 )
97 return false;
98 if( buf != 0 )
99 return !bHaveSeeked; //true;
100 else
101 {
102 // sio << "Gats::GatsStream::skipReadNulls(): Null byte read, not header yet..." << sio.nl;
103 qbRead.seek( 1 );
104 bHaveSeeked = true;
105 }
106 }
107}
108
diff --git a/c++-libbu++/src/gatsstream.h b/c++-libbu++/src/gatsstream.h
new file mode 100644
index 0000000..39719cf
--- /dev/null
+++ b/c++-libbu++/src/gatsstream.h
@@ -0,0 +1,56 @@
1#ifndef GATS_STREAM_H
2#define GATS_STREAM_H
3
4#include <bu/stream.h>
5#include <bu/queuebuf.h>
6
7namespace Gats
8{
9 class Object;
10
11 class GatsStream
12 {
13 public:
14 GatsStream( Bu::Stream &rStream );
15 virtual ~GatsStream();
16
17 /**
18 * Read an object packet from the assosiated stream. This will make
19 * every effort to only read exactly enough data to describe one packet,
20 * in case you want to do other things with your stream. It will
21 * automatically skip NULL byte spacing between packets, which makes
22 * a convinient padding method for encrypted data streams. Since
23 * sizing information is available in the packet header exact amounts
24 * of data can be read, however this function doesn't assume that it
25 * can read the entire object in one operation. If it fails to read
26 * a complete packet in one call, it will keep the data it's read so
27 * far buffered and return NULL, ready for another attempt. You can
28 * use the function hasReadBuffer() to deterimne if readObject()
29 * has read part of an object packet or not. If readObject returns
30 * non-null then hasReadBuffer should return false on it's next call.
31 */
32 Gats::Object *readObject();
33
34 /**
35 * Write an object
36 */
37 void writeObject( Gats::Object *pObject );
38
39 /**
40 * Tells you if there is data still in the read buffer, i.e. that a
41 * packet is part way through being read. If readObject has returned
42 * non-null in the most recent call, this should always be false.
43 */
44 bool hasReadBuffer() { return qbRead.getSize() > 0; }
45 int getReadBufferSize() { return qbRead.getSize(); }
46
47 private:
48 bool skipReadNulls();
49
50 private:
51 Bu::Stream &rStream;
52 Bu::QueueBuf qbRead;
53 };
54};
55
56#endif
diff --git a/c++-libbu++/src/integer.cpp b/c++-libbu++/src/integer.cpp
new file mode 100644
index 0000000..e89ac1d
--- /dev/null
+++ b/c++-libbu++/src/integer.cpp
@@ -0,0 +1,39 @@
1#include "gats/integer.h"
2
3#include <bu/formatter.h>
4
5Gats::Integer::Integer() :
6 iVal( 0 )
7{
8}
9
10Gats::Integer::Integer( int64_t iVal ) :
11 iVal( iVal )
12{
13}
14
15Gats::Integer::~Integer()
16{
17}
18
19Gats::Object *Gats::Integer::clone() const
20{
21 return new Gats::Integer( iVal );
22}
23
24void Gats::Integer::write( Bu::Stream &rOut ) const
25{
26 rOut.write("i", 1 );
27 writePackedInt( rOut, iVal );
28}
29
30void Gats::Integer::read( Bu::Stream &rIn, char cType )
31{
32 readPackedInt( rIn, iVal );
33}
34
35Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Integer &i )
36{
37 return f << "(int) " << i.getValue();
38}
39
diff --git a/c++-libbu++/src/integer.h b/c++-libbu++/src/integer.h
new file mode 100644
index 0000000..a5e0d58
--- /dev/null
+++ b/c++-libbu++/src/integer.h
@@ -0,0 +1,86 @@
1#ifndef GATS_INTEGER_H
2#define GATS_INTEGER_H
3
4#include "gats/object.h"
5
6#include <stdint.h>
7
8#include <bu/stream.h>
9
10namespace Gats
11{
12 class Integer : public Gats::Object
13 {
14 public:
15 Integer();
16 Integer( int64_t iVal );
17 virtual ~Integer();
18
19 virtual Object *clone() const;
20
21 virtual Type getType() const { return typeInteger; }
22 int64_t getValue() const { return iVal; }
23
24 virtual void write( Bu::Stream &rOut ) const;
25 virtual void read( Bu::Stream &rIn, char cType );
26
27 template<typename itype>
28 static void readPackedInt( Bu::Stream &rStream, itype &rOut )
29 {
30 int8_t b;
31 rOut = 0;
32 bool bNeg;
33
34 rStream.read( &b, 1 );
35 bNeg = ( b&0x40 );
36 rOut |= (itype(b&0x3F));
37 int c = 0;
38 while( (b&0x80) )
39 {
40 rStream.read( &b, 1 );
41 rOut |= (itype(b&0x7F)) << (6+7*(c++));
42 }
43 if( bNeg ) rOut = -rOut;
44 }
45
46 template<typename itype>
47 static void writePackedInt( Bu::Stream &rStream, itype iIn )
48 {
49 uint8_t b;
50
51 if( iIn < 0 )
52 {
53 iIn = -iIn;
54 b = (iIn&0x3F);
55 if( iIn > b )
56 b |= 0x80 | 0x40;
57 else
58 b |= 0x40;
59 }
60 else
61 {
62 b = (iIn&0x3F);
63 if( iIn > b )
64 b |= 0x80;
65 }
66 rStream.write( &b, 1 );
67 iIn = iIn >> 6;
68
69 while( iIn )
70 {
71 b = (iIn&0x7F);
72 if( iIn > b )
73 b |= 0x80;
74 rStream.write( &b, 1 );
75 iIn = iIn >> 7;
76 }
77 }
78
79 private:
80 int64_t iVal;
81 };
82};
83
84Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Integer &i );
85
86#endif
diff --git a/c++-libbu++/src/list.cpp b/c++-libbu++/src/list.cpp
new file mode 100644
index 0000000..d081a22
--- /dev/null
+++ b/c++-libbu++/src/list.cpp
@@ -0,0 +1,205 @@
1#include "gats/list.h"
2
3#include "gats/string.h"
4#include "gats/integer.h"
5#include "gats/float.h"
6#include "gats/boolean.h"
7#include "gats/dictionary.h"
8
9#include <bu/formatter.h>
10#include <bu/stream.h>
11
12Gats::List::List()
13{
14}
15
16Gats::List::~List()
17{
18 for( iterator i = begin(); i; i++ )
19 {
20 delete *i;
21 }
22}
23
24Gats::Object *Gats::List::clone() const
25{
26 Gats::List *pClone = new Gats::List;
27 for( const_iterator i = begin(); i; i++ )
28 {
29 pClone->append( (*i)->clone() );
30 }
31 return pClone;
32}
33
34void Gats::List::write( Bu::Stream &rOut ) const
35{
36 rOut.write("l", 1 );
37 for( const_iterator i = begin(); i; i++ )
38 {
39 (*i)->write( rOut );
40 }
41 rOut.write("e", 1 );
42}
43
44void Gats::List::read( Bu::Stream &rIn, char cType )
45{
46 for(;;)
47 {
48 Gats::Object *pObj = Gats::Object::read( rIn );
49 if( pObj == NULL )
50 break;
51 append( pObj );
52 }
53}
54
55void Gats::List::append( const char *s )
56{
57 Bu::List<Gats::Object *>::append( new Gats::String( s ) );
58}
59
60void Gats::List::append( const Bu::String &s )
61{
62 Bu::List<Gats::Object *>::append( new Gats::String( s ) );
63}
64
65void Gats::List::append( int32_t i )
66{
67 Bu::List<Gats::Object *>::append( new Gats::Integer( i ) );
68}
69
70void Gats::List::append( int64_t i )
71{
72 Bu::List<Gats::Object *>::append( new Gats::Integer( i ) );
73}
74
75void Gats::List::append( double d )
76{
77 Bu::List<Gats::Object *>::append( new Gats::Float( d ) );
78}
79
80void Gats::List::appendStr( const Bu::String &s )
81{
82 Bu::List<Gats::Object *>::append( new Gats::String( s ) );
83}
84
85void Gats::List::appendInt( int64_t i )
86{
87 Bu::List<Gats::Object *>::append( new Gats::Integer( i ) );
88}
89
90void Gats::List::appendFloat( double d )
91{
92 Bu::List<Gats::Object *>::append( new Gats::Float( d ) );
93}
94
95void Gats::List::appendBool( bool b )
96{
97 Bu::List<Gats::Object *>::append( new Gats::Boolean( b ) );
98}
99
100void Gats::List::appendList( Gats::List *pL )
101{
102 Bu::List<Gats::Object *>::append( pL );
103}
104
105void Gats::List::appendDict( Gats::Dictionary *pD )
106{
107 Bu::List<Gats::Object *>::append( pD );
108}
109
110Gats::List *Gats::List::appendList()
111{
112 Gats::List *pLst = new Gats::List();
113 appendList( pLst );
114 return pLst;
115}
116
117Gats::Dictionary *Gats::List::appendDict()
118{
119 Gats::Dictionary *pDict = new Gats::Dictionary();
120 appendDict( pDict );
121 return pDict;
122}
123
124void Gats::List::prepend( const char *s )
125{
126 Bu::List<Gats::Object *>::prepend( new Gats::String( s ) );
127}
128
129void Gats::List::prepend( const Bu::String &s )
130{
131 Bu::List<Gats::Object *>::prepend( new Gats::String( s ) );
132}
133
134void Gats::List::prepend( int32_t i )
135{
136 Bu::List<Gats::Object *>::prepend( new Gats::Integer( i ) );
137}
138
139void Gats::List::prepend( int64_t i )
140{
141 Bu::List<Gats::Object *>::prepend( new Gats::Integer( i ) );
142}
143
144void Gats::List::prepend( double d )
145{
146 Bu::List<Gats::Object *>::prepend( new Gats::Float( d ) );
147}
148
149void Gats::List::prependStr( const Bu::String &s )
150{
151 Bu::List<Gats::Object *>::prepend( new Gats::String( s ) );
152}
153
154void Gats::List::prependInt( int64_t i )
155{
156 Bu::List<Gats::Object *>::prepend( new Gats::Integer( i ) );
157}
158
159void Gats::List::prependFloat( double d )
160{
161 Bu::List<Gats::Object *>::prepend( new Gats::Float( d ) );
162}
163
164void Gats::List::prependBool( bool b )
165{
166 Bu::List<Gats::Object *>::prepend( new Gats::Boolean( b ) );
167}
168
169void Gats::List::prependList( Gats::List *pL )
170{
171 Bu::List<Gats::Object *>::prepend( pL );
172}
173
174void Gats::List::prependDict( Gats::Dictionary *pD )
175{
176 Bu::List<Gats::Object *>::prepend( pD );
177}
178
179Gats::List *Gats::List::prependList()
180{
181 Gats::List *pLst = new Gats::List();
182 prependList( pLst );
183 return pLst;
184}
185
186Gats::Dictionary *Gats::List::prependDict()
187{
188 Gats::Dictionary *pDict = new Gats::Dictionary();
189 prependDict( pDict );
190 return pDict;
191}
192
193Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::List &l )
194{
195 f << "(list) [";
196 f.incIndent();
197 for( Gats::List::const_iterator i = l.begin(); i; i++ )
198 {
199 f << f.nl << **i;
200 }
201 f.decIndent();
202 f << f.nl << "]";
203 return f;
204}
205
diff --git a/c++-libbu++/src/list.h b/c++-libbu++/src/list.h
new file mode 100644
index 0000000..5c1cd6e
--- /dev/null
+++ b/c++-libbu++/src/list.h
@@ -0,0 +1,58 @@
1#ifndef GATS_LIST_H
2#define GATS_LIST_H
3
4#include "gats/object.h"
5#include <bu/list.h>
6#include <bu/string.h>
7
8namespace Gats
9{
10 class Dictionary;
11
12 class List : public Gats::Object, public Bu::List<Gats::Object *>
13 {
14 public:
15 List();
16 virtual ~List();
17
18 virtual Object *clone() const;
19 virtual Type getType() const { return typeList; }
20
21 virtual void write( Bu::Stream &rOut ) const;
22 virtual void read( Bu::Stream &rIn, char cType );
23
24 void append( const char *s );
25 void append( const Bu::String &s );
26 void append( int32_t i );
27 void append( int64_t i );
28 void append( double d );
29 using Bu::List<Gats::Object *>::append;
30 void appendStr( const Bu::String &s );
31 void appendInt( int64_t i );
32 void appendFloat( double d );
33 void appendBool( bool b );
34 void appendList( Gats::List *pL );
35 void appendDict( Gats::Dictionary *pD );
36 Gats::List *appendList();
37 Gats::Dictionary *appendDict();
38
39 void prepend( const char *s );
40 void prepend( const Bu::String &s );
41 void prepend( int32_t i );
42 void prepend( int64_t i );
43 void prepend( double d );
44 using Bu::List<Gats::Object *>::prepend;
45 void prependStr( const Bu::String &s );
46 void prependInt( int64_t i );
47 void prependFloat( double d );
48 void prependBool( bool b );
49 void prependList( Gats::List *pL );
50 void prependDict( Gats::Dictionary *pD );
51 Gats::List *prependList();
52 Gats::Dictionary *prependDict();
53 };
54};
55
56Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::List &l );
57
58#endif
diff --git a/c++-libbu++/src/null.cpp b/c++-libbu++/src/null.cpp
new file mode 100644
index 0000000..13a61ed
--- /dev/null
+++ b/c++-libbu++/src/null.cpp
@@ -0,0 +1,33 @@
1#include "gats/null.h"
2
3#include <bu/formatter.h>
4#include <bu/stream.h>
5
6Gats::Null::Null()
7{
8}
9
10Gats::Null::~Null()
11{
12}
13
14Gats::Object *Gats::Null::clone() const
15{
16 return new Gats::Null();
17}
18
19void Gats::Null::write( Bu::Stream &rOut ) const
20{
21 rOut.write("n", 1 );
22}
23
24void Gats::Null::read( Bu::Stream &rIn, char cType )
25{
26 // Nothing to do...
27}
28
29Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Null &b )
30{
31 return f << "(null)";
32}
33
diff --git a/c++-libbu++/src/null.h b/c++-libbu++/src/null.h
new file mode 100644
index 0000000..afa2d0a
--- /dev/null
+++ b/c++-libbu++/src/null.h
@@ -0,0 +1,24 @@
1#ifndef GATS_NULL_H
2#define GATS_NULL_H
3
4#include "gats/object.h"
5
6namespace Gats
7{
8 class Null : public Gats::Object
9 {
10 public:
11 Null();
12 virtual ~Null();
13
14 virtual Type getType() const { return typeNull; }
15 virtual Object *clone() const;
16
17 virtual void write( Bu::Stream &rOut ) const;
18 virtual void read( Bu::Stream &rIn, char cType );
19 };
20};
21
22Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Null &b );
23
24#endif
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
diff --git a/c++-libbu++/src/object.h b/c++-libbu++/src/object.h
new file mode 100644
index 0000000..2724189
--- /dev/null
+++ b/c++-libbu++/src/object.h
@@ -0,0 +1,55 @@
1#ifndef GATS_OBJECT_H
2#define GATS_OBJECT_H
3
4#include <bu/string.h>
5
6namespace Bu
7{
8 class Stream;
9 class Formatter;
10};
11
12namespace Gats
13{
14 enum Type
15 {
16 typeDictionary,
17 typeList,
18 typeString,
19 typeInteger,
20 typeFloat,
21 typeBoolean,
22 typeNull
23 };
24
25 /**
26 * The baseclass for every type that can be stored in a packet.
27 */
28 class Object
29 {
30 public:
31 Object();
32 virtual ~Object();
33
34 virtual Type getType() const =0;
35
36 virtual void write( Bu::Stream &rOut ) const=0;
37 virtual void read( Bu::Stream &rIn, char cType )=0;
38 virtual Object *clone() const=0;
39
40 static Object *read( Bu::Stream &rIn );
41 static Object *strToGats( const Bu::String &sStr );
42
43 private:
44 static Object *strToGats( Bu::String::const_iterator &i );
45 static Bu::String token( Bu::String::const_iterator &i );
46 static void skipWs( Bu::String::const_iterator &i );
47 };
48
49 const char *typeToStr( Type t );
50};
51
52Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Object &obj );
53Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::Type &t );
54
55#endif
diff --git a/c++-libbu++/src/protocolgats.cpp b/c++-libbu++/src/protocolgats.cpp
new file mode 100644
index 0000000..827eb65
--- /dev/null
+++ b/c++-libbu++/src/protocolgats.cpp
@@ -0,0 +1,56 @@
1#include "gats/protocolgats.h"
2#include "gats/gatsstream.h"
3
4#include <bu/client.h>
5
6#include <bu/sio.h>
7using namespace Bu;
8
9Gats::ProtocolGats::ProtocolGats() :
10 pStream( NULL ),
11 pUsedClient( NULL )
12{
13}
14
15Gats::ProtocolGats::~ProtocolGats()
16{
17 delete pStream;
18 pStream = NULL;
19}
20
21void Gats::ProtocolGats::onNewConnection( Bu::Client *pClient )
22{
23 if( pStream == NULL )
24 {
25 pStream = new Gats::GatsStream( *pClient );
26 pUsedClient = pClient;
27 }
28}
29
30void Gats::ProtocolGats::onNewData( Bu::Client *pClient )
31{
32 if( pStream == NULL )
33 {
34 pStream = new Gats::GatsStream( *pClient );
35 pUsedClient = pClient;
36 }
37 else if( pClient != pUsedClient )
38 {
39 throw Bu::ExceptionBase("ProtocolGats requires that you maintain a "
40 "1:1 relationship between client and protocol objects.");
41 }
42
43 for(;;)
44 {
45 Gats::Object *pObj = pStream->readObject();
46 if( pObj == NULL )
47 break;
48 onNewObject( pClient, pObj );
49 }
50}
51
52void Gats::ProtocolGats::writeObject( Gats::Object *pObj )
53{
54 pStream->writeObject( pObj );
55}
56
diff --git a/c++-libbu++/src/protocolgats.h b/c++-libbu++/src/protocolgats.h
new file mode 100644
index 0000000..7ed58d4
--- /dev/null
+++ b/c++-libbu++/src/protocolgats.h
@@ -0,0 +1,30 @@
1#ifndef GATS_PROTOCOL_GATS_H
2#define GATS_PROTOCOL_GATS_H
3
4#include <bu/protocol.h>
5
6namespace Gats
7{
8 class Object;
9 class GatsStream;
10
11 class ProtocolGats : public Bu::Protocol
12 {
13 public:
14 ProtocolGats();
15 virtual ~ProtocolGats();
16
17 virtual void onNewConnection( Bu::Client *pClient );
18 virtual void onNewData( Bu::Client *pClient );
19
20 virtual void onNewObject( Bu::Client *pClient, Gats::Object *pObj )=0;
21
22 void writeObject( Gats::Object *pObj );
23
24 private:
25 Gats::GatsStream *pStream;
26 Bu::Client *pUsedClient;
27 };
28};
29
30#endif
diff --git a/c++-libbu++/src/string.cpp b/c++-libbu++/src/string.cpp
new file mode 100644
index 0000000..de66d5d
--- /dev/null
+++ b/c++-libbu++/src/string.cpp
@@ -0,0 +1,70 @@
1#include "gats/string.h"
2
3#include "gats/integer.h"
4
5#include <bu/formatter.h>
6
7Gats::String::String()
8{
9}
10
11Gats::String::String( const char *s ) :
12 Bu::String( s )
13{
14}
15
16Gats::String::String( const char *s, long iLength ) :
17 Bu::String( s, iLength )
18{
19}
20
21Gats::String::String( long iLength ) :
22 Bu::String( iLength )
23{
24}
25
26Gats::String::String( const String &s ) :
27 Bu::String( s )
28{
29}
30
31Gats::String::String( const Bu::String &s ) :
32 Bu::String( s )
33{
34}
35
36Gats::String::~String()
37{
38}
39
40Gats::Object *Gats::String::clone() const
41{
42 return new Gats::String( Bu::String::clone() );
43}
44
45void Gats::String::write( Bu::Stream &rOut ) const
46{
47 rOut.write("s", 1 );
48 uint32_t iSize = getSize();
49 Gats::Integer::writePackedInt( rOut, iSize );
50 rOut.write( getStr(), iSize );
51}
52
53void Gats::String::read( Bu::Stream &rIn, char cType )
54{
55 uint32_t iSize;
56 Gats::Integer::readPackedInt( rIn, iSize );
57 setSize( iSize );
58 rIn.read( getStr(), iSize );
59}
60
61Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::String &s )
62{
63 for( Gats::String::const_iterator i = s.begin(); i; i++ )
64 {
65 if( *i >= 127 || *i <= 31 )
66 return f << "(binary str) " << s.getSize() << " bytes";
67 }
68 return f << "(str) \"" << dynamic_cast<const Bu::String &>(s) << "\"";
69}
70
diff --git a/c++-libbu++/src/string.h b/c++-libbu++/src/string.h
new file mode 100644
index 0000000..de8eedd
--- /dev/null
+++ b/c++-libbu++/src/string.h
@@ -0,0 +1,32 @@
1#ifndef GATS_STRING_H
2#define GATS_STRING_H
3
4#include "gats/object.h"
5#include <bu/string.h>
6
7namespace Gats
8{
9 class String : public Gats::Object, public Bu::String
10 {
11 public:
12 String();
13 String( const char *s );
14 String( const char *s, long iLength );
15 String( long iLength );
16 String( const String &s );
17 String( const Bu::String &s );
18 virtual ~String();
19
20 virtual Object *clone() const;
21 virtual Type getType() const { return typeString; }
22
23 virtual void write( Bu::Stream &rOut ) const;
24 virtual void read( Bu::Stream &rIn, char cType );
25
26 private:
27 };
28};
29
30Bu::Formatter &operator<<( Bu::Formatter &f, const Gats::String &s );
31
32#endif
diff --git a/c++-libbu++/src/tests/clone.cpp b/c++-libbu++/src/tests/clone.cpp
new file mode 100644
index 0000000..8533376
--- /dev/null
+++ b/c++-libbu++/src/tests/clone.cpp
@@ -0,0 +1,22 @@
1#include "gats/types.h"
2
3#include <bu/sio.h>
4
5using namespace Bu;
6
7int main( int argc, char *argv[] )
8{
9 Gats::Object *pBase = Gats::Object::strToGats("{\"Thing\": 3.14159, \"bool\": true, \"list\":[\"string\",44,{\"Stuff\":{\"list\":[],\"what?\":false}}]}");
10
11 sio << *pBase << sio.nl;
12
13 Gats::Object *pNew = pBase->clone();
14 delete pBase;
15
16 sio << *pNew << sio.nl;
17
18 delete pNew;
19
20 return 0;
21}
22
diff --git a/c++-libbu++/src/tests/dump.cpp b/c++-libbu++/src/tests/dump.cpp
new file mode 100644
index 0000000..e0dcb52
--- /dev/null
+++ b/c++-libbu++/src/tests/dump.cpp
@@ -0,0 +1,30 @@
1#include <bu/sio.h>
2#include <bu/file.h>
3#include <gats/gatsstream.h>
4#include <gats/types.h>
5
6using namespace Bu;
7
8int main( int argc, char *argv[] )
9{
10 File fIn( argv[1], File::Read );
11 Gats::GatsStream gsIn( fIn );
12
13 for(;;)
14 {
15 sio << "Reading from file position: " << fIn.tell() << sio.nl;
16 Gats::Object *pObj = gsIn.readObject();
17 if( !pObj )
18 {
19 if( gsIn.hasReadBuffer() )
20 {
21 sio << "Premature end of stream detected, have "
22 << gsIn.getReadBufferSize() << "b." << sio.nl;
23 }
24 return 0;
25 }
26
27 sio << *pObj << sio.nl;
28 }
29}
30
diff --git a/c++-libbu++/src/tests/int.cpp b/c++-libbu++/src/tests/int.cpp
new file mode 100644
index 0000000..c19df9c
--- /dev/null
+++ b/c++-libbu++/src/tests/int.cpp
@@ -0,0 +1,47 @@
1#include "gats/integer.h"
2
3#include <bu/sio.h>
4#include <bu/membuf.h>
5#include <stdlib.h>
6
7using namespace Bu;
8
9void hexdump( char *dat, int iSize )
10{
11 static const char *hex="0123456789ABCDEF";
12 printf("----\n");
13 for( int j = 0; j < iSize; j += 8 )
14 {
15 for( int k = j; /*k < iSize &&*/ k < j+8; k++ )
16 printf((k<iSize)?"%c%c ":" ", hex[(dat[k]>>4)&0x0F], hex[dat[k]&0x0F] );
17 printf("| ");
18 for( int k = j; k < iSize && k < j+8; k++ )
19 printf("%c ", (dat[k]>13&&dat[k]<127)?(dat[k]):('.') );
20 printf("\n");
21 }
22 printf("----\n");
23}
24
25int main( int argc, char *argv[] )
26{
27 for( int j = 1; j < argc; j++ )
28 {
29 int64_t i = strtoll( argv[j], NULL, 10 );
30 MemBuf mb;
31 Gats::Integer::writePackedInt( mb, i );
32 hexdump( mb.getString().getStr(), mb.getString().getSize() );
33 }
34/*
35 sio << "Before: " << i << sio.nl;
36 Gats::Integer::writePackedInt( mb, i );
37 mb.write("aaa", 3 );
38 mb.setPos( 0 );
39 Gats::Integer::readPackedInt( mb, i );
40 sio << "After: " << i << sio.nl;
41 char buf[4];
42 buf[mb.read( buf, 3 )] = '\0';
43 sio << "Extra: \"" << buf << "\"" << sio.nl;
44*/
45 return 0;
46}
47
diff --git a/c++-libbu++/src/types.h b/c++-libbu++/src/types.h
new file mode 100644
index 0000000..81240e8
--- /dev/null
+++ b/c++-libbu++/src/types.h
@@ -0,0 +1,8 @@
1#include "gats/object.h"
2#include "gats/boolean.h"
3#include "gats/dictionary.h"
4#include "gats/float.h"
5#include "gats/integer.h"
6#include "gats/list.h"
7#include "gats/string.h"
8#include "gats/null.h"
diff --git a/c++-libbu++/src/unit/basic.unit b/c++-libbu++/src/unit/basic.unit
new file mode 100644
index 0000000..2c2c31a
--- /dev/null
+++ b/c++-libbu++/src/unit/basic.unit
@@ -0,0 +1,191 @@
1// vim: syntax=cpp
2/*
3 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
4 *
5 * This file is part of the libbu++ library and is released under the
6 * terms of the license contained in the file LICENSE.
7 */
8
9#include "gats/dictionary.h"
10#include "gats/integer.h"
11#include "gats/float.h"
12#include "gats/list.h"
13#include "gats/boolean.h"
14#include "gats/string.h"
15#include "gats/null.h"
16#include "gats/gatsstream.h"
17
18#include "bu/membuf.h"
19#include "bu/list.h"
20#include "bu/sio.h"
21
22#include <stdlib.h>
23#include <math.h>
24
25using namespace Bu;
26
27suite Basic
28{
29 test integer
30 {
31 Bu::List<int64_t> lInts;
32 Bu::MemBuf mb;
33
34 int64_t i = 1;
35 for( int x = 0; x < 256; x++ )
36 {
37 lInts.append( i );
38 Gats::Integer( i ).write( mb );
39 i = -(i<<1)-i;
40 }
41
42 mb.setPos( 0 );
43
44 for( Bu::List<int64_t>::iterator j = lInts.begin(); j; j++ )
45 {
46 Gats::Object *pObj = Gats::Object::read( mb );
47 if( pObj->getType() != Gats::typeInteger )
48 unitFailed("Bad type read.");
49
50 if( dynamic_cast<Gats::Integer *>(pObj)->getValue() != *j )
51 unitFailed("Bad number.");
52 }
53 }
54
55 test string
56 {
57 Bu::List<Bu::String> lStrs;
58 Bu::MemBuf mb;
59
60 lStrs.append( Bu::String() );
61 Gats::String("").write( mb );
62
63 {
64 int iMax = 0;
65 for( int j = 1; j <= (1<<16); j=j<<1 )
66 iMax += j;
67 setStepCount( iMax );
68 }
69 for( int j = 1; j <= (1<<16); j=j<<1 )
70 {
71 Bu::String s( j );
72 for( int x = 0; x < j; x++ )
73 {
74 s[x] = (unsigned char)(random()%256);
75 }
76 incProgress( j );
77 Gats::String( s ).write( mb );
78 lStrs.append( s );
79 }
80
81 mb.setPos( 0 );
82
83 for( Bu::List<Bu::String>::iterator i = lStrs.begin(); i; i++ )
84 {
85 Gats::Object *pObj = Gats::Object::read( mb );
86 if( pObj->getType() != Gats::typeString )
87 unitFailed("Bad type read.");
88
89 if( *dynamic_cast<Gats::String *>(pObj) != *i )
90 unitFailed("Bad string.");
91 }
92 }
93
94 test boolean
95 {
96 Bu::List<bool> lBs;
97 Bu::MemBuf mb;
98
99 for( int j = 0; j < 1024; j++ )
100 {
101 if( random()%2 == 0 )
102 {
103 lBs.append( true );
104 Gats::Boolean( true ).write( mb );
105 }
106 else
107 {
108 lBs.append( false );
109 Gats::Boolean( false ).write( mb );
110 }
111 }
112
113 mb.setPos( 0 );
114
115 for( Bu::List<bool>::iterator i = lBs.begin(); i; i++ )
116 {
117 Gats::Object *pObj = Gats::Object::read( mb );
118 if( pObj->getType() != Gats::typeBoolean )
119 unitFailed("Bad type read.");
120
121 if( dynamic_cast<Gats::Boolean *>(pObj)->getValue() != *i )
122 unitFailed("Bad string.");
123 }
124 }
125
126 test floats
127 {
128 Bu::MemBuf mb;
129
130 Gats::Float( M_PI ).write( mb );
131
132 mb.setPos( 0 );
133
134 Gats::Object *pObj = Gats::Object::read( mb );
135 unitTest( pObj != NULL );
136 unitTest( pObj->getType() == Gats::typeFloat );
137 Gats::Float *pFlt = dynamic_cast<Gats::Float *>(pObj);
138 // sio << "old = " << M_PI << ", new = " << pFlt->getValue() << sio.nl;
139 unitTest( pFlt->getValue() == M_PI );
140
141 delete pObj;
142 }
143
144 test dictionary
145 {
146 MemBuf mb;
147
148 {
149 Gats::Dictionary dict;
150 dict.insert("bool", new Gats::Boolean(true) );
151 dict.insert("int", 33403055 );
152 dict.insert("str", "Hey there" );
153 dict.write( mb );
154 }
155
156 mb.setPos( 0 );
157
158 {
159 Gats::Object *pRead = Gats::Object::read( mb );
160 unitTest( pRead != NULL );
161 Gats::Dictionary *pDict = dynamic_cast<Gats::Dictionary *>(pRead);
162 unitTest( pDict != NULL );
163
164 unitTest( pDict->getBool("bool") == true );
165 unitTest( pDict->getInt("int") == 33403055 );
166 unitTest( pDict->getStr("str") == "Hey there" );
167 unitTest( pDict->getSize() == 3 );
168
169 delete pDict;
170 }
171 }
172
173 test null
174 {
175 MemBuf mb;
176 {
177 Gats::Null n;
178 Gats::GatsStream gs( mb );
179 gs.writeObject( &n );
180 }
181
182 mb.setPos( 0 );
183
184 {
185 Gats::GatsStream gs( mb );
186 Gats::Object *pObj = gs.readObject();
187 unitTest( pObj->getType() == Gats::typeNull );
188 delete pObj;
189 }
190 }
191}
diff --git a/c++-libbu++/src/unit/float.unit b/c++-libbu++/src/unit/float.unit
new file mode 100644
index 0000000..b1eb063
--- /dev/null
+++ b/c++-libbu++/src/unit/float.unit
@@ -0,0 +1,84 @@
1// vim: syntax=cpp
2/*
3 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
4 *
5 * This file is part of the libbu++ library and is released under the
6 * terms of the license contained in the file LICENSE.
7 */
8
9#include "gats/dictionary.h"
10#include "gats/float.h"
11#include "gats/string.h"
12
13#include "bu/membuf.h"
14#include "bu/list.h"
15#include "bu/sio.h"
16
17#include <stdlib.h>
18#include <math.h>
19
20using namespace Bu;
21
22suite Basic
23{
24 void rw( double dVal )
25 {
26 Bu::MemBuf mb;
27
28 Gats::Float( dVal ).write( mb );
29
30 mb.setPos( 0 );
31
32 Gats::Object *pObj = Gats::Object::read( mb );
33 unitTest( pObj != NULL );
34 unitTest( pObj->getType() == Gats::typeFloat );
35 Gats::Float *pFlt = dynamic_cast<Gats::Float *>(pObj);
36 Bu::String sHex;
37 for( Bu::String::iterator i = mb.getString().begin(); i; i++ )
38 {
39 sHex += "0123456789abcdef"[(((uint8_t)*i)>>4)&0x0f];
40 sHex += "0123456789abcdef"[(*i)&0x0f];
41 sHex += ' ';
42 }
43 printf("In: %a\nOut: %a\nRaw: %s\n", dVal, pFlt->getValue(), sHex.getStr() );
44 if( isnan( dVal ) )
45 unitTest( isnan(pFlt->getValue()) == isnan(dVal) );
46 else
47 unitTest( pFlt->getValue() == dVal );
48 unitTest( signbit(pFlt->getValue()) == signbit(dVal) );
49
50 delete pObj;
51 }
52
53 test positive
54 {
55 rw( 8485738457.0 );
56 rw( 63723.0 );
57 rw( 0.000000000000001928173 );
58 rw( 1.0 );
59 rw( 0.0 );
60 rw( M_PI );
61 }
62
63 test negitave
64 {
65 rw( -8485738457.0 );
66 rw( -63723.0 );
67 rw( -0.000000000000001928173 );
68 rw( -1.0 );
69 rw( -0.0 );
70 rw( -M_PI );
71 }
72
73 test inf
74 {
75 rw( INFINITY );
76 rw( -INFINITY );
77 }
78
79 test nan
80 {
81 rw( NAN );
82 rw( -NAN );
83 }
84}
diff --git a/c++-libbu++/src/unit/io.unit b/c++-libbu++/src/unit/io.unit
new file mode 100644
index 0000000..1a9747f
--- /dev/null
+++ b/c++-libbu++/src/unit/io.unit
@@ -0,0 +1,128 @@
1// vim: syntax=cpp
2/*
3 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
4 *
5 * This file is part of the libbu++ library and is released under the
6 * terms of the license contained in the file LICENSE.
7 */
8
9#include "gats/dictionary.h"
10#include "gats/integer.h"
11#include "gats/float.h"
12#include "gats/list.h"
13#include "gats/boolean.h"
14#include "gats/string.h"
15#include "gats/gatsstream.h"
16
17#include "bu/membuf.h"
18#include "bu/list.h"
19#include "bu/sio.h"
20
21#include <stdlib.h>
22
23using namespace Bu;
24
25suite Basic
26{
27 test basic
28 {
29 Bu::String sTmpFileName("temp-XXXXXXXXX");
30 Bu::File fIo = tempFile( sTmpFileName );
31
32 {
33 Gats::Dictionary dTest;
34 dTest.insert("age", 27 );
35 dTest.insert("firstName", "Mike");
36 dTest.insert("lastName", "Buland");
37 dTest.insert("awake", true );
38
39 Gats::GatsStream sGats( fIo );
40 sGats.writeObject( &dTest );
41 }
42
43 fIo.setPos( 0 );
44
45 {
46 Gats::GatsStream sGats( fIo );
47 Gats::Object *pObj = sGats.readObject();
48 unitTest( pObj != NULL );
49 unitTest( pObj->getType() == Gats::typeDictionary );
50 Gats::Dictionary *pDic = dynamic_cast<Gats::Dictionary *>(pObj);
51 unitTest( pDic->getSize() == 4 );
52 unitTest( pDic->getInt("age") == 27 );
53 unitTest( pDic->getStr("firstName") == "Mike" );
54 unitTest( pDic->getStr("lastName") == "Buland" );
55 unitTest( pDic->getBool("awake") == true );
56
57 delete pDic;
58 }
59 }
60
61 test spacers
62 {
63 Bu::String sTmpFileName("temp-XXXXXXXXX");
64 Bu::File fIo = tempFile( sTmpFileName );
65
66 {
67 Gats::GatsStream sGats( fIo );
68 Gats::Integer i( -157 );
69 sGats.writeObject( &i );
70 fIo.write( "\x00\x00\x00", 3 );
71 Gats::String s("negative one hundred and fifty seven");
72 sGats.writeObject( &s );
73 }
74
75 fIo.setPos( 0 );
76
77 {
78 Gats::GatsStream sGats( fIo );
79 Gats::Object *pObj1 = sGats.readObject();
80 unitTest( pObj1 != NULL );
81 unitTest( pObj1->getType() == Gats::typeInteger );
82 unitTest( dynamic_cast<Gats::Integer *>(pObj1)->getValue() == -157 );
83
84 Gats::Object *pObj2 = sGats.readObject();
85 unitTest( pObj2 != NULL );
86 unitTest( pObj2->getType() == Gats::typeString );
87 unitTest( *dynamic_cast<Gats::String *>(pObj2) ==
88 "negative one hundred and fifty seven" );
89
90 delete pObj1;
91 delete pObj2;
92 }
93 }
94
95 test biggerSpacers
96 {
97 Bu::String sTmpFileName("temp-XXXXXXXXX");
98 Bu::File fIo = tempFile( sTmpFileName );
99
100 {
101 Gats::GatsStream sGats( fIo );
102 Gats::Integer i( -157 );
103 sGats.writeObject( &i );
104 fIo.write( "\x00\x00\x00\x00\x00\x00\x00\x00\x00", 9 );
105 Gats::String s("negative one hundred and fifty seven");
106 sGats.writeObject( &s );
107 }
108
109 fIo.setPos( 0 );
110
111 {
112 Gats::GatsStream sGats( fIo );
113 Gats::Object *pObj1 = sGats.readObject();
114 unitTest( pObj1 != NULL );
115 unitTest( pObj1->getType() == Gats::typeInteger );
116 unitTest( dynamic_cast<Gats::Integer *>(pObj1)->getValue() == -157 );
117
118 Gats::Object *pObj2 = sGats.readObject();
119 unitTest( pObj2 != NULL );
120 unitTest( pObj2->getType() == Gats::typeString );
121 unitTest( *dynamic_cast<Gats::String *>(pObj2) ==
122 "negative one hundred and fifty seven" );
123
124 delete pObj1;
125 delete pObj2;
126 }
127 }
128}