BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / file_systems / nfs4 / XDR.cpp
blob86a646252594fe83785a9a1ddcb9a7517f625b1e
1 /*
2 * Copyright 2012 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Paweł Dziepak, pdziepak@quarnos.org
7 */
10 #include "XDR.h"
12 #include <stdlib.h>
13 #include <string.h>
15 #include <ByteOrder.h>
18 using namespace XDR;
20 Stream::Stream(void* buffer, uint32 size)
22 fBuffer(reinterpret_cast<uint32*>(buffer)),
23 fSize(size),
24 fPosition(0)
29 Stream::~Stream()
34 uint32
35 Stream::_PositionToSize() const
37 return fPosition * sizeof(uint32);
41 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;
47 return real_size;
51 ReadStream::ReadStream(void* buffer, uint32 size)
53 Stream(buffer, size),
54 fEOF(false)
59 ReadStream::~ReadStream()
64 int32
65 ReadStream::GetInt()
67 if (_PositionToSize() >= fSize) {
68 fEOF = true;
69 return 0;
72 return B_BENDIAN_TO_HOST_INT32(fBuffer[fPosition++]);
76 uint32
77 ReadStream::GetUInt()
79 if (_PositionToSize() >= fSize) {
80 fEOF = true;
81 return 0;
84 return B_BENDIAN_TO_HOST_INT32(fBuffer[fPosition++]);
88 int64
89 ReadStream::GetHyper()
91 if (_PositionToSize() + sizeof(int64) > fSize) {
92 fEOF = true;
93 return 0;
96 int64* ptr = reinterpret_cast<int64*>(fBuffer + fPosition);
97 fPosition += 2;
99 return B_BENDIAN_TO_HOST_INT64(*ptr);
103 uint64
104 ReadStream::GetUHyper()
106 if (_PositionToSize() + sizeof(uint64) > fSize) {
107 fEOF = true;
108 return 0;
111 uint64* ptr = reinterpret_cast<uint64*>(fBuffer + fPosition);
112 fPosition += 2;
114 return B_BENDIAN_TO_HOST_INT64(*ptr);
118 char*
119 ReadStream::GetString()
121 if (_PositionToSize() >= fSize) {
122 fEOF = true;
123 return NULL;
126 uint32 size;
127 const void* ptr = GetOpaque(&size);
128 if (ptr == NULL)
129 return NULL;
131 char* str = reinterpret_cast<char*>(malloc(size + 1));
132 if (str == NULL)
133 return NULL;
135 memcpy(str, ptr, size);
136 str[size] = 0;
138 return str;
142 const void*
143 ReadStream::GetOpaque(uint32* size)
145 if (_PositionToSize() >= fSize) {
146 fEOF = true;
147 return NULL;
150 void* ptr = NULL;
151 uint32 s = GetUInt();
152 if (s != 0) {
153 ptr = fBuffer + fPosition;
154 if (_PositionToSize() + s <= fSize)
155 fPosition += _RealSize(s) / sizeof(uint32);
156 else {
157 s = fSize - _PositionToSize();
158 fPosition = fSize;
162 if (size != NULL)
163 *size = s;
165 return ptr;
169 WriteStream::WriteStream()
171 Stream(malloc(kInitialSize), kInitialSize),
172 fError(B_OK)
177 WriteStream::WriteStream(const WriteStream& x)
179 Stream(malloc(x.fSize), x.fSize),
180 fError(x.fError)
182 fPosition = x.fPosition;
183 memcpy(fBuffer, x.fBuffer, fSize);
187 WriteStream::~WriteStream()
189 free(fBuffer);
193 void
194 WriteStream::Clear()
196 free(fBuffer);
197 fSize = kInitialSize;
198 fBuffer = reinterpret_cast<uint32*>(malloc(fSize));
199 fError = B_OK;
200 fPosition = 0;
204 status_t
205 WriteStream::InsertUInt(Stream::Position pos, uint32 x)
207 if (pos * sizeof(uint32) >= fSize) {
208 fError = B_BAD_VALUE;
209 return B_BAD_VALUE;
212 fBuffer[pos] = B_HOST_TO_BENDIAN_INT32(x);
213 return B_OK;
217 status_t
218 WriteStream::AddInt(int32 x)
220 status_t err = _CheckResize(sizeof(int32));
221 if (err != B_OK)
222 return err;
224 fBuffer[fPosition++] = B_HOST_TO_BENDIAN_INT32(x);
225 return B_OK;
229 status_t
230 WriteStream::AddUInt(uint32 x)
232 status_t err = _CheckResize(sizeof(uint32));
233 if (err != B_OK)
234 return err;
236 fBuffer[fPosition++] = B_HOST_TO_BENDIAN_INT32(x);
237 return B_OK;
241 status_t
242 WriteStream::AddHyper(int64 x)
244 status_t err = _CheckResize(sizeof(int64));
245 if (err != B_OK)
246 return err;
248 int64* ptr = reinterpret_cast<int64*>(fBuffer + fPosition);
249 *ptr = B_HOST_TO_BENDIAN_INT64(x);
250 fPosition += 2;
251 return B_OK;
255 status_t
256 WriteStream::AddUHyper(uint64 x)
258 status_t err = _CheckResize(sizeof(uint64));
259 if (err != B_OK)
260 return err;
262 uint64* ptr = reinterpret_cast<uint64*>(fBuffer + fPosition);
263 *ptr = B_HOST_TO_BENDIAN_INT64(x);
264 fPosition += 2;
265 return B_OK;
269 status_t
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);
279 status_t
280 WriteStream::AddOpaque(const void* ptr, uint32 size)
282 uint32 real_size = _RealSize(size);
283 status_t err = _CheckResize(real_size + sizeof(uint32));
284 if (err != B_OK)
285 return err;
287 AddUInt(size);
288 memset(fBuffer + fPosition, 0, real_size);
289 memcpy(fBuffer + fPosition, ptr, size);
290 fPosition += real_size / sizeof(int32);
292 return B_OK;
296 status_t
297 WriteStream::AddOpaque(const WriteStream& stream)
299 return AddOpaque(stream.Buffer(), stream.Size());
303 status_t
304 WriteStream::Append(const WriteStream& stream)
306 uint32 size = stream.Size();
307 status_t err = _CheckResize(size);
308 if (err != B_OK)
309 return err;
311 memcpy(fBuffer + fPosition, stream.Buffer(), size);
312 fPosition += size / sizeof(int32);
314 return B_OK;
318 status_t
319 WriteStream::_CheckResize(uint32 size)
321 if (_PositionToSize() + size <= fSize)
322 return B_OK;
324 uint32 new_size = max_c(fSize * 2, fPosition * sizeof(uint32) + size);
326 void* ptr = realloc(fBuffer, new_size);
327 if (ptr == NULL) {
328 fError = B_NO_MEMORY;
329 return B_NO_MEMORY;
332 fBuffer = reinterpret_cast<uint32*>(ptr);
333 fSize = new_size;
335 return B_OK;