tcp: Add APICall trace entry and move TRACEs into locked parts.
[haiku.git] / src / add-ons / translators / shared / StreamBuffer.cpp
blob63f28893c27dc655d6be4b874011d54da3d6c790
1 /*
2 * Copyright 2003-2008, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors :
6 * Michael Wilber
7 * Jérôme Duval
8 */
10 #include <stdio.h>
11 #include <string.h>
12 #include "StreamBuffer.h"
14 #ifndef min
15 #define min(x,y) (((x) < (y)) ? (x) : (y))
16 #endif
18 #ifndef max
19 #define max(x,y) (((x) > (y)) ? (x) : (y))
20 #endif
22 // ---------------------------------------------------------------
23 // Constructor
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.
30 // Preconditions:
32 // Parameters: pstream, the stream to be buffered
34 // nbuffersize, number of bytes to be read from
35 // pstream at a time
37 // Postconditions:
39 // Returns:
40 // ---------------------------------------------------------------
41 StreamBuffer::StreamBuffer(BPositionIO *pstream, size_t nbuffersize, bool toRead)
43 fStream = pstream;
44 fBuffer = NULL;
45 fBufferSize = 0;
46 fLen = 0;
47 fPos = 0;
48 fToRead = toRead;
50 if (!pstream)
51 return;
53 fBufferSize = max(nbuffersize, MIN_BUFFER_SIZE);
54 fBuffer = new uint8[fBufferSize];
57 // ---------------------------------------------------------------
58 // Destructor
60 // Destroys data allocated for this object
62 // Preconditions:
64 // Parameters:
66 // Postconditions:
68 // Returns:
69 // ---------------------------------------------------------------
70 StreamBuffer::~StreamBuffer()
72 if (!fToRead && fLen > 0)
73 fStream->Write(fBuffer, fLen);
74 delete[] fBuffer;
75 fBuffer = NULL;
78 // ---------------------------------------------------------------
79 // InitCheck
81 // Determines whether the constructor failed or not
83 // Preconditions:
85 // Parameters:
87 // Postconditions:
89 // Returns: B_OK if object has been initialized successfully,
90 // B_ERROR if not
91 // ---------------------------------------------------------------
92 status_t
93 StreamBuffer::InitCheck()
95 if (fStream && fBuffer)
96 return B_OK;
97 else
98 return B_ERROR;
101 // ---------------------------------------------------------------
102 // Read
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
113 // Postconditions:
115 // Returns: the number of bytes successfully read or an
116 // error code returned by BPositionIO::Read()
117 // ---------------------------------------------------------------
118 ssize_t
119 StreamBuffer::Read(void *_pinto, size_t nbytes)
121 if (_pinto == NULL)
122 return B_BAD_VALUE;
123 if (nbytes == 0)
124 return 0;
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);
131 fPos += totalRead;
132 pinto += totalRead;
133 nbytes -= totalRead;
135 while (nbytes > 0) {
136 result = _ReadStream();
137 if (result <= 0)
138 return result;
139 if (result > 0) {
140 size_t left = min(nbytes, fLen - fPos);
141 memcpy(pinto, fBuffer + fPos, left);
142 fPos += left;
143 pinto += left;
144 nbytes -= left;
145 totalRead += left;
149 return totalRead;
153 // ---------------------------------------------------------------
154 // Write
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 // ---------------------------------------------------------------
164 void
165 StreamBuffer::Write(void *pinto, size_t nbytes)
167 if (nbytes < fBufferSize - fLen) {
168 memcpy(fBuffer + fLen, pinto, nbytes);
169 fLen += nbytes;
170 } else {
171 if (fLen > 0) {
172 fStream->Write(fBuffer, fLen);
173 fLen = 0;
175 fStream->Write(pinto, nbytes);
180 // ---------------------------------------------------------------
181 // Seek
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
187 // must be valid
189 // Parameters:
191 // Postconditions:
193 // Returns: the new position
194 // ---------------------------------------------------------------
195 off_t
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) {
200 if (fToRead
201 && (fPos + position < fLen)
202 && (fPos + position >= 0)) {
203 fPos += position;
204 return Position();
205 } else if (!fToRead
206 && (fLen + position < fBufferSize)
207 && (fLen + position >= 0)) {
208 fLen += position;
209 return Position();
213 // flush if something to write
214 if (!fToRead
215 && fLen > 0) {
216 fStream->Write(fBuffer, fLen);
219 fLen = 0;
220 fPos = 0;
222 return fStream->Seek(position, seekMode);
226 // ---------------------------------------------------------------
227 // Position
229 // Returns the current position in the stream.
231 // Preconditions: fBuffer must be allocated and fBufferSize
232 // must be valid
234 // Parameters:
236 // Postconditions:
238 // Returns: the position
239 // ---------------------------------------------------------------
240 off_t
241 StreamBuffer::Position()
243 off_t position = fStream->Position();
244 if (fToRead)
245 position -= fPos;
246 else
247 position += fLen;
248 return position;
252 // ---------------------------------------------------------------
253 // _ReadStream
255 // Fills the stream buffer with data read in from the stream
257 // Preconditions: fBuffer must be allocated and fBufferSize
258 // must be valid
260 // Parameters:
262 // Postconditions:
264 // Returns: the number of bytes successfully read or an
265 // error code returned by BPositionIO::Read()
266 // ---------------------------------------------------------------
267 ssize_t
268 StreamBuffer::_ReadStream()
270 ssize_t len = fStream->Read(fBuffer, fBufferSize);
271 if (len < 0)
272 return len;
273 fLen = len;
274 fPos = 0;
275 return fLen;