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