summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/archable.cpp10
-rw-r--r--src/archable.h35
-rw-r--r--src/archive.cpp (renamed from src/old/serializer.cpp)103
-rw-r--r--src/archive.h93
-rw-r--r--src/exceptionbase.cpp (renamed from src/old/exceptionbase.cpp)16
-rw-r--r--src/exceptionbase.h114
-rw-r--r--src/exceptions.cpp10
-rw-r--r--src/exceptions.h28
-rw-r--r--src/fstring.cpp14
-rw-r--r--src/fstring.h653
-rw-r--r--src/hash.cpp101
-rw-r--r--src/hash.h745
-rw-r--r--src/old/exceptionbase.h105
-rw-r--r--src/old/exceptions.cpp8
-rw-r--r--src/old/exceptions.h25
-rw-r--r--src/old/fstring.cpp13
-rw-r--r--src/old/fstring.h651
-rw-r--r--src/old/hash.cpp113
-rw-r--r--src/old/hash.h744
-rw-r--r--src/old/hashable.cpp1
-rw-r--r--src/old/hashable.h12
-rw-r--r--src/old/serializable.cpp8
-rw-r--r--src/old/serializable.h34
-rw-r--r--src/old/serializer.h80
-rw-r--r--src/old/stream.cpp10
-rw-r--r--src/old/stream.h27
-rw-r--r--src/stream.cpp10
-rw-r--r--src/stream.h34
-rw-r--r--src/tests/archive.cpp7
29 files changed, 1913 insertions, 1891 deletions
diff --git a/src/archable.cpp b/src/archable.cpp
new file mode 100644
index 0000000..38fc31f
--- /dev/null
+++ b/src/archable.cpp
@@ -0,0 +1,10 @@
1#include "archable.h"
2
3Bu::Archable::Archable()
4{
5}
6
7Bu::Archable::~Archable()
8{
9}
10
diff --git a/src/archable.h b/src/archable.h
new file mode 100644
index 0000000..ed05a78
--- /dev/null
+++ b/src/archable.h
@@ -0,0 +1,35 @@
1#ifndef ARCHABLE_H
2#define ARCHABLE_H
3
4namespace Bu
5{
6 /**
7 * The base class for any class you want to archive. Simply include this as
8 * a base class, implement the purely virtual archive function and you've
9 * got an easily archiveable class.
10 */
11 class Archable
12 {
13 public:
14 /**
15 * Does nothing, here for completeness.
16 */
17 Archable();
18
19 /**
20 * Here to ensure the deconstructor is virtual.
21 */
22 virtual ~Archable();
23
24 /**
25 * This is the main workhorse of the archive system, just override and
26 * you've got a archiveable class. A reference to the Archive
27 * used is passed in as your only parameter, query it to discover if
28 * you are loading or saving.
29 * @param ar A reference to the Archive object to use.
30 */
31 virtual void archive( class Archive &ar )=0;
32 };
33}
34
35#endif
diff --git a/src/old/serializer.cpp b/src/archive.cpp
index 636224e..5f5145c 100644
--- a/src/old/serializer.cpp
+++ b/src/archive.cpp
@@ -1,152 +1,150 @@
1#include "serializer.h" 1#include "archive.h"
2#include "serializable.h"
3#include <list>
4 2
5Serializer::Serializer(bool bLoading): 3Bu::Archive::Archive(bool bLoading):
6 bLoading(bLoading) 4 bLoading(bLoading)
7{ 5{
8} 6}
9Serializer::~Serializer() 7Bu::Archive::~Archive()
10{ 8{
11} 9}
12 10
13bool Serializer::isLoading() 11bool Bu::Archive::isLoading()
14{ 12{
15 return bLoading; 13 return bLoading;
16} 14}
17Serializer &Serializer::operator<<(bool p) 15Bu::Archive &Bu::Archive::operator<<(bool p)
18{ 16{
19 write( &p, sizeof(p) ); 17 write( &p, sizeof(p) );
20 return *this; 18 return *this;
21} 19}
22Serializer &Serializer::operator<<(int8_t p) 20Bu::Archive &Bu::Archive::operator<<(int8_t p)
23{ 21{
24 write( &p, sizeof(p) ); 22 write( &p, sizeof(p) );
25 return *this; 23 return *this;
26} 24}
27Serializer &Serializer::operator<<(int16_t p) 25Bu::Archive &Bu::Archive::operator<<(int16_t p)
28{ 26{
29 write( &p, sizeof(p) ); 27 write( &p, sizeof(p) );
30 return *this; 28 return *this;
31} 29}
32Serializer &Serializer::operator<<(int32_t p) 30Bu::Archive &Bu::Archive::operator<<(int32_t p)
33{ 31{
34 write( &p, sizeof(p) ); 32 write( &p, sizeof(p) );
35 return *this; 33 return *this;
36} 34}
37Serializer &Serializer::operator<<(int64_t p) 35Bu::Archive &Bu::Archive::operator<<(int64_t p)
38{ 36{
39 write( &p, sizeof(p) ); 37 write( &p, sizeof(p) );
40 return *this; 38 return *this;
41} 39}
42Serializer &Serializer::operator<<(uint8_t p) 40Bu::Archive &Bu::Archive::operator<<(uint8_t p)
43{ 41{
44 write( &p, sizeof(p) ); 42 write( &p, sizeof(p) );
45 return *this; 43 return *this;
46} 44}
47Serializer &Serializer::operator<<(uint16_t p) 45Bu::Archive &Bu::Archive::operator<<(uint16_t p)
48{ 46{
49 write( &p, sizeof(p) ); 47 write( &p, sizeof(p) );
50 return *this; 48 return *this;
51} 49}
52Serializer &Serializer::operator<<(uint32_t p) 50Bu::Archive &Bu::Archive::operator<<(uint32_t p)
53{ 51{
54 write( &p, sizeof(p) ); 52 write( &p, sizeof(p) );
55 return *this; 53 return *this;
56} 54}
57Serializer &Serializer::operator<<(uint64_t p) 55Bu::Archive &Bu::Archive::operator<<(uint64_t p)
58{ 56{
59 write( &p, sizeof(p) ); 57 write( &p, sizeof(p) );
60 return *this; 58 return *this;
61} 59}
62Serializer &Serializer::operator<<(long p) 60Bu::Archive &Bu::Archive::operator<<(long p)
63{ 61{
64 write( &p, sizeof(p) ); 62 write( &p, sizeof(p) );
65 return *this; 63 return *this;
66} 64}
67Serializer &Serializer::operator<<(float p) 65Bu::Archive &Bu::Archive::operator<<(float p)
68{ 66{
69 write( &p, sizeof(p) ); 67 write( &p, sizeof(p) );
70 return *this; 68 return *this;
71} 69}
72Serializer &Serializer::operator<<(double p) 70Bu::Archive &Bu::Archive::operator<<(double p)
73{ 71{
74 write( &p, sizeof(p) ); 72 write( &p, sizeof(p) );
75 return *this; 73 return *this;
76} 74}
77Serializer &Serializer::operator<<(long double p) 75Bu::Archive &Bu::Archive::operator<<(long double p)
78{ 76{
79 write( &p, sizeof(p) ); 77 write( &p, sizeof(p) );
80 return *this; 78 return *this;
81} 79}
82 80
83Serializer &Serializer::operator>>(bool &p) 81Bu::Archive &Bu::Archive::operator>>(bool &p)
84{ 82{
85 read( &p, sizeof(p) ); 83 read( &p, sizeof(p) );
86 return *this; 84 return *this;
87} 85}
88Serializer &Serializer::operator>>(int8_t &p) 86Bu::Archive &Bu::Archive::operator>>(int8_t &p)
89{ 87{
90 read( &p, sizeof(p) ); 88 read( &p, sizeof(p) );
91 return *this; 89 return *this;
92} 90}
93Serializer &Serializer::operator>>(int16_t &p) 91Bu::Archive &Bu::Archive::operator>>(int16_t &p)
94{ 92{
95 read( &p, sizeof(p) ); 93 read( &p, sizeof(p) );
96 return *this; 94 return *this;
97} 95}
98Serializer &Serializer::operator>>(int32_t &p) 96Bu::Archive &Bu::Archive::operator>>(int32_t &p)
99{ 97{
100 read( &p, sizeof(p) ); 98 read( &p, sizeof(p) );
101 return *this; 99 return *this;
102} 100}
103Serializer &Serializer::operator>>(int64_t &p) 101Bu::Archive &Bu::Archive::operator>>(int64_t &p)
104{ 102{
105 read( &p, sizeof(p) ); 103 read( &p, sizeof(p) );
106 return *this; 104 return *this;
107} 105}
108Serializer &Serializer::operator>>(uint8_t &p) 106Bu::Archive &Bu::Archive::operator>>(uint8_t &p)
109{ 107{
110 read( &p, sizeof(p) ); 108 read( &p, sizeof(p) );
111 return *this; 109 return *this;
112} 110}
113Serializer &Serializer::operator>>(uint16_t &p) 111Bu::Archive &Bu::Archive::operator>>(uint16_t &p)
114{ 112{
115 read( &p, sizeof(p) ); 113 read( &p, sizeof(p) );
116 return *this; 114 return *this;
117} 115}
118Serializer &Serializer::operator>>(uint32_t &p) 116Bu::Archive &Bu::Archive::operator>>(uint32_t &p)
119{ 117{
120 read( &p, sizeof(p) ); 118 read( &p, sizeof(p) );
121 return *this; 119 return *this;
122} 120}
123Serializer &Serializer::operator>>(uint64_t &p) 121Bu::Archive &Bu::Archive::operator>>(uint64_t &p)
124{ 122{
125 read( &p, sizeof(p) ); 123 read( &p, sizeof(p) );
126 return *this; 124 return *this;
127} 125}
128Serializer &Serializer::operator>>(long &p) 126Bu::Archive &Bu::Archive::operator>>(long &p)
129{ 127{
130 read( &p, sizeof(p) ); 128 read( &p, sizeof(p) );
131 return *this; 129 return *this;
132} 130}
133Serializer &Serializer::operator>>(float &p) 131Bu::Archive &Bu::Archive::operator>>(float &p)
134{ 132{
135 read( &p, sizeof(p) ); 133 read( &p, sizeof(p) );
136 return *this; 134 return *this;
137} 135}
138Serializer &Serializer::operator>>(double &p) 136Bu::Archive &Bu::Archive::operator>>(double &p)
139{ 137{
140 read( &p, sizeof(p) ); 138 read( &p, sizeof(p) );
141 return *this; 139 return *this;
142} 140}
143Serializer &Serializer::operator>>(long double &p) 141Bu::Archive &Bu::Archive::operator>>(long double &p)
144{ 142{
145 read( &p, sizeof(p) ); 143 read( &p, sizeof(p) );
146 return *this; 144 return *this;
147} 145}
148 146
149Serializer &Serializer::operator&&(bool &p) 147Bu::Archive &Bu::Archive::operator&&(bool &p)
150{ 148{
151 if (bLoading) 149 if (bLoading)
152 { 150 {
@@ -158,7 +156,7 @@ Serializer &Serializer::operator&&(bool &p)
158 } 156 }
159} 157}
160 158
161Serializer &Serializer::operator&&(int8_t &p) 159Bu::Archive &Bu::Archive::operator&&(int8_t &p)
162{ 160{
163 if (bLoading) 161 if (bLoading)
164 { 162 {
@@ -170,7 +168,7 @@ Serializer &Serializer::operator&&(int8_t &p)
170 } 168 }
171} 169}
172 170
173Serializer &Serializer::operator&&(int16_t &p) 171Bu::Archive &Bu::Archive::operator&&(int16_t &p)
174{ 172{
175 if (bLoading) 173 if (bLoading)
176 { 174 {
@@ -182,7 +180,7 @@ Serializer &Serializer::operator&&(int16_t &p)
182 } 180 }
183} 181}
184 182
185Serializer &Serializer::operator&&(int32_t &p) 183Bu::Archive &Bu::Archive::operator&&(int32_t &p)
186{ 184{
187 if (bLoading) 185 if (bLoading)
188 { 186 {
@@ -194,7 +192,7 @@ Serializer &Serializer::operator&&(int32_t &p)
194 } 192 }
195} 193}
196 194
197Serializer &Serializer::operator&&(int64_t &p) 195Bu::Archive &Bu::Archive::operator&&(int64_t &p)
198{ 196{
199 if (bLoading) 197 if (bLoading)
200 { 198 {
@@ -206,7 +204,7 @@ Serializer &Serializer::operator&&(int64_t &p)
206 } 204 }
207} 205}
208 206
209Serializer &Serializer::operator&&(uint8_t &p) 207Bu::Archive &Bu::Archive::operator&&(uint8_t &p)
210{ 208{
211 if (bLoading) 209 if (bLoading)
212 { 210 {
@@ -218,7 +216,7 @@ Serializer &Serializer::operator&&(uint8_t &p)
218 } 216 }
219} 217}
220 218
221Serializer &Serializer::operator&&(uint16_t &p) 219Bu::Archive &Bu::Archive::operator&&(uint16_t &p)
222{ 220{
223 if (bLoading) 221 if (bLoading)
224 { 222 {
@@ -230,7 +228,7 @@ Serializer &Serializer::operator&&(uint16_t &p)
230 } 228 }
231} 229}
232 230
233Serializer &Serializer::operator&&(uint32_t &p) 231Bu::Archive &Bu::Archive::operator&&(uint32_t &p)
234{ 232{
235 if (bLoading) 233 if (bLoading)
236 { 234 {
@@ -242,7 +240,7 @@ Serializer &Serializer::operator&&(uint32_t &p)
242 } 240 }
243} 241}
244 242
245Serializer &Serializer::operator&&(uint64_t &p) 243Bu::Archive &Bu::Archive::operator&&(uint64_t &p)
246{ 244{
247 if (bLoading) 245 if (bLoading)
248 { 246 {
@@ -254,7 +252,7 @@ Serializer &Serializer::operator&&(uint64_t &p)
254 } 252 }
255} 253}
256 254
257Serializer &Serializer::operator&&(float &p) 255Bu::Archive &Bu::Archive::operator&&(float &p)
258{ 256{
259 if (bLoading) 257 if (bLoading)
260 { 258 {
@@ -266,7 +264,7 @@ Serializer &Serializer::operator&&(float &p)
266 } 264 }
267} 265}
268 266
269Serializer &Serializer::operator&&(double &p) 267Bu::Archive &Bu::Archive::operator&&(double &p)
270{ 268{
271 if (bLoading) 269 if (bLoading)
272 { 270 {
@@ -278,7 +276,7 @@ Serializer &Serializer::operator&&(double &p)
278 } 276 }
279} 277}
280 278
281Serializer &Serializer::operator&&(long double &p) 279Bu::Archive &Bu::Archive::operator&&(long double &p)
282{ 280{
283 if (bLoading) 281 if (bLoading)
284 { 282 {
@@ -291,19 +289,20 @@ Serializer &Serializer::operator&&(long double &p)
291} 289}
292 290
293 291
294Serializer &operator<<(Serializer &s, Serializable &p) 292Bu::Archive &Bu::operator<<(Bu::Archive &s, Bu::Archable &p)
295{ 293{
296 p.serialize( s ); 294 p.archive( s );
297 return s; 295 return s;
298} 296}
299 297
300Serializer &operator>>(Serializer &s, Serializable &p) 298Bu::Archive &Bu::operator>>(Bu::Archive &s, Bu::Archable &p)
301{ 299{
302 p.serialize( s ); 300 p.archive( s );
303 return s; 301 return s;
304} 302}
305 303
306Serializer &operator&&(Serializer &s, Serializable &p) 304/*
305Bu::Archive &Bu::operator&&(Bu::Archive &s, Bu::Archable &p)
307{ 306{
308 if (s.isLoading()) 307 if (s.isLoading())
309 { 308 {
@@ -313,9 +312,9 @@ Serializer &operator&&(Serializer &s, Serializable &p)
313 { 312 {
314 return s << p; 313 return s << p;
315 } 314 }
316} 315}*/
317 316
318Serializer &operator<<( Serializer &ar, std::string &s ) 317Bu::Archive &Bu::operator<<( Bu::Archive &ar, std::string &s )
319{ 318{
320 ar << (uint32_t)s.length(); 319 ar << (uint32_t)s.length();
321 ar.write( s.c_str(), s.length() ); 320 ar.write( s.c_str(), s.length() );
@@ -323,7 +322,7 @@ Serializer &operator<<( Serializer &ar, std::string &s )
323 return ar; 322 return ar;
324} 323}
325 324
326Serializer &operator>>( Serializer &ar, std::string &s ) 325Bu::Archive &Bu::operator>>( Bu::Archive &ar, std::string &s )
327{ 326{
328 uint32_t l; 327 uint32_t l;
329 ar >> l; 328 ar >> l;
diff --git a/src/archive.h b/src/archive.h
new file mode 100644
index 0000000..7de9220
--- /dev/null
+++ b/src/archive.h
@@ -0,0 +1,93 @@
1#ifndef ARCHIVE_H
2#define ARCHIVE_H
3
4#include <stdint.h>
5#include <string>
6#include "archable.h"
7
8namespace Bu
9{
10 class Archive
11 {
12 private:
13 bool bLoading;
14 public:
15 bool isLoading();
16
17 enum
18 {
19 load = true,
20 save = false
21 };
22
23 Archive( bool bLoading );
24 virtual ~Archive();
25 virtual void close()=0;
26
27 virtual void write(const void *, int32_t)=0;
28 virtual void read(void *, int32_t)=0;
29
30 virtual Archive &operator<<(bool);
31 virtual Archive &operator<<(int8_t);
32 virtual Archive &operator<<(int16_t);
33 virtual Archive &operator<<(int32_t);
34 virtual Archive &operator<<(int64_t);
35 virtual Archive &operator<<(uint8_t);
36 virtual Archive &operator<<(uint16_t);
37 virtual Archive &operator<<(uint32_t);
38 virtual Archive &operator<<(uint64_t);
39 virtual Archive &operator<<(long);
40 virtual Archive &operator<<(float);
41 virtual Archive &operator<<(double);
42 virtual Archive &operator<<(long double);
43
44 virtual Archive &operator>>(bool &);
45 virtual Archive &operator>>(int8_t &);
46 virtual Archive &operator>>(int16_t &);
47 virtual Archive &operator>>(int32_t &);
48 virtual Archive &operator>>(int64_t &);
49 virtual Archive &operator>>(uint8_t &);
50 virtual Archive &operator>>(uint16_t &);
51 virtual Archive &operator>>(uint32_t &);
52 virtual Archive &operator>>(uint64_t &);
53 virtual Archive &operator>>(long &);
54 virtual Archive &operator>>(float &);
55 virtual Archive &operator>>(double &);
56 virtual Archive &operator>>(long double &);
57
58 virtual Archive &operator&&(bool &);
59 virtual Archive &operator&&(int8_t &);
60 virtual Archive &operator&&(int16_t &);
61 virtual Archive &operator&&(int32_t &);
62 virtual Archive &operator&&(int64_t &);
63 virtual Archive &operator&&(uint8_t &);
64 virtual Archive &operator&&(uint16_t &);
65 virtual Archive &operator&&(uint32_t &);
66 virtual Archive &operator&&(uint64_t &);
67 virtual Archive &operator&&(float &);
68 virtual Archive &operator&&(double &);
69 virtual Archive &operator&&(long double &);
70 };
71
72 Archive &operator<<(Archive &, class Bu::Archable &);
73 Archive &operator>>(Archive &, class Bu::Archable &);
74 //Archive &operator&&(Archive &s, class Bu::Archable &p);
75
76 Archive &operator<<(Archive &, std::string &);
77 Archive &operator>>(Archive &, std::string &);
78 //Archive &operator&&(Archive &, std::string &);
79
80 template<typename T> Archive &operator&&( Archive &ar, T &dat )
81 {
82 if( ar.isLoading() )
83 {
84 return ar >> dat;
85 }
86 else
87 {
88 return ar << dat;
89 }
90 }
91}
92
93#endif
diff --git a/src/old/exceptionbase.cpp b/src/exceptionbase.cpp
index f3d22da..f6ec625 100644
--- a/src/old/exceptionbase.cpp
+++ b/src/exceptionbase.cpp
@@ -1,7 +1,7 @@
1#include "exceptionbase.h" 1#include "exceptionbase.h"
2#include <stdarg.h> 2#include <stdarg.h>
3 3
4ExceptionBase::ExceptionBase( const char *lpFormat, ... ) throw() : 4Bu::ExceptionBase::ExceptionBase( const char *lpFormat, ... ) throw() :
5 nErrorCode( 0 ), 5 nErrorCode( 0 ),
6 sWhat( NULL ) 6 sWhat( NULL )
7{ 7{
@@ -12,7 +12,7 @@ ExceptionBase::ExceptionBase( const char *lpFormat, ... ) throw() :
12 va_end(ap); 12 va_end(ap);
13} 13}
14 14
15ExceptionBase::ExceptionBase( int nCode, const char *lpFormat, ... ) throw() : 15Bu::ExceptionBase::ExceptionBase( int nCode, const char *lpFormat, ... ) throw() :
16 nErrorCode( nCode ), 16 nErrorCode( nCode ),
17 sWhat( NULL ) 17 sWhat( NULL )
18{ 18{
@@ -23,13 +23,13 @@ ExceptionBase::ExceptionBase( int nCode, const char *lpFormat, ... ) throw() :
23 va_end(ap); 23 va_end(ap);
24} 24}
25 25
26ExceptionBase::ExceptionBase( int nCode ) throw() : 26Bu::ExceptionBase::ExceptionBase( int nCode ) throw() :
27 nErrorCode( nCode ), 27 nErrorCode( nCode ),
28 sWhat( NULL ) 28 sWhat( NULL )
29{ 29{
30} 30}
31 31
32ExceptionBase::~ExceptionBase() throw() 32Bu::ExceptionBase::~ExceptionBase() throw()
33{ 33{
34 if( sWhat ) 34 if( sWhat )
35 { 35 {
@@ -38,7 +38,7 @@ ExceptionBase::~ExceptionBase() throw()
38 } 38 }
39} 39}
40 40
41void ExceptionBase::setWhat( const char *lpFormat, va_list &vargs ) 41void Bu::ExceptionBase::setWhat( const char *lpFormat, va_list &vargs )
42{ 42{
43 if( sWhat ) delete[] sWhat; 43 if( sWhat ) delete[] sWhat;
44 int nSize; 44 int nSize;
@@ -48,7 +48,7 @@ void ExceptionBase::setWhat( const char *lpFormat, va_list &vargs )
48 vsnprintf( sWhat, nSize+1, lpFormat, vargs ); 48 vsnprintf( sWhat, nSize+1, lpFormat, vargs );
49} 49}
50 50
51void ExceptionBase::setWhat( const char *lpText ) 51void Bu::ExceptionBase::setWhat( const char *lpText )
52{ 52{
53 if( sWhat ) delete[] sWhat; 53 if( sWhat ) delete[] sWhat;
54 int nSize; 54 int nSize;
@@ -58,12 +58,12 @@ void ExceptionBase::setWhat( const char *lpText )
58 strcpy( sWhat, lpText ); 58 strcpy( sWhat, lpText );
59} 59}
60 60
61const char *ExceptionBase::what() const throw() 61const char *Bu::ExceptionBase::what() const throw()
62{ 62{
63 return sWhat; 63 return sWhat;
64} 64}
65 65
66int ExceptionBase::getErrorCode() 66int Bu::ExceptionBase::getErrorCode()
67{ 67{
68 return nErrorCode; 68 return nErrorCode;
69} 69}
diff --git a/src/exceptionbase.h b/src/exceptionbase.h
new file mode 100644
index 0000000..fd78089
--- /dev/null
+++ b/src/exceptionbase.h
@@ -0,0 +1,114 @@
1#ifndef EXCEPTION_BASE_H
2#define EXCEPTION_BASE_H
3
4#include <string>
5#include <exception>
6#include <stdarg.h>
7
8namespace Bu
9{
10 /**
11 * A generalized Exception base class. This is nice for making general and
12 * flexible child classes that can create new error code classes.
13 *
14 * In order to create your own exception class use these two lines.
15 *
16 * in your header: subExceptionDecl( NewClassName );
17 *
18 * in your source: subExcpetienDef( NewClassName );
19 */
20 class ExceptionBase : public std::exception
21 {
22 public:
23 /**
24 * Construct an exception with an error code of zero, but with a
25 * description. The use of this is not reccomended most of the time,
26 * it's generally best to include an error code with the exception so
27 * your program can handle the exception in a better way.
28 * @param sFormat The format of the text. See printf for more info.
29 */
30 ExceptionBase( const char *sFormat, ... ) throw();
31
32 /**
33 *
34 * @param nCode
35 * @param sFormat
36 */
37 ExceptionBase( int nCode, const char *sFormat, ... ) throw();
38
39 /**
40 *
41 * @param nCode
42 * @return
43 */
44 ExceptionBase( int nCode=0 ) throw();
45
46 /**
47 *
48 * @return
49 */
50 virtual ~ExceptionBase() throw();
51
52 /**
53 *
54 * @return
55 */
56 virtual const char *what() const throw();
57
58 /**
59 *
60 * @return
61 */
62 int getErrorCode();
63
64 /**
65 *
66 * @param lpFormat
67 * @param vargs
68 */
69 void setWhat( const char *lpFormat, va_list &vargs );
70
71 /**
72 *
73 * @param lpText
74 */
75 void setWhat( const char *lpText );
76
77 private:
78 int nErrorCode; /**< The code for the error that occured. */
79 char *sWhat; /**< The text string telling people what went wrong. */
80 };
81}
82
83#define subExceptionDecl( name ) \
84class name : public ExceptionBase \
85{ \
86 public: \
87 name( const char *sFormat, ... ) throw (); \
88 name( int nCode, const char *sFormat, ... ) throw(); \
89 name( int nCode=0 ) throw (); \
90};
91
92#define subExceptionDef( name ) \
93name::name( const char *lpFormat, ... ) throw() : \
94 ExceptionBase( 0 ) \
95{ \
96 va_list ap; \
97 va_start( ap, lpFormat ); \
98 setWhat( lpFormat, ap ); \
99 va_end( ap ); \
100} \
101name::name( int nCode, const char *lpFormat, ... ) throw() : \
102 ExceptionBase( nCode ) \
103{ \
104 va_list ap; \
105 va_start( ap, lpFormat ); \
106 setWhat( lpFormat, ap ); \
107 va_end( ap ); \
108} \
109name::name( int nCode ) throw() : \
110 ExceptionBase( nCode ) \
111{ \
112}
113
114#endif
diff --git a/src/exceptions.cpp b/src/exceptions.cpp
new file mode 100644
index 0000000..37f09a4
--- /dev/null
+++ b/src/exceptions.cpp
@@ -0,0 +1,10 @@
1#include "exceptions.h"
2#include <stdarg.h>
3
4namespace Bu
5{
6 subExceptionDef( XmlException )
7 subExceptionDef( FileException )
8 subExceptionDef( ConnectionException )
9 subExceptionDef( PluginException )
10}
diff --git a/src/exceptions.h b/src/exceptions.h
new file mode 100644
index 0000000..b28d292
--- /dev/null
+++ b/src/exceptions.h
@@ -0,0 +1,28 @@
1#ifndef EXCEPTIONS_H
2#define EXCEPTIONS_H
3
4#include "exceptionbase.h"
5#include <stdarg.h>
6
7namespace Bu
8{
9 subExceptionDecl( XmlException )
10 subExceptionDecl( FileException )
11 subExceptionDecl( ConnectionException )
12 subExceptionDecl( PluginException )
13
14 enum eFileException
15 {
16 excodeEOF
17 };
18
19 enum eConnectionException
20 {
21 excodeReadError,
22 excodeBadReadError,
23 excodeConnectionClosed,
24 excodeSocketTimeout
25 };
26}
27
28#endif
diff --git a/src/fstring.cpp b/src/fstring.cpp
new file mode 100644
index 0000000..56d2173
--- /dev/null
+++ b/src/fstring.cpp
@@ -0,0 +1,14 @@
1#include "fstring.h"
2#include "hash.h"
3
4template<> uint32_t Bu::__calcHashCode<Bu::FString>( const Bu::FString &k )
5{
6 return __calcHashCode( k.c_str() );
7}
8
9template<> bool Bu::__cmpHashKeys<Bu::FString>(
10 const Bu::FString &a, const Bu::FString &b )
11{
12 return a == b;
13}
14
diff --git a/src/fstring.h b/src/fstring.h
new file mode 100644
index 0000000..717068f
--- /dev/null
+++ b/src/fstring.h
@@ -0,0 +1,653 @@
1#ifndef F_STRING_H
2#define F_STRING_H
3
4#include <stdint.h>
5#include <memory>
6#include "archable.h"
7#include "archive.h"
8#include "hash.h"
9
10namespace Bu
11{
12 template< typename chr >
13 struct FStringChunk
14 {
15 long nLength;
16 chr *pData;
17 FStringChunk *pNext;
18 };
19
20 /**
21 * Flexible String class. This class was designed with string passing and
22 * generation in mind. Like the standard string class you can specify what
23 * datatype to use for each character. Unlike the standard string class,
24 * collection of appended and prepended terms is done lazily, making long
25 * operations that involve many appends very inexpensive. In addition internal
26 * ref-counting means that if you pass strings around between functions there's
27 * almost no overhead in time or memory since a reference is created and no
28 * data is actually copied. This also means that you never need to put any
29 * FBasicString into a ref-counting container class.
30 */
31 template< typename chr, typename chralloc=std::allocator<chr>, typename chunkalloc=std::allocator<struct FStringChunk<chr> > >
32 class FBasicString : public Archable
33 {
34#ifndef VALTEST
35#define cpy( dest, src, size ) memcpy( dest, src, size*sizeof(chr) )
36#endif
37 private:
38 typedef struct FStringChunk<chr> Chunk;
39 typedef struct FBasicString<chr, chralloc, chunkalloc> MyType;
40
41 public:
42 FBasicString() :
43 nLength( 0 ),
44 pnRefs( NULL ),
45 pFirst( NULL ),
46 pLast( NULL )
47 {
48 }
49
50 FBasicString( const chr *pData ) :
51 nLength( 0 ),
52 pnRefs( NULL ),
53 pFirst( NULL ),
54 pLast( NULL )
55 {
56 append( pData );
57 }
58
59 FBasicString( const chr *pData, long nLength ) :
60 nLength( 0 ),
61 pnRefs( NULL ),
62 pFirst( NULL ),
63 pLast( NULL )
64 {
65 append( pData, nLength );
66 }
67
68 FBasicString( const MyType &rSrc ) :
69 nLength( 0 ),
70 pnRefs( NULL ),
71 pFirst( NULL ),
72 pLast( NULL )
73 {
74 // Here we have no choice but to copy, since the other guy is a const.
75 // In the case that the source were flat, we could get a reference, it
76 // would make some things faster, but not matter in many other cases.
77
78 joinShare( rSrc );
79 //copyFrom( rSrc );
80 }
81
82 FBasicString( const MyType &rSrc, long nLength ) :
83 nLength( 0 ),
84 pnRefs( NULL ),
85 pFirst( NULL ),
86 pLast( NULL )
87 {
88 append( rSrc.pFirst->pData, nLength );
89 }
90
91 FBasicString( const MyType &rSrc, long nStart, long nLength ) :
92 nLength( 0 ),
93 pnRefs( NULL ),
94 pFirst( NULL ),
95 pLast( NULL )
96 {
97 append( rSrc.pFirst->pData+nStart, nLength );
98 }
99
100 FBasicString( long nSize ) :
101 nLength( nSize ),
102 pnRefs( NULL ),
103 pFirst( NULL ),
104 pLast( NULL )
105 {
106 pFirst = pLast = newChunk( nSize );
107 }
108
109 virtual ~FBasicString()
110 {
111 clear();
112 }
113
114 void append( const chr *pData )
115 {
116 long nLen;
117 for( nLen = 0; pData[nLen] != (chr)0; nLen++ );
118
119 Chunk *pNew = newChunk( nLen );
120 cpy( pNew->pData, pData, nLen );
121
122 appendChunk( pNew );
123 }
124
125 void append( const chr *pData, long nLen )
126 {
127 Chunk *pNew = newChunk( nLen );
128
129 cpy( pNew->pData, pData, nLen );
130
131 appendChunk( pNew );
132 }
133
134 void prepend( const chr *pData )
135 {
136 long nLen;
137 for( nLen = 0; pData[nLen] != (chr)0; nLen++ );
138
139 Chunk *pNew = newChunk( nLen );
140 cpy( pNew->pData, pData, nLen );
141
142 prependChunk( pNew );
143 }
144
145 void prepend( const chr *pData, long nLen )
146 {
147 Chunk *pNew = newChunk( nLen );
148
149 cpy( pNew->pData, pData, nLen );
150
151 prependChunk( pNew );
152 }
153
154 void clear()
155 {
156 realClear();
157 }
158
159 void resize( long nNewSize )
160 {
161 if( nLength == nNewSize )
162 return;
163
164 flatten();
165
166 Chunk *pNew = newChunk( nNewSize );
167 long nNewLen = (nNewSize<nLength)?(nNewSize):(nLength);
168 cpy( pNew->pData, pFirst->pData, nNewLen );
169 pNew->pData[nNewLen] = (chr)0;
170 aChr.deallocate( pFirst->pData, pFirst->nLength+1 );
171 aChunk.deallocate( pFirst, 1 );
172 pFirst = pLast = pNew;
173 nLength = nNewSize;
174 }
175
176 long getSize() const
177 {
178 return nLength;
179 }
180
181 chr *getStr()
182 {
183 if( pFirst == NULL )
184 return NULL;
185
186 flatten();
187 return pFirst->pData;
188 }
189
190 const chr *getStr() const
191 {
192 if( pFirst == NULL )
193 return NULL;
194
195 flatten();
196 return pFirst->pData;
197 }
198
199 chr *c_str()
200 {
201 if( pFirst == NULL )
202 return NULL;
203
204 flatten();
205 return pFirst->pData;
206 }
207
208 const chr *c_str() const
209 {
210 if( pFirst == NULL )
211 return NULL;
212
213 flatten();
214 return pFirst->pData;
215 }
216
217 MyType &operator +=( const chr *pData )
218 {
219 append( pData );
220
221 return (*this);
222 }
223
224 MyType &operator +=( const MyType &rSrc )
225 {
226 rSrc.flatten();
227 append( rSrc.pFirst->pData, rSrc.nLength );
228
229 return (*this);
230 }
231
232 MyType &operator +=( const chr pData )
233 {
234 chr tmp[2] = { pData, (chr)0 };
235 append( tmp );
236
237 return (*this);
238 }
239
240 MyType &operator =( const chr *pData )
241 {
242 clear();
243 append( pData );
244
245 return (*this);
246 }
247
248 MyType &operator =( const MyType &rSrc )
249 {
250 //if( rSrc.isFlat() )
251 //{
252 joinShare( rSrc );
253 //}
254 //else
255 //{
256 // copyFrom( rSrc );
257 //}
258 //
259
260 return (*this);
261 }
262
263 bool operator ==( const chr *pData ) const
264 {
265 if( pFirst == NULL ) {
266 if( pData == NULL )
267 return true;
268 return false;
269 }
270
271 flatten();
272 const chr *a = pData;
273 chr *b = pFirst->pData;
274 for( ; *a!=(chr)0; a++, b++ )
275 {
276 if( *a != *b )
277 return false;
278 }
279
280 return true;
281 }
282
283 bool operator ==( const MyType &pData ) const
284 {
285 if( pFirst == pData.pFirst )
286 return true;
287 if( pFirst == NULL )
288 return false;
289
290 flatten();
291 pData.flatten();
292 const chr *a = pData.pFirst->pData;
293 chr *b = pFirst->pData;
294 for( ; *a!=(chr)0; a++, b++ )
295 {
296 if( *a != *b )
297 return false;
298 }
299
300 return true;
301 }
302
303 bool operator !=(const chr *pData ) const
304 {
305 return !(*this == pData);
306 }
307
308 bool operator !=(const MyType &pData ) const
309 {
310 return !(*this == pData);
311 }
312
313 chr &operator[]( long nIndex )
314 {
315 flatten();
316
317 return pFirst->pData[nIndex];
318 }
319
320 const chr &operator[]( long nIndex ) const
321 {
322 flatten();
323
324 return pFirst->pData[nIndex];
325 }
326
327 bool isWS( long nIndex ) const
328 {
329 flatten();
330
331 return pFirst->pData[nIndex]==' ' || pFirst->pData[nIndex]=='\t'
332 || pFirst->pData[nIndex]=='\r' || pFirst->pData[nIndex]=='\n';
333 }
334
335 bool isAlpha( long nIndex ) const
336 {
337 flatten();
338
339 return (pFirst->pData[nIndex] >= 'a' && pFirst->pData[nIndex] <= 'z')
340 || (pFirst->pData[nIndex] >= 'A' && pFirst->pData[nIndex] <= 'Z');
341 }
342
343 void toLower()
344 {
345 flatten();
346 unShare();
347
348 for( long j = 0; j < nLength; j++ )
349 {
350 if( pFirst->pData[j] >= 'A' && pFirst->pData[j] <= 'Z' )
351 pFirst->pData[j] -= 'A'-'a';
352 }
353 }
354
355 void toUpper()
356 {
357 flatten();
358 unShare();
359
360 for( long j = 0; j < nLength; j++ )
361 {
362 if( pFirst->pData[j] >= 'a' && pFirst->pData[j] <= 'z' )
363 pFirst->pData[j] += 'A'-'a';
364 }
365 }
366
367 void archive( class Archive &ar )
368 {
369 if( ar.isLoading() )
370 {
371 clear();
372 long nLen;
373 ar >> nLen;
374
375 Chunk *pNew = newChunk( nLen );
376 ar.read( pNew->pData, nLen*sizeof(chr) );
377 appendChunk( pNew );
378 }
379 else
380 {
381 flatten();
382
383 ar << nLength;
384 ar.write( pFirst->pData, nLength*sizeof(chr) );
385 }
386 }
387
388 private:
389 void flatten() const
390 {
391 if( isFlat() )
392 return;
393
394 if( pFirst == NULL )
395 return;
396
397 unShare();
398
399 Chunk *pNew = newChunk( nLength );
400 chr *pos = pNew->pData;
401 Chunk *i = pFirst;
402 for(;;)
403 {
404 cpy( pos, i->pData, i->nLength );
405 pos += i->nLength;
406 i = i->pNext;
407 if( i == NULL )
408 break;
409 }
410 realClear();
411
412 pLast = pFirst = pNew;
413 nLength = pNew->nLength;
414 }
415
416 void realClear() const
417 {
418 if( pFirst == NULL )
419 return;
420
421 if( isShared() )
422 {
423 decRefs();
424 }
425 else
426 {
427 Chunk *i = pFirst;
428 for(;;)
429 {
430 Chunk *n = i->pNext;
431 aChr.deallocate( i->pData, i->nLength+1 );
432 aChunk.deallocate( i, 1 );
433 if( n == NULL )
434 break;
435 i = n;
436 }
437 pFirst = pLast = NULL;
438 nLength = 0;
439 }
440 }
441
442 void copyFrom( const FBasicString<chr, chralloc, chunkalloc> &rSrc )
443 {
444 if( rSrc.pFirst == NULL )
445 return;
446
447 decRefs();
448
449 Chunk *pNew = newChunk( rSrc.nLength );
450 chr *pos = pNew->pData;
451 Chunk *i = rSrc.pFirst;
452 for(;;)
453 {
454 cpy( pos, i->pData, i->nLength );
455 pos += i->nLength;
456 i = i->pNext;
457 if( i == NULL )
458 break;
459 }
460 clear();
461
462 appendChunk( pNew );
463 }
464
465 bool isFlat() const
466 {
467 return (pFirst == pLast);
468 }
469
470 bool isShared() const
471 {
472 return (pnRefs != NULL);
473 }
474
475 Chunk *newChunk() const
476 {
477 Chunk *pNew = aChunk.allocate( 1 );
478 pNew->pNext = NULL;
479 return pNew;
480 }
481
482 Chunk *newChunk( long nLen ) const
483 {
484 Chunk *pNew = aChunk.allocate( 1 );
485 pNew->pNext = NULL;
486 pNew->nLength = nLen;
487 pNew->pData = aChr.allocate( nLen+1 );
488 pNew->pData[nLen] = (chr)0;
489 return pNew;
490 }
491
492 void appendChunk( Chunk *pNewChunk )
493 {
494 unShare();
495
496 if( pFirst == NULL )
497 pLast = pFirst = pNewChunk;
498 else
499 {
500 pLast->pNext = pNewChunk;
501 pLast = pNewChunk;
502 }
503
504 nLength += pNewChunk->nLength;
505 }
506
507 void prependChunk( Chunk *pNewChunk )
508 {
509 unShare();
510
511 if( pFirst == NULL )
512 pLast = pFirst = pNewChunk;
513 else
514 {
515 pNewChunk->pNext = pFirst;
516 pFirst = pNewChunk;
517 }
518
519 nLength += pNewChunk->nLength;
520 }
521
522 void joinShare( MyType &rSrc )
523 {
524 clear();
525
526 if( !rSrc.isFlat() )
527 rSrc.flatten();
528
529 rSrc.initCount();
530 pnRefs = rSrc.pnRefs;
531 (*pnRefs)++;
532 nLength = rSrc.nLength;
533 pFirst = rSrc.pFirst;
534 pLast = rSrc.pLast;
535 }
536
537 void joinShare( const MyType &rSrc )
538 {
539 clear();
540
541 rSrc.flatten();
542
543 if( !rSrc.isShared() )
544 {
545 rSrc.pnRefs = new uint32_t;
546 (*rSrc.pnRefs) = 1;
547 }
548 pnRefs = rSrc.pnRefs;
549 (*pnRefs)++;
550 nLength = rSrc.nLength;
551 pFirst = rSrc.pFirst;
552 pLast = rSrc.pLast;
553 }
554
555 /**
556 * This takes an object that was shared and makes a copy of the base data
557 * that was being shared so that this copy can be changed. This should be
558 * added before any call that will change this object;
559 */
560 void unShare() const
561 {
562 if( isShared() == false )
563 return;
564
565 Chunk *pNew = newChunk( nLength );
566 chr *pos = pNew->pData;
567 Chunk *i = pFirst;
568 for(;;)
569 {
570 cpy( pos, i->pData, i->nLength );
571 pos += i->nLength;
572 i = i->pNext;
573 if( i == NULL )
574 break;
575 }
576 decRefs();
577 pLast = pFirst = pNew;
578 nLength = pNew->nLength;
579 }
580
581 /**
582 * This decrements our ref count and pulls us out of the share. If the ref
583 * count hits zero because of this, it destroys the share. This is not
584 * safe to call on it's own, it's much better to call unShare.
585 */
586 void decRefs() const
587 {
588 if( isShared() )
589 {
590 (*pnRefs)--;
591 if( (*pnRefs) == 0 )
592 destroyShare();
593 else
594 {
595 pnRefs = NULL;
596 pFirst = NULL;
597 pLast = NULL;
598 nLength = 0;
599 }
600 }
601 }
602
603 /**
604 * While the unShare function removes an instance from a share, this
605 * function destroys the data that was in the share, removing the share
606 * itself. This should only be called when the refcount for the share has
607 * or is about to reach zero.
608 */
609 void destroyShare() const
610 {
611 delete pnRefs;
612 pnRefs = NULL;
613 realClear();
614 }
615
616#ifdef VALTEST
617 void cpy( chr *dest, const chr *src, long count ) const
618 {
619 for( int j = 0; j < count; j++ )
620 {
621 *dest = *src;
622 dest++;
623 src++;
624 }
625 }
626#endif
627
628 void initCount() const
629 {
630 if( !isShared() )
631 {
632 pnRefs = new uint32_t;
633 (*pnRefs) = 1;
634 }
635 }
636
637 private:
638 mutable long nLength;
639 mutable uint32_t *pnRefs;
640 mutable Chunk *pFirst;
641 mutable Chunk *pLast;
642
643 mutable chralloc aChr;
644 mutable chunkalloc aChunk;
645 };
646
647 typedef FBasicString<char> FString;
648
649 template<> uint32_t __calcHashCode<FString>( const FString &k );
650 template<> bool __cmpHashKeys<FString>( const FString &a, const FString &b );
651}
652
653#endif
diff --git a/src/hash.cpp b/src/hash.cpp
new file mode 100644
index 0000000..a207c29
--- /dev/null
+++ b/src/hash.cpp
@@ -0,0 +1,101 @@
1#include "hash.h"
2
3namespace Bu { subExceptionDef( HashException ) }
4
5template<> uint32_t Bu::__calcHashCode<int>( const int &k )
6{
7 return k;
8}
9
10template<> bool Bu::__cmpHashKeys<int>( const int &a, const int &b )
11{
12 return a == b;
13}
14
15template<> uint32_t Bu::__calcHashCode<unsigned int>( const unsigned int &k )
16{
17 return k;
18}
19
20template<> bool Bu::__cmpHashKeys<unsigned int>( const unsigned int &a, const unsigned int &b )
21{
22 return a == b;
23}
24
25template<>
26uint32_t Bu::__calcHashCode<const char *>( const char * const &k )
27{
28 if (k == NULL)
29 {
30 return 0;
31 }
32
33 unsigned long int nPos = 0;
34 for( const char *s = k; *s; s++ )
35 {
36 nPos = *s + (nPos << 6) + (nPos << 16) - nPos;
37 }
38
39 return nPos;
40}
41
42template<> bool Bu::__cmpHashKeys<const char *>( const char * const &a, const char * const &b )
43{
44 if( a == b )
45 return true;
46
47 for(int j=0; a[j] == b[j]; j++ )
48 if( a[j] == '\0' )
49 return true;
50
51 return false;
52}
53
54template<>
55uint32_t Bu::__calcHashCode<char *>( char * const &k )
56{
57 if (k == NULL)
58 {
59 return 0;
60 }
61
62 unsigned long int nPos = 0;
63 for( const char *s = k; *s; s++ )
64 {
65 nPos = *s + (nPos << 6) + (nPos << 16) - nPos;
66 }
67
68 return nPos;
69}
70
71template<> bool Bu::__cmpHashKeys<char *>( char * const &a, char * const &b )
72{
73 if( a == b )
74 return true;
75
76 for(int j=0; a[j] == b[j]; j++ )
77 if( a[j] == '\0' )
78 return true;
79
80 return false;
81}
82
83template<> uint32_t Bu::__calcHashCode<std::string>( const std::string &k )
84{
85 std::string::size_type j, sz = k.size();
86 const char *s = k.c_str();
87
88 unsigned long int nPos = 0;
89 for( j = 0; j < sz; j++, s++ )
90 {
91 nPos = *s + (nPos << 6) + (nPos << 16) - nPos;
92 }
93
94 return nPos;
95}
96
97template<> bool Bu::__cmpHashKeys<std::string>( const std::string &a, const std::string &b )
98{
99 return a == b;
100}
101
diff --git a/src/hash.h b/src/hash.h
new file mode 100644
index 0000000..9e498f1
--- /dev/null
+++ b/src/hash.h
@@ -0,0 +1,745 @@
1#ifndef HASH_H
2#define HASH_H
3
4#include <stddef.h>
5#include <string.h>
6#include <memory>
7#include <iostream>
8#include <list>
9#include <utility>
10#include "exceptionbase.h"
11#include "archable.h"
12#include "archive.h"
13
14#define bitsToBytes( n ) (n/32+(n%32>0 ? 1 : 0))
15
16namespace Bu
17{
18 subExceptionDecl( HashException )
19
20 enum eHashException
21 {
22 excodeNotFilled
23 };
24
25 template<typename T>
26 uint32_t __calcHashCode( const T &k );
27
28 template<typename T>
29 bool __cmpHashKeys( const T &a, const T &b );
30
31 struct __calcNextTSize_fast
32 {
33 uint32_t operator()( uint32_t nCapacity, uint32_t nFill, uint32_t nDeleted ) const
34 {
35 if( nDeleted >= nCapacity/2 )
36 return nCapacity;
37 return nCapacity*2+1;
38 }
39 };
40
41 template<typename key, typename value, typename sizecalc = __calcNextTSize_fast, typename keyalloc = std::allocator<key>, typename valuealloc = std::allocator<value>, typename challoc = std::allocator<uint32_t> >
42 class Hash;
43
44 template< typename key, typename _value, typename sizecalc = __calcNextTSize_fast, typename keyalloc = std::allocator<key>, typename valuealloc = std::allocator<_value>, typename challoc = std::allocator<uint32_t> >
45 struct HashProxy
46 {
47 friend class Hash<key, _value, sizecalc, keyalloc, valuealloc, challoc>;
48 private:
49 HashProxy( Hash<key, _value, sizecalc, keyalloc, valuealloc, challoc> &h, key *k, uint32_t nPos, uint32_t hash ) :
50 hsh( h ),
51 pKey( k ),
52 nPos( nPos ),
53 hash( hash ),
54 bFilled( false )
55 {
56 }
57
58 HashProxy( Hash<key, _value, sizecalc, keyalloc, valuealloc, challoc> &h, uint32_t nPos, _value *pValue ) :
59 hsh( h ),
60 nPos( nPos ),
61 pValue( pValue ),
62 bFilled( true )
63 {
64 }
65
66 Hash<key, _value, sizecalc, keyalloc, valuealloc, challoc> &hsh;
67 key *pKey;
68 uint32_t nPos;
69 _value *pValue;
70 uint32_t hash;
71 bool bFilled;
72
73 public:
74 operator _value &()
75 {
76 if( bFilled == false )
77 throw HashException(
78 excodeNotFilled,
79 "No data assosiated with that key."
80 );
81 return *pValue;
82 }
83
84 _value &value()
85 {
86 if( bFilled == false )
87 throw HashException(
88 excodeNotFilled,
89 "No data assosiated with that key."
90 );
91 return *pValue;
92 }
93
94 bool isFilled()
95 {
96 return bFilled;
97 }
98
99 void erase()
100 {
101 if( bFilled )
102 {
103 hsh._erase( nPos );
104 hsh.onDelete();
105 }
106 }
107
108 _value operator=( _value nval )
109 {
110 if( bFilled )
111 {
112 hsh.va.destroy( pValue );
113 hsh.va.construct( pValue, nval );
114 hsh.onUpdate();
115 }
116 else
117 {
118 hsh.fill( nPos, *pKey, nval, hash );
119 hsh.onInsert();
120 }
121
122 return nval;
123 }
124
125 _value *operator->()
126 {
127 if( bFilled == false )
128 throw HashException(
129 excodeNotFilled,
130 "No data assosiated with that key."
131 );
132 return pValue;
133 }
134 };
135
136 template<typename key, typename value, typename sizecalc, typename keyalloc, typename valuealloc, typename challoc >
137 class Hash
138 {
139 friend struct HashProxy<key, value, sizecalc, keyalloc, valuealloc, challoc>;
140 public:
141 Hash() :
142 nCapacity( 11 ),
143 nFilled( 0 ),
144 nDeleted( 0 ),
145 bFilled( NULL ),
146 bDeleted( NULL ),
147 aKeys( NULL ),
148 aValues( NULL ),
149 aHashCodes( NULL )
150 {
151 nKeysSize = bitsToBytes( nCapacity );
152 bFilled = ca.allocate( nKeysSize );
153 bDeleted = ca.allocate( nKeysSize );
154 clearBits();
155
156 aHashCodes = ca.allocate( nCapacity );
157 aKeys = ka.allocate( nCapacity );
158 aValues = va.allocate( nCapacity );
159 }
160
161 Hash( const Hash &src ) :
162 nCapacity( src.nCapacity ),
163 nFilled( 0 ),
164 nDeleted( 0 ),
165 bFilled( NULL ),
166 bDeleted( NULL ),
167 aKeys( NULL ),
168 aValues( NULL ),
169 aHashCodes( NULL )
170 {
171 nKeysSize = bitsToBytes( nCapacity );
172 bFilled = ca.allocate( nKeysSize );
173 bDeleted = ca.allocate( nKeysSize );
174 clearBits();
175
176 aHashCodes = ca.allocate( nCapacity );
177 aKeys = ka.allocate( nCapacity );
178 aValues = va.allocate( nCapacity );
179
180 for( uint32_t j = 0; j < src.nCapacity; j++ )
181 {
182 if( src.isFilled( j ) )
183 {
184 insert( src.aKeys[j], src.aValues[j] );
185 }
186 }
187 }
188
189 Hash &operator=( const Hash &src )
190 {
191 for( uint32_t j = 0; j < nCapacity; j++ )
192 {
193 if( isFilled( j ) )
194 if( !isDeleted( j ) )
195 {
196 va.destroy( &aValues[j] );
197 ka.destroy( &aKeys[j] );
198 }
199 }
200 va.deallocate( aValues, nCapacity );
201 ka.deallocate( aKeys, nCapacity );
202 ca.deallocate( bFilled, nKeysSize );
203 ca.deallocate( bDeleted, nKeysSize );
204 ca.deallocate( aHashCodes, nCapacity );
205
206 nFilled = 0;
207 nDeleted = 0;
208 nCapacity = src.nCapacity;
209 nKeysSize = bitsToBytes( nCapacity );
210 bFilled = ca.allocate( nKeysSize );
211 bDeleted = ca.allocate( nKeysSize );
212 clearBits();
213
214 aHashCodes = ca.allocate( nCapacity );
215 aKeys = ka.allocate( nCapacity );
216 aValues = va.allocate( nCapacity );
217
218 for( uint32_t j = 0; j < src.nCapacity; j++ )
219 {
220 if( src.isFilled( j ) )
221 {
222 insert( src.aKeys[j], src.aValues[j] );
223 }
224 }
225
226 return *this;
227 }
228
229 virtual ~Hash()
230 {
231 for( uint32_t j = 0; j < nCapacity; j++ )
232 {
233 if( isFilled( j ) )
234 if( !isDeleted( j ) )
235 {
236 va.destroy( &aValues[j] );
237 ka.destroy( &aKeys[j] );
238 }
239 }
240 va.deallocate( aValues, nCapacity );
241 ka.deallocate( aKeys, nCapacity );
242 ca.deallocate( bFilled, nKeysSize );
243 ca.deallocate( bDeleted, nKeysSize );
244 ca.deallocate( aHashCodes, nCapacity );
245 }
246
247 uint32_t getCapacity()
248 {
249 return nCapacity;
250 }
251
252 uint32_t getFill()
253 {
254 return nFilled;
255 }
256
257 uint32_t size()
258 {
259 return nFilled-nDeleted;
260 }
261
262 uint32_t getDeleted()
263 {
264 return nDeleted;
265 }
266
267 virtual HashProxy<key, value, sizecalc, keyalloc, valuealloc, challoc> operator[]( key k )
268 {
269 uint32_t hash = __calcHashCode( k );
270 bool bFill;
271 uint32_t nPos = probe( hash, k, bFill );
272
273 if( bFill )
274 {
275 return HashProxy<key, value, sizecalc, keyalloc, valuealloc, challoc>( *this, nPos, &aValues[nPos] );
276 }
277 else
278 {
279 return HashProxy<key, value, sizecalc, keyalloc, valuealloc, challoc>( *this, &k, nPos, hash );
280 }
281 }
282
283 virtual void insert( key k, value v )
284 {
285 uint32_t hash = __calcHashCode( k );
286 bool bFill;
287 uint32_t nPos = probe( hash, k, bFill );
288
289 if( bFill )
290 {
291 va.destroy( &aValues[nPos] );
292 va.construct( &aValues[nPos], v );
293 onUpdate();
294 }
295 else
296 {
297 fill( nPos, k, v, hash );
298 onInsert();
299 }
300 }
301
302 virtual void erase( key k )
303 {
304 uint32_t hash = __calcHashCode( k );
305 bool bFill;
306 uint32_t nPos = probe( hash, k, bFill );
307
308 if( bFill )
309 {
310 _erase( nPos );
311 onDelete();
312 }
313 }
314
315 struct iterator;
316 virtual void erase( struct iterator &i )
317 {
318 if( this != &i.hsh )
319 throw HashException("This iterator didn't come from this Hash.");
320 if( isFilled( i.nPos ) && !isDeleted( i.nPos ) )
321 {
322 _erase( i.nPos );
323 onDelete();
324 }
325 }
326
327 virtual void clear()
328 {
329 for( uint32_t j = 0; j < nCapacity; j++ )
330 {
331 if( isFilled( j ) )
332 if( !isDeleted( j ) )
333 {
334 va.destroy( &aValues[j] );
335 ka.destroy( &aKeys[j] );
336 onDelete();
337 }
338 }
339
340 clearBits();
341 }
342
343 virtual value &get( key k )
344 {
345 uint32_t hash = __calcHashCode( k );
346 bool bFill;
347 uint32_t nPos = probe( hash, k, bFill );
348
349 if( bFill )
350 {
351 return aValues[nPos];
352 }
353 else
354 {
355 throw HashException(
356 excodeNotFilled,
357 "No data assosiated with that key."
358 );
359 }
360 }
361
362 virtual bool has( key k )
363 {
364 bool bFill;
365 probe( __calcHashCode( k ), k, bFill, false );
366
367 return bFill;
368 }
369
370 typedef struct iterator
371 {
372 friend class Hash<key, value, sizecalc, keyalloc, valuealloc, challoc>;
373 private:
374 iterator( Hash<key, value, sizecalc, keyalloc, valuealloc, challoc> &hsh ) :
375 hsh( hsh ),
376 nPos( 0 ),
377 bFinished( false )
378 {
379 nPos = hsh.getFirstPos( bFinished );
380 }
381
382 iterator( Hash<key, value, sizecalc, keyalloc, valuealloc, challoc> &hsh, bool bDone ) :
383 hsh( hsh ),
384 nPos( 0 ),
385 bFinished( bDone )
386 {
387 }
388
389 Hash<key, value, sizecalc, keyalloc, valuealloc, challoc> &hsh;
390 uint32_t nPos;
391 bool bFinished;
392
393 public:
394 iterator operator++( int )
395 {
396 if( bFinished == false )
397 nPos = hsh.getNextPos( nPos, bFinished );
398
399 return *this;
400 }
401
402 iterator operator++()
403 {
404 if( bFinished == false )
405 nPos = hsh.getNextPos( nPos, bFinished );
406
407 return *this;
408 }
409
410 bool operator==( const iterator &oth )
411 {
412 if( bFinished != oth.bFinished )
413 return false;
414 if( bFinished == true )
415 {
416 return true;
417 }
418 else
419 {
420 if( oth.nPos == nPos )
421 return true;
422 return false;
423 }
424 }
425
426 bool operator!=( const iterator &oth )
427 {
428 return !(*this == oth );
429 }
430
431 iterator operator=( const iterator &oth )
432 {
433 if( &hsh != &oth.hsh )
434 throw HashException(
435 "Cannot mix iterators from different hash objects.");
436 nPos = oth.nPos;
437 bFinished = oth.bFinished;
438 }
439
440 std::pair<key,value> operator *()
441 {
442 return hsh.getAtPos( nPos );
443 }
444
445 key &getKey()
446 {
447 return hsh.getKeyAtPos( nPos );
448 }
449
450 value &getValue()
451 {
452 return hsh.getValueAtPos( nPos );
453 }
454 };
455
456 iterator begin()
457 {
458 return iterator( *this );
459 }
460
461 iterator end()
462 {
463 return iterator( *this, true );
464 }
465
466 std::list<key> getKeys()
467 {
468 std::list<key> lKeys;
469
470 for( uint32_t j = 0; j < nCapacity; j++ )
471 {
472 if( isFilled( j ) )
473 {
474 if( !isDeleted( j ) )
475 {
476 lKeys.push_back( aKeys[j] );
477 }
478 }
479 }
480
481 return lKeys;
482 }
483
484 protected:
485 virtual void onInsert() {}
486 virtual void onUpdate() {}
487 virtual void onDelete() {}
488 virtual void onReHash() {}
489
490 virtual void clearBits()
491 {
492 for( uint32_t j = 0; j < nKeysSize; j++ )
493 {
494 bFilled[j] = bDeleted[j] = 0;
495 }
496 }
497
498 virtual void fill( uint32_t loc, key &k, value &v, uint32_t hash )
499 {
500 bFilled[loc/32] |= (1<<(loc%32));
501 va.construct( &aValues[loc], v );
502 ka.construct( &aKeys[loc], k );
503 aHashCodes[loc] = hash;
504 nFilled++;
505 //printf("Filled: %d, Deleted: %d, Capacity: %d\n",
506 // nFilled, nDeleted, nCapacity );
507 }
508
509 virtual void _erase( uint32_t loc )
510 {
511 bDeleted[loc/32] |= (1<<(loc%32));
512 va.destroy( &aValues[loc] );
513 ka.destroy( &aKeys[loc] );
514 nDeleted++;
515 //printf("Filled: %d, Deleted: %d, Capacity: %d\n",
516 // nFilled, nDeleted, nCapacity );
517 }
518
519 virtual std::pair<key,value> getAtPos( uint32_t nPos )
520 {
521 return std::pair<key,value>(aKeys[nPos],aValues[nPos]);
522 }
523
524 virtual key &getKeyAtPos( uint32_t nPos )
525 {
526 return aKeys[nPos];
527 }
528
529 virtual value &getValueAtPos( uint32_t nPos )
530 {
531 return aValues[nPos];
532 }
533
534 virtual uint32_t getFirstPos( bool &bFinished )
535 {
536 for( uint32_t j = 0; j < nCapacity; j++ )
537 {
538 if( isFilled( j ) )
539 if( !isDeleted( j ) )
540 return j;
541 }
542
543 bFinished = true;
544 return 0;
545 }
546
547 virtual uint32_t getNextPos( uint32_t nPos, bool &bFinished )
548 {
549 for( uint32_t j = nPos+1; j < nCapacity; j++ )
550 {
551 if( isFilled( j ) )
552 if( !isDeleted( j ) )
553 return j;
554 }
555
556 bFinished = true;
557 return 0;
558 }
559
560 uint32_t probe( uint32_t hash, key k, bool &bFill, bool rehash=true )
561 {
562 uint32_t nCur = hash%nCapacity;
563
564 // First we scan to see if the key is already there, abort if we
565 // run out of probing room, or we find a non-filled entry
566 for( int8_t j = 0;
567 isFilled( nCur ) && j < 32;
568 nCur = (nCur + (1<<j))%nCapacity, j++
569 )
570 {
571 // Is this the same hash code we were looking for?
572 if( hash == aHashCodes[nCur] )
573 {
574 // Skip over deleted entries. Deleted entries are also filled,
575 // so we only have to do this check here.
576 if( isDeleted( nCur ) )
577 continue;
578
579 // Is it really the same key? (for safety)
580 if( __cmpHashKeys( aKeys[nCur], k ) == true )
581 {
582 bFill = true;
583 return nCur;
584 }
585 }
586 }
587
588 // This is our insurance, if the table is full, then go ahead and
589 // rehash, then try again.
590 if( isFilled( nCur ) && rehash == true )
591 {
592 reHash( szCalc(getCapacity(), getFill(), getDeleted()) );
593
594 // This is potentially dangerous, and could cause an infinite loop.
595 // Be careful writing probe, eh?
596 return probe( hash, k, bFill );
597 }
598
599 bFill = false;
600 return nCur;
601 }
602
603 void reHash( uint32_t nNewSize )
604 {
605 //printf("---REHASH---");
606 //printf("Filled: %d, Deleted: %d, Capacity: %d\n",
607 // nFilled, nDeleted, nCapacity );
608
609 // Save all the old data
610 uint32_t nOldCapacity = nCapacity;
611 uint32_t *bOldFilled = bFilled;
612 uint32_t *aOldHashCodes = aHashCodes;
613 uint32_t nOldKeysSize = nKeysSize;
614 uint32_t *bOldDeleted = bDeleted;
615 value *aOldValues = aValues;
616 key *aOldKeys = aKeys;
617
618 // Calculate new sizes
619 nCapacity = nNewSize;
620 nKeysSize = bitsToBytes( nCapacity );
621
622 // Allocate new memory + prep
623 bFilled = ca.allocate( nKeysSize );
624 bDeleted = ca.allocate( nKeysSize );
625 clearBits();
626
627 aHashCodes = ca.allocate( nCapacity );
628 aKeys = ka.allocate( nCapacity );
629 aValues = va.allocate( nCapacity );
630
631 nDeleted = nFilled = 0;
632
633 // Re-insert all of the old data (except deleted items)
634 for( uint32_t j = 0; j < nOldCapacity; j++ )
635 {
636 if( (bOldFilled[j/32]&(1<<(j%32)))!=0 &&
637 (bOldDeleted[j/32]&(1<<(j%32)))==0 )
638 {
639 insert( aOldKeys[j], aOldValues[j] );
640 }
641 }
642
643 // Delete all of the old data
644 for( uint32_t j = 0; j < nOldCapacity; j++ )
645 {
646 if( (bOldFilled[j/32]&(1<<(j%32)))!=0 )
647 {
648 va.destroy( &aOldValues[j] );
649 ka.destroy( &aOldKeys[j] );
650 }
651 }
652 va.deallocate( aOldValues, nOldCapacity );
653 ka.deallocate( aOldKeys, nOldCapacity );
654 ca.deallocate( bOldFilled, nOldKeysSize );
655 ca.deallocate( bOldDeleted, nOldKeysSize );
656 ca.deallocate( aOldHashCodes, nOldCapacity );
657 }
658
659 virtual bool isFilled( uint32_t loc ) const
660 {
661 return (bFilled[loc/32]&(1<<(loc%32)))!=0;
662 }
663
664 virtual bool isDeleted( uint32_t loc )
665 {
666 return (bDeleted[loc/32]&(1<<(loc%32)))!=0;
667 }
668
669 protected:
670 uint32_t nCapacity;
671 uint32_t nFilled;
672 uint32_t nDeleted;
673 uint32_t *bFilled;
674 uint32_t *bDeleted;
675 uint32_t nKeysSize;
676 key *aKeys;
677 value *aValues;
678 uint32_t *aHashCodes;
679 valuealloc va;
680 keyalloc ka;
681 challoc ca;
682 sizecalc szCalc;
683 };
684
685 template<> uint32_t __calcHashCode<int>( const int &k );
686 template<> bool __cmpHashKeys<int>( const int &a, const int &b );
687
688 template<> uint32_t __calcHashCode<unsigned int>( const unsigned int &k );
689 template<> bool __cmpHashKeys<unsigned int>( const unsigned int &a, const unsigned int &b );
690
691 template<> uint32_t __calcHashCode<const char *>( const char * const &k );
692 template<> bool __cmpHashKeys<const char *>( const char * const &a, const char * const &b );
693
694 template<> uint32_t __calcHashCode<char *>( char * const &k );
695 template<> bool __cmpHashKeys<char *>( char * const &a, char * const &b );
696
697 template<> uint32_t __calcHashCode<std::string>( const std::string &k );
698 template<> bool __cmpHashKeys<std::string>( const std::string &a, const std::string &b );
699
700 template<typename key, typename value>
701 Archive &operator<<( Archive &ar, Hash<key,value> &h )
702 {
703 ar << h.size();
704 for( typename Hash<key,value>::iterator i = h.begin(); i != h.end(); i++ )
705 {
706 std::pair<key,value> p = *i;
707 ar << p.first << p.second;
708 }
709
710 return ar;
711 }
712
713 template<typename key, typename value>
714 Archive &operator>>( Archive &ar, Hash<key,value> &h )
715 {
716 h.clear();
717 uint32_t nSize;
718 ar >> nSize;
719
720 for( uint32_t j = 0; j < nSize; j++ )
721 {
722 key k; value v;
723 ar >> k >> v;
724 h.insert( k, v );
725 }
726
727 return ar;
728 }
729
730 /*
731 template<typename key, typename value>
732 Serializer &operator&&( Serializer &ar, Hash<key,value> &h )
733 {
734 if( ar.isLoading() )
735 {
736 return ar >> h;
737 }
738 else
739 {
740 return ar << h;
741 }
742 }*/
743}
744
745#endif
diff --git a/src/old/exceptionbase.h b/src/old/exceptionbase.h
deleted file mode 100644
index 6f1eca7..0000000
--- a/src/old/exceptionbase.h
+++ /dev/null
@@ -1,105 +0,0 @@
1#ifndef EXCEPTION_BASE_H
2#define EXCEPTION_BASE_H
3
4#include <string>
5#include <exception>
6#include <stdarg.h>
7
8/**
9 * A generalized Exception base class. This is nice for making general and
10 * flexible child classes that can create new error code classes.
11 */
12class ExceptionBase : public std::exception
13{
14public:
15 /**
16 * Construct an exception with an error code of zero, but with a
17 * description. The use of this is not reccomended most of the time, it's
18 * generally best to include an error code with the exception so your
19 * program can handle the exception in a better way.
20 * @param sFormat The format of the text. See printf for more info.
21 */
22 ExceptionBase( const char *sFormat, ... ) throw();
23
24 /**
25 *
26 * @param nCode
27 * @param sFormat
28 */
29 ExceptionBase( int nCode, const char *sFormat, ... ) throw();
30
31 /**
32 *
33 * @param nCode
34 * @return
35 */
36 ExceptionBase( int nCode=0 ) throw();
37
38 /**
39 *
40 * @return
41 */
42 virtual ~ExceptionBase() throw();
43
44 /**
45 *
46 * @return
47 */
48 virtual const char *what() const throw();
49
50 /**
51 *
52 * @return
53 */
54 int getErrorCode();
55
56 /**
57 *
58 * @param lpFormat
59 * @param vargs
60 */
61 void setWhat( const char *lpFormat, va_list &vargs );
62
63 /**
64 *
65 * @param lpText
66 */
67 void setWhat( const char *lpText );
68
69private:
70 int nErrorCode; /**< The code for the error that occured. */
71 char *sWhat; /**< The text string telling people what went wrong. */
72};
73
74#define subExceptionDecl( name ) \
75class name : public ExceptionBase \
76{ \
77 public: \
78 name( const char *sFormat, ... ) throw (); \
79 name( int nCode, const char *sFormat, ... ) throw(); \
80 name( int nCode=0 ) throw (); \
81};
82
83#define subExceptionDef( name ) \
84name::name( const char *lpFormat, ... ) throw() : \
85 ExceptionBase( 0 ) \
86{ \
87 va_list ap; \
88 va_start( ap, lpFormat ); \
89 setWhat( lpFormat, ap ); \
90 va_end( ap ); \
91} \
92name::name( int nCode, const char *lpFormat, ... ) throw() : \
93 ExceptionBase( nCode ) \
94{ \
95 va_list ap; \
96 va_start( ap, lpFormat ); \
97 setWhat( lpFormat, ap ); \
98 va_end( ap ); \
99} \
100name::name( int nCode ) throw() : \
101 ExceptionBase( nCode ) \
102{ \
103}
104
105#endif
diff --git a/src/old/exceptions.cpp b/src/old/exceptions.cpp
deleted file mode 100644
index ce79a5e..0000000
--- a/src/old/exceptions.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
1#include "exceptions.h"
2#include <stdarg.h>
3
4subExceptionDef( XmlException )
5subExceptionDef( FileException )
6subExceptionDef( ConnectionException )
7subExceptionDef( PluginException )
8
diff --git a/src/old/exceptions.h b/src/old/exceptions.h
deleted file mode 100644
index 0ab2b15..0000000
--- a/src/old/exceptions.h
+++ /dev/null
@@ -1,25 +0,0 @@
1#ifndef EXCEPTIONS_H
2#define EXCEPTIONS_H
3
4#include "exceptionbase.h"
5#include <stdarg.h>
6
7subExceptionDecl( XmlException )
8subExceptionDecl( FileException )
9subExceptionDecl( ConnectionException )
10subExceptionDecl( PluginException )
11
12enum eFileException
13{
14 excodeEOF
15};
16
17enum eConnectionException
18{
19 excodeReadError,
20 excodeBadReadError,
21 excodeConnectionClosed,
22 excodeSocketTimeout
23};
24
25#endif
diff --git a/src/old/fstring.cpp b/src/old/fstring.cpp
deleted file mode 100644
index 82d024d..0000000
--- a/src/old/fstring.cpp
+++ /dev/null
@@ -1,13 +0,0 @@
1#include "fstring.h"
2#include "hash.h"
3
4template<> uint32_t __calcHashCode<FString>( const FString &k )
5{
6 return __calcHashCode( k.c_str() );
7}
8
9template<> bool __cmpHashKeys<FString>( const FString &a, const FString &b )
10{
11 return a == b;
12}
13
diff --git a/src/old/fstring.h b/src/old/fstring.h
deleted file mode 100644
index c5397cc..0000000
--- a/src/old/fstring.h
+++ /dev/null
@@ -1,651 +0,0 @@
1#ifndef F_STRING_H
2#define F_STRING_H
3
4#include <stdint.h>
5#include <memory>
6#include "serializable.h"
7#include "serializer.h"
8
9template< typename chr >
10struct FStringChunk
11{
12 long nLength;
13 chr *pData;
14 FStringChunk *pNext;
15};
16
17/**
18 * Flexible String class. This class was designed with string passing and
19 * generation in mind. Like the standard string class you can specify what
20 * datatype to use for each character. Unlike the standard string class,
21 * collection of appended and prepended terms is done lazily, making long
22 * operations that involve many appends very inexpensive. In addition internal
23 * ref-counting means that if you pass strings around between functions there's
24 * almost no overhead in time or memory since a reference is created and no
25 * data is actually copied. This also means that you never need to put any
26 * FBasicString into a ref-counting container class.
27 */
28template< typename chr, typename chralloc=std::allocator<chr>, typename chunkalloc=std::allocator<struct FStringChunk<chr> > >
29class FBasicString : public Serializable
30{
31#ifndef VALTEST
32#define cpy( dest, src, size ) memcpy( dest, src, size*sizeof(chr) )
33#endif
34private:
35 typedef struct FStringChunk<chr> Chunk;
36 typedef struct FBasicString<chr, chralloc, chunkalloc> MyType;
37
38public:
39 FBasicString() :
40 nLength( 0 ),
41 pnRefs( NULL ),
42 pFirst( NULL ),
43 pLast( NULL )
44 {
45 }
46
47 FBasicString( const chr *pData ) :
48 nLength( 0 ),
49 pnRefs( NULL ),
50 pFirst( NULL ),
51 pLast( NULL )
52 {
53 append( pData );
54 }
55
56 FBasicString( const chr *pData, long nLength ) :
57 nLength( 0 ),
58 pnRefs( NULL ),
59 pFirst( NULL ),
60 pLast( NULL )
61 {
62 append( pData, nLength );
63 }
64
65 FBasicString( const MyType &rSrc ) :
66 nLength( 0 ),
67 pnRefs( NULL ),
68 pFirst( NULL ),
69 pLast( NULL )
70 {
71 // Here we have no choice but to copy, since the other guy is a const.
72 // In the case that the source were flat, we could get a reference, it
73 // would make some things faster, but not matter in many other cases.
74
75 joinShare( rSrc );
76 //copyFrom( rSrc );
77 }
78
79 FBasicString( const MyType &rSrc, long nLength ) :
80 nLength( 0 ),
81 pnRefs( NULL ),
82 pFirst( NULL ),
83 pLast( NULL )
84 {
85 append( rSrc.pFirst->pData, nLength );
86 }
87
88 FBasicString( const MyType &rSrc, long nStart, long nLength ) :
89 nLength( 0 ),
90 pnRefs( NULL ),
91 pFirst( NULL ),
92 pLast( NULL )
93 {
94 append( rSrc.pFirst->pData+nStart, nLength );
95 }
96
97 FBasicString( long nSize ) :
98 nLength( nSize ),
99 pnRefs( NULL ),
100 pFirst( NULL ),
101 pLast( NULL )
102 {
103 pFirst = pLast = newChunk( nSize );
104 }
105
106 virtual ~FBasicString()
107 {
108 clear();
109 }
110
111 void append( const chr *pData )
112 {
113 long nLen;
114 for( nLen = 0; pData[nLen] != (chr)0; nLen++ );
115
116 Chunk *pNew = newChunk( nLen );
117 cpy( pNew->pData, pData, nLen );
118
119 appendChunk( pNew );
120 }
121
122 void append( const chr *pData, long nLen )
123 {
124 Chunk *pNew = newChunk( nLen );
125
126 cpy( pNew->pData, pData, nLen );
127
128 appendChunk( pNew );
129 }
130
131 void prepend( const chr *pData )
132 {
133 long nLen;
134 for( nLen = 0; pData[nLen] != (chr)0; nLen++ );
135
136 Chunk *pNew = newChunk( nLen );
137 cpy( pNew->pData, pData, nLen );
138
139 prependChunk( pNew );
140 }
141
142 void prepend( const chr *pData, long nLen )
143 {
144 Chunk *pNew = newChunk( nLen );
145
146 cpy( pNew->pData, pData, nLen );
147
148 prependChunk( pNew );
149 }
150
151 void clear()
152 {
153 realClear();
154 }
155
156 void resize( long nNewSize )
157 {
158 if( nLength == nNewSize )
159 return;
160
161 flatten();
162
163 Chunk *pNew = newChunk( nNewSize );
164 long nNewLen = (nNewSize<nLength)?(nNewSize):(nLength);
165 cpy( pNew->pData, pFirst->pData, nNewLen );
166 pNew->pData[nNewLen] = (chr)0;
167 aChr.deallocate( pFirst->pData, pFirst->nLength+1 );
168 aChunk.deallocate( pFirst, 1 );
169 pFirst = pLast = pNew;
170 nLength = nNewSize;
171 }
172
173 long getSize() const
174 {
175 return nLength;
176 }
177
178 chr *getStr()
179 {
180 if( pFirst == NULL )
181 return NULL;
182
183 flatten();
184 return pFirst->pData;
185 }
186
187 const chr *getStr() const
188 {
189 if( pFirst == NULL )
190 return NULL;
191
192 flatten();
193 return pFirst->pData;
194 }
195
196 chr *c_str()
197 {
198 if( pFirst == NULL )
199 return NULL;
200
201 flatten();
202 return pFirst->pData;
203 }
204
205 const chr *c_str() const
206 {
207 if( pFirst == NULL )
208 return NULL;
209
210 flatten();
211 return pFirst->pData;
212 }
213
214 MyType &operator +=( const chr *pData )
215 {
216 append( pData );
217
218 return (*this);
219 }
220
221 MyType &operator +=( const MyType &rSrc )
222 {
223 rSrc.flatten();
224 append( rSrc.pFirst->pData, rSrc.nLength );
225
226 return (*this);
227 }
228
229 MyType &operator +=( const chr pData )
230 {
231 chr tmp[2] = { pData, (chr)0 };
232 append( tmp );
233
234 return (*this);
235 }
236
237 MyType &operator =( const chr *pData )
238 {
239 clear();
240 append( pData );
241
242 return (*this);
243 }
244
245 MyType &operator =( const MyType &rSrc )
246 {
247 //if( rSrc.isFlat() )
248 //{
249 joinShare( rSrc );
250 //}
251 //else
252 //{
253 // copyFrom( rSrc );
254 //}
255 //
256
257 return (*this);
258 }
259
260 bool operator ==( const chr *pData ) const
261 {
262 if( pFirst == NULL ) {
263 if( pData == NULL )
264 return true;
265 return false;
266 }
267
268 flatten();
269 const chr *a = pData;
270 chr *b = pFirst->pData;
271 for( ; *a!=(chr)0; a++, b++ )
272 {
273 if( *a != *b )
274 return false;
275 }
276
277 return true;
278 }
279
280 bool operator ==( const MyType &pData ) const
281 {
282 if( pFirst == pData.pFirst )
283 return true;
284 if( pFirst == NULL )
285 return false;
286
287 flatten();
288 pData.flatten();
289 const chr *a = pData.pFirst->pData;
290 chr *b = pFirst->pData;
291 for( ; *a!=(chr)0; a++, b++ )
292 {
293 if( *a != *b )
294 return false;
295 }
296
297 return true;
298 }
299
300 bool operator !=(const chr *pData ) const
301 {
302 return !(*this == pData);
303 }
304
305 bool operator !=(const MyType &pData ) const
306 {
307 return !(*this == pData);
308 }
309
310 chr &operator[]( long nIndex )
311 {
312 flatten();
313
314 return pFirst->pData[nIndex];
315 }
316
317 const chr &operator[]( long nIndex ) const
318 {
319 flatten();
320
321 return pFirst->pData[nIndex];
322 }
323
324 bool isWS( long nIndex ) const
325 {
326 flatten();
327
328 return pFirst->pData[nIndex]==' ' || pFirst->pData[nIndex]=='\t'
329 || pFirst->pData[nIndex]=='\r' || pFirst->pData[nIndex]=='\n';
330 }
331
332 bool isAlpha( long nIndex ) const
333 {
334 flatten();
335
336 return (pFirst->pData[nIndex] >= 'a' && pFirst->pData[nIndex] <= 'z')
337 || (pFirst->pData[nIndex] >= 'A' && pFirst->pData[nIndex] <= 'Z');
338 }
339
340 void toLower()
341 {
342 flatten();
343 unShare();
344
345 for( long j = 0; j < nLength; j++ )
346 {
347 if( pFirst->pData[j] >= 'A' && pFirst->pData[j] <= 'Z' )
348 pFirst->pData[j] -= 'A'-'a';
349 }
350 }
351
352 void toUpper()
353 {
354 flatten();
355 unShare();
356
357 for( long j = 0; j < nLength; j++ )
358 {
359 if( pFirst->pData[j] >= 'a' && pFirst->pData[j] <= 'z' )
360 pFirst->pData[j] += 'A'-'a';
361 }
362 }
363
364 void serialize( class Serializer &ar )
365 {
366 if( ar.isLoading() )
367 {
368 clear();
369 long nLen;
370 ar >> nLen;
371
372 Chunk *pNew = newChunk( nLen );
373 ar.read( pNew->pData, nLen*sizeof(chr) );
374 appendChunk( pNew );
375 }
376 else
377 {
378 flatten();
379
380 ar << nLength;
381 ar.write( pFirst->pData, nLength*sizeof(chr) );
382 }
383 }
384
385private:
386 void flatten() const
387 {
388 if( isFlat() )
389 return;
390
391 if( pFirst == NULL )
392 return;
393
394 unShare();
395
396 Chunk *pNew = newChunk( nLength );
397 chr *pos = pNew->pData;
398 Chunk *i = pFirst;
399 for(;;)
400 {
401 cpy( pos, i->pData, i->nLength );
402 pos += i->nLength;
403 i = i->pNext;
404 if( i == NULL )
405 break;
406 }
407 realClear();
408
409 pLast = pFirst = pNew;
410 nLength = pNew->nLength;
411 }
412
413 void realClear() const
414 {
415 if( pFirst == NULL )
416 return;
417
418 if( isShared() )
419 {
420 decRefs();
421 }
422 else
423 {
424 Chunk *i = pFirst;
425 for(;;)
426 {
427 Chunk *n = i->pNext;
428 aChr.deallocate( i->pData, i->nLength+1 );
429 aChunk.deallocate( i, 1 );
430 if( n == NULL )
431 break;
432 i = n;
433 }
434 pFirst = pLast = NULL;
435 nLength = 0;
436 }
437 }
438
439 void copyFrom( const FBasicString<chr, chralloc, chunkalloc> &rSrc )
440 {
441 if( rSrc.pFirst == NULL )
442 return;
443
444 decRefs();
445
446 Chunk *pNew = newChunk( rSrc.nLength );
447 chr *pos = pNew->pData;
448 Chunk *i = rSrc.pFirst;
449 for(;;)
450 {
451 cpy( pos, i->pData, i->nLength );
452 pos += i->nLength;
453 i = i->pNext;
454 if( i == NULL )
455 break;
456 }
457 clear();
458
459 appendChunk( pNew );
460 }
461
462 bool isFlat() const
463 {
464 return (pFirst == pLast);
465 }
466
467 bool isShared() const
468 {
469 return (pnRefs != NULL);
470 }
471
472 Chunk *newChunk() const
473 {
474 Chunk *pNew = aChunk.allocate( 1 );
475 pNew->pNext = NULL;
476 return pNew;
477 }
478
479 Chunk *newChunk( long nLen ) const
480 {
481 Chunk *pNew = aChunk.allocate( 1 );
482 pNew->pNext = NULL;
483 pNew->nLength = nLen;
484 pNew->pData = aChr.allocate( nLen+1 );
485 pNew->pData[nLen] = (chr)0;
486 return pNew;
487 }
488
489 void appendChunk( Chunk *pNewChunk )
490 {
491 unShare();
492
493 if( pFirst == NULL )
494 pLast = pFirst = pNewChunk;
495 else
496 {
497 pLast->pNext = pNewChunk;
498 pLast = pNewChunk;
499 }
500
501 nLength += pNewChunk->nLength;
502 }
503
504 void prependChunk( Chunk *pNewChunk )
505 {
506 unShare();
507
508 if( pFirst == NULL )
509 pLast = pFirst = pNewChunk;
510 else
511 {
512 pNewChunk->pNext = pFirst;
513 pFirst = pNewChunk;
514 }
515
516 nLength += pNewChunk->nLength;
517 }
518
519 void joinShare( MyType &rSrc )
520 {
521 clear();
522
523 if( !rSrc.isFlat() )
524 rSrc.flatten();
525
526 rSrc.initCount();
527 pnRefs = rSrc.pnRefs;
528 (*pnRefs)++;
529 nLength = rSrc.nLength;
530 pFirst = rSrc.pFirst;
531 pLast = rSrc.pLast;
532 }
533
534 void joinShare( const MyType &rSrc )
535 {
536 clear();
537
538 rSrc.flatten();
539
540 if( !rSrc.isShared() )
541 {
542 rSrc.pnRefs = new uint32_t;
543 (*rSrc.pnRefs) = 1;
544 }
545 pnRefs = rSrc.pnRefs;
546 (*pnRefs)++;
547 nLength = rSrc.nLength;
548 pFirst = rSrc.pFirst;
549 pLast = rSrc.pLast;
550 }
551
552 /**
553 * This takes an object that was shared and makes a copy of the base data
554 * that was being shared so that this copy can be changed. This should be
555 * added before any call that will change this object;
556 */
557 void unShare() const
558 {
559 if( isShared() == false )
560 return;
561
562 Chunk *pNew = newChunk( nLength );
563 chr *pos = pNew->pData;
564 Chunk *i = pFirst;
565 for(;;)
566 {
567 cpy( pos, i->pData, i->nLength );
568 pos += i->nLength;
569 i = i->pNext;
570 if( i == NULL )
571 break;
572 }
573 decRefs();
574 pLast = pFirst = pNew;
575 nLength = pNew->nLength;
576 }
577
578 /**
579 * This decrements our ref count and pulls us out of the share. If the ref
580 * count hits zero because of this, it destroys the share. This is not
581 * safe to call on it's own, it's much better to call unShare.
582 */
583 void decRefs() const
584 {
585 if( isShared() )
586 {
587 (*pnRefs)--;
588 if( (*pnRefs) == 0 )
589 destroyShare();
590 else
591 {
592 pnRefs = NULL;
593 pFirst = NULL;
594 pLast = NULL;
595 nLength = 0;
596 }
597 }
598 }
599
600 /**
601 * While the unShare function removes an instance from a share, this
602 * function destroys the data that was in the share, removing the share
603 * itself. This should only be called when the refcount for the share has
604 * or is about to reach zero.
605 */
606 void destroyShare() const
607 {
608 delete pnRefs;
609 pnRefs = NULL;
610 realClear();
611 }
612
613#ifdef VALTEST
614 void cpy( chr *dest, const chr *src, long count ) const
615 {
616 for( int j = 0; j < count; j++ )
617 {
618 *dest = *src;
619 dest++;
620 src++;
621 }
622 }
623#endif
624
625 void initCount() const
626 {
627 if( !isShared() )
628 {
629 pnRefs = new uint32_t;
630 (*pnRefs) = 1;
631 }
632 }
633
634private:
635 mutable long nLength;
636 mutable uint32_t *pnRefs;
637 mutable Chunk *pFirst;
638 mutable Chunk *pLast;
639
640 mutable chralloc aChr;
641 mutable chunkalloc aChunk;
642};
643
644typedef FBasicString<char> FString;
645
646#include "hash.h"
647template<> uint32_t __calcHashCode<FString>( const FString &k );
648template<> bool __cmpHashKeys<FString>( const FString &a, const FString &b );
649
650
651#endif
diff --git a/src/old/hash.cpp b/src/old/hash.cpp
deleted file mode 100644
index c52e6b1..0000000
--- a/src/old/hash.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
1#include "hash.h"
2
3subExceptionDef( HashException )
4
5template<> uint32_t __calcHashCode<int>( const int &k )
6{
7 return k;
8}
9
10template<> bool __cmpHashKeys<int>( const int &a, const int &b )
11{
12 return a == b;
13}
14
15template<> uint32_t __calcHashCode<unsigned int>( const unsigned int &k )
16{
17 return k;
18}
19
20template<> bool __cmpHashKeys<unsigned int>( const unsigned int &a, const unsigned int &b )
21{
22 return a == b;
23}
24
25template<>
26uint32_t __calcHashCode<const char *>( const char * const &k )
27{
28 if (k == NULL)
29 {
30 return 0;
31 }
32
33 unsigned long int nPos = 0;
34 for( const char *s = k; *s; s++ )
35 {
36 nPos = *s + (nPos << 6) + (nPos << 16) - nPos;
37 }
38
39 return nPos;
40}
41
42template<> bool __cmpHashKeys<const char *>( const char * const &a, const char * const &b )
43{
44 if( a == b )
45 return true;
46
47 for(int j=0; a[j] == b[j]; j++ )
48 if( a[j] == '\0' )
49 return true;
50
51 return false;
52}
53
54template<>
55uint32_t __calcHashCode<char *>( char * const &k )
56{
57 if (k == NULL)
58 {
59 return 0;
60 }
61
62 unsigned long int nPos = 0;
63 for( const char *s = k; *s; s++ )
64 {
65 nPos = *s + (nPos << 6) + (nPos << 16) - nPos;
66 }
67
68 return nPos;
69}
70
71template<> bool __cmpHashKeys<char *>( char * const &a, char * const &b )
72{
73 if( a == b )
74 return true;
75
76 for(int j=0; a[j] == b[j]; j++ )
77 if( a[j] == '\0' )
78 return true;
79
80 return false;
81}
82
83template<> uint32_t __calcHashCode<std::string>( const std::string &k )
84{
85 std::string::size_type j, sz = k.size();
86 const char *s = k.c_str();
87
88 unsigned long int nPos = 0;
89 for( j = 0; j < sz; j++, s++ )
90 {
91 nPos = *s + (nPos << 6) + (nPos << 16) - nPos;
92 }
93
94 return nPos;
95}
96
97template<> bool __cmpHashKeys<std::string>( const std::string &a, const std::string &b )
98{
99 return a == b;
100}
101
102template<> uint32_t __calcHashCode<Hashable>( const Hashable &k )
103{
104 return 0;
105 //return k.getHashCode();
106}
107
108template<> bool __cmpHashKeys<Hashable>( const Hashable &a, const Hashable &b )
109{
110 return false;
111 //return a.compareForHash( b );
112}
113
diff --git a/src/old/hash.h b/src/old/hash.h
deleted file mode 100644
index e819379..0000000
--- a/src/old/hash.h
+++ /dev/null
@@ -1,744 +0,0 @@
1#ifndef HASH_H
2#define HASH_H
3
4#include <stddef.h>
5#include <string.h>
6#include <memory>
7#include <iostream>
8#include <list>
9#include "exceptionbase.h"
10#include "hashable.h"
11#include "serializable.h"
12#include "serializer.h"
13
14#define bitsToBytes( n ) (n/32+(n%32>0 ? 1 : 0))
15
16subExceptionDecl( HashException )
17
18enum eHashException
19{
20 excodeNotFilled
21};
22
23template<typename T>
24uint32_t __calcHashCode( const T &k );
25
26template<typename T>
27bool __cmpHashKeys( const T &a, const T &b );
28
29struct __calcNextTSize_fast
30{
31 uint32_t operator()( uint32_t nCapacity, uint32_t nFill, uint32_t nDeleted ) const
32 {
33 if( nDeleted >= nCapacity/2 )
34 return nCapacity;
35 return nCapacity*2+1;
36 }
37};
38
39template<typename key, typename value, typename sizecalc = __calcNextTSize_fast, typename keyalloc = std::allocator<key>, typename valuealloc = std::allocator<value>, typename challoc = std::allocator<uint32_t> >
40class Hash;
41
42template< typename key, typename _value, typename sizecalc = __calcNextTSize_fast, typename keyalloc = std::allocator<key>, typename valuealloc = std::allocator<_value>, typename challoc = std::allocator<uint32_t> >
43struct HashProxy
44{
45 friend class Hash<key, _value, sizecalc, keyalloc, valuealloc, challoc>;
46private:
47 HashProxy( Hash<key, _value, sizecalc, keyalloc, valuealloc, challoc> &h, key *k, uint32_t nPos, uint32_t hash ) :
48 hsh( h ),
49 pKey( k ),
50 nPos( nPos ),
51 hash( hash ),
52 bFilled( false )
53 {
54 }
55
56 HashProxy( Hash<key, _value, sizecalc, keyalloc, valuealloc, challoc> &h, uint32_t nPos, _value *pValue ) :
57 hsh( h ),
58 nPos( nPos ),
59 pValue( pValue ),
60 bFilled( true )
61 {
62 }
63
64 Hash<key, _value, sizecalc, keyalloc, valuealloc, challoc> &hsh;
65 key *pKey;
66 uint32_t nPos;
67 _value *pValue;
68 uint32_t hash;
69 bool bFilled;
70
71public:
72 operator _value &()
73 {
74 if( bFilled == false )
75 throw HashException(
76 excodeNotFilled,
77 "No data assosiated with that key."
78 );
79 return *pValue;
80 }
81
82 _value &value()
83 {
84 if( bFilled == false )
85 throw HashException(
86 excodeNotFilled,
87 "No data assosiated with that key."
88 );
89 return *pValue;
90 }
91
92 bool isFilled()
93 {
94 return bFilled;
95 }
96
97 void erase()
98 {
99 if( bFilled )
100 {
101 hsh._erase( nPos );
102 hsh.onDelete();
103 }
104 }
105
106 _value operator=( _value nval )
107 {
108 if( bFilled )
109 {
110 hsh.va.destroy( pValue );
111 hsh.va.construct( pValue, nval );
112 hsh.onUpdate();
113 }
114 else
115 {
116 hsh.fill( nPos, *pKey, nval, hash );
117 hsh.onInsert();
118 }
119
120 return nval;
121 }
122
123 _value *operator->()
124 {
125 if( bFilled == false )
126 throw HashException(
127 excodeNotFilled,
128 "No data assosiated with that key."
129 );
130 return pValue;
131 }
132};
133
134template<typename key, typename value, typename sizecalc, typename keyalloc, typename valuealloc, typename challoc >
135class Hash
136{
137 friend struct HashProxy<key, value, sizecalc, keyalloc, valuealloc, challoc>;
138public:
139 Hash() :
140 nCapacity( 11 ),
141 nFilled( 0 ),
142 nDeleted( 0 ),
143 bFilled( NULL ),
144 bDeleted( NULL ),
145 aKeys( NULL ),
146 aValues( NULL ),
147 aHashCodes( NULL )
148 {
149 nKeysSize = bitsToBytes( nCapacity );
150 bFilled = ca.allocate( nKeysSize );
151 bDeleted = ca.allocate( nKeysSize );
152 clearBits();
153
154 aHashCodes = ca.allocate( nCapacity );
155 aKeys = ka.allocate( nCapacity );
156 aValues = va.allocate( nCapacity );
157 }
158
159 Hash( const Hash &src ) :
160 nCapacity( src.nCapacity ),
161 nFilled( 0 ),
162 nDeleted( 0 ),
163 bFilled( NULL ),
164 bDeleted( NULL ),
165 aKeys( NULL ),
166 aValues( NULL ),
167 aHashCodes( NULL )
168 {
169 nKeysSize = bitsToBytes( nCapacity );
170 bFilled = ca.allocate( nKeysSize );
171 bDeleted = ca.allocate( nKeysSize );
172 clearBits();
173
174 aHashCodes = ca.allocate( nCapacity );
175 aKeys = ka.allocate( nCapacity );
176 aValues = va.allocate( nCapacity );
177
178 for( uint32_t j = 0; j < src.nCapacity; j++ )
179 {
180 if( src.isFilled( j ) )
181 {
182 insert( src.aKeys[j], src.aValues[j] );
183 }
184 }
185 }
186
187 Hash &operator=( const Hash &src )
188 {
189 for( uint32_t j = 0; j < nCapacity; j++ )
190 {
191 if( isFilled( j ) )
192 if( !isDeleted( j ) )
193 {
194 va.destroy( &aValues[j] );
195 ka.destroy( &aKeys[j] );
196 }
197 }
198 va.deallocate( aValues, nCapacity );
199 ka.deallocate( aKeys, nCapacity );
200 ca.deallocate( bFilled, nKeysSize );
201 ca.deallocate( bDeleted, nKeysSize );
202 ca.deallocate( aHashCodes, nCapacity );
203
204 nFilled = 0;
205 nDeleted = 0;
206 nCapacity = src.nCapacity;
207 nKeysSize = bitsToBytes( nCapacity );
208 bFilled = ca.allocate( nKeysSize );
209 bDeleted = ca.allocate( nKeysSize );
210 clearBits();
211
212 aHashCodes = ca.allocate( nCapacity );
213 aKeys = ka.allocate( nCapacity );
214 aValues = va.allocate( nCapacity );
215
216 for( uint32_t j = 0; j < src.nCapacity; j++ )
217 {
218 if( src.isFilled( j ) )
219 {
220 insert( src.aKeys[j], src.aValues[j] );
221 }
222 }
223
224 return *this;
225 }
226
227 virtual ~Hash()
228 {
229 for( uint32_t j = 0; j < nCapacity; j++ )
230 {
231 if( isFilled( j ) )
232 if( !isDeleted( j ) )
233 {
234 va.destroy( &aValues[j] );
235 ka.destroy( &aKeys[j] );
236 }
237 }
238 va.deallocate( aValues, nCapacity );
239 ka.deallocate( aKeys, nCapacity );
240 ca.deallocate( bFilled, nKeysSize );
241 ca.deallocate( bDeleted, nKeysSize );
242 ca.deallocate( aHashCodes, nCapacity );
243 }
244
245 uint32_t getCapacity()
246 {
247 return nCapacity;
248 }
249
250 uint32_t getFill()
251 {
252 return nFilled;
253 }
254
255 uint32_t size()
256 {
257 return nFilled-nDeleted;
258 }
259
260 uint32_t getDeleted()
261 {
262 return nDeleted;
263 }
264
265 virtual HashProxy<key, value, sizecalc, keyalloc, valuealloc, challoc> operator[]( key k )
266 {
267 uint32_t hash = __calcHashCode( k );
268 bool bFill;
269 uint32_t nPos = probe( hash, k, bFill );
270
271 if( bFill )
272 {
273 return HashProxy<key, value, sizecalc, keyalloc, valuealloc, challoc>( *this, nPos, &aValues[nPos] );
274 }
275 else
276 {
277 return HashProxy<key, value, sizecalc, keyalloc, valuealloc, challoc>( *this, &k, nPos, hash );
278 }
279 }
280
281 virtual void insert( key k, value v )
282 {
283 uint32_t hash = __calcHashCode( k );
284 bool bFill;
285 uint32_t nPos = probe( hash, k, bFill );
286
287 if( bFill )
288 {
289 va.destroy( &aValues[nPos] );
290 va.construct( &aValues[nPos], v );
291 onUpdate();
292 }
293 else
294 {
295 fill( nPos, k, v, hash );
296 onInsert();
297 }
298 }
299
300 virtual void erase( key k )
301 {
302 uint32_t hash = __calcHashCode( k );
303 bool bFill;
304 uint32_t nPos = probe( hash, k, bFill );
305
306 if( bFill )
307 {
308 _erase( nPos );
309 onDelete();
310 }
311 }
312
313 struct iterator;
314 virtual void erase( struct iterator &i )
315 {
316 if( this != &i.hsh )
317 throw HashException("This iterator didn't come from this Hash.");
318 if( isFilled( i.nPos ) && !isDeleted( i.nPos ) )
319 {
320 _erase( i.nPos );
321 onDelete();
322 }
323 }
324
325 virtual void clear()
326 {
327 for( uint32_t j = 0; j < nCapacity; j++ )
328 {
329 if( isFilled( j ) )
330 if( !isDeleted( j ) )
331 {
332 va.destroy( &aValues[j] );
333 ka.destroy( &aKeys[j] );
334 onDelete();
335 }
336 }
337
338 clearBits();
339 }
340
341 virtual value &get( key k )
342 {
343 uint32_t hash = __calcHashCode( k );
344 bool bFill;
345 uint32_t nPos = probe( hash, k, bFill );
346
347 if( bFill )
348 {
349 return aValues[nPos];
350 }
351 else
352 {
353 throw HashException(
354 excodeNotFilled,
355 "No data assosiated with that key."
356 );
357 }
358 }
359
360 virtual bool has( key k )
361 {
362 bool bFill;
363 probe( __calcHashCode( k ), k, bFill, false );
364
365 return bFill;
366 }
367
368 typedef struct iterator
369 {
370 friend class Hash<key, value, sizecalc, keyalloc, valuealloc, challoc>;
371 private:
372 iterator( Hash<key, value, sizecalc, keyalloc, valuealloc, challoc> &hsh ) :
373 hsh( hsh ),
374 nPos( 0 ),
375 bFinished( false )
376 {
377 nPos = hsh.getFirstPos( bFinished );
378 }
379
380 iterator( Hash<key, value, sizecalc, keyalloc, valuealloc, challoc> &hsh, bool bDone ) :
381 hsh( hsh ),
382 nPos( 0 ),
383 bFinished( bDone )
384 {
385 }
386
387 Hash<key, value, sizecalc, keyalloc, valuealloc, challoc> &hsh;
388 uint32_t nPos;
389 bool bFinished;
390
391 public:
392 iterator operator++( int )
393 {
394 if( bFinished == false )
395 nPos = hsh.getNextPos( nPos, bFinished );
396
397 return *this;
398 }
399
400 iterator operator++()
401 {
402 if( bFinished == false )
403 nPos = hsh.getNextPos( nPos, bFinished );
404
405 return *this;
406 }
407
408 bool operator==( const iterator &oth )
409 {
410 if( bFinished != oth.bFinished )
411 return false;
412 if( bFinished == true )
413 {
414 return true;
415 }
416 else
417 {
418 if( oth.nPos == nPos )
419 return true;
420 return false;
421 }
422 }
423
424 bool operator!=( const iterator &oth )
425 {
426 return !(*this == oth );
427 }
428
429 iterator operator=( const iterator &oth )
430 {
431 if( &hsh != &oth.hsh )
432 throw HashException(
433 "Cannot mix iterators from different hash objects.");
434 nPos = oth.nPos;
435 bFinished = oth.bFinished;
436 }
437
438 std::pair<key,value> operator *()
439 {
440 return hsh.getAtPos( nPos );
441 }
442
443 key &getKey()
444 {
445 return hsh.getKeyAtPos( nPos );
446 }
447
448 value &getValue()
449 {
450 return hsh.getValueAtPos( nPos );
451 }
452 };
453
454 iterator begin()
455 {
456 return iterator( *this );
457 }
458
459 iterator end()
460 {
461 return iterator( *this, true );
462 }
463
464 std::list<key> getKeys()
465 {
466 std::list<key> lKeys;
467
468 for( uint32_t j = 0; j < nCapacity; j++ )
469 {
470 if( isFilled( j ) )
471 {
472 if( !isDeleted( j ) )
473 {
474 lKeys.push_back( aKeys[j] );
475 }
476 }
477 }
478
479 return lKeys;
480 }
481
482protected:
483 virtual void onInsert() {}
484 virtual void onUpdate() {}
485 virtual void onDelete() {}
486 virtual void onReHash() {}
487
488 virtual void clearBits()
489 {
490 for( uint32_t j = 0; j < nKeysSize; j++ )
491 {
492 bFilled[j] = bDeleted[j] = 0;
493 }
494 }
495
496 virtual void fill( uint32_t loc, key &k, value &v, uint32_t hash )
497 {
498 bFilled[loc/32] |= (1<<(loc%32));
499 va.construct( &aValues[loc], v );
500 ka.construct( &aKeys[loc], k );
501 aHashCodes[loc] = hash;
502 nFilled++;
503 //printf("Filled: %d, Deleted: %d, Capacity: %d\n",
504 // nFilled, nDeleted, nCapacity );
505 }
506
507 virtual void _erase( uint32_t loc )
508 {
509 bDeleted[loc/32] |= (1<<(loc%32));
510 va.destroy( &aValues[loc] );
511 ka.destroy( &aKeys[loc] );
512 nDeleted++;
513 //printf("Filled: %d, Deleted: %d, Capacity: %d\n",
514 // nFilled, nDeleted, nCapacity );
515 }
516
517 virtual std::pair<key,value> getAtPos( uint32_t nPos )
518 {
519 return std::pair<key,value>(aKeys[nPos],aValues[nPos]);
520 }
521
522 virtual key &getKeyAtPos( uint32_t nPos )
523 {
524 return aKeys[nPos];
525 }
526
527 virtual value &getValueAtPos( uint32_t nPos )
528 {
529 return aValues[nPos];
530 }
531
532 virtual uint32_t getFirstPos( bool &bFinished )
533 {
534 for( uint32_t j = 0; j < nCapacity; j++ )
535 {
536 if( isFilled( j ) )
537 if( !isDeleted( j ) )
538 return j;
539 }
540
541 bFinished = true;
542 return 0;
543 }
544
545 virtual uint32_t getNextPos( uint32_t nPos, bool &bFinished )
546 {
547 for( uint32_t j = nPos+1; j < nCapacity; j++ )
548 {
549 if( isFilled( j ) )
550 if( !isDeleted( j ) )
551 return j;
552 }
553
554 bFinished = true;
555 return 0;
556 }
557
558 uint32_t probe( uint32_t hash, key k, bool &bFill, bool rehash=true )
559 {
560 uint32_t nCur = hash%nCapacity;
561
562 // First we scan to see if the key is already there, abort if we
563 // run out of probing room, or we find a non-filled entry
564 for( int8_t j = 0;
565 isFilled( nCur ) && j < 32;
566 nCur = (nCur + (1<<j))%nCapacity, j++
567 )
568 {
569 // Is this the same hash code we were looking for?
570 if( hash == aHashCodes[nCur] )
571 {
572 // Skip over deleted entries. Deleted entries are also filled,
573 // so we only have to do this check here.
574 if( isDeleted( nCur ) )
575 continue;
576
577 // Is it really the same key? (for safety)
578 if( __cmpHashKeys( aKeys[nCur], k ) == true )
579 {
580 bFill = true;
581 return nCur;
582 }
583 }
584 }
585
586 // This is our insurance, if the table is full, then go ahead and
587 // rehash, then try again.
588 if( isFilled( nCur ) && rehash == true )
589 {
590 reHash( szCalc(getCapacity(), getFill(), getDeleted()) );
591
592 // This is potentially dangerous, and could cause an infinite loop.
593 // Be careful writing probe, eh?
594 return probe( hash, k, bFill );
595 }
596
597 bFill = false;
598 return nCur;
599 }
600
601 void reHash( uint32_t nNewSize )
602 {
603 //printf("---REHASH---");
604 //printf("Filled: %d, Deleted: %d, Capacity: %d\n",
605 // nFilled, nDeleted, nCapacity );
606
607 // Save all the old data
608 uint32_t nOldCapacity = nCapacity;
609 uint32_t *bOldFilled = bFilled;
610 uint32_t *aOldHashCodes = aHashCodes;
611 uint32_t nOldKeysSize = nKeysSize;
612 uint32_t *bOldDeleted = bDeleted;
613 value *aOldValues = aValues;
614 key *aOldKeys = aKeys;
615
616 // Calculate new sizes
617 nCapacity = nNewSize;
618 nKeysSize = bitsToBytes( nCapacity );
619
620 // Allocate new memory + prep
621 bFilled = ca.allocate( nKeysSize );
622 bDeleted = ca.allocate( nKeysSize );
623 clearBits();
624
625 aHashCodes = ca.allocate( nCapacity );
626 aKeys = ka.allocate( nCapacity );
627 aValues = va.allocate( nCapacity );
628
629 nDeleted = nFilled = 0;
630
631 // Re-insert all of the old data (except deleted items)
632 for( uint32_t j = 0; j < nOldCapacity; j++ )
633 {
634 if( (bOldFilled[j/32]&(1<<(j%32)))!=0 &&
635 (bOldDeleted[j/32]&(1<<(j%32)))==0 )
636 {
637 insert( aOldKeys[j], aOldValues[j] );
638 }
639 }
640
641 // Delete all of the old data
642 for( uint32_t j = 0; j < nOldCapacity; j++ )
643 {
644 if( (bOldFilled[j/32]&(1<<(j%32)))!=0 )
645 {
646 va.destroy( &aOldValues[j] );
647 ka.destroy( &aOldKeys[j] );
648 }
649 }
650 va.deallocate( aOldValues, nOldCapacity );
651 ka.deallocate( aOldKeys, nOldCapacity );
652 ca.deallocate( bOldFilled, nOldKeysSize );
653 ca.deallocate( bOldDeleted, nOldKeysSize );
654 ca.deallocate( aOldHashCodes, nOldCapacity );
655 }
656
657 virtual bool isFilled( uint32_t loc ) const
658 {
659 return (bFilled[loc/32]&(1<<(loc%32)))!=0;
660 }
661
662 virtual bool isDeleted( uint32_t loc )
663 {
664 return (bDeleted[loc/32]&(1<<(loc%32)))!=0;
665 }
666
667protected:
668 uint32_t nCapacity;
669 uint32_t nFilled;
670 uint32_t nDeleted;
671 uint32_t *bFilled;
672 uint32_t *bDeleted;
673 uint32_t nKeysSize;
674 key *aKeys;
675 value *aValues;
676 uint32_t *aHashCodes;
677 valuealloc va;
678 keyalloc ka;
679 challoc ca;
680 sizecalc szCalc;
681};
682
683template<> uint32_t __calcHashCode<int>( const int &k );
684template<> bool __cmpHashKeys<int>( const int &a, const int &b );
685
686template<> uint32_t __calcHashCode<unsigned int>( const unsigned int &k );
687template<> bool __cmpHashKeys<unsigned int>( const unsigned int &a, const unsigned int &b );
688
689template<> uint32_t __calcHashCode<const char *>( const char * const &k );
690template<> bool __cmpHashKeys<const char *>( const char * const &a, const char * const &b );
691
692template<> uint32_t __calcHashCode<char *>( char * const &k );
693template<> bool __cmpHashKeys<char *>( char * const &a, char * const &b );
694
695template<> uint32_t __calcHashCode<std::string>( const std::string &k );
696template<> bool __cmpHashKeys<std::string>( const std::string &a, const std::string &b );
697
698template<> uint32_t __calcHashCode<Hashable>( const Hashable &k );
699template<> bool __cmpHashKeys<Hashable>( const Hashable &a, const Hashable &b );
700
701template<typename key, typename value>
702Serializer &operator<<( Serializer &ar, Hash<key,value> &h )
703{
704 ar << h.size();
705 for( typename Hash<key,value>::iterator i = h.begin(); i != h.end(); i++ )
706 {
707 std::pair<key,value> p = *i;
708 ar << p.first << p.second;
709 }
710
711 return ar;
712}
713
714template<typename key, typename value>
715Serializer &operator>>( Serializer &ar, Hash<key,value> &h )
716{
717 h.clear();
718 uint32_t nSize;
719 ar >> nSize;
720
721 for( uint32_t j = 0; j < nSize; j++ )
722 {
723 key k; value v;
724 ar >> k >> v;
725 h.insert( k, v );
726 }
727
728 return ar;
729}
730
731template<typename key, typename value>
732Serializer &operator&&( Serializer &ar, Hash<key,value> &h )
733{
734 if( ar.isLoading() )
735 {
736 return ar >> h;
737 }
738 else
739 {
740 return ar << h;
741 }
742}
743
744#endif
diff --git a/src/old/hashable.cpp b/src/old/hashable.cpp
deleted file mode 100644
index 8565956..0000000
--- a/src/old/hashable.cpp
+++ /dev/null
@@ -1 +0,0 @@
1#include "hashable.h"
diff --git a/src/old/hashable.h b/src/old/hashable.h
deleted file mode 100644
index 98643d5..0000000
--- a/src/old/hashable.h
+++ /dev/null
@@ -1,12 +0,0 @@
1#ifndef HASHABLE_H
2#define HASHABLE_H
3
4class Hashable
5{
6public:
7 virtual ~Hashable() {};
8 virtual unsigned long int getHashCode() = 0;
9 virtual bool compareForHash( Hashable &other ) = 0;
10};
11
12#endif
diff --git a/src/old/serializable.cpp b/src/old/serializable.cpp
deleted file mode 100644
index fd50943..0000000
--- a/src/old/serializable.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
1#include "serializable.h"
2
3Serializable::Serializable()
4{
5}
6Serializable::~Serializable()
7{
8}
diff --git a/src/old/serializable.h b/src/old/serializable.h
deleted file mode 100644
index 06def29..0000000
--- a/src/old/serializable.h
+++ /dev/null
@@ -1,34 +0,0 @@
1#ifndef SERIALIZER_H
2#define SERIALIZER_H
3
4//#include "serializer.h"
5
6/**
7 * The base class for any class you want to serialize. Simply include this as
8 * a base class, implement the purely virtual serialize function and you've got
9 * an easily serializable class.
10 */
11class Serializable
12{
13public:
14 /**
15 * Does nothing, here for completeness.
16 */
17 Serializable();
18
19 /**
20 * Here to ensure the deconstructor is virtual.
21 */
22 virtual ~Serializable();
23
24 /**
25 * This is the main workhorse of the serialization system, just override and
26 * you've got a serializable class. A reference to the Serializer archive
27 * used is passed in as your only parameter, query it to discover if you are
28 * loading or saving.
29 * @param ar A reference to the Serializer object to use.
30 */
31 virtual void serialize( class Serializer &ar )=0;
32};
33
34#endif
diff --git a/src/old/serializer.h b/src/old/serializer.h
deleted file mode 100644
index 3af489c..0000000
--- a/src/old/serializer.h
+++ /dev/null
@@ -1,80 +0,0 @@
1#ifndef SERIALIZABLE_H
2#define SERIALIZABLE_H
3
4#include <stdint.h>
5#include <string>
6#include <list>
7//#include "serializable.h"
8
9class Serializer
10{
11private:
12 bool bLoading;
13public:
14 bool isLoading();
15
16 enum
17 {
18 load = true,
19 save = false
20 };
21
22 Serializer(bool bLoading);
23 virtual ~Serializer();
24 virtual void close()=0;
25
26 virtual void write(const void *, int32_t)=0;
27 virtual void read(void *, int32_t)=0;
28
29 virtual Serializer &operator<<(bool);
30 virtual Serializer &operator<<(int8_t);
31 virtual Serializer &operator<<(int16_t);
32 virtual Serializer &operator<<(int32_t);
33 virtual Serializer &operator<<(int64_t);
34 virtual Serializer &operator<<(uint8_t);
35 virtual Serializer &operator<<(uint16_t);
36 virtual Serializer &operator<<(uint32_t);
37 virtual Serializer &operator<<(uint64_t);
38 virtual Serializer &operator<<(long);
39 virtual Serializer &operator<<(float);
40 virtual Serializer &operator<<(double);
41 virtual Serializer &operator<<(long double);
42
43 virtual Serializer &operator>>(bool &);
44 virtual Serializer &operator>>(int8_t &);
45 virtual Serializer &operator>>(int16_t &);
46 virtual Serializer &operator>>(int32_t &);
47 virtual Serializer &operator>>(int64_t &);
48 virtual Serializer &operator>>(uint8_t &);
49 virtual Serializer &operator>>(uint16_t &);
50 virtual Serializer &operator>>(uint32_t &);
51 virtual Serializer &operator>>(uint64_t &);
52 virtual Serializer &operator>>(long &);
53 virtual Serializer &operator>>(float &);
54 virtual Serializer &operator>>(double &);
55 virtual Serializer &operator>>(long double &);
56
57 virtual Serializer &operator&&(bool &);
58 virtual Serializer &operator&&(int8_t &);
59 virtual Serializer &operator&&(int16_t &);
60 virtual Serializer &operator&&(int32_t &);
61 virtual Serializer &operator&&(int64_t &);
62 virtual Serializer &operator&&(uint8_t &);
63 virtual Serializer &operator&&(uint16_t &);
64 virtual Serializer &operator&&(uint32_t &);
65 virtual Serializer &operator&&(uint64_t &);
66 virtual Serializer &operator&&(float &);
67 virtual Serializer &operator&&(double &);
68 virtual Serializer &operator&&(long double &);
69
70 //virtual Serializer &operator&(Serializable &);
71};
72
73Serializer &operator<<(Serializer &, class Serializable &);
74Serializer &operator>>(Serializer &, class Serializable &);
75Serializer &operator&&(Serializer &s, class Serializable &p);
76
77Serializer &operator<<(Serializer &, std::string &);
78Serializer &operator>>(Serializer &, std::string &);
79
80#endif
diff --git a/src/old/stream.cpp b/src/old/stream.cpp
deleted file mode 100644
index 856a58d..0000000
--- a/src/old/stream.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
1#include "stream.h"
2
3Stream::Stream()
4{
5}
6
7Stream::~Stream()
8{
9}
10
diff --git a/src/old/stream.h b/src/old/stream.h
deleted file mode 100644
index e086e28..0000000
--- a/src/old/stream.h
+++ /dev/null
@@ -1,27 +0,0 @@
1#ifndef STREAM_H
2#define STREAM_H
3
4#include <stdint.h>
5#include <stdio.h>
6
7class Stream
8{
9public:
10 Stream();
11 virtual ~Stream();
12
13 virtual void close() = 0;
14 virtual size_t read( char *pBuf, size_t nBytes ) = 0;
15 virtual size_t write( const char *pBuf, size_t nBytes ) = 0;
16
17 virtual long tell() = 0;
18 virtual void seek( long offset ) = 0;
19 virtual void setPos( long pos ) = 0;
20 virtual void setPosEnd( long pos ) = 0;
21 virtual bool isEOS() = 0;
22
23private:
24
25};
26
27#endif
diff --git a/src/stream.cpp b/src/stream.cpp
new file mode 100644
index 0000000..267a7d1
--- /dev/null
+++ b/src/stream.cpp
@@ -0,0 +1,10 @@
1#include "stream.h"
2
3Bu::Stream::Stream()
4{
5}
6
7Bu::Stream::~Stream()
8{
9}
10
diff --git a/src/stream.h b/src/stream.h
new file mode 100644
index 0000000..274f4fd
--- /dev/null
+++ b/src/stream.h
@@ -0,0 +1,34 @@
1#ifndef STREAM_H
2#define STREAM_H
3
4#include <stdint.h>
5#include <stdio.h>
6
7namespace Bu
8{
9 class Stream
10 {
11 public:
12 Stream();
13 virtual ~Stream();
14
15 virtual void close() = 0;
16 virtual size_t read( char *pBuf, size_t nBytes ) = 0;
17 virtual size_t write( const char *pBuf, size_t nBytes ) = 0;
18
19 virtual long tell() = 0;
20 virtual void seek( long offset ) = 0;
21 virtual void setPos( long pos ) = 0;
22 virtual void setPosEnd( long pos ) = 0;
23 virtual bool isEOS() = 0;
24
25 virtual bool canRead() = 0;
26 virtual bool canWrite() = 0;
27 virtual bool canSeek() = 0;
28
29 private:
30
31 };
32}
33
34#endif
diff --git a/src/tests/archive.cpp b/src/tests/archive.cpp
new file mode 100644
index 0000000..fb0d97c
--- /dev/null
+++ b/src/tests/archive.cpp
@@ -0,0 +1,7 @@
1#include "archive.h"
2
3int main()
4{
5 //Archive
6}
7