xref: /haiku/src/kits/network/libnetapi/DynamicBuffer.cpp (revision 550d24175fdf61ba73af4ef30c28386894deb4d0)
1 /*
2  * Copyright 2009, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *              Bruno Albuquerque, bga@bug-br.org.br
7  */
8 
9 #include "DynamicBuffer.h"
10 
11 #include <Errors.h>
12 #include <SupportDefs.h>
13 
14 
15 DynamicBuffer::DynamicBuffer(size_t _initialSize) :
16 	fBuffer(NULL),
17 	fBufferSize(0),
18 	fDataStart(0),
19 	fDataEnd(0),
20 	fInit(B_NO_INIT)
21 {
22 	if (_initialSize > 0) {
23 		fBuffer = new unsigned char[_initialSize];
24 		if (fBuffer != NULL) {
25 			fBufferSize = _initialSize;
26 			fInit = B_OK;
27 		}
28 	}
29 }
30 
31 
32 DynamicBuffer::~DynamicBuffer()
33 {
34 	delete[] fBuffer;
35 	fBufferSize = 0;
36 	fDataStart = 0;
37 	fDataEnd = 0;
38 }
39 
40 
41 status_t
42 DynamicBuffer::InitCheck() const
43 {
44 	return fInit;
45 }
46 
47 
48 status_t
49 DynamicBuffer::Insert(const void* _data, size_t _size)
50 {
51 	if (fInit != B_OK)
52 		return fInit;
53 
54 	status_t result = _GrowToFit(_size);
55 	if (result != B_OK)
56 		return result;
57 
58 	memcpy(fBuffer + fDataEnd, _data, _size);
59 	fDataEnd += _size;
60 
61 	return B_OK;
62 }
63 
64 
65 status_t
66 DynamicBuffer::Remove(void* _data, size_t _size)
67 {
68 	if (fInit != B_OK)
69 		return fInit;
70 
71 	if (fDataStart + _size > fDataEnd)
72 		return B_BUFFER_OVERFLOW;
73 
74 	memcpy(_data, fBuffer + fDataStart, _size);
75 	fDataStart += _size;
76 
77 	if (fDataStart == fDataEnd)
78 		fDataStart = fDataEnd = 0;
79 
80 	return B_OK;
81 }
82 
83 
84 unsigned char*
85 DynamicBuffer::Data() const
86 {
87 	return fBuffer + fDataStart;
88 }
89 
90 
91 size_t
92 DynamicBuffer::Size() const
93 {
94 	return fBufferSize;
95 }
96 
97 
98 size_t
99 DynamicBuffer::BytesRemaining() const
100 {
101 	return fDataEnd - fDataStart;
102 }
103 
104 
105 void
106 DynamicBuffer::PrintToStream()
107 {
108 	printf("Current buffer size : %ld\n", fBufferSize);
109 	printf("Data start position : %ld\n", fDataStart);
110 	printf("Data end position   : %ld\n", fDataEnd);
111 	printf("Bytes wasted        : %ld\n", fDataStart);
112 	printf("Bytes available     : %ld\n", fBufferSize - fDataEnd);
113 }
114 
115 
116 status_t
117 DynamicBuffer::_GrowToFit(size_t _size)
118 {
119 	if (_size <= fBufferSize - fDataEnd)
120 		return B_OK;
121 
122 	size_t newSize = (fBufferSize + _size) * 2;
123 
124 	unsigned char* newBuffer = new unsigned char[newSize];
125 	if (newBuffer == NULL)
126 		return B_NO_MEMORY;
127 
128 	if (fDataStart != fDataEnd) {
129 		memcpy(newBuffer, fBuffer + fDataStart, fDataEnd - fDataStart);
130 	}
131 
132 	delete[] fBuffer;
133 	fBuffer = newBuffer;
134 	fDataEnd -= fDataStart;
135 	fDataStart = 0;
136 	fBufferSize = newSize;
137 
138 	return B_OK;
139 }
140