source: box/trunk/lib/common/CollectInBufferStream.cpp @ 217

Revision 217, 7.6 KB checked in by martin, 6 years ago (diff)

Set svn:eol-style as appropriate for all files

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    CollectInBufferStream.cpp
5//              Purpose: Collect data in a buffer, and then read it out.
6//              Created: 2003/08/26
7//
8// --------------------------------------------------------------------------
9
10#include "Box.h"
11
12#include <string.h>
13
14#include "CollectInBufferStream.h"
15#include "CommonException.h"
16
17#include "MemLeakFindOn.h"
18
19#define INITIAL_BUFFER_SIZE     1024
20#define MAX_BUFFER_ADDITION     (1024*64)
21
22// --------------------------------------------------------------------------
23//
24// Function
25//              Name:    CollectInBufferStream::CollectInBufferStream()
26//              Purpose: Constructor
27//              Created: 2003/08/26
28//
29// --------------------------------------------------------------------------
30CollectInBufferStream::CollectInBufferStream()
31        : mBuffer(INITIAL_BUFFER_SIZE),
32          mBufferSize(INITIAL_BUFFER_SIZE),
33          mBytesInBuffer(0),
34          mReadPosition(0),
35          mInWritePhase(true)
36{
37}
38
39// --------------------------------------------------------------------------
40//
41// Function
42//              Name:    CollectInBufferStream::~CollectInBufferStream()
43//              Purpose: Destructor
44//              Created: 2003/08/26
45//
46// --------------------------------------------------------------------------
47CollectInBufferStream::~CollectInBufferStream()
48{
49}
50
51// --------------------------------------------------------------------------
52//
53// Function
54//              Name:    CollectInBufferStream::Read(void *, int, int)
55//              Purpose: As interface. But only works in read phase
56//              Created: 2003/08/26
57//
58// --------------------------------------------------------------------------
59int CollectInBufferStream::Read(void *pBuffer, int NBytes, int Timeout)
60{
61        if(mInWritePhase != false) { THROW_EXCEPTION(CommonException, CollectInBufferStreamNotInCorrectPhase) }
62       
63        // Adjust to number of bytes left
64        if(NBytes > (mBytesInBuffer - mReadPosition))
65        {
66                NBytes = (mBytesInBuffer - mReadPosition);
67        }
68        ASSERT(NBytes >= 0);
69        if(NBytes <= 0) return 0;       // careful now
70       
71        // Copy in the requested number of bytes and adjust the read pointer
72        ::memcpy(pBuffer, ((char*)mBuffer) + mReadPosition, NBytes);
73        mReadPosition += NBytes;
74       
75        return NBytes;
76}
77
78// --------------------------------------------------------------------------
79//
80// Function
81//              Name:    CollectInBufferStream::BytesLeftToRead()
82//              Purpose: As interface. But only works in read phase
83//              Created: 2003/08/26
84//
85// --------------------------------------------------------------------------
86IOStream::pos_type CollectInBufferStream::BytesLeftToRead()
87{
88        if(mInWritePhase != false) { THROW_EXCEPTION(CommonException, CollectInBufferStreamNotInCorrectPhase) }
89       
90        return (mBytesInBuffer - mReadPosition);
91}
92
93// --------------------------------------------------------------------------
94//
95// Function
96//              Name:    CollectInBufferStream::Write(void *, int)
97//              Purpose: As interface. But only works in write phase
98//              Created: 2003/08/26
99//
100// --------------------------------------------------------------------------
101void CollectInBufferStream::Write(const void *pBuffer, int NBytes)
102{
103        if(mInWritePhase != true) { THROW_EXCEPTION(CommonException, CollectInBufferStreamNotInCorrectPhase) }
104       
105        // Enough space in the buffer
106        if((mBytesInBuffer + NBytes) > mBufferSize)
107        {
108                // Need to reallocate... what's the block size we'll use?
109                int allocateBlockSize = mBufferSize;
110                if(allocateBlockSize > MAX_BUFFER_ADDITION)
111                {
112                        allocateBlockSize = MAX_BUFFER_ADDITION;
113                }
114               
115                // Write it the easy way. Although it's not the most efficient...
116                int newSize = mBufferSize;
117                while(newSize < (mBytesInBuffer + NBytes))
118                {
119                        newSize += allocateBlockSize;
120                }
121               
122                // Reallocate buffer
123                mBuffer.Resize(newSize);
124               
125                // Store new size
126                mBufferSize = newSize;
127        }
128       
129        // Copy in data and adjust counter
130        ::memcpy(((char*)mBuffer) + mBytesInBuffer, pBuffer, NBytes);
131        mBytesInBuffer += NBytes;
132}
133
134// --------------------------------------------------------------------------
135//
136// Function
137//              Name:    CollectInBufferStream::GetPosition()
138//              Purpose: In write phase, returns the number of bytes written, in read
139//                               phase, the number of bytes to go
140//              Created: 2003/08/26
141//
142// --------------------------------------------------------------------------
143IOStream::pos_type CollectInBufferStream::GetPosition() const
144{
145        return mInWritePhase?mBytesInBuffer:mReadPosition;
146}
147
148// --------------------------------------------------------------------------
149//
150// Function
151//              Name:    CollectInBufferStream::Seek(pos_type, int)
152//              Purpose: As interface. But read phase only.
153//              Created: 2003/08/26
154//
155// --------------------------------------------------------------------------
156void CollectInBufferStream::Seek(pos_type Offset, int SeekType)
157{
158        if(mInWritePhase != false) { THROW_EXCEPTION(CommonException, CollectInBufferStreamNotInCorrectPhase) }
159       
160        int newPos = 0;
161        switch(SeekType)
162        {
163        case IOStream::SeekType_Absolute:
164                newPos = Offset;
165                break;
166        case IOStream::SeekType_Relative:
167                newPos = mReadPosition + Offset;
168                break;
169        case IOStream::SeekType_End:
170                newPos = mBytesInBuffer + Offset;
171                break;
172        default:
173                THROW_EXCEPTION(CommonException, IOStreamBadSeekType)
174                break;
175        }
176       
177        // Make sure it doesn't go over
178        if(newPos > mBytesInBuffer)
179        {
180                newPos = mBytesInBuffer;
181        }
182        // or under
183        if(newPos < 0)
184        {
185                newPos = 0;
186        }
187       
188        // Set the new read position
189        mReadPosition = newPos;
190}
191
192// --------------------------------------------------------------------------
193//
194// Function
195//              Name:    CollectInBufferStream::StreamDataLeft()
196//              Purpose: As interface
197//              Created: 2003/08/26
198//
199// --------------------------------------------------------------------------
200bool CollectInBufferStream::StreamDataLeft()
201{
202        return mInWritePhase?(false):(mReadPosition < mBytesInBuffer);
203}
204
205// --------------------------------------------------------------------------
206//
207// Function
208//              Name:    CollectInBufferStream::StreamClosed()
209//              Purpose: As interface
210//              Created: 2003/08/26
211//
212// --------------------------------------------------------------------------
213bool CollectInBufferStream::StreamClosed()
214{
215        return !mInWritePhase;
216}
217
218// --------------------------------------------------------------------------
219//
220// Function
221//              Name:    CollectInBufferStream::SetForReading()
222//              Purpose: Switch to read phase, after all data written
223//              Created: 2003/08/26
224//
225// --------------------------------------------------------------------------
226void CollectInBufferStream::SetForReading()
227{
228        if(mInWritePhase != true) { THROW_EXCEPTION(CommonException, CollectInBufferStreamNotInCorrectPhase) }
229       
230        // Move to read phase
231        mInWritePhase = false;
232}
233
234// --------------------------------------------------------------------------
235//
236// Function
237//              Name:    CollectInBufferStream::GetBuffer()
238//              Purpose: Returns the buffer
239//              Created: 2003/09/05
240//
241// --------------------------------------------------------------------------
242void *CollectInBufferStream::GetBuffer() const
243{
244        return mBuffer.GetPtr();
245}
246
247// --------------------------------------------------------------------------
248//
249// Function
250//              Name:    CollectInBufferStream::GetSize()
251//              Purpose: Returns the buffer size
252//              Created: 2003/09/05
253//
254// --------------------------------------------------------------------------
255int CollectInBufferStream::GetSize() const
256{
257        return mBytesInBuffer;
258}
259
260// --------------------------------------------------------------------------
261//
262// Function
263//              Name:    CollectInBufferStream::Reset()
264//              Purpose: Reset the stream, so it is empty and ready to be written to.
265//              Created: 8/12/03
266//
267// --------------------------------------------------------------------------
268void CollectInBufferStream::Reset()
269{
270        mInWritePhase = true;
271        mBytesInBuffer = 0;
272        mReadPosition = 0;
273}
274
Note: See TracBrowser for help on using the repository browser.