summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--default.bld2
-rw-r--r--src/myriad.cpp69
-rw-r--r--src/myriad.h41
-rw-r--r--src/myriadstream.cpp157
-rw-r--r--src/myriadstream.h12
-rw-r--r--src/tools/myriad.cpp112
6 files changed, 262 insertions, 131 deletions
diff --git a/default.bld b/default.bld
index 6c9c4bb..9d94f73 100644
--- a/default.bld
+++ b/default.bld
@@ -11,7 +11,7 @@
11 * and actually does a better job with a number of things. 11 * and actually does a better job with a number of things.
12 */ 12 */
13 13
14CXXFLAGS += "-ggdb -W -Wall"; 14CXXFLAGS += "-ggdb -W -Wall -I.";
15 15
16action "default" 16action "default"
17{ 17{
diff --git a/src/myriad.cpp b/src/myriad.cpp
index d3914df..a1a5c38 100644
--- a/src/myriad.cpp
+++ b/src/myriad.cpp
@@ -77,14 +77,18 @@ void Bu::Myriad::initialize()
77 iBlocks = iSize/iBlockSize; 77 iBlocks = iSize/iBlockSize;
78 sio << "Myriad: iSize=" << iSize << ", iBlockSize=" << iBlockSize 78 sio << "Myriad: iSize=" << iSize << ", iBlockSize=" << iBlockSize
79 << ", iBlocks=" << iBlocks << ", iStreams=" << iStreams << sio.nl; 79 << ", iBlocks=" << iBlocks << ", iStreams=" << iStreams << sio.nl;
80 80
81 // Don't do this, just read the damn header.
82 sio << "Myriad: Don't do this, just read the damn header (line 82)"
83 << sio.nl;
84
81 int iHeaderSize = 14 + 8 + 4; 85 int iHeaderSize = 14 + 8 + 4;
82 int iHeaderBlocks = blkDiv( iHeaderSize+4, iBlockSize ); 86 int iHeaderBlocks = 0; //blkDiv( iHeaderSize+4, iBlockSize );
83 87
84 while( iHeaderSize > iHeaderBlocks*iBlockSize ) 88 while( iHeaderSize > iHeaderBlocks*iBlockSize )
85 { 89 {
86 iHeaderSize = 14 + 8 + 4*iHeaderBlocks;
87 iHeaderBlocks = blkDiv( iHeaderSize+4, iBlockSize ); 90 iHeaderBlocks = blkDiv( iHeaderSize+4, iBlockSize );
91 iHeaderSize = 14 + 8 + 4*iHeaderBlocks;
88 } 92 }
89 93
90 sio << "Myriad: iHeaderSize=" << iHeaderSize 94 sio << "Myriad: iHeaderSize=" << iHeaderSize
@@ -102,7 +106,8 @@ void Bu::Myriad::initialize()
102 sStore.read( &s.iId, 4 ); 106 sStore.read( &s.iId, 4 );
103 sStore.read( &s.iSize, 4 ); 107 sStore.read( &s.iSize, 4 );
104 int iSBlocks = blkDiv(s.iSize, iBlockSize); 108 int iSBlocks = blkDiv(s.iSize, iBlockSize);
105 sio << "Myriad: - Stream::iId=" << s.iId << ", Stream::iSize=" << s.iSize 109 sio << "Myriad: - Stream::iId=" << s.iId
110 << ", Stream::iSize=" << s.iSize
106 << ", Stream::aBlocks=" << iSBlocks 111 << ", Stream::aBlocks=" << iSBlocks
107 << ", sStore.tell()=" << sStore.tell() << sio.nl; 112 << ", sStore.tell()=" << sStore.tell() << sio.nl;
108 for( int k = 0; k < iSBlocks; k++ ) 113 for( int k = 0; k < iSBlocks; k++ )
@@ -133,7 +138,7 @@ void Bu::Myriad::initialize()
133 } 138 }
134 } 139 }
135 140
136 sio << bsBlockUsed.toString() << sio.nl; 141 sio << "Myriad: Blocks used: " << bsBlockUsed.toString() << sio.nl;
137 142
138 //printf("%d blocks, %db each, %db block offset\n", 143 //printf("%d blocks, %db each, %db block offset\n",
139 // iBlocks, iBlockSize, iBlockStart ); 144 // iBlocks, iBlockSize, iBlockStart );
@@ -143,7 +148,7 @@ void Bu::Myriad::initialize()
143void Bu::Myriad::initialize( int iBlockSize, int iPreAllocate ) 148void Bu::Myriad::initialize( int iBlockSize, int iPreAllocate )
144{ 149{
145 int iHeaderSize = 14 + 8 + 4; 150 int iHeaderSize = 14 + 8 + 4;
146 int iHeaderBlocks = blkDiv( iHeaderSize+4, iBlockSize ); 151 int iHeaderBlocks = 0; //blkDiv( iHeaderSize+4, iBlockSize );
147 char cBuf = 1; 152 char cBuf = 1;
148 int iBuf = 0; 153 int iBuf = 0;
149 154
@@ -152,13 +157,13 @@ void Bu::Myriad::initialize( int iBlockSize, int iPreAllocate )
152 157
153 while( iHeaderSize > iHeaderBlocks*iBlockSize ) 158 while( iHeaderSize > iHeaderBlocks*iBlockSize )
154 { 159 {
155 iHeaderSize = 14 + 8 + 4*iHeaderBlocks;
156 iHeaderBlocks = blkDiv( iHeaderSize+4, iBlockSize ); 160 iHeaderBlocks = blkDiv( iHeaderSize+4, iBlockSize );
161 iHeaderSize = 14 + 8 + 4*iHeaderBlocks;
157 } 162 }
158 163
159 iPreAllocate += iHeaderBlocks; 164 iPreAllocate += iHeaderBlocks;
160 165
161 sio << "Myriad: iHeaderSize=" << iHeaderSize << ", iBlockSize=" 166 sio << "Myriad: iHeaderSize=" << iHeaderSize << ", iBlockSize="
162 << iBlockSize << ", iHeaderBlocks=" << iHeaderBlocks << sio.nl; 167 << iBlockSize << ", iHeaderBlocks=" << iHeaderBlocks << sio.nl;
163 168
164 bsBlockUsed.setSize( iPreAllocate, true ); 169 bsBlockUsed.setSize( iPreAllocate, true );
@@ -204,6 +209,7 @@ void Bu::Myriad::initialize( int iBlockSize, int iPreAllocate )
204 this->iBlocks = iPreAllocate; 209 this->iBlocks = iPreAllocate;
205 210
206 pStr->iSize = sStore.tell(); 211 pStr->iSize = sStore.tell();
212 sio << "Myriad: Actual end of header stream = " << pStr->iSize << sio.nl;
207 213
208 //hStreams.insert( 0, BlockArray( 0 ) ); 214 //hStreams.insert( 0, BlockArray( 0 ) );
209} 215}
@@ -229,9 +235,9 @@ int Bu::Myriad::createStream( int iPreAllocate )
229 for( int j = 0; j < iPreAllocate; j++ ) 235 for( int j = 0; j < iPreAllocate; j++ )
230 { 236 {
231 int iFreeBlock = findEmptyBlock(); 237 int iFreeBlock = findEmptyBlock();
232 sio << "Myriad: Adding block " << j << sio.nl; 238 sio << "Myriad: Adding block " << iFreeBlock << sio.nl;
233 pStr->aBlocks.append( j ); 239 pStr->aBlocks.append( iFreeBlock );
234 bsBlockUsed.setBit( j ); 240 bsBlockUsed.setBit( iFreeBlock );
235 } 241 }
236 242
237 return 0; 243 return 0;
@@ -261,9 +267,9 @@ void Bu::Myriad::deleteStream( int /*iID*/ )
261{ 267{
262} 268}
263 269
264Bu::MyriadStream Bu::Myriad::openStream( int iID ) 270Bu::MyriadStream Bu::Myriad::openStream( int iId )
265{ 271{
266 return MyriadStream( *this, iID ); 272 return MyriadStream( *this, findStream( iId ) );
267} 273}
268 274
269int Bu::Myriad::getBlockSize() 275int Bu::Myriad::getBlockSize()
@@ -281,4 +287,41 @@ int Bu::Myriad::getNumUsedBlocks()
281 return iUsed; 287 return iUsed;
282} 288}
283 289
290Bu::Myriad::Stream *Bu::Myriad::findStream( int iId )
291{
292 for( StreamArray::iterator i = aStreams.begin(); i; i++ )
293 {
294 if( (*i)->iId == iId )
295 return *i;
296 }
297
298 return NULL;
299}
300
301Bu::Myriad::Block *Bu::Myriad::getBlock( int iBlock )
302{
303 sio << "Myriad: Reading block " << iBlock << ", bytes "
304 << iBlockSize*iBlock << "-" << iBlockSize*(iBlock+1) << sio.nl;
305 Block *pBlock = new Block;
306 pBlock->pData = new char[iBlockSize];
307 sStore.setPos( iBlockSize * iBlock );
308 sStore.read( pBlock->pData, iBlockSize );
309 pBlock->bChanged = false;
310 pBlock->iBlockIndex = iBlock;
311
312 return pBlock;
313}
314
315void Bu::Myriad::releaseBlock( Bu::Myriad::Block *pBlock )
316{
317 sio << "Myriad: Releasing block " << pBlock->iBlockIndex << sio.nl;
318 if( pBlock->bChanged )
319 {
320 sio << "Myriad: - Block changed, writing back to stream." << sio.nl;
321 sStore.setPos( iBlockSize * pBlock->iBlockIndex );
322 sStore.write( pBlock->pData, iBlockSize );
323 }
324 delete[] pBlock->pData;
325 delete pBlock;
326}
284 327
diff --git a/src/myriad.h b/src/myriad.h
index f6d5e51..0344057 100644
--- a/src/myriad.h
+++ b/src/myriad.h
@@ -30,7 +30,7 @@ namespace Bu
30 * Header format is as follows: 30 * Header format is as follows:
31 * 31 *
32 * MMMMvBssssSSSS* 32 * MMMMvBssssSSSS*
33 * M = Magic number 33 * M = Magic number (FFC399BD)
34 * v = version number 34 * v = version number
35 * B = Bits per int 35 * B = Bits per int
36 * s = Blocksize in bytes 36 * s = Blocksize in bytes
@@ -95,12 +95,12 @@ namespace Bu
95 /** 95 /**
96 * Delete a stream that's already within the Myriad. 96 * Delete a stream that's already within the Myriad.
97 */ 97 */
98 void deleteStream( int iID ); 98 void deleteStream( int iId );
99 99
100 /** 100 /**
101 * Return a new Stream object assosiated with the given stream ID. 101 * Return a new Stream object assosiated with the given stream ID.
102 */ 102 */
103 MyriadStream openStream( int iID ); 103 MyriadStream openStream( int iId );
104 104
105 int getBlockSize(); 105 int getBlockSize();
106 int getNumBlocks(); 106 int getNumBlocks();
@@ -118,25 +118,42 @@ namespace Bu
118 { 118 {
119 blockUnused = 0xFFFFFFFFUL 119 blockUnused = 0xFFFFFFFFUL
120 }; 120 };
121
122 typedef Bu::Array<int> BlockArray;
123 class Stream
124 {
125 public:
126 int iId;
127 int iSize;
128 BlockArray aBlocks;
129 };
130 typedef Bu::Array<Stream *> StreamArray;
131
132 class Block
133 {
134 public:
135 char *pData;
136 bool bChanged;
137 int iBlockIndex;
138 };
121 139
122 void updateHeader(); 140 void updateHeader();
123 int findEmptyBlock(); 141 int findEmptyBlock();
124 142
143 /**
144 *@todo Change this to use a binary search, it's nicer.
145 */
146 Stream *findStream( int iId );
147
148 Block *getBlock( int iBlock );
149 void releaseBlock( Block *pBlock );
150
125 private: 151 private:
126 Bu::Stream &sStore; 152 Bu::Stream &sStore;
127 int iBlockSize; 153 int iBlockSize;
128 int iBlocks; 154 int iBlocks;
129 int iUsed; 155 int iUsed;
130 Bu::BitString bsBlockUsed; 156 Bu::BitString bsBlockUsed;
131 typedef Bu::Array<int> BlockArray;
132 class Stream
133 {
134 public:
135 int iId;
136 int iSize;
137 BlockArray aBlocks;
138 };
139 typedef Bu::Array<Stream *> StreamArray;
140 StreamArray aStreams; 157 StreamArray aStreams;
141 }; 158 };
142}; 159};
diff --git a/src/myriadstream.cpp b/src/myriadstream.cpp
index 04f98ed..0e6fc89 100644
--- a/src/myriadstream.cpp
+++ b/src/myriadstream.cpp
@@ -6,19 +6,22 @@
6 */ 6 */
7 7
8#include "bu/myriadstream.h" 8#include "bu/myriadstream.h"
9#include "bu/sio.h"
10
11using Bu::sio;
12using Bu::Fmt;
9 13
10#include <string.h> 14#include <string.h>
11 15
12Bu::MyriadStream::MyriadStream( Myriad &rMyriad, uint32_t uStream ) : 16Bu::MyriadStream::MyriadStream( Bu::Myriad &rMyriad,
17 Bu::Myriad::Stream *pStream ) :
13 rMyriad( rMyriad ), 18 rMyriad( rMyriad ),
14 uStream( uStream ), 19 pStream( pStream ),
15 pCurBlock( NULL ), 20 pCurBlock( NULL ),
16 uCurBlock( uStream ), 21 iPos( 0 )
17 uSize( 0 ),
18 uBlockSize( rMyriad.iBlockSize ),
19 uPos( 0 )
20{ 22{
21 //printf("MyriadStream::allocated\n"); 23 sio << "MyriadStream: Created, iId=" << pStream->iId << ", iSize="
24 << pStream->iSize << sio.nl;
22 //pCurBlock = rMyriad.newBlock(); 25 //pCurBlock = rMyriad.newBlock();
23 //rMyriad.getBlock( uStream, pCurBlock ); 26 //rMyriad.getBlock( uStream, pCurBlock );
24 //uSize = pCurBlock->uBytesUsed; 27 //uSize = pCurBlock->uBytesUsed;
@@ -26,7 +29,8 @@ Bu::MyriadStream::MyriadStream( Myriad &rMyriad, uint32_t uStream ) :
26 29
27Bu::MyriadStream::~MyriadStream() 30Bu::MyriadStream::~MyriadStream()
28{ 31{
29 //printf("Destroying stream?\n"); 32 if( pCurBlock )
33 rMyriad.releaseBlock( pCurBlock );
30 //rMyriad.updateStreamSize( uStream, uSize ); 34 //rMyriad.updateStreamSize( uStream, uSize );
31 //rMyriad.deleteBlock( pCurBlock ); 35 //rMyriad.deleteBlock( pCurBlock );
32} 36}
@@ -37,57 +41,54 @@ void Bu::MyriadStream::close()
37 41
38size_t Bu::MyriadStream::read( void *pBuf, size_t nBytes ) 42size_t Bu::MyriadStream::read( void *pBuf, size_t nBytes )
39{ 43{
40 /* 44 sio << "MyriadStream: Read: Started, asked to read " << nBytes << "b."
41 if( nBytes == 0 ) 45 << sio.nl;
46 if( nBytes <= 0 )
42 return 0; 47 return 0;
43 if( nBytes + uPos > uSize ) 48 if( nBytes > pStream->iSize-iPos )
44 nBytes = uSize - uPos; 49 nBytes = pStream->iSize-iPos;
45 if( (uPos%uBlockSize)+nBytes < uBlockSize ) 50 int iLeft = nBytes;
51 sio << "MyriadStream: Read: Started, going to read " << nBytes << "b."
52 << sio.nl;
53 if( pCurBlock == NULL )
46 { 54 {
47 size_t iRead = nBytes; 55 sio << "MyriadStream: Read: No block loaded, loading initial block."
48 if( iRead > pCurBlock->uBytesUsed-(uPos%uBlockSize) ) 56 << sio.nl;
49 iRead = pCurBlock->uBytesUsed-(uPos%uBlockSize); 57 pCurBlock = rMyriad.getBlock(
50 memcpy( pBuf, pCurBlock->pData+(uPos%uBlockSize), iRead ); 58 pStream->aBlocks[iPos/rMyriad.iBlockSize]
51 //printf("read buffill: %ub, %u-%u/%u -> %d-%d/%d (a:%u)", 59 );
52 // iRead, uPos, uPos+iRead-1, uSize, 0, iRead-1, nBytes, uCurBlock );
53 uPos += iRead;
54 //printf(" -- %u\n", uPos%uBlockSize );
55 //printf("ra: block %u = %ub:%u (%ub total)\n",
56 // uCurBlock, uPos, nBytes, uSize );
57
58 // This can't happen, if we're right on a boundery, it goes to the
59 // other case
60 //if( uPos%uBlockSize == 0 )
61 // uCurBlock = rMyriad.getNextBlock( uCurBlock, pCurBlock, false );
62 return iRead;
63 } 60 }
64 else 61 while( iLeft > 0 )
65 { 62 {
66 size_t nTotal = 0; 63 int iCurBlock = pStream->aBlocks[iPos/rMyriad.iBlockSize];
67 for(;;) 64 if( pCurBlock->iBlockIndex != iCurBlock )
68 { 65 {
69 uint32_t iRead = nBytes; 66 sio << "MyriadStream: Read: Loading new block " << iCurBlock << "."
70 if( iRead > uBlockSize-(uPos%uBlockSize) ) 67 << sio.nl;
71 iRead = uBlockSize-(uPos%uBlockSize); 68 rMyriad.releaseBlock( pCurBlock );
72 if( iRead > pCurBlock->uBytesUsed-(uPos%uBlockSize) ) 69 pCurBlock = rMyriad.getBlock( iCurBlock );
73 iRead = pCurBlock->uBytesUsed-(uPos%uBlockSize);
74 memcpy( ((char *)pBuf)+nTotal,
75 pCurBlock->pData+(uPos%uBlockSize), iRead );
76 //printf(" read buffill: %ub, %u-%u/%u -> %d-%d/%d (b:%u)\n",
77 // iRead, uPos, uPos+iRead-1, uSize,
78 // nTotal, nTotal+nBytes-1, nBytes, uCurBlock );
79 uPos += iRead;
80 nBytes -= iRead;
81 nTotal += iRead;
82 //printf("rb: block %u = %ub:%u (%ub total)\n",
83 // uCurBlock, uPos, iRead, uSize );
84 if( uPos%uBlockSize == 0 )
85 uCurBlock = rMyriad.getNextBlock( uCurBlock, pCurBlock, false );
86 if( nBytes == 0 || uPos >= uSize )
87 return nTotal;
88 } 70 }
89 }*/ 71
90 return 0; 72 int iAmnt = Bu::min(
73 rMyriad.iBlockSize - iPos%rMyriad.iBlockSize,
74 iLeft
75 );
76// if( iLeft > iAmnt )
77// iAmnt = iLeft;
78 sio << "MyriadStream: Read: Copying out bytes: "
79 << (iPos%rMyriad.iBlockSize) << " - "
80 << iAmnt
81 << ", " << iLeft << "b left." << sio.nl;
82 memcpy(
83 pBuf,
84 pCurBlock->pData+iPos%rMyriad.iBlockSize,
85 iAmnt
86 );
87 iPos += iAmnt;
88 pBuf = &((char *)pBuf)[iAmnt];
89 iLeft -= iAmnt;
90 }
91 return nBytes;
91} 92}
92 93
93size_t Bu::MyriadStream::write( const void *pBuf, size_t nBytes ) 94size_t Bu::MyriadStream::write( const void *pBuf, size_t nBytes )
@@ -101,22 +102,22 @@ size_t Bu::MyriadStream::write( const void *pBuf, size_t nBytes )
101 uCurBlock = rMyriad.getNextBlock( uCurBlock, pCurBlock ); 102 uCurBlock = rMyriad.getNextBlock( uCurBlock, pCurBlock );
102 } */ 103 } */
103 /* 104 /*
104 if( (uPos%uBlockSize)+nBytes < uBlockSize ) 105 if( (iPos%uBlockSize)+nBytes < uBlockSize )
105 { 106 {
106 //printf("wa: %u:%u:%u:%u -> ", uPos, uPos%uBlockSize, uSize, pCurBlock->uBytesUsed ); 107 //printf("wa: %u:%u:%u:%u -> ", iPos, iPos%uBlockSize, uSize, pCurBlock->uBytesUsed );
107 memcpy( pCurBlock->pData+(uPos%uBlockSize), pBuf, nBytes ); 108 memcpy( pCurBlock->pData+(iPos%uBlockSize), pBuf, nBytes );
108 //printf("write buffill: %ub, %u-%u/%u -> %d-%d/%d (a:%u:%u)\n", 109 //printf("write buffill: %ub, %u-%u/%u -> %d-%d/%d (a:%u:%u)\n",
109 // nBytes, 0, nBytes-1, nBytes, 110 // nBytes, 0, nBytes-1, nBytes,
110 // uPos, uPos+nBytes-1, uSize, uCurBlock, 111 // iPos, iPos+nBytes-1, uSize, uCurBlock,
111 // pCurBlock->uBytesUsed ); 112 // pCurBlock->uBytesUsed );
112 if( (uPos%uBlockSize)+nBytes > pCurBlock->uBytesUsed ) 113 if( (iPos%uBlockSize)+nBytes > pCurBlock->uBytesUsed )
113 pCurBlock->uBytesUsed = (uPos%uBlockSize)+nBytes; 114 pCurBlock->uBytesUsed = (iPos%uBlockSize)+nBytes;
114 rMyriad.setBlock( uCurBlock, pCurBlock ); 115 rMyriad.setBlock( uCurBlock, pCurBlock );
115 uPos += nBytes; 116 iPos += nBytes;
116 if( uPos > uSize ) 117 if( iPos > uSize )
117 uSize = uPos; 118 uSize = iPos;
118 //printf("block %u = %ub (%ub total) %d:%u\n", 119 //printf("block %u = %ub (%ub total) %d:%u\n",
119 // uCurBlock, pCurBlock->uBytesUsed, uSize, nBytes, uPos ); 120 // uCurBlock, pCurBlock->uBytesUsed, uSize, nBytes, iPos );
120 return nBytes; 121 return nBytes;
121 } 122 }
122 else 123 else
@@ -124,27 +125,27 @@ size_t Bu::MyriadStream::write( const void *pBuf, size_t nBytes )
124 size_t nTotal = 0; 125 size_t nTotal = 0;
125 for(;;) 126 for(;;)
126 { 127 {
127 uint32_t uNow = uBlockSize-(uPos%uBlockSize); 128 uint32_t uNow = uBlockSize-(iPos%uBlockSize);
128 //printf("uNow: %u (%u-(%u%%%u)) %d req\n", uNow, uBlockSize, uPos, uBlockSize, nBytes ); 129 //printf("uNow: %u (%u-(%u%%%u)) %d req\n", uNow, uBlockSize, iPos, uBlockSize, nBytes );
129 if( nBytes < uNow ) 130 if( nBytes < uNow )
130 uNow = nBytes; 131 uNow = nBytes;
131 memcpy( pCurBlock->pData+(uPos%uBlockSize), 132 memcpy( pCurBlock->pData+(iPos%uBlockSize),
132 &((char *)pBuf)[nTotal], uNow ); 133 &((char *)pBuf)[nTotal], uNow );
133 //printf("write buffill: %ub, %u-%u/%u -> %d-%d/%d (b:%u:%u)\n", 134 //printf("write buffill: %ub, %u-%u/%u -> %d-%d/%d (b:%u:%u)\n",
134 // uNow, nTotal, nTotal+uNow-1, nBytes, 135 // uNow, nTotal, nTotal+uNow-1, nBytes,
135 // uPos, uPos+uNow-1, uSize, uCurBlock, pCurBlock->uBytesUsed ); 136 // iPos, iPos+uNow-1, uSize, uCurBlock, pCurBlock->uBytesUsed );
136 if( (uPos%uBlockSize)+uNow > pCurBlock->uBytesUsed ) 137 if( (iPos%uBlockSize)+uNow > pCurBlock->uBytesUsed )
137 pCurBlock->uBytesUsed = (uPos%uBlockSize)+uNow; 138 pCurBlock->uBytesUsed = (iPos%uBlockSize)+uNow;
138 rMyriad.setBlock( uCurBlock, pCurBlock ); 139 rMyriad.setBlock( uCurBlock, pCurBlock );
139 uPos += uNow; 140 iPos += uNow;
140 if( uPos > uSize ) 141 if( iPos > uSize )
141 uSize = uPos; 142 uSize = iPos;
142 nTotal += uNow; 143 nTotal += uNow;
143 nBytes -= uNow; 144 nBytes -= uNow;
144 //printf("wb: block %u = %ub (%ub total)\n", 145 //printf("wb: block %u = %ub (%ub total)\n",
145 // uCurBlock, pCurBlock->uBytesUsed, uSize ); 146 // uCurBlock, pCurBlock->uBytesUsed, uSize );
146 //if( pCurBlock->uBytesUsed == uBlockSize ) 147 //if( pCurBlock->uBytesUsed == uBlockSize )
147 if( uPos%uBlockSize == 0 ) 148 if( iPos%uBlockSize == 0 )
148 uCurBlock = rMyriad.getNextBlock( uCurBlock, pCurBlock ); 149 uCurBlock = rMyriad.getNextBlock( uCurBlock, pCurBlock );
149 if( nBytes == 0 ) 150 if( nBytes == 0 )
150 return nTotal; 151 return nTotal;
@@ -155,27 +156,27 @@ size_t Bu::MyriadStream::write( const void *pBuf, size_t nBytes )
155 156
156long Bu::MyriadStream::tell() 157long Bu::MyriadStream::tell()
157{ 158{
158 return uPos; 159 return iPos;
159} 160}
160 161
161void Bu::MyriadStream::seek( long offset ) 162void Bu::MyriadStream::seek( long offset )
162{ 163{
163 uPos += offset; 164 iPos += offset;
164} 165}
165 166
166void Bu::MyriadStream::setPos( long pos ) 167void Bu::MyriadStream::setPos( long pos )
167{ 168{
168 uPos = pos; 169 iPos = pos;
169} 170}
170 171
171void Bu::MyriadStream::setPosEnd( long pos ) 172void Bu::MyriadStream::setPosEnd( long pos )
172{ 173{
173 uPos = uSize-pos-1; 174 iPos = pStream->iSize-pos-1;
174} 175}
175 176
176bool Bu::MyriadStream::isEos() 177bool Bu::MyriadStream::isEos()
177{ 178{
178 return true; 179 return iPos >= pStream->iSize;
179} 180}
180 181
181bool Bu::MyriadStream::isOpen() 182bool Bu::MyriadStream::isOpen()
diff --git a/src/myriadstream.h b/src/myriadstream.h
index 29ab777..e2e3ba7 100644
--- a/src/myriadstream.h
+++ b/src/myriadstream.h
@@ -20,7 +20,7 @@ namespace Bu
20 /** 20 /**
21 * These can only be created by the Myriad class. 21 * These can only be created by the Myriad class.
22 */ 22 */
23 MyriadStream( Myriad &rMyriad, uint32_t uStream ); 23 MyriadStream( Myriad &rMyriad, Myriad::Stream *pStream );
24 24
25 public: 25 public:
26 virtual ~MyriadStream(); 26 virtual ~MyriadStream();
@@ -46,12 +46,10 @@ namespace Bu
46 46
47 private: 47 private:
48 Myriad &rMyriad; 48 Myriad &rMyriad;
49 uint32_t uStream; 49 Myriad::Stream *pStream;
50 char *pCurBlock; 50 Myriad::Block *pCurBlock;
51 uint32_t uCurBlock; 51 int iBlockSize;
52 uint32_t uSize; 52 int iPos;
53 uint32_t uBlockSize;
54 uint32_t uPos;
55 }; 53 };
56}; 54};
57 55
diff --git a/src/tools/myriad.cpp b/src/tools/myriad.cpp
index b3067d2..95b4503 100644
--- a/src/tools/myriad.cpp
+++ b/src/tools/myriad.cpp
@@ -19,6 +19,8 @@ enum Mode
19{ 19{
20 modeCreate, 20 modeCreate,
21 modeInfo, 21 modeInfo,
22 modeStreamNew,
23 modeStreamRead,
22 24
23 modeNone 25 modeNone
24}; 26};
@@ -29,22 +31,32 @@ public:
29 Options( int argc, char *argv[] ) : 31 Options( int argc, char *argv[] ) :
30 eMode( modeNone ), 32 eMode( modeNone ),
31 iBlockSize( 64 ), 33 iBlockSize( 64 ),
32 iPreallocate( 0 ) 34 iPreallocate( 0 ),
35 iStream( 0 )
33 { 36 {
34 addHelpBanner("Mode of operation:"); 37 addHelpBanner("Mode of operation:");
35 addOption( eMode, 'c', "create", "Create a new NIDS file." ); 38 addOption( eMode, 'c', "create",
36 addOption( eMode, "info", "Display some info about a NIDS file." ); 39 "Create a new Myriad file." );
40 addOption( eMode, 'i', "info",
41 "Display some info about a Myriad file." );
42 addOption( eMode, 'n', "new",
43 "Create a new sub-stream in a Myriad file.");
44 addOption( eMode, 'r', "read",
45 "Read a stream from a Myriad file.");
37 addHelpOption(); 46 addHelpOption();
38 47
39 addHelpBanner("\nGeneral options:"); 48 addHelpBanner("\nGeneral options:");
40 addOption( iBlockSize, 'b', "block-size", "Set the block size." ); 49 addOption( iBlockSize, 'b', "block-size", "Set the block size." );
41 addOption( iPreallocate, 'p', "preallocate", 50 addOption( iPreallocate, 'p', "preallocate",
42 "Number of blocks to preallocate." ); 51 "Number of blocks to preallocate." );
43 addOption( sOutput, 'o', "output", "Set the output filename." ); 52 addOption( sFile, 'f', "file", "Set the Myriad filename." );
44 addOption( sInput, 'i', "input", "Set the input filename." ); 53 addOption( iStream, 's', "stream", "Substream to work with.");
54 addOption( sSrc, "src", "Source file for copying into a Myriad file.");
45 55
46 setOverride( "create", "create" ); 56 setOverride( "create", "create" );
47 setOverride( "info", "info" ); 57 setOverride( "info", "info" );
58 setOverride( "new", "new" );
59 setOverride( "read", "read" );
48 60
49 parse( argc, argv ); 61 parse( argc, argv );
50 } 62 }
@@ -52,17 +64,22 @@ public:
52 Mode eMode; 64 Mode eMode;
53 int iBlockSize; 65 int iBlockSize;
54 int iPreallocate; 66 int iPreallocate;
55 Bu::FString sOutput; 67 int iStream;
56 Bu::FString sInput; 68 Bu::FString sFile;
69 Bu::FString sSrc;
57}; 70};
58 71
59Bu::Formatter &operator>>( Bu::Formatter &f, Mode &m ) 72Bu::Formatter &operator>>( Bu::Formatter &f, Mode &m )
60{ 73{
61 Bu::FString sTok = f.readToken(); 74 Bu::FString sTok = f.readToken();
62 if( sTok == "create" || sTok == "c" ) 75 if( sTok == "create" )
63 m = modeCreate; 76 m = modeCreate;
64 else if( sTok == "info" ) 77 else if( sTok == "info" )
65 m = modeInfo; 78 m = modeInfo;
79 else if( sTok == "new" )
80 m = modeStreamNew;
81 else if( sTok == "read" )
82 m = modeStreamRead;
66 else 83 else
67 m = modeNone; 84 m = modeNone;
68 return f; 85 return f;
@@ -75,32 +92,87 @@ int main( int argc, char *argv[] )
75 switch( opts.eMode ) 92 switch( opts.eMode )
76 { 93 {
77 case modeCreate: 94 case modeCreate:
78 if( !opts.sOutput.isSet() ) 95 if( !opts.sFile.isSet() )
79 { 96 {
80 sio << "Please specify an output file to create a stream for." 97 sio << "Please specify a file to create." << sio.nl;
81 << sio.nl;
82 return 0; 98 return 0;
83 } 99 }
84 else 100 else
85 { 101 {
86 File fOut( opts.sOutput, File::WriteNew ); 102 File fOut( opts.sFile, File::WriteNew );
87 Myriad n( fOut ); 103 Myriad m( fOut );
88 n.initialize( opts.iBlockSize, opts.iPreallocate ); 104 m.initialize( opts.iBlockSize, opts.iPreallocate );
89 } 105 }
90 break; 106 break;
91 107
92 case modeInfo: 108 case modeInfo:
93 if( !opts.sInput.isSet() ) 109 if( !opts.sFile.isSet() )
94 { 110 {
95 sio << "Please specify an input file to display info about." 111 sio << "Please specify a file to display info about." << sio.nl;
96 << sio.nl;
97 return 0; 112 return 0;
98 } 113 }
99 else 114 else
100 { 115 {
101 File fIn( opts.sInput, File::Read ); 116 File fIn( opts.sFile, File::Read );
102 Myriad n( fIn ); 117 Myriad m( fIn );
103 n.initialize(); 118 m.initialize();
119 }
120 break;
121
122 case modeStreamNew:
123 if( !opts.sFile.isSet() )
124 {
125 sio << "Please specify a file manipulate." << sio.nl;
126 return 0;
127 }
128 else
129 {
130 File fOut( opts.sFile, File::Write|File::Read );
131 Myriad m( fOut );
132 m.initialize();
133 m.createStream( opts.iPreallocate );
134 }
135 break;
136
137 case modeStreamRead:
138 if( !opts.sFile.isSet() )
139 {
140 sio << "Please specify a file manipulate." << sio.nl;
141 return 0;
142 }
143 else
144 {
145 File fOut( opts.sFile, File::Read );
146 Myriad m( fOut );
147 m.initialize();
148 MyriadStream s = m.openStream( opts.iStream );
149 sio << "Stream " << opts.iStream << ":" << sio.nl;
150 char buf[8];
151 int iPos = 0;
152 while( !s.isEos() )
153 {
154 size_t sAmnt = s.read( buf, 8 );
155 sio << Fmt(5) << iPos << ": ";
156 iPos += sAmnt;
157 for( size_t j = 0; j < sAmnt; j++ )
158 {
159 sio << Fmt::hex(2) << (int)((unsigned char)buf[j])
160 << " ";
161 }
162 for( size_t j = sAmnt; j < 8; j++ )
163 {
164 sio << "-- ";
165 }
166 sio << "| ";
167 for( size_t j = 0; j < sAmnt; j++ )
168 {
169 if( buf[j] >= 32 && buf[j] <= 126 )
170 sio << buf[j] << " ";
171 else
172 sio << " ";
173 }
174 sio << sio.nl;
175 }
104 } 176 }
105 break; 177 break;
106 178