xref: /haiku/src/kits/network/libnetapi/DynamicBuffer.cpp (revision a12096e5c750114919a92a25c89ed00ef8f77f0e)
1550d2417SBruno G. Albuquerque /*
2550d2417SBruno G. Albuquerque  * Copyright 2009, Haiku, Inc. All Rights Reserved.
3550d2417SBruno G. Albuquerque  * Distributed under the terms of the MIT License.
4550d2417SBruno G. Albuquerque  *
5550d2417SBruno G. Albuquerque  * Authors:
6550d2417SBruno G. Albuquerque  *              Bruno Albuquerque, bga@bug-br.org.br
7550d2417SBruno G. Albuquerque  */
8550d2417SBruno G. Albuquerque 
9550d2417SBruno G. Albuquerque #include "DynamicBuffer.h"
10550d2417SBruno G. Albuquerque 
11*a12096e5SBruno G. Albuquerque #include <stdio.h>
12*a12096e5SBruno G. Albuquerque 
13550d2417SBruno G. Albuquerque #include <Errors.h>
14550d2417SBruno G. Albuquerque #include <SupportDefs.h>
15550d2417SBruno G. Albuquerque 
16*a12096e5SBruno G. Albuquerque #include <new>
17550d2417SBruno G. Albuquerque 
18c98ce75fSBruno G. Albuquerque DynamicBuffer::DynamicBuffer(size_t initialSize) :
19550d2417SBruno G. Albuquerque 	fBuffer(NULL),
20550d2417SBruno G. Albuquerque 	fBufferSize(0),
21550d2417SBruno G. Albuquerque 	fDataStart(0),
22550d2417SBruno G. Albuquerque 	fDataEnd(0),
23550d2417SBruno G. Albuquerque 	fInit(B_NO_INIT)
24550d2417SBruno G. Albuquerque {
25c98ce75fSBruno G. Albuquerque 	if (initialSize > 0) {
26c98ce75fSBruno G. Albuquerque 		fBuffer = new (std::nothrow) unsigned char[initialSize];
27550d2417SBruno G. Albuquerque 		if (fBuffer != NULL) {
28c98ce75fSBruno G. Albuquerque 			fBufferSize = initialSize;
29550d2417SBruno G. Albuquerque 			fInit = B_OK;
30550d2417SBruno G. Albuquerque 		}
31550d2417SBruno G. Albuquerque 	}
32550d2417SBruno G. Albuquerque }
33550d2417SBruno G. Albuquerque 
34550d2417SBruno G. Albuquerque 
35550d2417SBruno G. Albuquerque DynamicBuffer::~DynamicBuffer()
36550d2417SBruno G. Albuquerque {
37550d2417SBruno G. Albuquerque 	delete[] fBuffer;
38550d2417SBruno G. Albuquerque 	fBufferSize = 0;
39550d2417SBruno G. Albuquerque 	fDataStart = 0;
40550d2417SBruno G. Albuquerque 	fDataEnd = 0;
41550d2417SBruno G. Albuquerque }
42550d2417SBruno G. Albuquerque 
43550d2417SBruno G. Albuquerque 
44*a12096e5SBruno G. Albuquerque DynamicBuffer::DynamicBuffer(const DynamicBuffer& buffer) :
45*a12096e5SBruno G. Albuquerque 	fBuffer(NULL),
46*a12096e5SBruno G. Albuquerque 	fBufferSize(0),
47*a12096e5SBruno G. Albuquerque 	fDataStart(0),
48*a12096e5SBruno G. Albuquerque 	fDataEnd(0),
49*a12096e5SBruno G. Albuquerque 	fInit(B_NO_INIT)
50*a12096e5SBruno G. Albuquerque {
51*a12096e5SBruno G. Albuquerque 	fInit = buffer.fInit;
52*a12096e5SBruno G. Albuquerque 	if (fInit == B_OK) {
53*a12096e5SBruno G. Albuquerque 		status_t result = _GrowToFit(buffer.fBufferSize, true);
54*a12096e5SBruno G. Albuquerque 		if (result == B_OK) {
55*a12096e5SBruno G. Albuquerque 			memcpy(fBuffer, buffer.fBuffer, fBufferSize);
56*a12096e5SBruno G. Albuquerque 			fDataStart = buffer.fDataStart;
57*a12096e5SBruno G. Albuquerque 			fDataEnd = buffer.fDataEnd;
58*a12096e5SBruno G. Albuquerque 		} else
59*a12096e5SBruno G. Albuquerque 			fInit = result;
60*a12096e5SBruno G. Albuquerque 	}
61*a12096e5SBruno G. Albuquerque }
62*a12096e5SBruno G. Albuquerque 
63*a12096e5SBruno G. Albuquerque 
64550d2417SBruno G. Albuquerque status_t
65550d2417SBruno G. Albuquerque DynamicBuffer::InitCheck() const
66550d2417SBruno G. Albuquerque {
67550d2417SBruno G. Albuquerque 	return fInit;
68550d2417SBruno G. Albuquerque }
69550d2417SBruno G. Albuquerque 
70550d2417SBruno G. Albuquerque 
71550d2417SBruno G. Albuquerque status_t
72c98ce75fSBruno G. Albuquerque DynamicBuffer::Insert(const void* data, size_t size)
73550d2417SBruno G. Albuquerque {
74550d2417SBruno G. Albuquerque 	if (fInit != B_OK)
75550d2417SBruno G. Albuquerque 		return fInit;
76550d2417SBruno G. Albuquerque 
77c98ce75fSBruno G. Albuquerque 	status_t result = _GrowToFit(size);
78550d2417SBruno G. Albuquerque 	if (result != B_OK)
79550d2417SBruno G. Albuquerque 		return result;
80550d2417SBruno G. Albuquerque 
81c98ce75fSBruno G. Albuquerque 	memcpy(fBuffer + fDataEnd, data, size);
82c98ce75fSBruno G. Albuquerque 	fDataEnd += size;
83550d2417SBruno G. Albuquerque 
84550d2417SBruno G. Albuquerque 	return B_OK;
85550d2417SBruno G. Albuquerque }
86550d2417SBruno G. Albuquerque 
87550d2417SBruno G. Albuquerque 
88550d2417SBruno G. Albuquerque status_t
89c98ce75fSBruno G. Albuquerque DynamicBuffer::Remove(void* data, size_t size)
90550d2417SBruno G. Albuquerque {
91550d2417SBruno G. Albuquerque 	if (fInit != B_OK)
92550d2417SBruno G. Albuquerque 		return fInit;
93550d2417SBruno G. Albuquerque 
94c98ce75fSBruno G. Albuquerque 	if (fDataStart + size > fDataEnd)
95550d2417SBruno G. Albuquerque 		return B_BUFFER_OVERFLOW;
96550d2417SBruno G. Albuquerque 
97b93465f1SBruno G. Albuquerque 	memcpy(data, fBuffer + fDataStart, size);
98c98ce75fSBruno G. Albuquerque 	fDataStart += size;
99550d2417SBruno G. Albuquerque 
100550d2417SBruno G. Albuquerque 	if (fDataStart == fDataEnd)
101550d2417SBruno G. Albuquerque 		fDataStart = fDataEnd = 0;
102550d2417SBruno G. Albuquerque 
103550d2417SBruno G. Albuquerque 	return B_OK;
104550d2417SBruno G. Albuquerque }
105550d2417SBruno G. Albuquerque 
106550d2417SBruno G. Albuquerque 
107550d2417SBruno G. Albuquerque unsigned char*
108550d2417SBruno G. Albuquerque DynamicBuffer::Data() const
109550d2417SBruno G. Albuquerque {
110550d2417SBruno G. Albuquerque 	return fBuffer + fDataStart;
111550d2417SBruno G. Albuquerque }
112550d2417SBruno G. Albuquerque 
113550d2417SBruno G. Albuquerque 
114550d2417SBruno G. Albuquerque size_t
115550d2417SBruno G. Albuquerque DynamicBuffer::Size() const
116550d2417SBruno G. Albuquerque {
117550d2417SBruno G. Albuquerque 	return fBufferSize;
118550d2417SBruno G. Albuquerque }
119550d2417SBruno G. Albuquerque 
120550d2417SBruno G. Albuquerque 
121550d2417SBruno G. Albuquerque size_t
122550d2417SBruno G. Albuquerque DynamicBuffer::BytesRemaining() const
123550d2417SBruno G. Albuquerque {
124550d2417SBruno G. Albuquerque 	return fDataEnd - fDataStart;
125550d2417SBruno G. Albuquerque }
126550d2417SBruno G. Albuquerque 
127550d2417SBruno G. Albuquerque 
128550d2417SBruno G. Albuquerque void
129550d2417SBruno G. Albuquerque DynamicBuffer::PrintToStream()
130550d2417SBruno G. Albuquerque {
131550d2417SBruno G. Albuquerque 	printf("Current buffer size : %ld\n", fBufferSize);
132550d2417SBruno G. Albuquerque 	printf("Data start position : %ld\n", fDataStart);
133550d2417SBruno G. Albuquerque 	printf("Data end position   : %ld\n", fDataEnd);
134550d2417SBruno G. Albuquerque 	printf("Bytes wasted        : %ld\n", fDataStart);
135550d2417SBruno G. Albuquerque 	printf("Bytes available     : %ld\n", fBufferSize - fDataEnd);
136550d2417SBruno G. Albuquerque }
137550d2417SBruno G. Albuquerque 
138550d2417SBruno G. Albuquerque 
139550d2417SBruno G. Albuquerque status_t
140*a12096e5SBruno G. Albuquerque DynamicBuffer::_GrowToFit(size_t size, bool exact)
141550d2417SBruno G. Albuquerque {
142b93465f1SBruno G. Albuquerque 	if (size <= fBufferSize - fDataEnd)
143550d2417SBruno G. Albuquerque 		return B_OK;
144550d2417SBruno G. Albuquerque 
145*a12096e5SBruno G. Albuquerque 	size_t newSize;
146*a12096e5SBruno G. Albuquerque 	if (!exact)
147*a12096e5SBruno G. Albuquerque 		newSize = (fBufferSize + size) * 2;
148*a12096e5SBruno G. Albuquerque 	else
149*a12096e5SBruno G. Albuquerque 		newSize = size;
150550d2417SBruno G. Albuquerque 
151c98ce75fSBruno G. Albuquerque 	unsigned char* newBuffer = new (std::nothrow) unsigned char[newSize];
152550d2417SBruno G. Albuquerque 	if (newBuffer == NULL)
153550d2417SBruno G. Albuquerque 		return B_NO_MEMORY;
154550d2417SBruno G. Albuquerque 
155550d2417SBruno G. Albuquerque 	if (fDataStart != fDataEnd) {
156550d2417SBruno G. Albuquerque 		memcpy(newBuffer, fBuffer + fDataStart, fDataEnd - fDataStart);
157550d2417SBruno G. Albuquerque 	}
158550d2417SBruno G. Albuquerque 
159550d2417SBruno G. Albuquerque 	delete[] fBuffer;
160550d2417SBruno G. Albuquerque 	fBuffer = newBuffer;
161550d2417SBruno G. Albuquerque 	fDataEnd -= fDataStart;
162550d2417SBruno G. Albuquerque 	fDataStart = 0;
163550d2417SBruno G. Albuquerque 	fBufferSize = newSize;
164550d2417SBruno G. Albuquerque 
165550d2417SBruno G. Albuquerque 	return B_OK;
166550d2417SBruno G. Albuquerque }
167