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
11a12096e5SBruno G. Albuquerque #include <stdio.h>
1231562415SKarsten Heimrich #include <string.h>
13a12096e5SBruno G. Albuquerque
14*25d34313SIngo Weinhold #include <algorithm>
15*25d34313SIngo Weinhold
16550d2417SBruno G. Albuquerque #include <Errors.h>
17550d2417SBruno G. Albuquerque #include <SupportDefs.h>
18550d2417SBruno G. Albuquerque
19a12096e5SBruno G. Albuquerque #include <new>
20550d2417SBruno G. Albuquerque
DynamicBuffer(size_t initialSize)21c98ce75fSBruno G. Albuquerque DynamicBuffer::DynamicBuffer(size_t initialSize) :
22550d2417SBruno G. Albuquerque fBuffer(NULL),
23550d2417SBruno G. Albuquerque fBufferSize(0),
24550d2417SBruno G. Albuquerque fDataStart(0),
25550d2417SBruno G. Albuquerque fDataEnd(0),
26550d2417SBruno G. Albuquerque fInit(B_NO_INIT)
27550d2417SBruno G. Albuquerque {
28c98ce75fSBruno G. Albuquerque fBuffer = new (std::nothrow) unsigned char[initialSize];
29550d2417SBruno G. Albuquerque if (fBuffer != NULL) {
30c98ce75fSBruno G. Albuquerque fBufferSize = initialSize;
31550d2417SBruno G. Albuquerque fInit = B_OK;
32550d2417SBruno G. Albuquerque }
33550d2417SBruno G. Albuquerque }
34550d2417SBruno G. Albuquerque
35550d2417SBruno G. Albuquerque
~DynamicBuffer()36550d2417SBruno G. Albuquerque DynamicBuffer::~DynamicBuffer()
37550d2417SBruno G. Albuquerque {
38550d2417SBruno G. Albuquerque delete[] fBuffer;
39550d2417SBruno G. Albuquerque fBufferSize = 0;
40550d2417SBruno G. Albuquerque fDataStart = 0;
41550d2417SBruno G. Albuquerque fDataEnd = 0;
42550d2417SBruno G. Albuquerque }
43550d2417SBruno G. Albuquerque
44550d2417SBruno G. Albuquerque
DynamicBuffer(const DynamicBuffer & buffer)45a12096e5SBruno G. Albuquerque DynamicBuffer::DynamicBuffer(const DynamicBuffer& buffer) :
46a12096e5SBruno G. Albuquerque fBuffer(NULL),
47a12096e5SBruno G. Albuquerque fBufferSize(0),
48a12096e5SBruno G. Albuquerque fDataStart(0),
49a12096e5SBruno G. Albuquerque fDataEnd(0),
50a12096e5SBruno G. Albuquerque fInit(B_NO_INIT)
51a12096e5SBruno G. Albuquerque {
52a12096e5SBruno G. Albuquerque fInit = buffer.fInit;
53a12096e5SBruno G. Albuquerque if (fInit == B_OK) {
54a12096e5SBruno G. Albuquerque status_t result = _GrowToFit(buffer.fBufferSize, true);
55a12096e5SBruno G. Albuquerque if (result == B_OK) {
56a12096e5SBruno G. Albuquerque memcpy(fBuffer, buffer.fBuffer, fBufferSize);
57a12096e5SBruno G. Albuquerque fDataStart = buffer.fDataStart;
58a12096e5SBruno G. Albuquerque fDataEnd = buffer.fDataEnd;
59a12096e5SBruno G. Albuquerque } else
60a12096e5SBruno G. Albuquerque fInit = result;
61a12096e5SBruno G. Albuquerque }
62a12096e5SBruno G. Albuquerque }
63a12096e5SBruno G. Albuquerque
64a12096e5SBruno G. Albuquerque
65550d2417SBruno G. Albuquerque status_t
InitCheck() const66550d2417SBruno G. Albuquerque DynamicBuffer::InitCheck() const
67550d2417SBruno G. Albuquerque {
68550d2417SBruno G. Albuquerque return fInit;
69550d2417SBruno G. Albuquerque }
70550d2417SBruno G. Albuquerque
71550d2417SBruno G. Albuquerque
726926863eSIngo Weinhold ssize_t
Write(const void * data,size_t size)73739f15e1SIngo Weinhold DynamicBuffer::Write(const void* data, size_t size)
74550d2417SBruno G. Albuquerque {
75550d2417SBruno G. Albuquerque if (fInit != B_OK)
76550d2417SBruno G. Albuquerque return fInit;
77550d2417SBruno G. Albuquerque
78c98ce75fSBruno G. Albuquerque status_t result = _GrowToFit(size);
79550d2417SBruno G. Albuquerque if (result != B_OK)
80550d2417SBruno G. Albuquerque return result;
81550d2417SBruno G. Albuquerque
82c98ce75fSBruno G. Albuquerque memcpy(fBuffer + fDataEnd, data, size);
83c98ce75fSBruno G. Albuquerque fDataEnd += size;
84550d2417SBruno G. Albuquerque
856926863eSIngo Weinhold return (ssize_t)size;
86550d2417SBruno G. Albuquerque }
87550d2417SBruno G. Albuquerque
88550d2417SBruno G. Albuquerque
89739f15e1SIngo Weinhold ssize_t
Read(void * data,size_t size)90739f15e1SIngo Weinhold DynamicBuffer::Read(void* data, size_t size)
91550d2417SBruno G. Albuquerque {
92550d2417SBruno G. Albuquerque if (fInit != B_OK)
93550d2417SBruno G. Albuquerque return fInit;
94550d2417SBruno G. Albuquerque
95*25d34313SIngo Weinhold size = std::min(size, Size());
96*25d34313SIngo Weinhold if (size == 0)
97*25d34313SIngo Weinhold return 0;
98550d2417SBruno G. Albuquerque
99b93465f1SBruno G. Albuquerque memcpy(data, fBuffer + fDataStart, size);
100c98ce75fSBruno G. Albuquerque fDataStart += size;
101550d2417SBruno G. Albuquerque
102550d2417SBruno G. Albuquerque if (fDataStart == fDataEnd)
103550d2417SBruno G. Albuquerque fDataStart = fDataEnd = 0;
104550d2417SBruno G. Albuquerque
105739f15e1SIngo Weinhold return size;
106550d2417SBruno G. Albuquerque }
107550d2417SBruno G. Albuquerque
108550d2417SBruno G. Albuquerque
109550d2417SBruno G. Albuquerque unsigned char*
Data() const110550d2417SBruno G. Albuquerque DynamicBuffer::Data() const
111550d2417SBruno G. Albuquerque {
112550d2417SBruno G. Albuquerque return fBuffer + fDataStart;
113550d2417SBruno G. Albuquerque }
114550d2417SBruno G. Albuquerque
115550d2417SBruno G. Albuquerque
116550d2417SBruno G. Albuquerque size_t
Size() const117550d2417SBruno G. Albuquerque DynamicBuffer::Size() const
118550d2417SBruno G. Albuquerque {
119b37fa18bSPhilippe Houdoin return fDataEnd - fDataStart;
120550d2417SBruno G. Albuquerque }
121550d2417SBruno G. Albuquerque
122550d2417SBruno G. Albuquerque
123550d2417SBruno G. Albuquerque size_t
BytesRemaining() const124550d2417SBruno G. Albuquerque DynamicBuffer::BytesRemaining() const
125550d2417SBruno G. Albuquerque {
126b37fa18bSPhilippe Houdoin return fBufferSize - fDataEnd;
127550d2417SBruno G. Albuquerque }
128550d2417SBruno G. Albuquerque
129550d2417SBruno G. Albuquerque
130550d2417SBruno G. Albuquerque void
PrintToStream()131550d2417SBruno G. Albuquerque DynamicBuffer::PrintToStream()
132550d2417SBruno G. Albuquerque {
133550d2417SBruno G. Albuquerque printf("Current buffer size : %ld\n", fBufferSize);
134550d2417SBruno G. Albuquerque printf("Data start position : %ld\n", fDataStart);
135550d2417SBruno G. Albuquerque printf("Data end position : %ld\n", fDataEnd);
136550d2417SBruno G. Albuquerque printf("Bytes wasted : %ld\n", fDataStart);
137550d2417SBruno G. Albuquerque printf("Bytes available : %ld\n", fBufferSize - fDataEnd);
138550d2417SBruno G. Albuquerque }
139550d2417SBruno G. Albuquerque
140550d2417SBruno G. Albuquerque
141550d2417SBruno G. Albuquerque status_t
_GrowToFit(size_t size,bool exact)142a12096e5SBruno G. Albuquerque DynamicBuffer::_GrowToFit(size_t size, bool exact)
143550d2417SBruno G. Albuquerque {
144b93465f1SBruno G. Albuquerque if (size <= fBufferSize - fDataEnd)
145550d2417SBruno G. Albuquerque return B_OK;
146550d2417SBruno G. Albuquerque
147a12096e5SBruno G. Albuquerque size_t newSize;
148a12096e5SBruno G. Albuquerque if (!exact)
149a12096e5SBruno G. Albuquerque newSize = (fBufferSize + size) * 2;
150a12096e5SBruno G. Albuquerque else
151a12096e5SBruno G. Albuquerque newSize = size;
152550d2417SBruno G. Albuquerque
153c98ce75fSBruno G. Albuquerque unsigned char* newBuffer = new (std::nothrow) unsigned char[newSize];
154550d2417SBruno G. Albuquerque if (newBuffer == NULL)
155550d2417SBruno G. Albuquerque return B_NO_MEMORY;
156550d2417SBruno G. Albuquerque
157754bbf48SJérôme Duval if (fDataStart != fDataEnd)
158550d2417SBruno G. Albuquerque memcpy(newBuffer, fBuffer + fDataStart, fDataEnd - fDataStart);
159550d2417SBruno G. Albuquerque
160550d2417SBruno G. Albuquerque delete[] fBuffer;
161550d2417SBruno G. Albuquerque fBuffer = newBuffer;
162550d2417SBruno G. Albuquerque fDataEnd -= fDataStart;
163550d2417SBruno G. Albuquerque fDataStart = 0;
164550d2417SBruno G. Albuquerque fBufferSize = newSize;
165550d2417SBruno G. Albuquerque
166550d2417SBruno G. Albuquerque return B_OK;
167550d2417SBruno G. Albuquerque }
168