diff options
author | Mike Buland <eichlan@xagasoft.com> | 2008-10-08 16:17:26 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2008-10-08 16:17:26 +0000 |
commit | 3f1c8998166466245aee2860197fb4908e55f1a2 (patch) | |
tree | b6d148679bbd87125f03cb723d5b59969b90c733 | |
parent | 5883662909051e99093514483c32e2539a3cf850 (diff) | |
download | libbu++-3f1c8998166466245aee2860197fb4908e55f1a2.tar.gz libbu++-3f1c8998166466245aee2860197fb4908e55f1a2.tar.bz2 libbu++-3f1c8998166466245aee2860197fb4908e55f1a2.tar.xz libbu++-3f1c8998166466245aee2860197fb4908e55f1a2.zip |
Ok...corrected a problem with new block allocation in nids, and it no longer
goes into an infinite loop while doing certain kinds of read. Also, it zeros
out new blocks to make things easier to cope with in the hex editor, it'll
probably also compress better.
I also fixed Bu::MemBuf so that you can now write to arbitrary places
mid-stream.
-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 ); } |