summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2007-04-03 04:50:36 +0000
committerMike Buland <eichlan@xagasoft.com>2007-04-03 04:50:36 +0000
commitda89e6d30e57bd6dbb10b4d36b093ce9bbf5c666 (patch)
tree0c8d31d13521011dc52a3fbadbf9e7e27929308f /src
parentf4c20290509d7ed3a8fd5304577e7a4cc0b9d974 (diff)
downloadlibbu++-da89e6d30e57bd6dbb10b4d36b093ce9bbf5c666.tar.gz
libbu++-da89e6d30e57bd6dbb10b4d36b093ce9bbf5c666.tar.bz2
libbu++-da89e6d30e57bd6dbb10b4d36b093ce9bbf5c666.tar.xz
libbu++-da89e6d30e57bd6dbb10b4d36b093ce9bbf5c666.zip
The first batch seem to have made it alright. Unfortunately the Archive class
isn't done yet, I'm going to make it rely on streams, so those will be next, then we can make it work all sortsa' well.
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