2 * Copyright 2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
6 * Paweł Dziepak, pdziepak@quarnos.org
15 #include <ByteOrder.h>
20 Stream::Stream(void* buffer
, uint32 size
)
22 fBuffer(reinterpret_cast<uint32
*>(buffer
)),
35 Stream::_PositionToSize() const
37 return fPosition
* sizeof(uint32
);
42 Stream::_RealSize(uint32 size
) const
44 uint32 real_size
= size
;
45 if (real_size
% 4 != 0)
46 real_size
= ((real_size
>> 2) + 1) << 2;
51 ReadStream::ReadStream(void* buffer
, uint32 size
)
59 ReadStream::~ReadStream()
67 if (_PositionToSize() >= fSize
) {
72 return B_BENDIAN_TO_HOST_INT32(fBuffer
[fPosition
++]);
79 if (_PositionToSize() >= fSize
) {
84 return B_BENDIAN_TO_HOST_INT32(fBuffer
[fPosition
++]);
89 ReadStream::GetHyper()
91 if (_PositionToSize() + sizeof(int64
) > fSize
) {
96 int64
* ptr
= reinterpret_cast<int64
*>(fBuffer
+ fPosition
);
99 return B_BENDIAN_TO_HOST_INT64(*ptr
);
104 ReadStream::GetUHyper()
106 if (_PositionToSize() + sizeof(uint64
) > fSize
) {
111 uint64
* ptr
= reinterpret_cast<uint64
*>(fBuffer
+ fPosition
);
114 return B_BENDIAN_TO_HOST_INT64(*ptr
);
119 ReadStream::GetString()
121 if (_PositionToSize() >= fSize
) {
127 const void* ptr
= GetOpaque(&size
);
131 char* str
= reinterpret_cast<char*>(malloc(size
+ 1));
135 memcpy(str
, ptr
, size
);
143 ReadStream::GetOpaque(uint32
* size
)
145 if (_PositionToSize() >= fSize
) {
151 uint32 s
= GetUInt();
153 ptr
= fBuffer
+ fPosition
;
154 if (_PositionToSize() + s
<= fSize
)
155 fPosition
+= _RealSize(s
) / sizeof(uint32
);
157 s
= fSize
- _PositionToSize();
169 WriteStream::WriteStream()
171 Stream(malloc(kInitialSize
), kInitialSize
),
177 WriteStream::WriteStream(const WriteStream
& x
)
179 Stream(malloc(x
.fSize
), x
.fSize
),
182 fPosition
= x
.fPosition
;
183 memcpy(fBuffer
, x
.fBuffer
, fSize
);
187 WriteStream::~WriteStream()
197 fSize
= kInitialSize
;
198 fBuffer
= reinterpret_cast<uint32
*>(malloc(fSize
));
205 WriteStream::InsertUInt(Stream::Position pos
, uint32 x
)
207 if (pos
* sizeof(uint32
) >= fSize
) {
208 fError
= B_BAD_VALUE
;
212 fBuffer
[pos
] = B_HOST_TO_BENDIAN_INT32(x
);
218 WriteStream::AddInt(int32 x
)
220 status_t err
= _CheckResize(sizeof(int32
));
224 fBuffer
[fPosition
++] = B_HOST_TO_BENDIAN_INT32(x
);
230 WriteStream::AddUInt(uint32 x
)
232 status_t err
= _CheckResize(sizeof(uint32
));
236 fBuffer
[fPosition
++] = B_HOST_TO_BENDIAN_INT32(x
);
242 WriteStream::AddHyper(int64 x
)
244 status_t err
= _CheckResize(sizeof(int64
));
248 int64
* ptr
= reinterpret_cast<int64
*>(fBuffer
+ fPosition
);
249 *ptr
= B_HOST_TO_BENDIAN_INT64(x
);
256 WriteStream::AddUHyper(uint64 x
)
258 status_t err
= _CheckResize(sizeof(uint64
));
262 uint64
* ptr
= reinterpret_cast<uint64
*>(fBuffer
+ fPosition
);
263 *ptr
= B_HOST_TO_BENDIAN_INT64(x
);
270 WriteStream::AddString(const char* str
, uint32 maxlen
)
272 uint32 len
= strlen(str
);
273 uint32 size
= maxlen
== 0 ? len
: min_c(maxlen
, len
);
275 return AddOpaque(str
, size
);
280 WriteStream::AddOpaque(const void* ptr
, uint32 size
)
282 uint32 real_size
= _RealSize(size
);
283 status_t err
= _CheckResize(real_size
+ sizeof(uint32
));
288 memset(fBuffer
+ fPosition
, 0, real_size
);
289 memcpy(fBuffer
+ fPosition
, ptr
, size
);
290 fPosition
+= real_size
/ sizeof(int32
);
297 WriteStream::AddOpaque(const WriteStream
& stream
)
299 return AddOpaque(stream
.Buffer(), stream
.Size());
304 WriteStream::Append(const WriteStream
& stream
)
306 uint32 size
= stream
.Size();
307 status_t err
= _CheckResize(size
);
311 memcpy(fBuffer
+ fPosition
, stream
.Buffer(), size
);
312 fPosition
+= size
/ sizeof(int32
);
319 WriteStream::_CheckResize(uint32 size
)
321 if (_PositionToSize() + size
<= fSize
)
324 uint32 new_size
= max_c(fSize
* 2, fPosition
* sizeof(uint32
) + size
);
326 void* ptr
= realloc(fBuffer
, new_size
);
328 fError
= B_NO_MEMORY
;
332 fBuffer
= reinterpret_cast<uint32
*>(ptr
);