aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2010-05-15 07:44:10 +0000
committerMike Buland <eichlan@xagasoft.com>2010-05-15 07:44:10 +0000
commit306b80c1cf9ab490a83b36d3e7cf07e09f9e5d68 (patch)
tree32c35f8507edb4ea403f4ebc4b625c1096f6f384
parent11413d228bae2919fe69c83b74c7ff49209dd65a (diff)
downloadlibbu++-306b80c1cf9ab490a83b36d3e7cf07e09f9e5d68.tar.gz
libbu++-306b80c1cf9ab490a83b36d3e7cf07e09f9e5d68.tar.bz2
libbu++-306b80c1cf9ab490a83b36d3e7cf07e09f9e5d68.tar.xz
libbu++-306b80c1cf9ab490a83b36d3e7cf07e09f9e5d68.zip
mkunit.sh was a little dumb, it didn't handle a number of things correctly.
I've written a new program that basically does the same thing, only it's much more clever, and does many more of the translations and conversions better, including the #line directives. Also, I dropped nids, we don't need it anymore. But now I'm ready to write some serious tests for myriad.
-rw-r--r--default.bld7
-rwxr-xr-xmkunit.sh38
-rw-r--r--src/buffer.cpp3
-rw-r--r--src/cachestorenids.cpp9
-rw-r--r--src/cachestorenids.h158
-rw-r--r--src/nids.cpp275
-rw-r--r--src/nids.h121
-rw-r--r--src/nidsstream.cpp237
-rw-r--r--src/nidsstream.h59
-rw-r--r--src/tests/nids.cpp57
-rw-r--r--src/tools/mkunit.cpp547
-rw-r--r--src/tools/nidstool.cpp248
-rw-r--r--src/unit/archive.unit337
-rw-r--r--src/unit/array.unit121
-rw-r--r--src/unit/file.unit123
-rw-r--r--src/unit/fstring.unit550
-rw-r--r--src/unit/hash.unit113
-rw-r--r--src/unit/list.unit206
-rw-r--r--src/unit/membuf.unit61
-rw-r--r--src/unit/queuebuf.unit148
-rw-r--r--src/unit/substream.unit74
-rw-r--r--src/unit/taf.unit180
-rw-r--r--src/unit/xml.unit13
23 files changed, 1521 insertions, 2164 deletions
diff --git a/default.bld b/default.bld
index 124a9ec..188d6de 100644
--- a/default.bld
+++ b/default.bld
@@ -29,6 +29,11 @@ action "all"
29 targets("tests")]; 29 targets("tests")];
30} 30}
31 31
32action "unit"
33{
34 build: targets("unit tests");
35}
36
32target files("src/*.h").replace("src/", "bu/") 37target files("src/*.h").replace("src/", "bu/")
33{ 38{
34 tag "header-links"; 39 tag "header-links";
@@ -157,7 +162,7 @@ rule "unit"
157 162
158 profile "build" 163 profile "build"
159 { 164 {
160 execute("./mkunit.sh \"${INPUT}\" \"${OUTPUT}\""); 165 execute("./mkunit \"${INPUT}\" \"${OUTPUT}\"");
161 } 166 }
162} 167}
163 168
diff --git a/mkunit.sh b/mkunit.sh
deleted file mode 100755
index b99b6d3..0000000
--- a/mkunit.sh
+++ /dev/null
@@ -1,38 +0,0 @@
1#!/bin/bash
2
3inputfile="$1"
4
5function mkfunc()
6{
7 line=$(grep -nh "{%$1" "$inputfile")
8 echo "#line ${line%%:*} \"$inputfile\" \\"
9 echo "void $1() /**< expect ${2:-pass} */"
10}
11
12function mkadd()
13{
14 ex="expectPass"
15 if [ "$2" == "fail" ]; then
16 ex="expectFail"
17 fi
18 echo "\\\\tadd( static_cast<Bu::UnitSuite::Test>(\\&Unit::$1), \"$1\", Bu::UnitSuite::${ex} );\\\\n"
19}
20
21sedbits=""
22init="#include \"bu/unitsuite.h\"\\\\n\\\\nclass Unit : public Bu::UnitSuite\\\\n{\\\\npublic:\\\\n\\\\nUnit()\\\\n{\\\\n\\\\tsetName(\"${1%.*}\");\\\\n"
23for i in $(grep {% "$1"); do
24 sedbits="${sedbits}s@${i}@$(mkfunc $(echo $i | sed -e 's/.*{%\(.*\)}/\1/' -e 's/:/ /g'))@\n"
25 init="${init}$(mkadd $(echo $i | sed -e 's/.*{%\(.*\)}/\1/' -e 's/:/ /g'))"
26done
27
28init="${init}\\\\n}\\\\n\\\\nvirtual ~Unit() { }\\\\n\\\\n"
29
30sedbits="${sedbits}s@.*{=Init}@${init}@\n"
31
32temp=$(mktemp)
33echo -e "$sedbits" > $temp
34sed -f $temp $1 > $2
35echo -e "\n};\n\nint main( int argc, char *argv[] )\n{\n\treturn Unit().run( argc, argv );\n}\n" >> $2
36
37rm $temp
38
diff --git a/src/buffer.cpp b/src/buffer.cpp
index 654fa13..fa27116 100644
--- a/src/buffer.cpp
+++ b/src/buffer.cpp
@@ -34,7 +34,8 @@ void Bu::Buffer::start()
34 34
35size_t Bu::Buffer::stop() 35size_t Bu::Buffer::stop()
36{ 36{
37 return 0; 37 iReadBufFill = iReadPos = iWriteBufFill = iWritePos = 0;
38 return sSoFar;
38} 39}
39 40
40void Bu::Buffer::fillReadBuf() 41void Bu::Buffer::fillReadBuf()
diff --git a/src/cachestorenids.cpp b/src/cachestorenids.cpp
deleted file mode 100644
index 85e9cba..0000000
--- a/src/cachestorenids.cpp
+++ /dev/null
@@ -1,9 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/cachestorenids.h"
9
diff --git a/src/cachestorenids.h b/src/cachestorenids.h
deleted file mode 100644
index 293f521..0000000
--- a/src/cachestorenids.h
+++ /dev/null
@@ -1,158 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_CACHE_STORE_NIDS_H
9#define BU_CACHE_STORE_NIDS_H
10
11#include "bu/fstring.h"
12#include "bu/stream.h"
13#include "bu/nids.h"
14#include "bu/nidsstream.h"
15#include "bu/cachestore.h"
16
17#include "bu/file.h"
18#include "bu/archive.h"
19
20namespace Bu
21{
22 template<class keytype, class obtype>
23 keytype __cacheGetKey( const obtype *pObj );
24
25 template<class keytype, class obtype>
26 obtype *__cacheStoreNidsAlloc( const keytype &key )
27 {
28 return new obtype();
29 }
30
31 template<class keytype, class obtype>
32 void __cacheStoreNidsStore( Bu::Stream &s, obtype &rObj,
33 const keytype & )
34 {
35 Bu::Archive ar( s, Bu::Archive::save );
36 ar << rObj;
37 }
38
39 template<class keytype, class obtype>
40 obtype *__cacheStoreNidsLoad( Bu::Stream &s, const keytype &key )
41 {
42 obtype *pObj = __cacheStoreNidsAlloc<keytype, obtype>( key );
43 Bu::Archive ar( s, Bu::Archive::load );
44 ar >> (*pObj);
45 return pObj;
46 }
47
48 template<class keytype, class obtype>
49 class CacheStoreNids : public CacheStore<keytype, obtype>
50 {
51 public:
52 CacheStoreNids( Bu::Stream &sArch,
53 int iBlockSize=1024, int iPreAllocate=1 ) :
54 nStore( sArch )
55 {
56 try
57 {
58 nStore.initialize();
59 NidsStream ns = nStore.openStream( 0 );
60 Bu::Archive ar( ns, Bu::Archive::load );
61 ar >> hId;
62 }
63 catch( Bu::NidsException &e )
64 {
65 nStore.initialize( iBlockSize, iPreAllocate );
66 int iStream = nStore.createStream();
67 if( iStream != 0 )
68 throw Bu::ExceptionBase("That's...horrible...id = %d.\n\n", iStream );
69 NidsStream ns = nStore.openStream( 0 );
70 Bu::Archive ar( ns, Bu::Archive::save );
71 ar << hId;
72 }
73 }
74
75 virtual ~CacheStoreNids()
76 {
77 NidsStream ns = nStore.openStream( 0 );
78 Bu::Archive ar( ns, Bu::Archive::save );
79 ar << hId;
80 }
81
82 virtual obtype *load( const keytype &key )
83 {
84 int iStream = hId.get( key );
85 NidsStream ns = nStore.openStream( iStream );
86 obtype *pOb = __cacheStoreNidsLoad<keytype, obtype>( ns, key );
87 return pOb;
88 }
89
90 virtual void unload( obtype *pObj, const keytype &key )
91 {
92 delete pObj;
93 }
94
95 virtual keytype create( obtype *pSrc )
96 {
97 keytype key = __cacheGetKey<keytype, obtype>( pSrc );
98 int iStream = nStore.createStream();
99 hId.insert( key, iStream );
100 NidsStream ns = nStore.openStream( iStream );
101 __cacheStoreNidsStore<keytype, obtype>( ns, *pSrc, key );
102 return key;
103 }
104
105 virtual void sync()
106 {
107 NidsStream ns = nStore.openStream( 0 );
108 Bu::Archive ar( ns, Bu::Archive::save );
109 ar << hId;
110 }
111
112 virtual void sync( obtype *pSrc, const keytype &key )
113 {
114 int iStream = hId.get( key );
115 NidsStream ns = nStore.openStream( iStream );
116 __cacheStoreNidsStore<keytype, obtype>( ns, *pSrc, key );
117 }
118
119 virtual void destroy( obtype *pObj, const keytype &key )
120 {
121 int iStream = hId.get( key );
122 nStore.deleteStream( iStream );
123 hId.erase( key );
124 delete pObj;
125 sync();
126 }
127
128 virtual void destroy( const keytype &key )
129 {
130 int iStream = hId.get( key );
131 nStore.deleteStream( iStream );
132 hId.erase( key );
133 sync();
134 }
135
136 virtual bool has( const keytype &key )
137 {
138 return hId.has( key );
139 }
140
141 virtual Bu::List<keytype> getKeys()
142 {
143 return hId.getKeys();
144 }
145
146 virtual int getSize()
147 {
148 return hId.getSize();
149 }
150
151 private:
152 Nids nStore;
153 typedef Bu::Hash<keytype, long> NidHash;
154 NidHash hId;
155 };
156};
157
158#endif
diff --git a/src/nids.cpp b/src/nids.cpp
deleted file mode 100644
index 6628f14..0000000
--- a/src/nids.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/nids.h"
9#include "bu/stream.h"
10#include "bu/nidsstream.h"
11#include <stdio.h>
12
13#define NIDS_MAGIC_CODE ((unsigned char *)"\xFF\xC3\x99\xBD")
14
15namespace Bu
16{
17 subExceptionDef( NidsException )
18}
19
20Bu::Nids::Nids( Bu::Stream &sStore ) :
21 sStore( sStore ),
22 iBlockSize( 0 ),
23 iBlocks( 0 ),
24 iBlockStart( -1 ),
25 iUsed( 0 )
26{
27}
28
29Bu::Nids::~Nids()
30{
31 updateHeader();
32}
33
34void Bu::Nids::sync()
35{
36 updateHeader();
37
38 // Later, also flush all caches.
39}
40
41void Bu::Nids::initialize()
42{
43 unsigned char buf[4];
44 if( sStore.read( buf, 4 ) < 4 )
45 throw NidsException("Input stream appears to be empty.");
46 if( memcmp( buf, NIDS_MAGIC_CODE, 4 ) )
47 {
48 throw NidsException(
49 "Stream does not appear to be a valid NIDS format.");
50 }
51 sStore.read( buf, 2 );
52 if( buf[0] != 0 )
53 throw NidsException(
54 "We can only handle version 0 for now.");
55 if( buf[1] != 4 )
56 throw NidsException(
57 "We can only handle 4-byte words at the moment.");
58 sStore.read( &iBlockSize, 4 );
59 sStore.read( &iBlocks, 4 );
60 sStore.read( &iUsed, 4 ); // number of used blocks...
61 sStore.seek( 7 ); // skip reserved space.
62 iBlockStart = sStore.tell();
63
64 //printf("%d blocks, %db each, %db block offset\n",
65 // iBlocks, iBlockSize, iBlockStart );
66
67 bsBlockUsed.setSize( iBlocks, true );
68 Block bTmp;
69 for( int j = 0; j < iBlocks; j++ )
70 {
71 sStore.seek( iBlockStart+iBlockSize*j );
72 sStore.read( &bTmp, sizeof(bTmp) );
73 if( bTmp.uFirstBlock != blockUnused )
74 bsBlockUsed.setBit( j );
75 }
76}
77
78void Bu::Nids::initialize( int iBlockSize, int iPreAllocate )
79{
80 char cBuf = 0;
81 int iBuf = 0;
82
83 // Magic number
84 sStore.write( NIDS_MAGIC_CODE, 4 );
85
86 // Version (0)
87 sStore.write( &cBuf, 1 );
88
89 // Bytes per int
90 cBuf = 4;
91 sStore.write( &cBuf, 1 );
92
93 // The size of each block and the number of blocks we're pre-allocating
94 sStore.write( &iBlockSize, 4 );
95 sStore.write( &iPreAllocate, 4 );
96
97 // The number of used blocks
98 sStore.write( &iBuf, 4 );
99
100 // Reserved space
101 sStore.write( "\x00\x00\x00\x00\x00\x00\x00", 7 );
102
103 this->iBlockSize = iBlockSize;
104 this->iBlocks = iPreAllocate;
105 this->iBlockStart = sStore.tell();
106 //printf("iBlockStart = %d\n", this->iBlockStart );
107 bsBlockUsed.setSize( iPreAllocate, true );
108
109 //printf("%d blocks, %db each, %db block offset\n",
110 // iBlocks, iBlockSize, iBlockStart );
111
112 Block *block = (Block *)new char[iBlockSize];
113 memset( block, 0, iBlockSize );
114 block->uFirstBlock = block->uNextBlock /*=block->uPrevBlock*/ = blockUnused;
115 for( int j = 0; j < iPreAllocate; j++ )
116 {
117 sStore.write( block, iBlockSize );
118 }
119 delete[] (char *)block;
120}
121
122void Bu::Nids::updateHeader()
123{
124 if( !sStore.canWrite() )
125 return;
126 sStore.setPos( 10 ); // Skip the magic number, version, bpi, block size
127 sStore.write( &iBlocks, 4 );
128 sStore.write( &iUsed, 4 );
129}
130
131void Bu::Nids::initBlock( uint32_t uPos, uint32_t uFirstBlock,
132 /*uint32_t uPrevBlock,*/ bool bNew )
133{
134 Block b = { uPos, blockUnused, /*uPrevBlock, 0,*/ 0, { } };
135 if( uFirstBlock != blockUnused )
136 b.uFirstBlock = uFirstBlock;
137 bsBlockUsed.setBit( uPos );
138 sStore.setPos( iBlockStart+(iBlockSize*uPos) );
139 sStore.write( &b, sizeof(Block) );
140 if( bNew )
141 {
142 // It's a new one, at the end, write some zeros.
143 int iSize = iBlockSize-sizeof(Block);
144 char *buf = new char[iSize];
145 memset( buf, 0, iSize );
146 sStore.write( buf, iSize );
147 delete[] buf;
148 }
149 iUsed++;
150}
151
152uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, /*uint32_t uPrevBlock,*/
153 int /*iPreAllocate*/ )
154{
155 for( int j = 0; j < iBlocks; j++ )
156 {
157 if( !bsBlockUsed.getBit( j ) )
158 {
159 initBlock( j, uFirstBlock/*, uPrevBlock*/ );
160 return j;
161 }
162 }
163 // Oh, we don't have any blocks left...allocate a new one.
164 iBlocks++;
165 bsBlockUsed.setSize( iBlocks, false );
166 initBlock( iBlocks-1, uFirstBlock/*, uPrevBlock*/, true );
167 return iBlocks-1;
168}
169
170int Bu::Nids::createStream( int iPreAllocate )
171{
172 return createBlock( blockUnused, /*blockUnused,*/ iPreAllocate );
173}
174
175void Bu::Nids::deleteStream( int /*iID*/ )
176{
177}
178
179Bu::NidsStream Bu::Nids::openStream( int iID )
180{
181 if( iBlockStart < 0 )
182 {
183 initialize();
184 }
185 return NidsStream( *this, iID );
186}
187
188int Bu::Nids::getBlockSize()
189{
190 return iBlockSize;
191}
192
193int Bu::Nids::getNumBlocks()
194{
195 return iBlocks;
196}
197
198int Bu::Nids::getNumUsedBlocks()
199{
200 return iUsed;
201}
202
203int Bu::Nids::getBlockStart()
204{
205 return iBlockStart;
206}
207
208int Bu::Nids::getBlockOverhead()
209{
210 return sizeof(Block);
211}
212
213/*
214void Bu::Nids::extendStream( int iID, int iBlockCount )
215{
216}*/
217
218void Bu::Nids::getBlock( uint32_t uIndex, Bu::Nids::Block *pBlock )
219{
220 sStore.setPos( iBlockStart + (iBlockSize*uIndex) );
221 sStore.read( pBlock, iBlockSize );
222}
223
224void Bu::Nids::setBlock( uint32_t uIndex, Bu::Nids::Block *pBlock )
225{
226 sStore.setPos( iBlockStart + (iBlockSize*uIndex) );
227 sStore.write( pBlock, iBlockSize );
228}
229
230void Bu::Nids::updateStreamSize( uint32_t uIndex, uint32_t uSize )
231{
232 if( !sStore.canWrite() )
233 return;
234 sStore.setPos( iBlockStart + (iBlockSize*uIndex)+4*2 );
235 sStore.write( &uSize, 4 );
236}
237
238uint32_t Bu::Nids::getNextBlock( uint32_t uIndex,
239 struct Bu::Nids::Block *pBlock, bool bCreate )
240{
241 uint32_t uNew;
242 if( pBlock->uNextBlock == blockUnused )
243 {
244 if( bCreate )
245 {
246 uNew = createBlock( pBlock->uFirstBlock, uIndex );
247 sStore.setPos( iBlockStart + (iBlockSize*uIndex)+1*4 );
248 sStore.write( &uNew, 4 );
249 getBlock( uNew, pBlock );
250 //printf("Allocated new block (%u) for stream %u.\n",
251 // uNew, pBlock->uFirstBlock );
252 }
253 else
254 {
255 throw Bu::NidsException("Reached end of stream.");
256 }
257 }
258 else
259 {
260 uNew = pBlock->uNextBlock;
261 getBlock( pBlock->uNextBlock, pBlock );
262 }
263 return uNew;
264}
265
266Bu::Nids::Block *Bu::Nids::newBlock()
267{
268 return (Block *)new char[iBlockSize];
269}
270
271void Bu::Nids::deleteBlock( Block *pBlock )
272{
273 delete[] (char *)pBlock;
274}
275
diff --git a/src/nids.h b/src/nids.h
deleted file mode 100644
index 0976e67..0000000
--- a/src/nids.h
+++ /dev/null
@@ -1,121 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_NIDS_H
9#define BU_NIDS_H
10
11#include <stdint.h>
12#include "bu/bitstring.h"
13#include "bu/exceptionbase.h"
14
15namespace Bu
16{
17 class Stream;
18 class NidsStream;
19
20 subExceptionDecl( NidsException )
21
22 /**
23 * Numerically Indexed Data Streams. This is a working name so I can
24 * actually get some code written instead of agonizing over the name.
25 *
26 * This is a system for creating streams that contain other streams in
27 * a flexible block-allocated system.
28 */
29 class Nids
30 {
31 friend class NidsStream;
32 public:
33 Nids( Bu::Stream &sStore );
34 virtual ~Nids();
35
36 /**
37 * Initialize this object based on the data already in the assosiated
38 * stream. This will be called automatically for you if you forget,
39 * but if you want to pre-initialize for some reason, just call this
40 * once before you actually start doing anything with your Nids.
41 */
42 void initialize();
43
44 /**
45 * Create a new Nids system in the assosiated stream. This should be
46 * used carefully, it will destroy all data already within the stream.
47 * More options will probably be added soon.
48 */
49 void initialize( int iBlockSize, int iPreAllocate=1 );
50
51 /**
52 * Create a new stream within the Nids system. The ID of the new stream
53 * is returned.
54 */
55 int createStream( int iPreAllocate=1 );
56
57 /**
58 * Delete a stream that's already within the Nids.
59 */
60 void deleteStream( int iID );
61
62 /**
63 * Return a new Stream object assosiated with the given stream ID.
64 */
65 NidsStream openStream( int iID );
66
67 int getBlockSize();
68 int getNumBlocks();
69 int getNumUsedBlocks();
70 int getBlockStart();
71 int getBlockOverhead();
72
73 /**
74 * Syncronize the header data, etc. with the storage stream. It's not
75 * a bad idea to call this periodically.
76 */
77 void sync();
78
79 private:
80 typedef struct Block
81 {
82 uint32_t uFirstBlock;
83 uint32_t uNextBlock;
84 // uint32_t uPrevBlock;
85 uint32_t uBytesUsed;
86 // uint32_t uReserved;
87 unsigned char pData[0];
88 } Block;
89
90 enum
91 {
92 blockUnused = 0xFFFFFFFFUL
93 };
94
95 void initBlock( uint32_t uPos, uint32_t uFirstBlock,
96 /*uint32_t uPrevBlock,*/ bool bNew=false );
97 uint32_t createBlock( uint32_t uFirstBlock, /*uint32_t uPrevBlock,*/
98 int iPreAllocate=1 );
99 void getBlock( uint32_t uIndex, Block *pBlock );
100 void setBlock( uint32_t uIndex, Block *pBlock );
101 void updateStreamSize( uint32_t uIndex, uint32_t uSize );
102 uint32_t getNextBlock( uint32_t uIndex, Block *pBlock,
103 bool bCreate=true);
104
105 void updateHeader();
106
107 // Block allocation routines
108 Block *newBlock();
109 void deleteBlock( Block *pBlock );
110
111 private:
112 Bu::Stream &sStore;
113 int iBlockSize;
114 int iBlocks;
115 int iBlockStart;
116 int iUsed;
117 Bu::BitString bsBlockUsed;
118 };
119};
120
121#endif
diff --git a/src/nidsstream.cpp b/src/nidsstream.cpp
deleted file mode 100644
index 65c8962..0000000
--- a/src/nidsstream.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/nidsstream.h"
9
10#include <string.h>
11
12Bu::NidsStream::NidsStream( Nids &rNids, uint32_t uStream ) :
13 rNids( rNids ),
14 uStream( uStream ),
15 pCurBlock( NULL ),
16 uCurBlock( uStream ),
17 uSize( 0 ),
18 uBlockSize( rNids.iBlockSize-sizeof(Nids::Block) ),
19 uPos( 0 )
20{
21 //printf("NidsStream::allocated\n");
22 pCurBlock = rNids.newBlock();
23 rNids.getBlock( uStream, pCurBlock );
24 uSize = pCurBlock->uBytesUsed;
25}
26
27/*
28Bu::NidsStream::NidsStream( const Bu::NidsStream &rSrc ) :
29 Stream( rSrc ),
30 rNids( rSrc.rNids ),
31 uStream( rSrc.uStream ),
32 pCurBlock( NULL ),
33 uCurBlock( uStream ),
34 uSize( 0 ),
35 uBlockSize( rSrc.uBlockSize ),
36 iUsable( uBlockSize-sizeof(Nids::Block) ),
37 uPos( 0 )
38{
39 printf("NidsStream::copied\n");
40 pCurBlock = rNids.newBlock();
41 rNids.getBlock( uStream, pCurBlock );
42}*/
43
44Bu::NidsStream::~NidsStream()
45{
46 //printf("Destroying stream?\n");
47 rNids.updateStreamSize( uStream, uSize );
48 rNids.deleteBlock( pCurBlock );
49}
50
51void Bu::NidsStream::close()
52{
53}
54
55size_t Bu::NidsStream::read( void *pBuf, size_t nBytes )
56{
57 if( nBytes == 0 )
58 return 0;
59 if( nBytes + uPos > uSize )
60 nBytes = uSize - uPos;
61 if( (uPos%uBlockSize)+nBytes < uBlockSize )
62 {
63 size_t iRead = nBytes;
64 if( iRead > pCurBlock->uBytesUsed-(uPos%uBlockSize) )
65 iRead = pCurBlock->uBytesUsed-(uPos%uBlockSize);
66 memcpy( pBuf, pCurBlock->pData+(uPos%uBlockSize), iRead );
67 //printf("read buffill: %ub, %u-%u/%u -> %d-%d/%d (a:%u)",
68 // iRead, uPos, uPos+iRead-1, uSize, 0, iRead-1, nBytes, uCurBlock );
69 uPos += iRead;
70 //printf(" -- %u\n", uPos%uBlockSize );
71 //printf("ra: block %u = %ub:%u (%ub total)\n",
72 // uCurBlock, uPos, nBytes, uSize );
73
74 // This can't happen, if we're right on a boundery, it goes to the
75 // other case
76 //if( uPos%uBlockSize == 0 )
77 // uCurBlock = rNids.getNextBlock( uCurBlock, pCurBlock, false );
78 return iRead;
79 }
80 else
81 {
82 size_t nTotal = 0;
83 for(;;)
84 {
85 uint32_t iRead = nBytes;
86 if( iRead > uBlockSize-(uPos%uBlockSize) )
87 iRead = uBlockSize-(uPos%uBlockSize);
88 if( iRead > pCurBlock->uBytesUsed-(uPos%uBlockSize) )
89 iRead = pCurBlock->uBytesUsed-(uPos%uBlockSize);
90 memcpy( ((char *)pBuf)+nTotal,
91 pCurBlock->pData+(uPos%uBlockSize), iRead );
92 //printf(" read buffill: %ub, %u-%u/%u -> %d-%d/%d (b:%u)\n",
93 // iRead, uPos, uPos+iRead-1, uSize,
94 // nTotal, nTotal+nBytes-1, nBytes, uCurBlock );
95 uPos += iRead;
96 nBytes -= iRead;
97 nTotal += iRead;
98 //printf("rb: block %u = %ub:%u (%ub total)\n",
99 // uCurBlock, uPos, iRead, uSize );
100 if( uPos%uBlockSize == 0 )
101 uCurBlock = rNids.getNextBlock( uCurBlock, pCurBlock, false );
102 if( nBytes == 0 || uPos >= uSize )
103 return nTotal;
104 }
105 }
106 return 0;
107}
108
109size_t Bu::NidsStream::write( const void *pBuf, size_t nBytes )
110{
111 if( nBytes == 0 )
112 return 0;
113/* if( pCurBlock->uBytesUsed >= uBlockSize )
114 {
115 // We're at the end of our current block, allocate another before we do
116 // anything.
117 uCurBlock = rNids.getNextBlock( uCurBlock, pCurBlock );
118 } */
119 if( (uPos%uBlockSize)+nBytes < uBlockSize )
120 {
121 //printf("wa: %u:%u:%u:%u -> ", uPos, uPos%uBlockSize, uSize, pCurBlock->uBytesUsed );
122 memcpy( pCurBlock->pData+(uPos%uBlockSize), pBuf, nBytes );
123 //printf("write buffill: %ub, %u-%u/%u -> %d-%d/%d (a:%u:%u)\n",
124 // nBytes, 0, nBytes-1, nBytes,
125 // uPos, uPos+nBytes-1, uSize, uCurBlock,
126 // pCurBlock->uBytesUsed );
127 if( (uPos%uBlockSize)+nBytes > pCurBlock->uBytesUsed )
128 pCurBlock->uBytesUsed = (uPos%uBlockSize)+nBytes;
129 rNids.setBlock( uCurBlock, pCurBlock );
130 uPos += nBytes;
131 if( uPos > uSize )
132 uSize = uPos;
133 //printf("block %u = %ub (%ub total) %d:%u\n",
134 // uCurBlock, pCurBlock->uBytesUsed, uSize, nBytes, uPos );
135 return nBytes;
136 }
137 else
138 {
139 size_t nTotal = 0;
140 for(;;)
141 {
142 uint32_t uNow = uBlockSize-(uPos%uBlockSize);
143 //printf("uNow: %u (%u-(%u%%%u)) %d req\n", uNow, uBlockSize, uPos, uBlockSize, nBytes );
144 if( nBytes < uNow )
145 uNow = nBytes;
146 memcpy( pCurBlock->pData+(uPos%uBlockSize),
147 &((char *)pBuf)[nTotal], uNow );
148 //printf("write buffill: %ub, %u-%u/%u -> %d-%d/%d (b:%u:%u)\n",
149 // uNow, nTotal, nTotal+uNow-1, nBytes,
150 // uPos, uPos+uNow-1, uSize, uCurBlock, pCurBlock->uBytesUsed );
151 if( (uPos%uBlockSize)+uNow > pCurBlock->uBytesUsed )
152 pCurBlock->uBytesUsed = (uPos%uBlockSize)+uNow;
153 rNids.setBlock( uCurBlock, pCurBlock );
154 uPos += uNow;
155 if( uPos > uSize )
156 uSize = uPos;
157 nTotal += uNow;
158 nBytes -= uNow;
159 //printf("wb: block %u = %ub (%ub total)\n",
160 // uCurBlock, pCurBlock->uBytesUsed, uSize );
161 //if( pCurBlock->uBytesUsed == uBlockSize )
162 if( uPos%uBlockSize == 0 )
163 uCurBlock = rNids.getNextBlock( uCurBlock, pCurBlock );
164 if( nBytes == 0 )
165 return nTotal;
166 }
167 }
168}
169
170long Bu::NidsStream::tell()
171{
172 return uPos;
173}
174
175void Bu::NidsStream::seek( long offset )
176{
177 uPos += offset;
178}
179
180void Bu::NidsStream::setPos( long pos )
181{
182 uPos = pos;
183}
184
185void Bu::NidsStream::setPosEnd( long pos )
186{
187 uPos = uSize-pos-1;
188}
189
190bool Bu::NidsStream::isEos()
191{
192 return true;
193}
194
195bool Bu::NidsStream::isOpen()
196{
197 return true;
198}
199
200void Bu::NidsStream::flush()
201{
202}
203
204bool Bu::NidsStream::canRead()
205{
206 return true;
207}
208
209bool Bu::NidsStream::canWrite()
210{
211 return true;
212}
213
214bool Bu::NidsStream::isReadable()
215{
216 return true;
217}
218
219bool Bu::NidsStream::isWritable()
220{
221 return true;
222}
223
224bool Bu::NidsStream::isSeekable()
225{
226 return true;
227}
228
229bool Bu::NidsStream::isBlocking()
230{
231 return true;
232}
233
234void Bu::NidsStream::setBlocking( bool /*bBlocking*/ )
235{
236}
237
diff --git a/src/nidsstream.h b/src/nidsstream.h
deleted file mode 100644
index c8c8ce0..0000000
--- a/src/nidsstream.h
+++ /dev/null
@@ -1,59 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#ifndef BU_NIDS_STREAM_H
9#define BU_NIDS_STREAM_H
10
11#include "bu/stream.h"
12#include "bu/nids.h"
13
14namespace Bu
15{
16 class NidsStream : public Bu::Stream
17 {
18 friend class Nids;
19 private:
20 /**
21 * These can only be created by the Nids class.
22 */
23 NidsStream( Nids &rNids, uint32_t uStream );
24
25 public:
26// NidsStream( const NidsStream &rSrc );
27 virtual ~NidsStream();
28
29 virtual void close();
30 virtual size_t read( void *pBuf, size_t nBytes );
31 virtual size_t write( const void *pBuf, size_t nBytes );
32 using Stream::write;
33 virtual long tell();
34 virtual void seek( long offset );
35 virtual void setPos( long pos );
36 virtual void setPosEnd( long pos );
37 virtual bool isEos();
38 virtual bool isOpen();
39 virtual void flush();
40 virtual bool canRead();
41 virtual bool canWrite();
42 virtual bool isReadable();
43 virtual bool isWritable();
44 virtual bool isSeekable();
45 virtual bool isBlocking();
46 virtual void setBlocking( bool bBlocking=true );
47
48 private:
49 Nids &rNids;
50 uint32_t uStream;
51 Nids::Block *pCurBlock;
52 uint32_t uCurBlock;
53 uint32_t uSize;
54 uint32_t uBlockSize;
55 uint32_t uPos;
56 };
57};
58
59#endif
diff --git a/src/tests/nids.cpp b/src/tests/nids.cpp
deleted file mode 100644
index 22bf450..0000000
--- a/src/tests/nids.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/file.h"
9#include "bu/nids.h"
10#include "bu/nidsstream.h"
11
12int main( int argc, char *argv[] )
13{
14 if( argc < 3 )
15 {
16 printf("usage: %s [r|w] <output>\n\n", argv[0] );
17 return 1;
18 }
19
20 if( argv[1][0] == 'w' )
21 {
22 Bu::File fOut( argv[2],
23 Bu::File::ReadWrite|Bu::File::Create|Bu::File::Truncate );
24 Bu::Nids n( fOut );
25
26 n.initialize( 32, 1 );
27/* Bu::NidsStream s = n.openStream( n.createStream() );
28
29 Bu::FString sBuf( 350 );
30 memset( sBuf.getStr(), 'a', 350 );
31 s.write( sBuf );*/
32 }
33 else if( argv[1][0] == 'r' )
34 {
35 Bu::File fOut( argv[2], Bu::File::Read );
36 Bu::Nids n( fOut );
37 n.initialize();
38/*
39 Bu::NidsStream s = n.openStream( 0 );
40 char buf[75];
41 for( int j = 0; j < 3; j++ )
42 {
43 int iRead = s.read( buf, 75 );
44 fwrite( buf, 1, iRead, stdout );
45 printf("\n(read %d chars)\n", iRead );
46 }
47 printf("Position: %ld\n", s.tell() );
48 */
49 }
50 else
51 {
52 printf("r or w, those are your choices.\n");
53 }
54
55 return 0;
56}
57
diff --git a/src/tools/mkunit.cpp b/src/tools/mkunit.cpp
new file mode 100644
index 0000000..43fab38
--- /dev/null
+++ b/src/tools/mkunit.cpp
@@ -0,0 +1,547 @@
1#include <bu/file.h>
2#include <bu/optparser.h>
3#include <bu/buffer.h>
4#include <bu/list.h>
5#include <bu/sio.h>
6#include <bu/variant.h>
7
8using namespace Bu;
9
10class Test
11{
12public:
13 Test() :
14 bExpectPass( true )
15 {
16 }
17
18 Bu::FString sName;
19 bool bExpectPass;
20};
21typedef Bu::List<Test> TestList;
22
23class Suite
24{
25public:
26 Bu::FString sName;
27 TestList lTest;
28};
29//typedef Bu::List<Suite> SuiteList;
30
31enum TokType
32{
33 tokFluff,
34 tokSuite,
35 tokTest,
36 tokChar,
37 tokBlock,
38 tokEof
39};
40
41Bu::Formatter &operator<<( Bu::Formatter &f, TokType t )
42{
43 switch( t )
44 {
45 case tokFluff: return f << "tokFluff";
46 case tokSuite: return f << "tokSuite";
47 case tokTest: return f << "tokTest";
48 case tokChar: return f << "tokChar";
49 case tokBlock: return f << "tokBlock";
50 case tokEof: return f << "tokEof";
51 }
52
53 return f;
54}
55
56Bu::Formatter &operator<<( Bu::Formatter &f, const Test &t )
57{
58 return f << "{" << t.sName << ", bExpectPass=" << t.bExpectPass << "}";
59}
60
61Bu::Formatter &operator<<( Bu::Formatter &f, const Suite &s )
62{
63 return f << "Suite[" << s.sName << "] = " << s.lTest << f.nl;
64}
65
66class Parser
67{
68public:
69 Parser( const Bu::FString &sFile ) :
70 fIn( sFile, File::Read ),
71 bIn( fIn ),
72 cBuf( 0 ),
73 bAvail( false ),
74 eMode( mRoot ),
75 iLine( 1 ),
76 iChar( 0 ),
77 iDepth( 0 )
78 {
79 }
80
81 char nextChar()
82 {
83 if( bAvail )
84 return cBuf;
85
86 if( bIn.read( &cBuf, 1 ) < 1 )
87 throw Bu::ExceptionBase("End of stream");
88 bAvail = true;
89
90 if( cBuf == '\n' )
91 {
92 iLine++;
93 iChar = 0;
94 }
95 else
96 iChar++;
97
98 return cBuf;
99 }
100
101 TokType nextToken( Variant &v, Bu::FString &sWsOut, int &iLineStart,
102 int &iCharStart )
103 {
104 Bu::FString sTok, sWs;
105
106 char buf;
107 try
108 {
109 buf = nextChar();
110 }
111 catch(...)
112 {
113 return tokEof;
114 }
115
116 for(;;)
117 {
118 if( buf == ' ' || buf == '\t' || buf == '\n' || buf == '\r' )
119 {
120 sWs += buf;
121 bAvail = false;
122 }
123 else
124 break;
125
126 try
127 {
128 buf = nextChar();
129 }
130 catch(...)
131 {
132 sWsOut = sWs;
133 return tokEof;
134 }
135 }
136
137 sWsOut = sWs;
138
139 iLineStart = iLine;
140 iCharStart = iChar;
141 bool bInStr = false;
142 bool bDblStr;
143
144 for(;;)
145 {
146 switch( eMode )
147 {
148 case mRoot:
149 if( buf == ' ' || buf == '\t' || buf == '\n'
150 || buf == '\r' )
151 {
152 if( sTok == "suite" )
153 return tokSuite;
154 else
155 {
156 v = sTok;
157 return tokFluff;
158 }
159 }
160 else if( buf == '(' || buf == ')' || buf == '{'
161 || buf == '}' || buf == ';' )
162 {
163 if( sTok.getSize() == 0 )
164 {
165 bAvail = false;
166 v = buf;
167 return tokChar;
168 }
169 else
170 {
171 v = sTok;
172 return tokFluff;
173 }
174 }
175 else
176 {
177 sTok += buf;
178 bAvail = false;
179 }
180 break;
181
182 case mSuite:
183 if( buf == ' ' || buf == '\t' || buf == '\n'
184 || buf == '\r' )
185 {
186 if( sTok == "test" )
187 return tokTest;
188 else
189 {
190 v = sTok;
191 return tokFluff;
192 }
193 }
194 else if( buf == '(' || buf == ')'
195 || buf == '}' || buf == ';' )
196 {
197 if( sTok.getSize() == 0 )
198 {
199 bAvail = false;
200 v = buf;
201 return tokChar;
202 }
203 else
204 {
205 v = sTok;
206 return tokFluff;
207 }
208 }
209 else if( buf == '{' )
210 {
211 if( sTok.getSize() > 0 )
212 {
213 v = sTok;
214 return tokFluff;
215 }
216 else
217 {
218 sTok += buf;
219 bAvail = false;
220 eMode = mBlock;
221 iDepth = 1;
222 }
223 }
224 else
225 {
226 sTok += buf;
227 bAvail = false;
228 }
229 break;
230
231 case mBlock:
232 if( bInStr )
233 {
234 if( buf == '\\' )
235 {
236 sTok += buf;
237 bAvail = false;
238 sTok += nextChar();
239 bAvail = false;
240 }
241 else if( bDblStr == true && buf == '\"' )
242 {
243 sTok += buf;
244 bAvail = false;
245 bInStr = false;
246 }
247 else if( bDblStr == false && buf == '\'' )
248 {
249 sTok += buf;
250 bAvail = false;
251 bInStr = false;
252 }
253 else
254 {
255 sTok += buf;
256 bAvail = false;
257 }
258 }
259 else
260 {
261 if( buf == '\"' )
262 {
263 bInStr = true;
264 bDblStr = true;
265 sTok += buf;
266 bAvail = false;
267 }
268 else if( buf == '\'' )
269 {
270 bInStr = true;
271 bDblStr = false;
272 sTok += buf;
273 bAvail = false;
274 }
275 else if( buf == '}' )
276 {
277 sTok += buf;
278 bAvail = false;
279 iDepth--;
280 if( iDepth == 0 )
281 {
282 v = sTok;
283 eMode = mSuite;
284 return tokBlock;
285 }
286 }
287 else if( buf == '{' )
288 {
289 sTok += buf;
290 bAvail = false;
291 iDepth++;
292 }
293 else
294 {
295 sTok += buf;
296 bAvail = false;
297 }
298 }
299 break;
300 }
301
302 buf = nextChar();
303 }
304 }
305
306 void firstPass()
307 {
308 Variant v;
309 Bu::FString sWs;
310 int iL, iC;
311 for(;;)
312 {
313 TokType t = nextToken( v, sWs, iL, iC );
314 if( t == tokEof )
315 return;
316 switch( eMode )
317 {
318 case mRoot:
319 if( t == tokSuite )
320 {
321 if( nextToken( v, sWs, iL, iC ) != tokFluff )
322 throw Bu::ExceptionBase("%d:%d: Expected string "
323 "following suite.", iL, iC );
324 s.sName = v.get<Bu::FString>();
325 if( nextToken( v, sWs, iL, iC ) != tokChar ||
326 v.get<char>() != '{' )
327 throw Bu::ExceptionBase("%d:%d: Expected {, got "
328 "'%s'", iL, iC, v.toString().getStr() );
329 eMode = mSuite;
330 }
331 break;
332
333 case mSuite:
334 switch( t )
335 {
336 case tokFluff:
337 break;
338
339 case tokBlock:
340 break;
341
342 case tokTest:
343 {
344 if( nextToken( v, sWs, iL, iC ) != tokFluff )
345 throw Bu::ExceptionBase("%d:%d: Expected "
346 "string following test.", iL, iC );
347 Test t;
348 t.sName = v.get<Bu::FString>();
349 if( nextToken( v, sWs, iL, iC ) != tokBlock )
350 throw Bu::ExceptionBase("%d:%d: Expected "
351 "{...} block.",
352 iL, iC );
353 s.lTest.append( t );
354 }
355 break;
356
357 case tokChar:
358 if( v.get<char>() == '}' )
359 {
360 eMode = mRoot;
361 }
362 else
363 {
364 }
365 break;
366
367 default:
368 sio << iL << ":" << iC << ": Unexpected "
369 << t << " found." << sio.nl;
370 return;
371 break;
372 }
373 break;
374
375 default:
376 sio << "???" << sio.nl;
377 break;
378 }
379 }
380 }
381
382 void secondPass( const Bu::FString &sOut )
383 {
384 File fOut( sOut, File::WriteNew );
385 Formatter f( fOut );
386 fIn.setPos( 0 );
387 bIn.stop();
388 bIn.start();
389 bAvail = false;
390 eMode = mRoot;
391 iLine = 1;
392 iChar = 0;
393 bool bHasIncluded = false;
394
395 Bu::FString sWs;
396 Variant v;
397 int iL, iC;
398 for(;;)
399 {
400 TokType t = nextToken( v, sWs, iL, iC );
401 switch( eMode )
402 {
403 case mRoot:
404 if( t == tokSuite )
405 {
406 fOut.write( sWs );
407 if( nextToken( v, sWs, iL, iC ) != tokFluff )
408 throw Bu::ExceptionBase("%d:%d: Expected string "
409 "following suite.", iL, iC );
410 s.sName = v.get<Bu::FString>();
411 if( nextToken( v, sWs, iL, iC ) != tokChar ||
412 v.get<char>() != '{' )
413 throw Bu::ExceptionBase("%d:%d: Expected {",
414 iL, iC );
415 eMode = mSuite;
416
417 if( bHasIncluded == false )
418 {
419 fOut.write("#include <bu/unitsuite.h>\n");
420 bHasIncluded = true;
421 }
422
423 Bu::FString sClass = "_UnitSuite_" + s.sName;
424 f << "class " << sClass
425 << " : public Bu::UnitSuite" << f.nl
426 << "{" << f.nl << "public:" << f.nl
427 << "\t" << sClass << "()" << f.nl
428 << "\t{" << f.nl
429 << "\t\tsetName(\"" << s.sName << "\");" << f.nl;
430 for( TestList::iterator i = s.lTest.begin(); i; i++ )
431 {
432 f << "\t\tadd( static_cast<Bu::UnitSuite::Test>("
433 "&" << sClass << "::" << (*i).sName << "), \""
434 << (*i).sName << "\", Bu::UnitSuite::"
435 "expectPass );" << f.nl;
436 }
437 f << "\t}" << f.nl << f.nl
438 << "\tvirtual ~" << sClass << "() { }" << f.nl
439 << f.nl;
440 }
441 else if( t == tokEof )
442 {
443 Bu::FString sClass = "_UnitSuite_" + s.sName;
444 f << sWs << f.nl << "int main( int argc, char *argv[] )"
445 << f.nl << "{" << f.nl << "\treturn " << sClass
446 << "().run( argc, argv );" << f.nl << "}" << f.nl;
447 }
448 else
449 {
450 fOut.write( sWs );
451 f << v;
452 }
453 break;
454
455 case mSuite:
456 switch( t )
457 {
458 case tokFluff:
459 fOut.write( sWs );
460 fOut.write( v.get<Bu::FString>() );
461 break;
462
463 case tokTest:
464 {
465 fOut.write( sWs );
466 if( nextToken( v, sWs, iL, iC ) != tokFluff )
467 throw Bu::ExceptionBase("%d:%d: Expected "
468 "string following test.", iL, iC );
469 Test t;
470 t.sName = v.get<Bu::FString>();
471 if( nextToken( v, sWs, iL, iC ) != tokBlock )
472 throw Bu::ExceptionBase("%d:%d: Expected "
473 "{...} block.",
474 iL, iC );
475
476 f << "\tvoid " << t.sName << "()"
477 << f.nl << "#line " << iL
478 << " \"" << sOut << "\"" << f.nl
479 << v << f.nl;
480 }
481 break;
482
483 case tokChar:
484 if( v.get<char>() == '}' )
485 {
486 f << "};" << f.nl << f.nl;
487 eMode = mRoot;
488 }
489 else
490 {
491 char buf = v.get<char>();
492 fOut.write( sWs );
493 fOut.write( &buf, 1 );
494 }
495 break;
496
497 case tokBlock:
498 fOut.write( sWs );
499 f << f.nl << "#line " << iL << " \"" << sOut
500 << "\"" << f.nl;
501 fOut.write( v.get<Bu::FString>() );
502
503 break;
504
505 default:
506 sio << iL << ":" << iC << ": Unexpected "
507 << t << " found." << sio.nl;
508 return;
509 break;
510 }
511 break;
512
513 default:
514 sio << "???" << sio.nl;
515 break;
516 }
517 if( t == tokEof )
518 return;
519 }
520 }
521
522private:
523 File fIn;
524 Buffer bIn;
525 char cBuf;
526 bool bAvail;
527 enum Mode
528 {
529 mRoot,
530 mSuite,
531 mBlock
532 };
533 Mode eMode;
534 int iLine, iChar;
535 int iDepth;
536 Suite s;
537};
538
539int main( int argc, char *argv[] )
540{
541 Parser p( argv[1] );
542
543 p.firstPass();
544
545 p.secondPass( argv[2] );
546}
547
diff --git a/src/tools/nidstool.cpp b/src/tools/nidstool.cpp
deleted file mode 100644
index 41179f9..0000000
--- a/src/tools/nidstool.cpp
+++ /dev/null
@@ -1,248 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/file.h"
9#include "bu/nids.h"
10#include "bu/nidsstream.h"
11#include "bu/paramproc.h"
12
13#include <stdlib.h>
14
15typedef struct Block
16{
17 uint32_t uFirstBlock;
18 uint32_t uNextBlock;
19 uint32_t uBytesUsed;
20} Block;
21
22class Param : public Bu::ParamProc
23{
24public:
25 Param( int argc, char *argv[] )
26 {
27 addHelpBanner("nidstool - Do stuff with nids files.\n\n");
28 addParam("info", 'i', mkproc(Param::procInfo),
29 "Print some info about the file.");
30 addParam("dump", 'd', mkproc(Param::procDump),
31 "Dump a stream to a file.");
32 addParam("analyze", 'a', mkproc(Param::procAnalyze),
33 "Analyze a nids file.");
34 addParam("copy", 'c', mkproc(Param::procCopy),
35 "Copy a nids file, changing settings.");
36 addParam("help", 'h', mkproc(Bu::ParamProc::help), "This help.");
37 process( argc, argv );
38 }
39
40 virtual ~Param()
41 {
42 }
43
44 void printInfo( Bu::Nids &n )
45 {
46 printf("File info:\n");
47 printf(" Header overhead: %db\n", n.getBlockStart() );
48 printf(" Block size: %db\n", n.getBlockSize() );
49 printf(" Block count: %d\n", n.getNumBlocks() );
50 printf(" Blocks used: %d (%d%%)\n", n.getNumUsedBlocks(),
51 n.getNumUsedBlocks()*100/n.getNumBlocks() );
52 printf(" Block overhead: %db\n", n.getBlockOverhead() );
53 printf(" Block storage: %db (%d%%)\n",
54 n.getBlockSize()-n.getBlockOverhead(),
55 (n.getBlockSize()-n.getBlockOverhead())*100/n.getBlockSize() );
56 }
57
58 int procInfo( int argc, char *argv[] )
59 {
60 if( argc < 1 )
61 {
62 printf("You must provide a file name.\n");
63 exit( 1 );
64 }
65
66 Bu::File fIn( argv[0], Bu::File::Read );
67 Bu::Nids n( fIn );
68 n.initialize();
69
70 printInfo( n );
71
72 if( argc >= 2 )
73 {
74 uint32_t uStream = strtoul( argv[1], NULL, 0 );
75 uint32_t uBlock = uStream;
76
77 Block b;
78
79 for(;;)
80 {
81 fIn.setPos( n.getBlockStart()+n.getBlockSize()*uBlock );
82 fIn.read( &b, sizeof(Block) );
83 printf("Stream %u: block %u, next %u, %ub used.\n",
84 uStream, uBlock, b.uNextBlock, b.uBytesUsed
85 );
86 if( b.uNextBlock == 0xFFFFFFFFUL )
87 break;
88 uBlock = b.uNextBlock;
89 }
90 printf("Stream End.\n");
91
92 return 2;
93 }
94
95 return 1;
96 }
97
98 int procDump( int argc, char *argv[] )
99 {
100 if( argc < 3 )
101 {
102 printf("You must provide a nids file, a stream id, and an output "
103 "file.\n");
104 exit( 1 );
105 }
106
107 Bu::File fIn( argv[0], Bu::File::Read );
108 Bu::Nids n( fIn );
109 n.initialize();
110
111 int iStream = strtol( argv[1], NULL, 0 );
112 Bu::NidsStream sIn = n.openStream( iStream );
113
114 Bu::File fOut( argv[2], Bu::File::Write|Bu::File::Create );
115 int iTotal = 0;
116 char buf[100];
117 for(;;)
118 {
119 int iRead = sIn.read( buf, 100 );
120 iTotal += fOut.write( buf, iRead );
121 if( iRead < 100 )
122 break;
123 }
124
125 printf("Wrote %db from stream %d in %s to %s.\n",
126 iTotal, iStream, argv[0], argv[2] );
127 return 3;
128 }
129
130 int procAnalyze( int argc, char *argv[] )
131 {
132 if( argc < 1 )
133 {
134 printf("You must provide a file name.\n");
135 exit( 1 );
136 }
137
138 Bu::File fIn( argv[0], Bu::File::Read );
139 Bu::Nids n( fIn );
140 n.initialize();
141
142 printInfo( n );
143
144 int iStreamCnt = 0;
145 int iStreamTotal = 0;
146 int iOneBlock = 0;
147 uint32_t iLargest = 0;
148 uint32_t iSmallest = 0;
149 int iWaste = 0;
150 int iUsable = n.getBlockSize()-n.getBlockOverhead();
151 Block b;
152 for( int j = 0; j < n.getNumBlocks(); j++ )
153 {
154 fIn.setPos( n.getBlockStart()+n.getBlockSize()*j );
155 fIn.read( &b, sizeof(Block) );
156 if( b.uFirstBlock != (uint32_t)j )
157 continue;
158
159 iStreamCnt++;
160 iStreamTotal += b.uBytesUsed;
161
162 if( b.uNextBlock == 0xFFFFFFFFUL )
163 {
164 iOneBlock++;
165 iWaste += iUsable - b.uBytesUsed;
166 }
167 else
168 {
169 iWaste += iUsable - (b.uBytesUsed%iUsable);
170 }
171
172 if( j == 0 )
173 {
174 iSmallest = iLargest = b.uBytesUsed;
175 }
176 else
177 {
178 if( iLargest < b.uBytesUsed )
179 iLargest = b.uBytesUsed;
180 if( iSmallest > b.uBytesUsed )
181 iSmallest = b.uBytesUsed;
182 }
183 }
184 printf("Steam analysis:\n");
185 printf(" Stream count: %d\n", iStreamCnt );
186 printf(" Stream size: %db/%db/%db (min/avr/max)\n",
187 iSmallest, iStreamTotal/iStreamCnt, iLargest );
188 printf(" One-block streams: %d (%d%%)\n",
189 iOneBlock, iOneBlock*100/iStreamCnt );
190 printf(" Total wasted space: %db (%d%%)\n",
191 iWaste, iWaste*100/iStreamTotal );
192 printf(" Avr blocks-per-stream: %f%%\n",
193 (float)n.getNumBlocks()/(float)iStreamCnt );
194
195 return 1;
196 }
197
198 int procCopy( int argc, char *argv[] )
199 {
200 if( argc < 3 )
201 {
202 printf("You must provide source stream, blocksize, destination.\n");
203 exit( 1 );
204 }
205
206 Bu::File fIn( argv[0], Bu::File::Read );
207 Bu::Nids nIn( fIn );
208 nIn.initialize();
209
210 Bu::File fOut( argv[2], Bu::File::Read|Bu::File::Write|Bu::File::Create|
211 Bu::File::Truncate );
212 Bu::Nids nOut( fOut );
213 nOut.initialize( strtol( argv[1], 0, NULL ) );
214
215 Block b;
216 for( int j = 0; j < nIn.getNumBlocks(); j++ )
217 {
218 fIn.setPos( nIn.getBlockStart()+nIn.getBlockSize()*j );
219 fIn.read( &b, sizeof(Block) );
220 if( b.uFirstBlock != (uint32_t)j )
221 continue;
222
223 Bu::NidsStream sIn = nIn.openStream( j );
224 int iNew = nOut.createStream();
225 Bu::NidsStream sOut = nOut.openStream( iNew );
226
227 char buf[1024];
228 for(;;)
229 {
230 int iRead = sIn.read( buf, 1024 );
231 sOut.write( buf, iRead );
232 if( iRead < 1024 )
233 break;
234 }
235 }
236
237 return 3;
238 }
239};
240
241
242int main( int argc, char *argv[] )
243{
244 Param p( argc, argv );
245
246 return 0;
247}
248
diff --git a/src/unit/archive.unit b/src/unit/archive.unit
index a0ae3ef..a7f2640 100644
--- a/src/unit/archive.unit
+++ b/src/unit/archive.unit
@@ -12,184 +12,185 @@
12 12
13using namespace Bu; 13using namespace Bu;
14 14
15{=Init} 15suite Archive
16
17{%testPrimitives}
18{ 16{
19 MemBuf mb; 17 test primitives
20 {
21 Archive ar( mb, Archive::save );
22 ar << (int8_t)1;
23 ar << (uint8_t)2;
24 ar << (int16_t)3;
25 ar << (uint16_t)4;
26 ar << (int32_t)5;
27 ar << (uint32_t)6;
28 ar << (int64_t)7;
29 ar << (uint64_t)8;
30 ar << (char)9;
31 ar << (unsigned char)10;
32 ar << (short)11;
33 ar << (unsigned short)12;
34 ar << (int)13;
35 ar << (unsigned int)14;
36 ar << (long)15;
37 ar << (unsigned long)16;
38 ar << (long long)17;
39 ar << (unsigned long long)18;
40 ar.close();
41 }
42 mb.setPos( 0 );
43 { 18 {
44 Archive ar( mb, Archive::load ); 19 MemBuf mb;
45 int8_t p1; 20 {
46 uint8_t p2; 21 Archive ar( mb, Archive::save );
47 int16_t p3; 22 ar << (int8_t)1;
48 uint16_t p4; 23 ar << (uint8_t)2;
49 int32_t p5; 24 ar << (int16_t)3;
50 uint32_t p6; 25 ar << (uint16_t)4;
51 int64_t p7; 26 ar << (int32_t)5;
52 uint64_t p8; 27 ar << (uint32_t)6;
53 char p9; 28 ar << (int64_t)7;
54 unsigned char p10; 29 ar << (uint64_t)8;
55 short p11; 30 ar << (char)9;
56 unsigned short p12; 31 ar << (unsigned char)10;
57 int p13; 32 ar << (short)11;
58 unsigned int p14; 33 ar << (unsigned short)12;
59 long p15; 34 ar << (int)13;
60 unsigned long p16; 35 ar << (unsigned int)14;
61 long long p17; 36 ar << (long)15;
62 unsigned long long p18; 37 ar << (unsigned long)16;
63 ar >> p1; 38 ar << (long long)17;
64 ar >> p2; 39 ar << (unsigned long long)18;
65 ar >> p3; 40 ar.close();
66 ar >> p4; 41 }
67 ar >> p5; 42 mb.setPos( 0 );
68 ar >> p6; 43 {
69 ar >> p7; 44 Archive ar( mb, Archive::load );
70 ar >> p8; 45 int8_t p1;
71 ar >> p9; 46 uint8_t p2;
72 ar >> p10; 47 int16_t p3;
73 ar >> p11; 48 uint16_t p4;
74 ar >> p12; 49 int32_t p5;
75 ar >> p13; 50 uint32_t p6;
76 ar >> p14; 51 int64_t p7;
77 ar >> p15; 52 uint64_t p8;
78 ar >> p16; 53 char p9;
79 ar >> p17; 54 unsigned char p10;
80 ar >> p18; 55 short p11;
81 unitTest( p1 == 1 ); 56 unsigned short p12;
82 unitTest( p2 == 2 ); 57 int p13;
83 unitTest( p3 == 3 ); 58 unsigned int p14;
84 unitTest( p4 == 4 ); 59 long p15;
85 unitTest( p5 == 5 ); 60 unsigned long p16;
86 unitTest( p6 == 6 ); 61 long long p17;
87 unitTest( p7 == 7 ); 62 unsigned long long p18;
88 unitTest( p8 == 8 ); 63 ar >> p1;
89 unitTest( p9 == 9 ); 64 ar >> p2;
90 unitTest( p10 == 10 ); 65 ar >> p3;
91 unitTest( p11 == 11 ); 66 ar >> p4;
92 unitTest( p12 == 12 ); 67 ar >> p5;
93 unitTest( p13 == 13 ); 68 ar >> p6;
94 unitTest( p14 == 14 ); 69 ar >> p7;
95 unitTest( p15 == 15 ); 70 ar >> p8;
96 unitTest( p16 == 16 ); 71 ar >> p9;
97 unitTest( p17 == 17 ); 72 ar >> p10;
98 unitTest( p18 == 18 ); 73 ar >> p11;
99 ar.close(); 74 ar >> p12;
75 ar >> p13;
76 ar >> p14;
77 ar >> p15;
78 ar >> p16;
79 ar >> p17;
80 ar >> p18;
81 unitTest( p1 == 1 );
82 unitTest( p2 == 2 );
83 unitTest( p3 == 3 );
84 unitTest( p4 == 4 );
85 unitTest( p5 == 5 );
86 unitTest( p6 == 6 );
87 unitTest( p7 == 7 );
88 unitTest( p8 == 8 );
89 unitTest( p9 == 9 );
90 unitTest( p10 == 10 );
91 unitTest( p11 == 11 );
92 unitTest( p12 == 12 );
93 unitTest( p13 == 13 );
94 unitTest( p14 == 14 );
95 unitTest( p15 == 15 );
96 unitTest( p16 == 16 );
97 unitTest( p17 == 17 );
98 unitTest( p18 == 18 );
99 ar.close();
100 }
100 } 101 }
101}
102 102
103{%testContainers1} 103 test containers1
104{
105 MemBuf mb;
106 {
107 Archive ar( mb, Archive::save );
108 FString sStr("This is a test string.");
109 List<int> lList;
110 lList.append( 10 );
111 lList.append( 20 );
112 lList.append( 30 );
113 lList.append( 40 );
114 ar << sStr;
115 ar << lList;
116 ar.close();
117 }
118 mb.setPos( 0 );
119 { 104 {
120 Archive ar( mb, Archive::load ); 105 MemBuf mb;
121 FString sStr; 106 {
122 List<int> lList; 107 Archive ar( mb, Archive::save );
123 ar >> sStr; 108 FString sStr("This is a test string.");
124 ar >> lList; 109 List<int> lList;
125 unitTest( sStr == "This is a test string." ); 110 lList.append( 10 );
126 unitTest( lList.getSize() == 4 ); 111 lList.append( 20 );
127 List<int>::iterator i = lList.begin(); 112 lList.append( 30 );
128 unitTest( *i == 10 ); i++; 113 lList.append( 40 );
129 unitTest( *i == 20 ); i++; 114 ar << sStr;
130 unitTest( *i == 30 ); i++; 115 ar << lList;
131 unitTest( *i == 40 ); 116 ar.close();
132 ar.close(); 117 }
118 mb.setPos( 0 );
119 {
120 Archive ar( mb, Archive::load );
121 FString sStr;
122 List<int> lList;
123 ar >> sStr;
124 ar >> lList;
125 unitTest( sStr == "This is a test string." );
126 unitTest( lList.getSize() == 4 );
127 List<int>::iterator i = lList.begin();
128 unitTest( *i == 10 ); i++;
129 unitTest( *i == 20 ); i++;
130 unitTest( *i == 30 ); i++;
131 unitTest( *i == 40 );
132 ar.close();
133 }
133 } 134 }
134}
135 135
136{%testContainers2} 136 test containers2
137{
138 MemBuf mb;
139 {
140 Archive ar( mb, Archive::save );
141 FString sStr("This is a test string.");
142 Array<int> lArray;
143 lArray.append( 10 );
144 lArray.append( 20 );
145 lArray.append( 30 );
146 lArray.append( 40 );
147 ar << sStr;
148 ar << lArray;
149 ar.close();
150 }
151 mb.setPos( 0 );
152 { 137 {
153 Archive ar( mb, Archive::load ); 138 MemBuf mb;
154 FString sStr; 139 {
155 Array<int> lArray; 140 Archive ar( mb, Archive::save );
156 ar >> sStr; 141 FString sStr("This is a test string.");
157 ar >> lArray; 142 Array<int> lArray;
158 unitTest( sStr == "This is a test string." ); 143 lArray.append( 10 );
159 unitTest( lArray.getSize() == 4 ); 144 lArray.append( 20 );
160 Array<int>::iterator i = lArray.begin(); 145 lArray.append( 30 );
161 unitTest( *i == 10 ); i++; 146 lArray.append( 40 );
162 unitTest( *i == 20 ); i++; 147 ar << sStr;
163 unitTest( *i == 30 ); i++; 148 ar << lArray;
164 unitTest( *i == 40 ); 149 ar.close();
165 ar.close(); 150 }
151 mb.setPos( 0 );
152 {
153 Archive ar( mb, Archive::load );
154 FString sStr;
155 Array<int> lArray;
156 ar >> sStr;
157 ar >> lArray;
158 unitTest( sStr == "This is a test string." );
159 unitTest( lArray.getSize() == 4 );
160 Array<int>::iterator i = lArray.begin();
161 unitTest( *i == 10 ); i++;
162 unitTest( *i == 20 ); i++;
163 unitTest( *i == 30 ); i++;
164 unitTest( *i == 40 );
165 ar.close();
166 }
166 } 167 }
167}
168 168
169{%testContainers3} 169 test containers3
170{
171 MemBuf mb;
172 {
173 Archive ar( mb, Archive::save );
174 Array<FString> lArray;
175 lArray.append( "10" );
176 lArray.append( "20" );
177 lArray.append( "30" );
178 lArray.append( "40" );
179 ar << lArray;
180 ar.close();
181 }
182 mb.setPos( 0 );
183 { 170 {
184 Archive ar( mb, Archive::load ); 171 MemBuf mb;
185 Array<FString> lArray; 172 {
186 ar >> lArray; 173 Archive ar( mb, Archive::save );
187 unitTest( lArray.getSize() == 4 ); 174 Array<FString> lArray;
188 Array<FString>::iterator i = lArray.begin(); 175 lArray.append( "10" );
189 unitTest( *i == "10" ); i++; 176 lArray.append( "20" );
190 unitTest( *i == "20" ); i++; 177 lArray.append( "30" );
191 unitTest( *i == "30" ); i++; 178 lArray.append( "40" );
192 unitTest( *i == "40" ); 179 ar << lArray;
193 ar.close(); 180 ar.close();
181 }
182 mb.setPos( 0 );
183 {
184 Archive ar( mb, Archive::load );
185 Array<FString> lArray;
186 ar >> lArray;
187 unitTest( lArray.getSize() == 4 );
188 Array<FString>::iterator i = lArray.begin();
189 unitTest( *i == "10" ); i++;
190 unitTest( *i == "20" ); i++;
191 unitTest( *i == "30" ); i++;
192 unitTest( *i == "40" );
193 ar.close();
194 }
194 } 195 }
195} 196}
diff --git a/src/unit/array.unit b/src/unit/array.unit
index ad249ef..1493033 100644
--- a/src/unit/array.unit
+++ b/src/unit/array.unit
@@ -9,76 +9,77 @@
9#include "bu/hash.h" 9#include "bu/hash.h"
10#include "bu/array.h" 10#include "bu/array.h"
11 11
12{=Init} 12suite Array
13
14{%general}
15{ 13{
16 Bu::Array<int> ai; 14 test general
15 {
16 Bu::Array<int> ai;
17 17
18 ai.append( 5 ); 18 ai.append( 5 );
19 ai.append( 10 ); 19 ai.append( 10 );
20 unitTest( ai.getSize() == 2 ); 20 unitTest( ai.getSize() == 2 );
21 unitTest( ai.getCapacity() == 10 ); 21 unitTest( ai.getCapacity() == 10 );
22 unitTest( ai[0] == 5 ); 22 unitTest( ai[0] == 5 );
23 unitTest( ai[1] == 10 ); 23 unitTest( ai[1] == 10 );
24} 24 }
25 25
26{%iterate1} 26 test iterate1
27{ 27 {
28 Bu::Array<int> ai; 28 Bu::Array<int> ai;
29 for( int j = 0; j < 10; j++ ) 29 for( int j = 0; j < 10; j++ )
30 ai.append( j ); 30 ai.append( j );
31 31
32 int j = 0; 32 int j = 0;
33 for( Bu::Array<int>::iterator i = ai.begin(); i != ai.end(); i++ ) 33 for( Bu::Array<int>::iterator i = ai.begin(); i != ai.end(); i++ )
34 unitTest( (*i) == j++ ); 34 unitTest( (*i) == j++ );
35 unitTest( j == 10 ); 35 unitTest( j == 10 );
36 36
37 const Bu::Array<int> &ci = ai; 37 const Bu::Array<int> &ci = ai;
38 j = 0; 38 j = 0;
39 for( Bu::Array<int>::const_iterator i = ci.begin(); i; i++ ) 39 for( Bu::Array<int>::const_iterator i = ci.begin(); i; i++ )
40 unitTest( (*i) == j++ ); 40 unitTest( (*i) == j++ );
41 unitTest( j == 10 ); 41 unitTest( j == 10 );
42} 42 }
43 43
44{%iterate2} 44 test iterate2
45{ 45 {
46 Bu::Array<int> ai; 46 Bu::Array<int> ai;
47 for( Bu::Array<int>::iterator i = ai.begin(); i != ai.end(); i++ ) 47 for( Bu::Array<int>::iterator i = ai.begin(); i != ai.end(); i++ )
48 unitFailed("Empty lists shouldn't be iterated through."); 48 unitFailed("Empty lists shouldn't be iterated through.");
49 for( Bu::Array<int>::iterator i = ai.begin(); i; i++ ) 49 for( Bu::Array<int>::iterator i = ai.begin(); i; i++ )
50 unitFailed("Empty lists shouldn't be iterated through."); 50 unitFailed("Empty lists shouldn't be iterated through.");
51} 51 }
52 52
53{%copy} 53 test copy
54{ 54 {
55 typedef Bu::Hash<Bu::FString, Bu::FString> StrHash; 55 typedef Bu::Hash<Bu::FString, Bu::FString> StrHash;
56 typedef Bu::Array<StrHash> StrHashArray; 56 typedef Bu::Array<StrHash> StrHashArray;
57 57
58 StrHash h1; 58 StrHash h1;
59 h1["Hi"] = "Yo"; 59 h1["Hi"] = "Yo";
60 h1["Bye"] = "Later"; 60 h1["Bye"] = "Later";
61 61
62 StrHash h2; 62 StrHash h2;
63 h2["Test"] = "Bloop"; 63 h2["Test"] = "Bloop";
64 h2["Foo"] = "ooF"; 64 h2["Foo"] = "ooF";
65 65
66 StrHashArray a1; 66 StrHashArray a1;
67 a1.append( h1 ); 67 a1.append( h1 );
68 a1.append( h2 ); 68 a1.append( h2 );
69 69
70 StrHashArray a2(a1); 70 StrHashArray a2(a1);
71 71
72 unitTest( a2[0].get("Hi") == "Yo" ); 72 unitTest( a2[0].get("Hi") == "Yo" );
73 unitTest( a2[0].get("Bye") == "Later" ); 73 unitTest( a2[0].get("Bye") == "Later" );
74 unitTest( a2[1].get("Test") == "Bloop" ); 74 unitTest( a2[1].get("Test") == "Bloop" );
75 unitTest( a2[1].get("Foo") == "ooF" ); 75 unitTest( a2[1].get("Foo") == "ooF" );
76 76
77 StrHashArray a3; 77 StrHashArray a3;
78 a3 = a1; 78 a3 = a1;
79 79
80 unitTest( a3[0].get("Hi") == "Yo" ); 80 unitTest( a3[0].get("Hi") == "Yo" );
81 unitTest( a3[0].get("Bye") == "Later" ); 81 unitTest( a3[0].get("Bye") == "Later" );
82 unitTest( a3[1].get("Test") == "Bloop" ); 82 unitTest( a3[1].get("Test") == "Bloop" );
83 unitTest( a3[1].get("Foo") == "ooF" ); 83 unitTest( a3[1].get("Foo") == "ooF" );
84 }
84} 85}
diff --git a/src/unit/file.unit b/src/unit/file.unit
index 11c82fb..f8cf7c1 100644
--- a/src/unit/file.unit
+++ b/src/unit/file.unit
@@ -12,84 +12,85 @@
12#include <sys/stat.h> 12#include <sys/stat.h>
13#include <unistd.h> 13#include <unistd.h>
14 14
15{=Init} 15suite File
16
17{%writeFull}
18{ 16{
19 Bu::File sf("testfile1", Bu::File::WriteNew ); 17 test writeFull
20 for( int c = 0; c < 256; c++ )
21 { 18 {
22 unsigned char ch = (unsigned char)c; 19 Bu::File sf("testfile1", Bu::File::WriteNew );
23 sf.write( &ch, 1 ); 20 for( int c = 0; c < 256; c++ )
24 unitTest( sf.tell() == c+1 ); 21 {
22 unsigned char ch = (unsigned char)c;
23 sf.write( &ch, 1 );
24 unitTest( sf.tell() == c+1 );
25 }
26 //unitTest( sf.canRead() == false );
27 //unitTest( sf.canWrite() == true );
28 //unitTest( sf.canSeek() == true );
29 sf.close();
30 struct stat sdat;
31 stat("testfile1", &sdat );
32 unitTest( sdat.st_size == 256 );
25 } 33 }
26 //unitTest( sf.canRead() == false );
27 //unitTest( sf.canWrite() == true );
28 //unitTest( sf.canSeek() == true );
29 sf.close();
30 struct stat sdat;
31 stat("testfile1", &sdat );
32 unitTest( sdat.st_size == 256 );
33}
34 34
35{%readBlocks} 35 test readBlocks
36{
37 Bu::File sf("testfile1", Bu::File::Read );
38 unsigned char buf[50];
39 size_t total = 0;
40 for(;;)
41 { 36 {
42 size_t s = sf.read( buf, 50 ); 37 Bu::File sf("testfile1", Bu::File::Read );
43 for( size_t c = 0; c < s; c++ ) 38 unsigned char buf[50];
39 size_t total = 0;
40 for(;;)
44 { 41 {
45 unitTest( buf[c] == (unsigned char)(c+total) ); 42 size_t s = sf.read( buf, 50 );
46 } 43 for( size_t c = 0; c < s; c++ )
47 total += s; 44 {
48 if( s < 50 ) 45 unitTest( buf[c] == (unsigned char)(c+total) );
49 { 46 }
50 unitTest( total == 256 ); 47 total += s;
51 unitTest( sf.isEos() == true ); 48 if( s < 50 )
52 break; 49 {
50 unitTest( total == 256 );
51 unitTest( sf.isEos() == true );
52 break;
53 }
53 } 54 }
55 sf.close();
54 } 56 }
55 sf.close();
56}
57 57
58{%readError1} 58 test readError1
59{
60 try
61 { 59 {
62 Bu::File sf("doesn'texist", Bu::File::Read ); 60 try
63 unitFailed("No exception thrown"); 61 {
64 } 62 Bu::File sf("doesn'texist", Bu::File::Read );
65 catch( Bu::FileException &e ) 63 unitFailed("No exception thrown");
66 { 64 }
67 return; 65 catch( Bu::FileException &e )
66 {
67 return;
68 }
68 } 69 }
69}
70 70
71{%readError2} 71 test readError2
72{
73 Bu::File sf("testfile1", Bu::File::Read );
74 char buf[256];
75 int r = sf.read( buf, 256 );
76 unitTest( r == 256 );
77 // You have to read past the end to set the EOS flag.
78 unitTest( sf.isEos() == false );
79 try
80 { 72 {
81 if( sf.read( buf, 5 ) > 0 ) 73 Bu::File sf("testfile1", Bu::File::Read );
74 char buf[256];
75 int r = sf.read( buf, 256 );
76 unitTest( r == 256 );
77 // You have to read past the end to set the EOS flag.
78 unitTest( sf.isEos() == false );
79 try
82 { 80 {
83 unitFailed("Non-zero read result"); 81 if( sf.read( buf, 5 ) > 0 )
82 {
83 unitFailed("Non-zero read result");
84 }
85 else
86 {
87 sf.close();
88 }
84 } 89 }
85 else 90 catch( Bu::FileException &e )
86 { 91 {
87 sf.close(); 92 sf.close();
93 return;
88 } 94 }
89 } 95 }
90 catch( Bu::FileException &e )
91 {
92 sf.close();
93 return;
94 }
95} 96}
diff --git a/src/unit/fstring.unit b/src/unit/fstring.unit
index 8aaae93..00b6eed 100644
--- a/src/unit/fstring.unit
+++ b/src/unit/fstring.unit
@@ -10,333 +10,333 @@
10 10
11#include <dirent.h> 11#include <dirent.h>
12 12
13{=Init} 13suite FString
14
15{%compare1}
16{ 14{
17 Bu::FString b("Bob"); 15 test compare1
18 unitTest( !(b == "Bobo") ); 16 {
19 unitTest( b == "Bob" ); 17 Bu::FString b("Bob");
20} 18 unitTest( !(b == "Bobo") );
19 unitTest( b == "Bob" );
20 }
21 21
22{%compare2} 22 test compare2
23{ 23 {
24 Bu::FString b("Bobo"); 24 Bu::FString b("Bobo");
25 unitTest( !(b == "Bob") ); 25 unitTest( !(b == "Bob") );
26 unitTest( b == "Bobo" ); 26 unitTest( b == "Bobo" );
27} 27 }
28 28
29{%appendSingle} 29 test appendSingle
30{ 30 {
31 Bu::FString b; 31 Bu::FString b;
32 for( char l = 'a'; l < 'g'; l++ ) 32 for( char l = 'a'; l < 'g'; l++ )
33 b += l; 33 b += l;
34 unitTest( b == "abcdef" ); 34 unitTest( b == "abcdef" );
35 unitTest( strcmp( b.getStr(), "abcdef" ) == 0 ); 35 unitTest( strcmp( b.getStr(), "abcdef" ) == 0 );
36} 36 }
37 37
38{%shared1} 38 test shared1
39{ 39 {
40 Bu::FString a("Hey there"); 40 Bu::FString a("Hey there");
41 Bu::FString b( a ); 41 Bu::FString b( a );
42 unitTest( a.getConstStr() == b.getConstStr() ); 42 unitTest( a.getConstStr() == b.getConstStr() );
43 b += " guy"; 43 b += " guy";
44 unitTest( a.getConstStr() != b.getConstStr() ); 44 unitTest( a.getConstStr() != b.getConstStr() );
45 a = b; 45 a = b;
46 unitTest( a.getConstStr() == b.getConstStr() ); 46 unitTest( a.getConstStr() == b.getConstStr() );
47} 47 }
48 48
49{%insert} 49 test insert
50{ 50 {
51 Bu::FString a("abcd"); 51 Bu::FString a("abcd");
52 a.insert( 2, "-!-", 3 ); 52 a.insert( 2, "-!-", 3 );
53 unitTest( a == "ab-!-cd" ); 53 unitTest( a == "ab-!-cd" );
54 54
55 a.insert( 0, "!!", 2 ); 55 a.insert( 0, "!!", 2 );
56 unitTest( a == "!!ab-!-cd" ); 56 unitTest( a == "!!ab-!-cd" );
57 57
58 a.insert( -10, "789", 3 ); 58 a.insert( -10, "789", 3 );
59 unitTest( a == "789!!ab-!-cd" ); 59 unitTest( a == "789!!ab-!-cd" );
60 60
61 a.insert( 12, "89", 2 ); 61 a.insert( 12, "89", 2 );
62 unitTest( a == "789!!ab-!-cd89" ); 62 unitTest( a == "789!!ab-!-cd89" );
63 63
64 a.insert( 1203, "12", 2 ); 64 a.insert( 1203, "12", 2 );
65 unitTest( a == "789!!ab-!-cd8912" ); 65 unitTest( a == "789!!ab-!-cd8912" );
66} 66 }
67 67
68{%remove} 68 test remove
69{ 69 {
70 Bu::FString a("abHEYcd"); 70 Bu::FString a("abHEYcd");
71 a.remove( 2, 3 ); 71 a.remove( 2, 3 );
72 unitTest( a == "abcd" ); 72 unitTest( a == "abcd" );
73 a.remove( 2, 5 ); 73 a.remove( 2, 5 );
74 unitTest( a == "ab" ); 74 unitTest( a == "ab" );
75 a += "cdefghijklmnop"; 75 a += "cdefghijklmnop";
76 a.remove( 5, 1 ); 76 a.remove( 5, 1 );
77 unitTest( a == "abcdeghijklmnop" ); 77 unitTest( a == "abcdeghijklmnop" );
78} 78 }
79 79
80{%add1} 80 test add1
81{ 81 {
82 Bu::FString a("hi there"); 82 Bu::FString a("hi there");
83 Bu::FString b(", yeah!"); 83 Bu::FString b(", yeah!");
84 Bu::FString c = a + b; 84 Bu::FString c = a + b;
85 85
86 unitTest( c == "hi there, yeah!" ); 86 unitTest( c == "hi there, yeah!" );
87} 87 }
88 88
89{%add2} 89 test add2
90{ 90 {
91 Bu::FString a("hi there"); 91 Bu::FString a("hi there");
92 Bu::FString c = a + ", yeah!"; 92 Bu::FString c = a + ", yeah!";
93 93
94 unitTest( c == "hi there, yeah!" ); 94 unitTest( c == "hi there, yeah!" );
95} 95 }
96 96
97{%add3} 97 test add3
98{ 98 {
99 Bu::FString a("hi there"); 99 Bu::FString a("hi there");
100 Bu::FString b(", yeah!"); 100 Bu::FString b(", yeah!");
101 Bu::FString c = a + ", Mr. Man" + b; 101 Bu::FString c = a + ", Mr. Man" + b;
102 102
103 unitTest( c == "hi there, Mr. Man, yeah!" ); 103 unitTest( c == "hi there, Mr. Man, yeah!" );
104} 104 }
105 105
106{%add4} 106 test add4
107{ 107 {
108 Bu::FString b(", yeah!"); 108 Bu::FString b(", yeah!");
109 Bu::FString c = "hi there" + b; 109 Bu::FString c = "hi there" + b;
110 110
111 unitTest( c == "hi there, yeah!" ); 111 unitTest( c == "hi there, yeah!" );
112} 112 }
113 113
114{%add5} 114 test add5
115{ 115 {
116 Bu::FString b; 116 Bu::FString b;
117 Bu::FString c = "sup?"; 117 Bu::FString c = "sup?";
118 b += "hey, " + c; 118 b += "hey, " + c;
119 119
120 unitTest( b == "hey, sup?" ); 120 unitTest( b == "hey, sup?" );
121} 121 }
122 122
123{%add6} 123 test add6
124{ 124 {
125 Bu::FString a("Hello"); 125 Bu::FString a("Hello");
126 char b[256] = {"Dude"}; 126 char b[256] = {"Dude"};
127 Bu::FString c = a + "/" + b; 127 Bu::FString c = a + "/" + b;
128 128
129 unitTest( c == "Hello/Dude" ); 129 unitTest( c == "Hello/Dude" );
130} 130 }
131 131
132{%add7} 132 test add7
133{ 133 {
134 const Bu::FString a("hello "); 134 const Bu::FString a("hello ");
135 Bu::FString b(" how "); 135 Bu::FString b(" how ");
136 unitTest( a == "hello " ); 136 unitTest( a == "hello " );
137 unitTest( a + "dude" == "hello dude" ); 137 unitTest( a + "dude" == "hello dude" );
138 unitTest( a + "dude" + b + "are you?" == "hello dude how are you?" ); 138 unitTest( a + "dude" + b + "are you?" == "hello dude how are you?" );
139} 139 }
140 140
141{%subStr1} 141 test subStr1
142{ 142 {
143 Bu::FString a("abcdefghijklmnop"); 143 Bu::FString a("abcdefghijklmnop");
144 Bu::FString::iterator i = a.find('f'); 144 Bu::FString::iterator i = a.find('f');
145 unitTest( a.getSubStr( i, Bu::FString::iterator() ) == "fghijklmnop" ); 145 unitTest( a.getSubStr( i, Bu::FString::iterator() ) == "fghijklmnop" );
146 Bu::FString::iterator j = i.find('l'); 146 Bu::FString::iterator j = i.find('l');
147 unitTest( a.getSubStr( i, j ) == "fghijk" ); 147 unitTest( a.getSubStr( i, j ) == "fghijk" );
148} 148 }
149 149
150{%compareSub1} 150 test compareSub1
151{ 151 {
152 Bu::FString a("just a string."); 152 Bu::FString a("just a string.");
153 unitTest( a.compareSub("a ", 5, 2) == true ); 153 unitTest( a.compareSub("a ", 5, 2) == true );
154 unitTest( a.compareSub("string.aoeu", 7, 11 ) == false ); 154 unitTest( a.compareSub("string.aoeu", 7, 11 ) == false );
155 unitTest( a.compareSub("string.aoeu", 7, 3 ) == true ); 155 unitTest( a.compareSub("string.aoeu", 7, 3 ) == true );
156} 156 }
157 157
158{%compareSub2} 158 test compareSub2
159{ 159 {
160 Bu::FString a("just a string."); 160 Bu::FString a("just a string.");
161 unitTest( a.compareSub(Bu::FString("a "), 5, 2) == true ); 161 unitTest( a.compareSub(Bu::FString("a "), 5, 2) == true );
162 unitTest( a.compareSub(Bu::FString("string.aoeu"), 7, 11 ) == false ); 162 unitTest( a.compareSub(Bu::FString("string.aoeu"), 7, 11 ) == false );
163 unitTest( a.compareSub(Bu::FString("string.aoeu"), 7, 3 ) == true ); 163 unitTest( a.compareSub(Bu::FString("string.aoeu"), 7, 3 ) == true );
164} 164 }
165 165
166{%iterator1} 166 test iterator1
167{
168 Bu::FString a("This is a test.");
169 Bu::FString b;
170 for( Bu::FString::iterator i = a.begin(); i; i++ )
171 { 167 {
172 b += *i; 168 Bu::FString a("This is a test.");
169 Bu::FString b;
170 for( Bu::FString::iterator i = a.begin(); i; i++ )
171 {
172 b += *i;
173 }
174 unitTest( a == b );
173 } 175 }
174 unitTest( a == b );
175}
176 176
177{%iterator2} 177 test iterator2
178{ 178 {
179 Bu::FString a("This is a test."); 179 Bu::FString a("This is a test.");
180 Bu::FString b("--This is a test."); 180 Bu::FString b("--This is a test.");
181 Bu::FString::iterator ai = a.begin(); 181 Bu::FString::iterator ai = a.begin();
182 Bu::FString::iterator bi = b.begin(); 182 Bu::FString::iterator bi = b.begin();
183 unitTest( ai.compare( bi ) == false ); 183 unitTest( ai.compare( bi ) == false );
184 unitTest( bi.compare( ai ) == false ); 184 unitTest( bi.compare( ai ) == false );
185 bi++; bi++; 185 bi++; bi++;
186 unitTest( ai.compare( bi ) == true ); 186 unitTest( ai.compare( bi ) == true );
187 unitTest( bi.compare( ai ) == true ); 187 unitTest( bi.compare( ai ) == true );
188} 188 }
189 189
190{%iterator3} 190 test iterator3
191{ 191 {
192 Bu::FString a("1234honour"); 192 Bu::FString a("1234honour");
193 Bu::FString b("--1234ueje"); 193 Bu::FString b("--1234ueje");
194 Bu::FString::iterator ai = a.begin(); 194 Bu::FString::iterator ai = a.begin();
195 Bu::FString::iterator bi = b.begin(); 195 Bu::FString::iterator bi = b.begin();
196 unitTest( ai.compare( bi, 4 ) == false ); 196 unitTest( ai.compare( bi, 4 ) == false );
197 unitTest( bi.compare( ai, 4 ) == false ); 197 unitTest( bi.compare( ai, 4 ) == false );
198 bi++; bi++; 198 bi++; bi++;
199 unitTest( ai.compare( bi, 4 ) == true ); 199 unitTest( ai.compare( bi, 4 ) == true );
200 unitTest( bi.compare( ai, 4 ) == true ); 200 unitTest( bi.compare( ai, 4 ) == true );
201 unitTest( ai.compare( bi, 5 ) == false ); 201 unitTest( ai.compare( bi, 5 ) == false );
202 unitTest( bi.compare( ai, 5 ) == false ); 202 unitTest( bi.compare( ai, 5 ) == false );
203 203
204} 204 }
205 205
206{%iterator4} 206 test iterator4
207{ 207 {
208 Bu::FString a("1234aoeu"); 208 Bu::FString a("1234aoeu");
209 Bu::FString::iterator ai = a.begin(); 209 Bu::FString::iterator ai = a.begin();
210 unitTest( ai.compare("1234") == false ); 210 unitTest( ai.compare("1234") == false );
211 unitTest( ai.compare("1234aoeu") == true ); 211 unitTest( ai.compare("1234aoeu") == true );
212 unitTest( ai.compare("1234aoeuee") == false ); 212 unitTest( ai.compare("1234aoeuee") == false );
213} 213 }
214 214
215{%iterator5} 215 test iterator5
216{ 216 {
217 Bu::FString a("1234aoeu"); 217 Bu::FString a("1234aoeu");
218 Bu::FString::iterator ai = a.begin(); 218 Bu::FString::iterator ai = a.begin();
219 unitTest( ai.compare("1234", 4) == true ); 219 unitTest( ai.compare("1234", 4) == true );
220 unitTest( ai.compare("1234aoeu", 8) == true ); 220 unitTest( ai.compare("1234aoeu", 8) == true );
221 unitTest( ai.compare("1234aoeuee", 10) == false ); 221 unitTest( ai.compare("1234aoeuee", 10) == false );
222} 222 }
223 223
224{%iterator6} 224 test iterator6
225{
226 Bu::FString a("just ->this part");
227 Bu::FString b;
228 Bu::FString::iterator s = a.begin();
229 for(; s; s++ )
230 { 225 {
231 if( *s == '>' ) 226 Bu::FString a("just ->this part");
227 Bu::FString b;
228 Bu::FString::iterator s = a.begin();
229 for(; s; s++ )
232 { 230 {
233 s++; 231 if( *s == '>' )
234 b.set( s ); 232 {
235 break; 233 s++;
234 b.set( s );
235 break;
236 }
236 } 237 }
237 } 238 unitTest( b == "this part" );
238 unitTest( b == "this part" );
239 239
240 b.append( s ); 240 b.append( s );
241 241
242 Bu::FString c; 242 Bu::FString c;
243 c.set( b.begin() ); 243 c.set( b.begin() );
244 244
245 // This is here because the comparison operator used to cause flattening. 245 // This is here because the comparison operator used to cause flattening.
246 unitTest( b == "this partthis part" ); 246 unitTest( b == "this partthis part" );
247 unitTest( c == b ); 247 unitTest( c == b );
248} 248 }
249 249
250{%iterator7} 250 test iterator7
251{
252 Bu::FString a("just [this] part");
253 Bu::FString b;
254 Bu::FString::iterator s = a.begin();
255 for(; s; s++ )
256 { 251 {
257 if( *s == '[' ) 252 Bu::FString a("just [this] part");
253 Bu::FString b;
254 Bu::FString::iterator s = a.begin();
255 for(; s; s++ )
258 { 256 {
259 s++; 257 if( *s == '[' )
260 break; 258 {
259 s++;
260 break;
261 }
261 } 262 }
262 } 263 Bu::FString::iterator e = s;
263 Bu::FString::iterator e = s; 264 for(; e; e++ )
264 for(; e; e++ )
265 {
266 if( *e == ']' )
267 { 265 {
268 b.set( s, e ); 266 if( *e == ']' )
269 break; 267 {
268 b.set( s, e );
269 break;
270 }
270 } 271 }
271 } 272 unitTest( b == "this" );
272 unitTest( b == "this" );
273 273
274 b.append( s, e ); 274 b.append( s, e );
275 275
276 for( Bu::FString::iterator i = b.begin(); i;) 276 for( Bu::FString::iterator i = b.begin(); i;)
277 {
278 Bu::FString::iterator k = i;
279 k++;
280 if( !k )
281 { 277 {
282 b.append( b.begin(), i ); 278 Bu::FString::iterator k = i;
283 break; 279 k++;
280 if( !k )
281 {
282 b.append( b.begin(), i );
283 break;
284 }
285 i = k;
284 } 286 }
285 i = k; 287 Bu::FString l;
286 } 288 l.set( b.begin() );
287 Bu::FString l; 289 unitTest( l == "thisthisthisthi" );
288 l.set( b.begin() ); 290 for( Bu::FString::iterator i = b.begin(); i;)
289 unitTest( l == "thisthisthisthi" );
290 for( Bu::FString::iterator i = b.begin(); i;)
291 {
292 Bu::FString::iterator k = i;
293 k++;
294 if( !k )
295 { 291 {
296 b.append( b.begin(), i ); 292 Bu::FString::iterator k = i;
297 break; 293 k++;
294 if( !k )
295 {
296 b.append( b.begin(), i );
297 break;
298 }
299 i = k;
298 } 300 }
299 i = k; 301 l.set( b.begin() );
302 unitTest( l == "thisthisthisthithisthisthisth" );
300 } 303 }
301 l.set( b.begin() );
302 unitTest( l == "thisthisthisthithisthisthisth" );
303}
304 304
305{%isSet1} 305 test isSet1
306{ 306 {
307 Bu::FString bob; 307 Bu::FString bob;
308 308
309 unitTest( bob.isSet() == false ); 309 unitTest( bob.isSet() == false );
310 bob = "something"; 310 bob = "something";
311 unitTest( bob.isSet() == true ); 311 unitTest( bob.isSet() == true );
312 bob = ""; 312 bob = "";
313 unitTest( bob.isSet() == false ); 313 unitTest( bob.isSet() == false );
314} 314 }
315 315
316{%swap1} 316 test swap1
317{ 317 {
318 Bu::FString a, b; 318 Bu::FString a, b;
319 a = "Goodbye"; 319 a = "Goodbye";
320 b = "Hello"; 320 b = "Hello";
321 Bu::swap( a, b ); 321 Bu::swap( a, b );
322 unitTest( a == "Hello" ); 322 unitTest( a == "Hello" );
323 unitTest( b == "Goodbye" ); 323 unitTest( b == "Goodbye" );
324} 324 }
325 325
326{%swap2} 326 test swap2
327{ 327 {
328 Bu::FString a, b; 328 Bu::FString a, b;
329 a = "Goodbye"; 329 a = "Goodbye";
330 b = "Hello"; 330 b = "Hello";
331 std::swap( a, b ); 331 std::swap( a, b );
332 unitTest( a == "Hello" ); 332 unitTest( a == "Hello" );
333 unitTest( b == "Goodbye" ); 333 unitTest( b == "Goodbye" );
334} 334 }
335 335
336{%replace1} 336 test replace1
337{ 337 {
338 Bu::FString a; 338 Bu::FString a;
339 a = "This is a test."; 339 a = "This is a test.";
340 unitTest( a.replace("i", "ooo") == "Thooos ooos a test." ); 340 unitTest( a.replace("i", "ooo") == "Thooos ooos a test." );
341 }
341} 342}
342
diff --git a/src/unit/hash.unit b/src/unit/hash.unit
index c0a10e3..e3d7e42 100644
--- a/src/unit/hash.unit
+++ b/src/unit/hash.unit
@@ -15,72 +15,73 @@ typedef Bu::Hash<Bu::FString, int> StrIntHash;
15typedef Bu::Hash<Bu::FString, Bu::FString> StrStrHash; 15typedef Bu::Hash<Bu::FString, Bu::FString> StrStrHash;
16typedef Bu::Hash<int, Bu::FString> IntStrHash; 16typedef Bu::Hash<int, Bu::FString> IntStrHash;
17 17
18{=Init} 18suite Hash
19
20{%probe1}
21{ 19{
22 StrIntHash h; 20 test probe1
23 char buf[20];
24 for(int i=1;i<10000;i++)
25 { 21 {
26 sprintf(buf,"%d",i); 22 StrIntHash h;
27 Bu::FString sTmp(buf); 23 char buf[20];
28 h[sTmp] = i; 24 for(int i=1;i<10000;i++)
29 unitTest( h.has(sTmp) ); 25 {
26 sprintf(buf,"%d",i);
27 Bu::FString sTmp(buf);
28 h[sTmp] = i;
29 unitTest( h.has(sTmp) );
30 }
30 } 31 }
31}
32
33{%insert1}
34{
35 StrIntHash h;
36 h["Hi"] = 42;
37 unitTest( h["Hi"] == 42 );
38}
39 32
40{%insert2} 33 test insert1
41{ 34 {
42 StrStrHash h; 35 StrIntHash h;
43 h["Hi"] = "Yo"; 36 h["Hi"] = 42;
44 h["Bye"] = "Later"; 37 unitTest( h["Hi"] == 42 );
45 unitTest( h["Hi"].getValue() == "Yo" ); 38 }
46 39
47 StrStrHash h2(h); 40 test insert2
48 unitTest( h2["Hi"].getValue() == "Yo" ); 41 {
49 unitTest( h2["Bye"].getValue() == "Later" ); 42 StrStrHash h;
43 h["Hi"] = "Yo";
44 h["Bye"] = "Later";
45 unitTest( h["Hi"].getValue() == "Yo" );
50 46
51 StrStrHash h3; 47 StrStrHash h2(h);
52 h3 = h; 48 unitTest( h2["Hi"].getValue() == "Yo" );
53 unitTest( h3["Hi"].getValue() == "Yo" ); 49 unitTest( h2["Bye"].getValue() == "Later" );
54 unitTest( h3["Bye"].getValue() == "Later" );
55}
56 50
57{%insert3} 51 StrStrHash h3;
58{ 52 h3 = h;
59 IntStrHash h; 53 unitTest( h3["Hi"].getValue() == "Yo" );
54 unitTest( h3["Bye"].getValue() == "Later" );
55 }
60 56
61 for( unsigned int i=1; i<50; i++ ) 57 test insert3
62 { 58 {
63 h[i] = "testing"; 59 IntStrHash h;
64 unitTest( h.getSize() == i );
65 }
66}
67 60
68{%erase1} 61 for( unsigned int i=1; i<50; i++ )
69{ 62 {
70 StrIntHash h; 63 h[i] = "testing";
71 h.insert("Number 1", 1 ); 64 unitTest( h.getSize() == i );
72 h.insert("Number 2", 2 ); 65 }
73 h.insert("Number 3", 3 ); 66 }
74 h.erase("Number 2");
75 h.get("Number 3");
76 try {
77 h.get("Number 2");
78 unitFailed("h.get(\"Number 2\") should have thrown an exception.");
79 } catch( Bu::HashException &e ) { }
80 67
81/* printf("\n"); 68 test erase1
82 for( StrIntHash::iterator i = h.begin(); i != h.end(); i++ )
83 { 69 {
84 printf(" - \"%s\" = %d\n", i.getKey().getStr(), i.getValue() ); 70 StrIntHash h;
85 } */ 71 h.insert("Number 1", 1 );
72 h.insert("Number 2", 2 );
73 h.insert("Number 3", 3 );
74 h.erase("Number 2");
75 h.get("Number 3");
76 try {
77 h.get("Number 2");
78 unitFailed("h.get(\"Number 2\") should have thrown an exception.");
79 } catch( Bu::HashException &e ) { }
80
81 /* printf("\n");
82 for( StrIntHash::iterator i = h.begin(); i != h.end(); i++ )
83 {
84 printf(" - \"%s\" = %d\n", i.getKey().getStr(), i.getValue() );
85 } */
86 }
86} 87}
diff --git a/src/unit/list.unit b/src/unit/list.unit
index 0dd9f40..66e45b2 100644
--- a/src/unit/list.unit
+++ b/src/unit/list.unit
@@ -11,138 +11,138 @@
11 11
12typedef Bu::List<int> IntList; 12typedef Bu::List<int> IntList;
13 13
14{=Init} 14suite List
15
16{%append}
17{ 15{
18 IntList lst; 16 test append
19 for( int j = 0; j < 50; j++ )
20 {
21 lst.append( j );
22 }
23 int j = 0;
24 for( IntList::iterator i = lst.begin(); i; i++, j++ )
25 { 17 {
26 unitTest( *i == j ); 18 IntList lst;
19 for( int j = 0; j < 50; j++ )
20 {
21 lst.append( j );
22 }
23 int j = 0;
24 for( IntList::iterator i = lst.begin(); i; i++, j++ )
25 {
26 unitTest( *i == j );
27 }
27 } 28 }
28}
29 29
30{%prepend} 30 test prepend
31{
32 IntList lst;
33 for( int j = 0; j < 50; j++ )
34 { 31 {
35 lst.prepend( j ); 32 IntList lst;
33 for( int j = 0; j < 50; j++ )
34 {
35 lst.prepend( j );
36 }
37 int j = 49;
38 for( IntList::iterator i = lst.begin(); i; i++, j-- )
39 {
40 unitTest( *i == j );
41 }
36 } 42 }
37 int j = 49;
38 for( IntList::iterator i = lst.begin(); i; i++, j-- )
39 {
40 unitTest( *i == j );
41 }
42}
43 43
44{%copy} 44 test copy
45{
46 IntList lst;
47 int j;
48 for( j = 0; j < 50; j++ )
49 { 45 {
50 lst.append( j ); 46 IntList lst;
47 int j;
48 for( j = 0; j < 50; j++ )
49 {
50 lst.append( j );
51 }
52 IntList lst2 = lst;
53
54 j = 0;
55 for( IntList::iterator i = lst2.begin(); i; i++, j++ )
56 {
57 unitTest( *i == j );
58 }
59 lst2.clear();
60 lst2 = lst;
61
62 j = 0;
63 for( IntList::iterator i = lst2.begin(); i; i++, j++ )
64 {
65 unitTest( *i == j );
66 }
51 } 67 }
52 IntList lst2 = lst;
53 68
54 j = 0; 69 test sort1
55 for( IntList::iterator i = lst2.begin(); i; i++, j++ )
56 { 70 {
57 unitTest( *i == j ); 71 IntList lst;
58 }
59 lst2.clear();
60 lst2 = lst;
61 72
62 j = 0; 73 lst.insertSorted( 5 );
63 for( IntList::iterator i = lst2.begin(); i; i++, j++ ) 74 lst.insertSorted( 1 );
64 { 75 lst.insertSorted( 10 );
65 unitTest( *i == j ); 76 lst.insertSorted( 3 );
66 }
67}
68
69{%sort1}
70{
71 IntList lst;
72 77
73 lst.insertSorted( 5 ); 78 unitTest( lst == IntList(1).append(3).append(5).append(10) );
74 lst.insertSorted( 1 ); 79 }
75 lst.insertSorted( 10 );
76 lst.insertSorted( 3 );
77
78 unitTest( lst == IntList(1).append(3).append(5).append(10) );
79}
80 80
81{%sort2} 81 test sort2
82{ 82 {
83 IntList lst; 83 IntList lst;
84 84
85 lst.insertSorted<Bu::__basicGTCmp<int> >( 5 ); 85 lst.insertSorted<Bu::__basicGTCmp<int> >( 5 );
86 lst.insertSorted<Bu::__basicGTCmp<int> >( 1 ); 86 lst.insertSorted<Bu::__basicGTCmp<int> >( 1 );
87 lst.insertSorted<Bu::__basicGTCmp<int> >( 10 ); 87 lst.insertSorted<Bu::__basicGTCmp<int> >( 10 );
88 lst.insertSorted<Bu::__basicGTCmp<int> >( 3 ); 88 lst.insertSorted<Bu::__basicGTCmp<int> >( 3 );
89 89
90 unitTest( lst == IntList(10).append(5).append(3).append(1) ); 90 unitTest( lst == IntList(10).append(5).append(3).append(1) );
91} 91 }
92 92
93{%sort3} 93 test sort3
94{ 94 {
95 IntList lst; 95 IntList lst;
96 Bu::__basicGTCmp<int> cmp; 96 Bu::__basicGTCmp<int> cmp;
97 97
98 lst.insertSorted( cmp, 5 ); 98 lst.insertSorted( cmp, 5 );
99 lst.insertSorted( cmp, 1 ); 99 lst.insertSorted( cmp, 1 );
100 lst.insertSorted( cmp, 10 ); 100 lst.insertSorted( cmp, 10 );
101 lst.insertSorted( cmp, 3 ); 101 lst.insertSorted( cmp, 3 );
102 102
103 unitTest( lst == IntList(10).append(5).append(3).append(1) ); 103 unitTest( lst == IntList(10).append(5).append(3).append(1) );
104} 104 }
105 105
106{%sort4} 106 test sort4
107{ 107 {
108 IntList lst; 108 IntList lst;
109 109
110 lst.append( 5 ); 110 lst.append( 5 );
111 lst.append( 1 ); 111 lst.append( 1 );
112 lst.append( 10 ); 112 lst.append( 10 );
113 lst.append( 3 ); 113 lst.append( 3 );
114 114
115 lst.sort(); 115 lst.sort();
116 116
117 unitTest( lst == IntList(1).append(3).append(5).append(10) ); 117 unitTest( lst == IntList(1).append(3).append(5).append(10) );
118} 118 }
119 119
120{%sort5} 120 test sort5
121{ 121 {
122 IntList lst; 122 IntList lst;
123 123
124 lst.append( 5 ); 124 lst.append( 5 );
125 lst.append( 1 ); 125 lst.append( 1 );
126 lst.append( 10 ); 126 lst.append( 10 );
127 lst.append( 3 ); 127 lst.append( 3 );
128 128
129 lst.sort<Bu::__basicGTCmp<int> >(); 129 lst.sort<Bu::__basicGTCmp<int> >();
130 130
131 unitTest( lst == IntList(10).append(5).append(3).append(1) ); 131 unitTest( lst == IntList(10).append(5).append(3).append(1) );
132} 132 }
133 133
134{%sort6} 134 test sort6
135{ 135 {
136 IntList lst; 136 IntList lst;
137 137
138 lst.append( 5 ); 138 lst.append( 5 );
139 lst.append( 1 ); 139 lst.append( 1 );
140 lst.append( 10 ); 140 lst.append( 10 );
141 lst.append( 3 ); 141 lst.append( 3 );
142 142
143 Bu::__basicGTCmp<int> x; 143 Bu::__basicGTCmp<int> x;
144 lst.sort( x ); 144 lst.sort( x );
145 145
146 unitTest( lst == IntList(10).append(5).append(3).append(1) ); 146 unitTest( lst == IntList(10).append(5).append(3).append(1) );
147 }
147} 148}
148
diff --git a/src/unit/membuf.unit b/src/unit/membuf.unit
index 883b7f8..1da3b90 100644
--- a/src/unit/membuf.unit
+++ b/src/unit/membuf.unit
@@ -8,38 +8,39 @@
8 8
9#include "bu/membuf.h" 9#include "bu/membuf.h"
10 10
11{=Init} 11suite MemBuf
12
13{%testWriteRead01}
14{ 12{
15 Bu::MemBuf mb; 13 test testWriteRead01
16 unitTest( mb.write("ab", 2 ) == 2 ); 14 {
17 unitTest( mb.write("cde", 3 ) == 3 ); 15 Bu::MemBuf mb;
18 unitTest( mb.write("FG", 2 ) == 2 ); 16 unitTest( mb.write("ab", 2 ) == 2 );
17 unitTest( mb.write("cde", 3 ) == 3 );
18 unitTest( mb.write("FG", 2 ) == 2 );
19 19
20 mb.setPos( 0 ); 20 mb.setPos( 0 );
21 21
22 char buf[8]; 22 char buf[8];
23 buf[7] = '\0'; 23 buf[7] = '\0';
24 unitTest( mb.read( buf, 7 ) == 7 ); 24 unitTest( mb.read( buf, 7 ) == 7 );
25 unitTest( !strncmp( buf, "abcdeFG", 7 ) ); 25 unitTest( !strncmp( buf, "abcdeFG", 7 ) );
26 unitTest( mb.read( buf, 7 ) == 0 ); 26 unitTest( mb.read( buf, 7 ) == 0 );
27 mb.seek( -3 ); 27 mb.seek( -3 );
28 unitTest( mb.read( buf, 7 ) == 3 ); 28 unitTest( mb.read( buf, 7 ) == 3 );
29 unitTest( !strncmp( buf, "eFG", 3 ) ); 29 unitTest( !strncmp( buf, "eFG", 3 ) );
30} 30 }
31 31
32{%testOverwrite1} 32 test testOverwrite1
33{ 33 {
34 Bu::MemBuf mb; 34 Bu::MemBuf mb;
35 unitTest( mb.write("0123456789") == 10 ); 35 unitTest( mb.write("0123456789") == 10 );
36 mb.setPos( 4 ); 36 mb.setPos( 4 );
37 unitTest( mb.write("-5-") == 3 ); 37 unitTest( mb.write("-5-") == 3 );
38 mb.setPos( 9 ); 38 mb.setPos( 9 );
39 mb.write("Hey!!!"); 39 mb.write("Hey!!!");
40 unitTest( mb.tell() == 15 ); 40 unitTest( mb.tell() == 15 );
41 char buf[50]; 41 char buf[50];
42 mb.setPos( 0 ); 42 mb.setPos( 0 );
43 buf[mb.read( buf, 50 )] = '\0'; 43 buf[mb.read( buf, 50 )] = '\0';
44 unitTest( !strcmp( buf, "0123-5-78Hey!!!" ) ); 44 unitTest( !strcmp( buf, "0123-5-78Hey!!!" ) );
45 }
45} 46}
diff --git a/src/unit/queuebuf.unit b/src/unit/queuebuf.unit
index 9ae7d36..29ba858 100644
--- a/src/unit/queuebuf.unit
+++ b/src/unit/queuebuf.unit
@@ -14,91 +14,91 @@
14 14
15#define RNDCHR ((char)(((double)random()/(double)RAND_MAX)*256.0)) 15#define RNDCHR ((char)(((double)random()/(double)RAND_MAX)*256.0))
16 16
17{=Init} 17suite QueueBuf
18
19{%testBasic01}
20{ 18{
21 Bu::QueueBuf qb; 19 test testBasic01
22 unitTest( qb.write("ab", 2 ) == 2 ); 20 {
23 unitTest( qb.write("cde", 3 ) == 3 ); 21 Bu::QueueBuf qb;
24 unitTest( qb.write("FG", 2 ) == 2 ); 22 unitTest( qb.write("ab", 2 ) == 2 );
23 unitTest( qb.write("cde", 3 ) == 3 );
24 unitTest( qb.write("FG", 2 ) == 2 );
25 25
26 char buf[8]; 26 char buf[8];
27 buf[7] = '\0'; 27 buf[7] = '\0';
28 unitTest( qb.read( buf, 7 ) == 7 ); 28 unitTest( qb.read( buf, 7 ) == 7 );
29 unitTest( !strncmp( buf, "abcdeFG", 7 ) ); 29 unitTest( !strncmp( buf, "abcdeFG", 7 ) );
30 unitTest( qb.read( buf, 7 ) == 0 ); 30 unitTest( qb.read( buf, 7 ) == 0 );
31} 31 }
32 32
33void QBUF_RANDSTR( Bu::FString &fill, unsigned int iSize ) 33 void QBUF_RANDSTR( Bu::FString &fill, unsigned int iSize )
34{
35 char c;
36 for( unsigned int i=0; i<iSize; ++i )
37 { 34 {
38 c = RNDCHR; 35 char c;
39 fill.append(&c,1); 36 for( unsigned int i=0; i<iSize; ++i )
37 {
38 c = RNDCHR;
39 fill.append(&c,1);
40 }
40 } 41 }
41}
42 42
43{%testAmounts} 43 test testAmounts
44{
45 srandom(time(NULL));
46 Bu::QueueBuf qb;
47 Bu::FString sTmp;
48 char buf[4096];
49
50 for( int i=0; i<200; ++i )
51 { 44 {
52 unsigned int iAmt = (int)RNDCHR+128; 45 srandom(time(NULL));
53 sTmp.clear(); 46 Bu::QueueBuf qb;
54 QBUF_RANDSTR( sTmp, iAmt ); 47 Bu::FString sTmp;
55 unitTest( qb.write( sTmp.getStr(), sTmp.getSize() ) == 48 char buf[4096];
56 (uint32_t)sTmp.getSize() );
57 size_t iRead = qb.read( buf, 4096 );
58 unitTest( iRead == iAmt );
59 }
60}
61 49
62void QBUF_HEXOUT( const char *s, int iSize ) 50 for( int i=0; i<200; ++i )
63{ 51 {
64 for( int i=0; i<iSize; ++i ) 52 unsigned int iAmt = (int)RNDCHR+128;
65 printf("%02x",(int)(uint8_t)s[i]); 53 sTmp.clear();
66} 54 QBUF_RANDSTR( sTmp, iAmt );
55 unitTest( qb.write( sTmp.getStr(), sTmp.getSize() ) ==
56 (uint32_t)sTmp.getSize() );
57 size_t iRead = qb.read( buf, 4096 );
58 unitTest( iRead == iAmt );
59 }
60 }
67 61
68void QBUF_HASH( Bu::FString &fill, const char *s, int iSize ) 62 void QBUF_HEXOUT( const char *s, int iSize )
69{ 63 {
70 Bu::Md5 hash; 64 for( int i=0; i<iSize; ++i )
71 hash.reset(); 65 printf("%02x",(int)(uint8_t)s[i]);
72 hash.addData( s, iSize ); 66 }
73 const Bu::FString &sTmp = hash.getResult();
74 fill.append( sTmp.getStr(), 16 );
75}
76 67
77{%testRandomData} 68 void QBUF_HASH( Bu::FString &fill, const char *s, int iSize )
78{ 69 {
79 srandom(time(NULL)); 70 Bu::Md5 hash;
80 Bu::QueueBuf qb; 71 hash.reset();
81 Bu::FString sTmp; 72 hash.addData( s, iSize );
82 Bu::FString sTmp2; 73 const Bu::FString &sTmp = hash.getResult();
83 char buf[4096]; 74 fill.append( sTmp.getStr(), 16 );
75 }
84 76
85 for( int i=0; i<200; ++i ) 77 test testRandomData
86 { 78 {
87 uint32_t iAmt = (uint32_t)RNDCHR+128; 79 srandom(time(NULL));
88 sTmp.clear(); 80 Bu::QueueBuf qb;
89 sTmp.append( (const char *)&iAmt, 4 ); 81 Bu::FString sTmp;
90 QBUF_RANDSTR( sTmp, iAmt ); 82 Bu::FString sTmp2;
91 sTmp2.clear(); 83 char buf[4096];
92 QBUF_HASH( sTmp2, sTmp.getStr()+4, iAmt ); 84
93 sTmp.append( sTmp2 ); 85 for( int i=0; i<200; ++i )
94 unitTest( qb.write( sTmp.getStr(), sTmp.getSize() ) == 86 {
95 (uint32_t)sTmp.getSize() ); 87 uint32_t iAmt = (uint32_t)RNDCHR+128;
96 size_t iRead = qb.read( buf, 4096 ); 88 sTmp.clear();
97 uint32_t iGotSize = *((uint32_t *)buf); 89 sTmp.append( (const char *)&iAmt, 4 );
98 unitTest( iRead == iGotSize+4+16 ); 90 QBUF_RANDSTR( sTmp, iAmt );
99 sTmp2.clear(); 91 sTmp2.clear();
100 QBUF_HASH( sTmp2, buf+4, iGotSize ); 92 QBUF_HASH( sTmp2, sTmp.getStr()+4, iAmt );
101 unitTest( !strncmp(sTmp2.getStr(),buf+4+iGotSize,16) ); 93 sTmp.append( sTmp2 );
94 unitTest( qb.write( sTmp.getStr(), sTmp.getSize() ) ==
95 (uint32_t)sTmp.getSize() );
96 size_t iRead = qb.read( buf, 4096 );
97 uint32_t iGotSize = *((uint32_t *)buf);
98 unitTest( iRead == iGotSize+4+16 );
99 sTmp2.clear();
100 QBUF_HASH( sTmp2, buf+4, iGotSize );
101 unitTest( !strncmp(sTmp2.getStr(),buf+4+iGotSize,16) );
102 }
102 } 103 }
103} 104}
104
diff --git a/src/unit/substream.unit b/src/unit/substream.unit
index 802ad4c..49817b0 100644
--- a/src/unit/substream.unit
+++ b/src/unit/substream.unit
@@ -9,44 +9,44 @@
9#include "bu/membuf.h" 9#include "bu/membuf.h"
10#include "bu/substream.h" 10#include "bu/substream.h"
11 11
12{=Init} 12suite SubStream
13
14{%testRead01}
15{ 13{
16 Bu::MemBuf mb("abcdefghijklmnopqrstuvwxyz"); 14 test testRead01
17 mb.seek( 4 ); 15 {
18 Bu::SubStream ss( mb, 10 ); 16 Bu::MemBuf mb("abcdefghijklmnopqrstuvwxyz");
19 unitTest( ss.readLine() == "efghijklmn" ); 17 mb.seek( 4 );
20} 18 Bu::SubStream ss( mb, 10 );
19 unitTest( ss.readLine() == "efghijklmn" );
20 }
21 21
22{%testRead02} 22 test testRead02
23{ 23 {
24 Bu::MemBuf mb("abcdefghijklmnopqrstuvwxyz"); 24 Bu::MemBuf mb("abcdefghijklmnopqrstuvwxyz");
25 mb.seek( 4 ); 25 mb.seek( 4 );
26 Bu::SubStream ss( mb, 10 ); 26 Bu::SubStream ss( mb, 10 );
27 char buf[8]; 27 char buf[8];
28 size_t iRead = ss.read( buf, 8 ); 28 size_t iRead = ss.read( buf, 8 );
29 unitTest( iRead == 8 ); 29 unitTest( iRead == 8 );
30 unitTest( strncmp( buf, "efghijkl", 8 ) == 0 ); 30 unitTest( strncmp( buf, "efghijkl", 8 ) == 0 );
31 unitTest( !ss.isEos() ); 31 unitTest( !ss.isEos() );
32 iRead = ss.read( buf, 8 ); 32 iRead = ss.read( buf, 8 );
33 unitTest( iRead == 2 ); 33 unitTest( iRead == 2 );
34 unitTest( strncmp( buf, "mn", 2 ) == 0 ); 34 unitTest( strncmp( buf, "mn", 2 ) == 0 );
35 unitTest( ss.isEos() ); 35 unitTest( ss.isEos() );
36} 36 }
37 37
38{%testRead03} 38 test testRead03
39{ 39 {
40 Bu::MemBuf mb("abcdefghijklmnopqrstuvwxyz"); 40 Bu::MemBuf mb("abcdefghijklmnopqrstuvwxyz");
41 mb.seek( 20 ); 41 mb.seek( 20 );
42 Bu::SubStream ss( mb, 10 ); 42 Bu::SubStream ss( mb, 10 );
43 char buf[8]; 43 char buf[8];
44 size_t iRead = ss.read( buf, 8 ); 44 size_t iRead = ss.read( buf, 8 );
45 unitTest( iRead == 6 ); 45 unitTest( iRead == 6 );
46 unitTest( strncmp( buf, "uvwxyz", 6 ) == 0 ); 46 unitTest( strncmp( buf, "uvwxyz", 6 ) == 0 );
47 unitTest( ss.isEos() ); 47 unitTest( ss.isEos() );
48 iRead = ss.read( buf, 8 ); 48 iRead = ss.read( buf, 8 );
49 unitTest( iRead == 0 ); 49 unitTest( iRead == 0 );
50 unitTest( ss.isEos() ); 50 unitTest( ss.isEos() );
51 }
51} 52}
52
diff --git a/src/unit/taf.unit b/src/unit/taf.unit
index a4f4f86..eb9475e 100644
--- a/src/unit/taf.unit
+++ b/src/unit/taf.unit
@@ -13,109 +13,109 @@
13#include <string.h> 13#include <string.h>
14#include <unistd.h> 14#include <unistd.h>
15 15
16{=Init} 16suite Taf
17
18{%read1}
19{ 17{
18 test read1
19 {
20#define FN_TMP ("/tmp/tmpXXXXXXXX") 20#define FN_TMP ("/tmp/tmpXXXXXXXX")
21 Bu::FString sFnTmp(FN_TMP); 21 Bu::FString sFnTmp(FN_TMP);
22 Bu::File fOut = Bu::File::tempFile( sFnTmp ); 22 Bu::File fOut = Bu::File::tempFile( sFnTmp );
23 const char *data = 23 const char *data =
24"{test: name=\"Bob\"}" 24 "{test: name=\"Bob\"}"
25; 25 ;
26 fOut.write(data,strlen(data)); 26 fOut.write(data,strlen(data));
27 fOut.close(); 27 fOut.close();
28 28
29 Bu::File fIn(sFnTmp.getStr(), Bu::File::Read ); 29 Bu::File fIn(sFnTmp.getStr(), Bu::File::Read );
30 Bu::TafReader tr(fIn); 30 Bu::TafReader tr(fIn);
31 31
32 Bu::TafGroup *tn = tr.readGroup(); 32 Bu::TafGroup *tn = tr.readGroup();
33 unitTest( !strcmp("Bob", tn->getProperty("name").getStr()) ); 33 unitTest( !strcmp("Bob", tn->getProperty("name").getStr()) );
34 delete tn; 34 delete tn;
35 35
36 unlink(sFnTmp.getStr()); 36 unlink(sFnTmp.getStr());
37#undef FN_TMP 37#undef FN_TMP
38} 38 }
39 39
40{%encode1} 40 test encode1
41{ 41 {
42 Bu::MemBuf mb; 42 Bu::MemBuf mb;
43 Bu::TafWriter tw( mb ); 43 Bu::TafWriter tw( mb );
44 44
45 Bu::TafGroup g("Test data"); 45 Bu::TafGroup g("Test data");
46 Bu::FString sData( 256 ); 46 Bu::FString sData( 256 );
47 for( int j = 0; j < 256; j++ ) 47 for( int j = 0; j < 256; j++ )
48 sData[j] = (unsigned char)j; 48 sData[j] = (unsigned char)j;
49 g.addChild( new Bu::TafProperty("Encoded", sData) ); 49 g.addChild( new Bu::TafProperty("Encoded", sData) );
50 tw.writeGroup( &g ); 50 tw.writeGroup( &g );
51 51
52 static const char *cmpdata = "{\"Test data\":\n \"Encoded\"=\"" 52 static const char *cmpdata = "{\"Test data\":\n \"Encoded\"=\""
53 "\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07" 53 "\\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07"
54 "\\x08\\x09\\x0A\\x0B\\x0C\\x0D\\x0E\\x0F" 54 "\\x08\\x09\\x0A\\x0B\\x0C\\x0D\\x0E\\x0F"
55 "\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17" 55 "\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17"
56 "\\x18\\x19\\x1A\\x1B\\x1C\\x1D\\x1E\\x1F" 56 "\\x18\\x19\\x1A\\x1B\\x1C\\x1D\\x1E\\x1F"
57 " !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCD" 57 " !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCD"
58 "EFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghi" 58 "EFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghi"
59 "jklmnopqrstuvwxyz{|}~\\x7F" 59 "jklmnopqrstuvwxyz{|}~\\x7F"
60 "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87" 60 "\\x80\\x81\\x82\\x83\\x84\\x85\\x86\\x87"
61 "\\x88\\x89\\x8A\\x8B\\x8C\\x8D\\x8E\\x8F" 61 "\\x88\\x89\\x8A\\x8B\\x8C\\x8D\\x8E\\x8F"
62 "\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97" 62 "\\x90\\x91\\x92\\x93\\x94\\x95\\x96\\x97"
63 "\\x98\\x99\\x9A\\x9B\\x9C\\x9D\\x9E\\x9F" 63 "\\x98\\x99\\x9A\\x9B\\x9C\\x9D\\x9E\\x9F"
64 "\\xA0\\xA1\\xA2\\xA3\\xA4\\xA5\\xA6\\xA7" 64 "\\xA0\\xA1\\xA2\\xA3\\xA4\\xA5\\xA6\\xA7"
65 "\\xA8\\xA9\\xAA\\xAB\\xAC\\xAD\\xAE\\xAF" 65 "\\xA8\\xA9\\xAA\\xAB\\xAC\\xAD\\xAE\\xAF"
66 "\\xB0\\xB1\\xB2\\xB3\\xB4\\xB5\\xB6\\xB7" 66 "\\xB0\\xB1\\xB2\\xB3\\xB4\\xB5\\xB6\\xB7"
67 "\\xB8\\xB9\\xBA\\xBB\\xBC\\xBD\\xBE\\xBF" 67 "\\xB8\\xB9\\xBA\\xBB\\xBC\\xBD\\xBE\\xBF"
68 "\\xC0\\xC1\\xC2\\xC3\\xC4\\xC5\\xC6\\xC7" 68 "\\xC0\\xC1\\xC2\\xC3\\xC4\\xC5\\xC6\\xC7"
69 "\\xC8\\xC9\\xCA\\xCB\\xCC\\xCD\\xCE\\xCF" 69 "\\xC8\\xC9\\xCA\\xCB\\xCC\\xCD\\xCE\\xCF"
70 "\\xD0\\xD1\\xD2\\xD3\\xD4\\xD5\\xD6\\xD7" 70 "\\xD0\\xD1\\xD2\\xD3\\xD4\\xD5\\xD6\\xD7"
71 "\\xD8\\xD9\\xDA\\xDB\\xDC\\xDD\\xDE\\xDF" 71 "\\xD8\\xD9\\xDA\\xDB\\xDC\\xDD\\xDE\\xDF"
72 "\\xE0\\xE1\\xE2\\xE3\\xE4\\xE5\\xE6\\xE7" 72 "\\xE0\\xE1\\xE2\\xE3\\xE4\\xE5\\xE6\\xE7"
73 "\\xE8\\xE9\\xEA\\xEB\\xEC\\xED\\xEE\\xEF" 73 "\\xE8\\xE9\\xEA\\xEB\\xEC\\xED\\xEE\\xEF"
74 "\\xF0\\xF1\\xF2\\xF3\\xF4\\xF5\\xF6\\xF7" 74 "\\xF0\\xF1\\xF2\\xF3\\xF4\\xF5\\xF6\\xF7"
75 "\\xF8\\xF9\\xFA\\xFB\\xFC\\xFD\\xFE\\xFF\"\n}\n"; 75 "\\xF8\\xF9\\xFA\\xFB\\xFC\\xFD\\xFE\\xFF\"\n}\n";
76 unitTest( mb.getString() == cmpdata ); 76 unitTest( mb.getString() == cmpdata );
77 mb.setPos( 0 ); 77 mb.setPos( 0 );
78 Bu::TafReader tr( mb ); 78 Bu::TafReader tr( mb );
79 Bu::TafGroup *rg = tr.readGroup(); 79 Bu::TafGroup *rg = tr.readGroup();
80 unitTest( rg->getProperty("Encoded") == sData ); 80 unitTest( rg->getProperty("Encoded") == sData );
81 delete rg; 81 delete rg;
82} 82 }
83 83
84{%emptyStr1} 84 test emptyStr1
85{ 85 {
86 Bu::MemBuf mb; 86 Bu::MemBuf mb;
87 Bu::TafWriter tw( mb ); 87 Bu::TafWriter tw( mb );
88 88
89 Bu::TafGroup g("Test Group"); 89 Bu::TafGroup g("Test Group");
90 Bu::FString sVal; 90 Bu::FString sVal;
91 g.addChild( new Bu::TafProperty("Lame", sVal) ); 91 g.addChild( new Bu::TafProperty("Lame", sVal) );
92 tw.writeGroup( &g ); 92 tw.writeGroup( &g );
93 93
94 unitTest( 94 unitTest(
95 mb.getString() == "{\"Test Group\":\n \"Lame\"=\"\"\n}\n" ); 95 mb.getString() == "{\"Test Group\":\n \"Lame\"=\"\"\n}\n" );
96} 96 }
97 97
98{%incomplete1} 98 test incomplete1
99{
100 try
101 { 99 {
102 Bu::MemBuf mb("{Lame: \"Hello=\""); 100 try
103 Bu::TafReader tr( mb ); 101 {
104 delete tr.readGroup(); 102 Bu::MemBuf mb("{Lame: \"Hello=\"");
105 unitFailed("Should have thrown an exception, didn't."); 103 Bu::TafReader tr( mb );
104 delete tr.readGroup();
105 unitFailed("Should have thrown an exception, didn't.");
106 }
107 catch( Bu::TafException &e )
108 {
109 // Woot
110 }
106 } 111 }
107 catch( Bu::TafException &e ) 112
113 test bypath1
108 { 114 {
109 // Woot 115 Bu::MemBuf mb("{outer: \"Hello=\" {inner: {final: test=hi} } }");
116 Bu::TafReader tr( mb );
117 const Bu::TafGroup *g = tr.readGroup();
118 unitTest( g->getChildByPath("inner/final")->getProperty("test") == "hi" );
119 unitTest( g->getByPath("inner/final/test") == "hi" );
110 } 120 }
111} 121}
112
113{%bypath1}
114{
115 Bu::MemBuf mb("{outer: \"Hello=\" {inner: {final: test=hi} } }");
116 Bu::TafReader tr( mb );
117 const Bu::TafGroup *g = tr.readGroup();
118 unitTest( g->getChildByPath("inner/final")->getProperty("test") == "hi" );
119 unitTest( g->getByPath("inner/final/test") == "hi" );
120}
121
diff --git a/src/unit/xml.unit b/src/unit/xml.unit
index 1398237..67216f0 100644
--- a/src/unit/xml.unit
+++ b/src/unit/xml.unit
@@ -10,11 +10,12 @@
10#include "bu/xmlreader.h" 10#include "bu/xmlreader.h"
11#include "bu/membuf.h" 11#include "bu/membuf.h"
12 12
13{=Init} 13suite Xml
14
15{%declaration}
16{ 14{
17 Bu::FString sXml("<?xml ?> <hi />"); 15 test declaration
18 Bu::MemBuf buf( sXml ); 16 {
19 Bu::XmlReader xr( buf ); 17 Bu::FString sXml("<?xml ?> <hi />");
18 Bu::MemBuf buf( sXml );
19 Bu::XmlReader xr( buf );
20 }
20} 21}