diff options
-rw-r--r-- | src/membuf.cpp | 26 | ||||
-rw-r--r-- | src/membuf.h | 5 | ||||
-rw-r--r-- | src/nids.cpp | 115 | ||||
-rw-r--r-- | src/nids.h | 14 | ||||
-rw-r--r-- | src/nidsstream.cpp | 40 | ||||
-rw-r--r-- | src/tests/nids.cpp | 40 | ||||
-rw-r--r-- | src/unit/membuf.cpp | 16 |
7 files changed, 185 insertions, 71 deletions
diff --git a/src/membuf.cpp b/src/membuf.cpp index 6d850bf..e7c7ac8 100644 --- a/src/membuf.cpp +++ b/src/membuf.cpp | |||
@@ -41,9 +41,29 @@ size_t Bu::MemBuf::read( void *pBuf, size_t nBytes ) | |||
41 | 41 | ||
42 | size_t Bu::MemBuf::write( const void *pBuf, size_t nBytes ) | 42 | size_t Bu::MemBuf::write( const void *pBuf, size_t nBytes ) |
43 | { | 43 | { |
44 | sBuf.append( (const char *)pBuf, nBytes ); | 44 | if( nPos == sBuf.getSize() ) |
45 | nPos += nBytes; | 45 | { |
46 | return nBytes; | 46 | // Easiest, just append the data. |
47 | sBuf.append( (const char *)pBuf, nBytes ); | ||
48 | nPos += nBytes; | ||
49 | return nBytes; | ||
50 | } | ||
51 | else | ||
52 | { | ||
53 | // Trickier, we must do this in two parts, overwrite, then append | ||
54 | // Frist, overwrite. | ||
55 | int iOver = sBuf.getSize() - nPos; | ||
56 | if( iOver > nBytes ) | ||
57 | iOver = nBytes; | ||
58 | memcpy( sBuf.getStr()+nPos, pBuf, iOver ); | ||
59 | // Then append | ||
60 | if( iOver < nBytes ) | ||
61 | { | ||
62 | sBuf.append( ((const char *)pBuf)+iOver, nBytes-iOver ); | ||
63 | } | ||
64 | nPos += nBytes; | ||
65 | return nBytes; | ||
66 | } | ||
47 | } | 67 | } |
48 | 68 | ||
49 | long Bu::MemBuf::tell() | 69 | long Bu::MemBuf::tell() |
diff --git a/src/membuf.h b/src/membuf.h index b728f38..15686e9 100644 --- a/src/membuf.h +++ b/src/membuf.h | |||
@@ -29,11 +29,6 @@ namespace Bu | |||
29 | virtual void close(); | 29 | virtual void close(); |
30 | virtual size_t read( void *pBuf, size_t nBytes ); | 30 | virtual size_t read( void *pBuf, size_t nBytes ); |
31 | 31 | ||
32 | /** | ||
33 | *@todo Allow writes at the current position, not just appending to | ||
34 | * the current buffer. This is a silly way to do it, but it covers all | ||
35 | * of our bases for now. | ||
36 | */ | ||
37 | virtual size_t write( const void *pBuf, size_t nBytes ); | 32 | virtual size_t write( const void *pBuf, size_t nBytes ); |
38 | using Stream::write; | 33 | using Stream::write; |
39 | virtual long tell(); | 34 | virtual long tell(); |
diff --git a/src/nids.cpp b/src/nids.cpp index a6596a2..06895ac 100644 --- a/src/nids.cpp +++ b/src/nids.cpp | |||
@@ -1,3 +1,10 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 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 | |||
1 | #include "bu/nids.h" | 8 | #include "bu/nids.h" |
2 | #include "bu/stream.h" | 9 | #include "bu/stream.h" |
3 | #include "bu/nidsstream.h" | 10 | #include "bu/nidsstream.h" |
@@ -16,30 +23,6 @@ Bu::Nids::Nids( Bu::Stream &sStore ) : | |||
16 | iBlocks( 0 ), | 23 | iBlocks( 0 ), |
17 | iBlockStart( -1 ) | 24 | iBlockStart( -1 ) |
18 | { | 25 | { |
19 | printf("blockUnused = %u\n", blockUnused ); | ||
20 | printf("Stream caps:\n" | ||
21 | " canRead: %s\n" | ||
22 | " canWrite: %s\n" | ||
23 | " isReadable: %s\n" | ||
24 | " isWritable: %s\n" | ||
25 | " isSeekable: %s\n" | ||
26 | " isBlocking: %s\n" | ||
27 | " isEOS: %s\n" | ||
28 | " isOpen: %s\n", | ||
29 | sStore.canRead()?"yes":"no", | ||
30 | sStore.canWrite()?"yes":"no", | ||
31 | sStore.isReadable()?"yes":"no", | ||
32 | sStore.isWritable()?"yes":"no", | ||
33 | sStore.isSeekable()?"yes":"no", | ||
34 | sStore.isBlocking()?"yes":"no", | ||
35 | sStore.isEOS()?"yes":"no", | ||
36 | sStore.isOpen()?"yes":"no" | ||
37 | ); | ||
38 | printf("sizeof(Block) = %db\n", sizeof(Block) ); | ||
39 | printf("Magic: %02X%02X%02X%02X\n", | ||
40 | NIDS_MAGIC_CODE[0], NIDS_MAGIC_CODE[1], | ||
41 | NIDS_MAGIC_CODE[2], NIDS_MAGIC_CODE[3] | ||
42 | ); | ||
43 | } | 26 | } |
44 | 27 | ||
45 | Bu::Nids::~Nids() | 28 | Bu::Nids::~Nids() |
@@ -49,6 +32,7 @@ Bu::Nids::~Nids() | |||
49 | void Bu::Nids::initialize() | 32 | void Bu::Nids::initialize() |
50 | { | 33 | { |
51 | unsigned char buf[4]; | 34 | unsigned char buf[4]; |
35 | int iUsed; | ||
52 | if( sStore.read( buf, 4 ) < 4 ) | 36 | if( sStore.read( buf, 4 ) < 4 ) |
53 | throw NidsException("Input stream appears to be empty."); | 37 | throw NidsException("Input stream appears to be empty."); |
54 | if( memcmp( buf, NIDS_MAGIC_CODE, 4 ) ) | 38 | if( memcmp( buf, NIDS_MAGIC_CODE, 4 ) ) |
@@ -56,8 +40,31 @@ void Bu::Nids::initialize() | |||
56 | throw NidsException( | 40 | throw NidsException( |
57 | "Stream does not appear to be a valid NIDS format."); | 41 | "Stream does not appear to be a valid NIDS format."); |
58 | } | 42 | } |
59 | 43 | sStore.read( buf, 2 ); | |
60 | 44 | if( buf[0] != 0 ) | |
45 | throw NidsException( | ||
46 | "We can only handle version 0 for now."); | ||
47 | if( buf[1] != 4 ) | ||
48 | throw NidsException( | ||
49 | "We can only handle 4-byte words at the moment."); | ||
50 | sStore.read( &iBlockSize, 4 ); | ||
51 | sStore.read( &iBlocks, 4 ); | ||
52 | sStore.read( &iUsed, 4 ); // number of used blocks... | ||
53 | sStore.seek( 7 ); // skip reserved space. | ||
54 | iBlockStart = sStore.tell(); | ||
55 | |||
56 | //printf("%d blocks, %db each, %db block offset\n", | ||
57 | // iBlocks, iBlockSize, iBlockStart ); | ||
58 | |||
59 | bsBlockUsed.setSize( iBlocks, true ); | ||
60 | Block bTmp; | ||
61 | for( int j = 0; j < iBlocks; j++ ) | ||
62 | { | ||
63 | sStore.seek( iBlockStart+iBlockSize*j ); | ||
64 | sStore.read( &bTmp, sizeof(bTmp) ); | ||
65 | if( bTmp.uFirstBlock != blockUnused ) | ||
66 | bsBlockUsed.setBit( j ); | ||
67 | } | ||
61 | } | 68 | } |
62 | 69 | ||
63 | void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) | 70 | void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) |
@@ -88,11 +95,11 @@ void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) | |||
88 | this->iBlockSize = iBlockSize; | 95 | this->iBlockSize = iBlockSize; |
89 | this->iBlocks = iPreAllocate; | 96 | this->iBlocks = iPreAllocate; |
90 | this->iBlockStart = sStore.tell(); | 97 | this->iBlockStart = sStore.tell(); |
91 | printf("iBlockStart = %d\n", this->iBlockStart ); | 98 | //printf("iBlockStart = %d\n", this->iBlockStart ); |
92 | bsBlockUsed.setSize( iPreAllocate, true ); | 99 | bsBlockUsed.setSize( iPreAllocate, true ); |
93 | 100 | ||
94 | printf("%d blocks, %db each, %db block offset\n", | 101 | //printf("%d blocks, %db each, %db block offset\n", |
95 | iBlocks, iBlockSize, iBlockStart ); | 102 | // iBlocks, iBlockSize, iBlockStart ); |
96 | 103 | ||
97 | Block *block = (Block *)new char[iBlockSize]; | 104 | Block *block = (Block *)new char[iBlockSize]; |
98 | memset( block, 0, iBlockSize ); | 105 | memset( block, 0, iBlockSize ); |
@@ -104,6 +111,26 @@ void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) | |||
104 | delete[] (char *)block; | 111 | delete[] (char *)block; |
105 | } | 112 | } |
106 | 113 | ||
114 | void Bu::Nids::initBlock( uint32_t uPos, uint32_t uFirstBlock, | ||
115 | uint32_t uPrevBlock, bool bNew ) | ||
116 | { | ||
117 | Block b = { uPos, blockUnused, uPrevBlock, 0, 0, { } }; | ||
118 | if( uFirstBlock != blockUnused ) | ||
119 | b.uFirstBlock = uFirstBlock; | ||
120 | bsBlockUsed.setBit( uPos ); | ||
121 | sStore.setPos( iBlockStart+(iBlockSize*uPos) ); | ||
122 | sStore.write( &b, sizeof(Block) ); | ||
123 | if( bNew ) | ||
124 | { | ||
125 | // It's a new one, at the end, write some zeros. | ||
126 | int iSize = iBlockSize-sizeof(Block); | ||
127 | char *buf = new char[iSize]; | ||
128 | memset( buf, 0, iSize ); | ||
129 | sStore.write( buf, iSize ); | ||
130 | delete[] buf; | ||
131 | } | ||
132 | } | ||
133 | |||
107 | uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, | 134 | uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, |
108 | int /*iPreAllocate*/ ) | 135 | int /*iPreAllocate*/ ) |
109 | { | 136 | { |
@@ -111,16 +138,15 @@ uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, | |||
111 | { | 138 | { |
112 | if( !bsBlockUsed.getBit( j ) ) | 139 | if( !bsBlockUsed.getBit( j ) ) |
113 | { | 140 | { |
114 | Block b = { j, blockUnused, uPrevBlock, 0, 0, { } }; | 141 | initBlock( j, uFirstBlock, uPrevBlock ); |
115 | if( uFirstBlock != blockUnused ) | ||
116 | b.uFirstBlock = uFirstBlock; | ||
117 | bsBlockUsed.setBit( j ); | ||
118 | sStore.setPos( iBlockStart+(iBlockSize*j) ); | ||
119 | sStore.write( &b, sizeof(b) ); | ||
120 | return j; | 142 | return j; |
121 | } | 143 | } |
122 | } | 144 | } |
123 | return blockUnused; | 145 | // Oh, we don't have any blocks left...allocate a new one. |
146 | iBlocks++; | ||
147 | bsBlockUsed.setSize( iBlocks, false ); | ||
148 | initBlock( iBlocks-1, uFirstBlock, uPrevBlock, true ); | ||
149 | return iBlocks-1; | ||
124 | } | 150 | } |
125 | 151 | ||
126 | int Bu::Nids::createStream( int iPreAllocate ) | 152 | int Bu::Nids::createStream( int iPreAllocate ) |
@@ -169,15 +195,22 @@ void Bu::Nids::updateStreamSize( uint32_t uIndex, uint32_t uSize ) | |||
169 | } | 195 | } |
170 | 196 | ||
171 | uint32_t Bu::Nids::getNextBlock( uint32_t uIndex, | 197 | uint32_t Bu::Nids::getNextBlock( uint32_t uIndex, |
172 | struct Bu::Nids::Block *pBlock ) | 198 | struct Bu::Nids::Block *pBlock, bool bCreate ) |
173 | { | 199 | { |
174 | uint32_t uNew; | 200 | uint32_t uNew; |
175 | if( pBlock->uNextBlock == blockUnused ) | 201 | if( pBlock->uNextBlock == blockUnused ) |
176 | { | 202 | { |
177 | uNew = createBlock( pBlock->uFirstBlock, uIndex ); | 203 | if( bCreate ) |
178 | sStore.setPos( iBlockStart + (iBlockSize*uIndex)+1*4 ); | 204 | { |
179 | sStore.write( &uNew, 4 ); | 205 | uNew = createBlock( pBlock->uFirstBlock, uIndex ); |
180 | getBlock( uNew, pBlock ); | 206 | sStore.setPos( iBlockStart + (iBlockSize*uIndex)+1*4 ); |
207 | sStore.write( &uNew, 4 ); | ||
208 | getBlock( uNew, pBlock ); | ||
209 | } | ||
210 | else | ||
211 | { | ||
212 | throw Bu::NidsException("Reached end of stream."); | ||
213 | } | ||
181 | } | 214 | } |
182 | else | 215 | else |
183 | { | 216 | { |
@@ -1,3 +1,10 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 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 | |||
1 | #ifndef BU_NIDS_H | 8 | #ifndef BU_NIDS_H |
2 | #define BU_NIDS_H | 9 | #define BU_NIDS_H |
3 | 10 | ||
@@ -75,12 +82,17 @@ namespace Bu | |||
75 | blockUnused = 0xFFFFFFFFUL | 82 | blockUnused = 0xFFFFFFFFUL |
76 | }; | 83 | }; |
77 | 84 | ||
85 | void initBlock( uint32_t uPos, uint32_t uFirstBlock, | ||
86 | uint32_t uPrevBlock, bool bNew=false ); | ||
78 | uint32_t createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, | 87 | uint32_t createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, |
79 | int iPreAllocate=1 ); | 88 | int iPreAllocate=1 ); |
80 | void getBlock( uint32_t uIndex, struct Nids::Block *pBlock ); | 89 | void getBlock( uint32_t uIndex, struct Nids::Block *pBlock ); |
81 | void setBlock( uint32_t uIndex, struct Nids::Block *pBlock ); | 90 | void setBlock( uint32_t uIndex, struct Nids::Block *pBlock ); |
82 | void updateStreamSize( uint32_t uIndex, uint32_t uSize ); | 91 | void updateStreamSize( uint32_t uIndex, uint32_t uSize ); |
83 | uint32_t getNextBlock( uint32_t uIndex, struct Nids::Block *pBlock ); | 92 | uint32_t getNextBlock( uint32_t uIndex, struct Nids::Block *pBlock, |
93 | bool bCreate=true); | ||
94 | |||
95 | // Block allocation routines | ||
84 | Block *newBlock(); | 96 | Block *newBlock(); |
85 | void deleteBlock( Block *pBlock ); | 97 | void deleteBlock( Block *pBlock ); |
86 | 98 | ||
diff --git a/src/nidsstream.cpp b/src/nidsstream.cpp index 740dc1f..4f692c6 100644 --- a/src/nidsstream.cpp +++ b/src/nidsstream.cpp | |||
@@ -9,7 +9,7 @@ Bu::NidsStream::NidsStream( Nids &rNids, uint32_t uStream ) : | |||
9 | uBlockSize( rNids.iBlockSize-sizeof(Nids::Block) ), | 9 | uBlockSize( rNids.iBlockSize-sizeof(Nids::Block) ), |
10 | uPos( 0 ) | 10 | uPos( 0 ) |
11 | { | 11 | { |
12 | printf("NidsStream::allocated\n"); | 12 | //printf("NidsStream::allocated\n"); |
13 | pCurBlock = rNids.newBlock(); | 13 | pCurBlock = rNids.newBlock(); |
14 | rNids.getBlock( uStream, pCurBlock ); | 14 | rNids.getBlock( uStream, pCurBlock ); |
15 | uSize = pCurBlock->uBytesUsed; | 15 | uSize = pCurBlock->uBytesUsed; |
@@ -34,6 +34,7 @@ Bu::NidsStream::NidsStream( const Bu::NidsStream &rSrc ) : | |||
34 | 34 | ||
35 | Bu::NidsStream::~NidsStream() | 35 | Bu::NidsStream::~NidsStream() |
36 | { | 36 | { |
37 | //printf("Destroying stream?\n"); | ||
37 | rNids.updateStreamSize( uStream, uSize ); | 38 | rNids.updateStreamSize( uStream, uSize ); |
38 | rNids.deleteBlock( pCurBlock ); | 39 | rNids.deleteBlock( pCurBlock ); |
39 | } | 40 | } |
@@ -47,20 +48,35 @@ size_t Bu::NidsStream::read( void *pBuf, size_t nBytes ) | |||
47 | if( uPos%uBlockSize+nBytes < uBlockSize ) | 48 | if( uPos%uBlockSize+nBytes < uBlockSize ) |
48 | { | 49 | { |
49 | size_t iRead = nBytes; | 50 | size_t iRead = nBytes; |
50 | if( iRead > pCurBlock->uBytesUsed ) | 51 | if( iRead > pCurBlock->uBytesUsed-(uPos%uBlockSize) ) |
51 | iRead = pCurBlock->uBytesUsed; | 52 | iRead = pCurBlock->uBytesUsed-(uPos%uBlockSize); |
52 | memcpy( pBuf, pCurBlock->pData+(uPos%uBlockSize), iRead ); | 53 | memcpy( pBuf, pCurBlock->pData+(uPos%uBlockSize), iRead ); |
53 | uPos += nBytes; | 54 | uPos += iRead; |
54 | printf("a: block %u = %ub (%ub total)\n", | 55 | //printf("a: block %u = %ub (%ub total)\n", |
55 | uCurBlock, pCurBlock->uBytesUsed, uSize ); | 56 | // uCurBlock, pCurBlock->uBytesUsed, uSize ); |
56 | return iRead; | 57 | return iRead; |
57 | } | 58 | } |
58 | else | 59 | else |
59 | { | 60 | { |
60 | //size_t iTotal = 0; | 61 | size_t nTotal = 0; |
61 | for(;;) | 62 | for(;;) |
62 | { | 63 | { |
63 | 64 | uint32_t iRead = nBytes; | |
65 | if( iRead > uBlockSize-(uPos%uBlockSize) ) | ||
66 | iRead = uBlockSize-(uPos%uBlockSize); | ||
67 | if( iRead > pCurBlock->uBytesUsed-(uPos%uBlockSize) ) | ||
68 | iRead = pCurBlock->uBytesUsed-(uPos%uBlockSize); | ||
69 | memcpy( ((char *)pBuf)+nTotal, | ||
70 | pCurBlock->pData+(uPos%uBlockSize), iRead ); | ||
71 | uPos += iRead; | ||
72 | nBytes -= iRead; | ||
73 | nTotal += iRead; | ||
74 | //printf("r: block %u = %ub/%ub (%ub total)\n", | ||
75 | // uCurBlock, iRead, pCurBlock->uBytesUsed, uSize ); | ||
76 | if( nBytes == 0 || uPos == uSize ) | ||
77 | return nTotal; | ||
78 | if( nTotal%uBlockSize == 0 ) | ||
79 | uCurBlock = rNids.getNextBlock( uCurBlock, pCurBlock, false ); | ||
64 | } | 80 | } |
65 | } | 81 | } |
66 | return 0; | 82 | return 0; |
@@ -75,8 +91,8 @@ size_t Bu::NidsStream::write( const void *pBuf, size_t nBytes ) | |||
75 | rNids.setBlock( uCurBlock, pCurBlock ); | 91 | rNids.setBlock( uCurBlock, pCurBlock ); |
76 | uPos += nBytes; | 92 | uPos += nBytes; |
77 | uSize += nBytes; | 93 | uSize += nBytes; |
78 | printf("a: block %u = %ub (%ub total)\n", | 94 | //printf("a: block %u = %ub (%ub total)\n", |
79 | uCurBlock, pCurBlock->uBytesUsed, uSize ); | 95 | // uCurBlock, pCurBlock->uBytesUsed, uSize ); |
80 | return nBytes; | 96 | return nBytes; |
81 | } | 97 | } |
82 | else | 98 | else |
@@ -95,8 +111,8 @@ size_t Bu::NidsStream::write( const void *pBuf, size_t nBytes ) | |||
95 | uPos += uNow; | 111 | uPos += uNow; |
96 | nTotal += uNow; | 112 | nTotal += uNow; |
97 | nBytes -= uNow; | 113 | nBytes -= uNow; |
98 | printf("b: block %u = %ub (%ub total)\n", | 114 | //printf("b: block %u = %ub (%ub total)\n", |
99 | uCurBlock, pCurBlock->uBytesUsed, uSize ); | 115 | // uCurBlock, pCurBlock->uBytesUsed, uSize ); |
100 | if( nBytes == 0 ) | 116 | if( nBytes == 0 ) |
101 | return nTotal; | 117 | return nTotal; |
102 | if( pCurBlock->uBytesUsed == uBlockSize ) | 118 | if( pCurBlock->uBytesUsed == uBlockSize ) |
diff --git a/src/tests/nids.cpp b/src/tests/nids.cpp index f50fde5..d531280 100644 --- a/src/tests/nids.cpp +++ b/src/tests/nids.cpp | |||
@@ -4,22 +4,44 @@ | |||
4 | 4 | ||
5 | int main( int argc, char *argv[] ) | 5 | int main( int argc, char *argv[] ) |
6 | { | 6 | { |
7 | if( argc < 2 ) | 7 | if( argc < 3 ) |
8 | { | 8 | { |
9 | printf("usage: %s <output>\n\n", argv[0] ); | 9 | printf("usage: %s [r|w] <output>\n\n", argv[0] ); |
10 | return 1; | 10 | return 1; |
11 | } | 11 | } |
12 | 12 | ||
13 | Bu::File fOut( argv[1], Bu::File::ReadWrite ); | 13 | if( argv[1][0] == 'w' ) |
14 | Bu::Nids n( fOut ); | 14 | { |
15 | Bu::File fOut( argv[2], | ||
16 | Bu::File::ReadWrite|Bu::File::Create|Bu::File::Truncate ); | ||
17 | Bu::Nids n( fOut ); | ||
15 | 18 | ||
16 | // n.initialize( 120, 5 ); | 19 | n.initialize( 120, 1 ); |
20 | Bu::NidsStream s = n.openStream( n.createStream() ); | ||
17 | 21 | ||
18 | Bu::NidsStream s = n.openStream( n.createStream() ); | 22 | Bu::FString sBuf( 350 ); |
23 | memset( sBuf.getStr(), 'a', 350 ); | ||
24 | s.write( sBuf ); | ||
25 | } | ||
26 | else if( argv[1][0] == 'r' ) | ||
27 | { | ||
28 | Bu::File fOut( argv[2], Bu::File::Read ); | ||
29 | Bu::Nids n( fOut ); | ||
19 | 30 | ||
20 | // Bu::FString sBuf( 350 ); | 31 | Bu::NidsStream s = n.openStream( 0 ); |
21 | // memset( sBuf.getStr(), 'a', 350 ); | 32 | char buf[75]; |
22 | // s.write( sBuf ); | 33 | for( int j = 0; j < 3; j++ ) |
34 | { | ||
35 | int iRead = s.read( buf, 75 ); | ||
36 | fwrite( buf, 1, iRead, stdout ); | ||
37 | printf("\n(read %d chars)\n", iRead ); | ||
38 | } | ||
39 | printf("Position: %ld\n", s.tell() ); | ||
40 | } | ||
41 | else | ||
42 | { | ||
43 | printf("r or w, those are your choices.\n"); | ||
44 | } | ||
23 | 45 | ||
24 | return 0; | 46 | return 0; |
25 | } | 47 | } |
diff --git a/src/unit/membuf.cpp b/src/unit/membuf.cpp index 3aebc4d..dc02aa3 100644 --- a/src/unit/membuf.cpp +++ b/src/unit/membuf.cpp | |||
@@ -15,6 +15,7 @@ public: | |||
15 | { | 15 | { |
16 | setName("MemBuf"); | 16 | setName("MemBuf"); |
17 | addTest( Unit::testWriteRead01 ); | 17 | addTest( Unit::testWriteRead01 ); |
18 | addTest( Unit::testOverwrite1 ); | ||
18 | } | 19 | } |
19 | 20 | ||
20 | virtual ~Unit() | 21 | virtual ~Unit() |
@@ -39,6 +40,21 @@ public: | |||
39 | unitTest( mb.read( buf, 7 ) == 3 ); | 40 | unitTest( mb.read( buf, 7 ) == 3 ); |
40 | unitTest( !strncmp( buf, "eFG", 3 ) ); | 41 | unitTest( !strncmp( buf, "eFG", 3 ) ); |
41 | } | 42 | } |
43 | |||
44 | void testOverwrite1() | ||
45 | { | ||
46 | Bu::MemBuf mb; | ||
47 | unitTest( mb.write("0123456789") == 10 ); | ||
48 | mb.setPos( 4 ); | ||
49 | unitTest( mb.write("-5-") == 3 ); | ||
50 | mb.setPos( 9 ); | ||
51 | mb.write("Hey!!!"); | ||
52 | unitTest( mb.tell() == 15 ); | ||
53 | char buf[50]; | ||
54 | mb.setPos( 0 ); | ||
55 | buf[mb.read( buf, 50 )] = '\0'; | ||
56 | unitTest( !strcmp( buf, "0123-5-78Hey!!!" ) ); | ||
57 | } | ||
42 | }; | 58 | }; |
43 | 59 | ||
44 | int main( int argc, char *argv[] ){ return Unit().run( argc, argv ); } | 60 | int main( int argc, char *argv[] ){ return Unit().run( argc, argv ); } |