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