2 * Copyright 2003-2008, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
12 #include "StreamBuffer.h"
15 #define min(x,y) (((x) < (y)) ? (x) : (y))
19 #define max(x,y) (((x) > (y)) ? (x) : (y))
22 // ---------------------------------------------------------------
25 // Initializes the StreamBuffer to read from pstream, buffering
26 // nbuffersize bytes of data at a time. Note that if nbuffersize
27 // is smaller than MIN_BUFFER_SIZE, MIN_BUFFER_SIZE is used
28 // as the buffer size.
32 // Parameters: pstream, the stream to be buffered
34 // nbuffersize, number of bytes to be read from
40 // ---------------------------------------------------------------
41 StreamBuffer::StreamBuffer(BPositionIO
*pstream
, size_t nbuffersize
, bool toRead
)
53 fBufferSize
= max(nbuffersize
, MIN_BUFFER_SIZE
);
54 fBuffer
= new uint8
[fBufferSize
];
57 // ---------------------------------------------------------------
60 // Destroys data allocated for this object
69 // ---------------------------------------------------------------
70 StreamBuffer::~StreamBuffer()
72 if (!fToRead
&& fLen
> 0)
73 fStream
->Write(fBuffer
, fLen
);
78 // ---------------------------------------------------------------
81 // Determines whether the constructor failed or not
89 // Returns: B_OK if object has been initialized successfully,
91 // ---------------------------------------------------------------
93 StreamBuffer::InitCheck()
95 if (fStream
&& fBuffer
)
101 // ---------------------------------------------------------------
104 // Copies up to nbytes of data from the stream into pinto
106 // Preconditions: ReadStream() must be called once before this
107 // function is called (the constructor does this)
109 // Parameters: pinto, the buffer to be copied to
111 // nbytes, the maximum number of bytes to copy
115 // Returns: the number of bytes successfully read or an
116 // error code returned by BPositionIO::Read()
117 // ---------------------------------------------------------------
119 StreamBuffer::Read(void *_pinto
, size_t nbytes
)
126 ssize_t result
= B_ERROR
;
127 uint8
*pinto
= (uint8
*)_pinto
;
129 size_t totalRead
= min(nbytes
, fLen
- fPos
);
130 memcpy(pinto
, fBuffer
+ fPos
, totalRead
);
136 result
= _ReadStream();
140 size_t left
= min(nbytes
, fLen
- fPos
);
141 memcpy(pinto
, fBuffer
+ fPos
, left
);
153 // ---------------------------------------------------------------
156 // Copies up to nbytes of data from pinto into the stream
158 // Parameters: pinto, the buffer to be copied from
159 // nbytes, the maximum number of bytes to copy
161 // Returns: the number of bytes successfully read or an
162 // error code returned by BPositionIO::Read()
163 // ---------------------------------------------------------------
165 StreamBuffer::Write(void *pinto
, size_t nbytes
)
167 if (nbytes
< fBufferSize
- fLen
) {
168 memcpy(fBuffer
+ fLen
, pinto
, nbytes
);
172 fStream
->Write(fBuffer
, fLen
);
175 fStream
->Write(pinto
, nbytes
);
180 // ---------------------------------------------------------------
183 // Seeks the stream to the given position. If the seek operation fails,
184 // the read buffer will be reset.
186 // Preconditions: fBuffer must be allocated and fBufferSize
193 // Returns: the new position
194 // ---------------------------------------------------------------
196 StreamBuffer::Seek(off_t position
, uint32 seekMode
)
198 // just seek in the current buffer if the new position is in it
199 if (seekMode
== SEEK_CUR
) {
201 && (fPos
+ position
< fLen
)
202 && (fPos
+ position
>= 0)) {
206 && (fLen
+ position
< fBufferSize
)
207 && (fLen
+ position
>= 0)) {
213 // flush if something to write
216 fStream
->Write(fBuffer
, fLen
);
222 return fStream
->Seek(position
, seekMode
);
226 // ---------------------------------------------------------------
229 // Returns the current position in the stream.
231 // Preconditions: fBuffer must be allocated and fBufferSize
238 // Returns: the position
239 // ---------------------------------------------------------------
241 StreamBuffer::Position()
243 off_t position
= fStream
->Position();
252 // ---------------------------------------------------------------
255 // Fills the stream buffer with data read in from the stream
257 // Preconditions: fBuffer must be allocated and fBufferSize
264 // Returns: the number of bytes successfully read or an
265 // error code returned by BPositionIO::Read()
266 // ---------------------------------------------------------------
268 StreamBuffer::_ReadStream()
270 ssize_t len
= fStream
->Read(fBuffer
, fBufferSize
);