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> 12*31562415SKarsten Heimrich #include <string.h> 13a12096e5SBruno G. Albuquerque 14550d2417SBruno G. Albuquerque #include <Errors.h> 15550d2417SBruno G. Albuquerque #include <SupportDefs.h> 16550d2417SBruno G. Albuquerque 17a12096e5SBruno G. Albuquerque #include <new> 18550d2417SBruno G. Albuquerque 19c98ce75fSBruno G. Albuquerque DynamicBuffer::DynamicBuffer(size_t initialSize) : 20550d2417SBruno G. Albuquerque fBuffer(NULL), 21550d2417SBruno G. Albuquerque fBufferSize(0), 22550d2417SBruno G. Albuquerque fDataStart(0), 23550d2417SBruno G. Albuquerque fDataEnd(0), 24550d2417SBruno G. Albuquerque fInit(B_NO_INIT) 25550d2417SBruno G. Albuquerque { 26c98ce75fSBruno G. Albuquerque if (initialSize > 0) { 27c98ce75fSBruno G. Albuquerque fBuffer = new (std::nothrow) unsigned char[initialSize]; 28550d2417SBruno G. Albuquerque if (fBuffer != NULL) { 29c98ce75fSBruno G. Albuquerque fBufferSize = initialSize; 30550d2417SBruno G. Albuquerque fInit = B_OK; 31550d2417SBruno G. Albuquerque } 32550d2417SBruno G. Albuquerque } 33550d2417SBruno G. Albuquerque } 34550d2417SBruno G. Albuquerque 35550d2417SBruno G. Albuquerque 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 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 66550d2417SBruno G. Albuquerque DynamicBuffer::InitCheck() const 67550d2417SBruno G. Albuquerque { 68550d2417SBruno G. Albuquerque return fInit; 69550d2417SBruno G. Albuquerque } 70550d2417SBruno G. Albuquerque 71550d2417SBruno G. Albuquerque 72550d2417SBruno G. Albuquerque status_t 73c98ce75fSBruno G. Albuquerque DynamicBuffer::Insert(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 85550d2417SBruno G. Albuquerque return B_OK; 86550d2417SBruno G. Albuquerque } 87550d2417SBruno G. Albuquerque 88550d2417SBruno G. Albuquerque 89550d2417SBruno G. Albuquerque status_t 90c98ce75fSBruno G. Albuquerque DynamicBuffer::Remove(void* data, size_t size) 91550d2417SBruno G. Albuquerque { 92550d2417SBruno G. Albuquerque if (fInit != B_OK) 93550d2417SBruno G. Albuquerque return fInit; 94550d2417SBruno G. Albuquerque 95c98ce75fSBruno G. Albuquerque if (fDataStart + size > fDataEnd) 96550d2417SBruno G. Albuquerque return B_BUFFER_OVERFLOW; 97550d2417SBruno G. Albuquerque 98b93465f1SBruno G. Albuquerque memcpy(data, fBuffer + fDataStart, size); 99c98ce75fSBruno G. Albuquerque fDataStart += size; 100550d2417SBruno G. Albuquerque 101550d2417SBruno G. Albuquerque if (fDataStart == fDataEnd) 102550d2417SBruno G. Albuquerque fDataStart = fDataEnd = 0; 103550d2417SBruno G. Albuquerque 104550d2417SBruno G. Albuquerque return B_OK; 105550d2417SBruno G. Albuquerque } 106550d2417SBruno G. Albuquerque 107550d2417SBruno G. Albuquerque 108550d2417SBruno G. Albuquerque unsigned char* 109550d2417SBruno G. Albuquerque DynamicBuffer::Data() const 110550d2417SBruno G. Albuquerque { 111550d2417SBruno G. Albuquerque return fBuffer + fDataStart; 112550d2417SBruno G. Albuquerque } 113550d2417SBruno G. Albuquerque 114550d2417SBruno G. Albuquerque 115550d2417SBruno G. Albuquerque size_t 116550d2417SBruno G. Albuquerque DynamicBuffer::Size() const 117550d2417SBruno G. Albuquerque { 118550d2417SBruno G. Albuquerque return fBufferSize; 119550d2417SBruno G. Albuquerque } 120550d2417SBruno G. Albuquerque 121550d2417SBruno G. Albuquerque 122550d2417SBruno G. Albuquerque size_t 123550d2417SBruno G. Albuquerque DynamicBuffer::BytesRemaining() const 124550d2417SBruno G. Albuquerque { 125550d2417SBruno G. Albuquerque return fDataEnd - fDataStart; 126550d2417SBruno G. Albuquerque } 127550d2417SBruno G. Albuquerque 128550d2417SBruno G. Albuquerque 129550d2417SBruno G. Albuquerque void 130550d2417SBruno G. Albuquerque DynamicBuffer::PrintToStream() 131550d2417SBruno G. Albuquerque { 132550d2417SBruno G. Albuquerque printf("Current buffer size : %ld\n", fBufferSize); 133550d2417SBruno G. Albuquerque printf("Data start position : %ld\n", fDataStart); 134550d2417SBruno G. Albuquerque printf("Data end position : %ld\n", fDataEnd); 135550d2417SBruno G. Albuquerque printf("Bytes wasted : %ld\n", fDataStart); 136550d2417SBruno G. Albuquerque printf("Bytes available : %ld\n", fBufferSize - fDataEnd); 137550d2417SBruno G. Albuquerque } 138550d2417SBruno G. Albuquerque 139550d2417SBruno G. Albuquerque 140550d2417SBruno G. Albuquerque status_t 141a12096e5SBruno G. Albuquerque DynamicBuffer::_GrowToFit(size_t size, bool exact) 142550d2417SBruno G. Albuquerque { 143b93465f1SBruno G. Albuquerque if (size <= fBufferSize - fDataEnd) 144550d2417SBruno G. Albuquerque return B_OK; 145550d2417SBruno G. Albuquerque 146a12096e5SBruno G. Albuquerque size_t newSize; 147a12096e5SBruno G. Albuquerque if (!exact) 148a12096e5SBruno G. Albuquerque newSize = (fBufferSize + size) * 2; 149a12096e5SBruno G. Albuquerque else 150a12096e5SBruno G. Albuquerque newSize = size; 151550d2417SBruno G. Albuquerque 152c98ce75fSBruno G. Albuquerque unsigned char* newBuffer = new (std::nothrow) unsigned char[newSize]; 153550d2417SBruno G. Albuquerque if (newBuffer == NULL) 154550d2417SBruno G. Albuquerque return B_NO_MEMORY; 155550d2417SBruno G. Albuquerque 156550d2417SBruno G. Albuquerque if (fDataStart != fDataEnd) { 157550d2417SBruno G. Albuquerque memcpy(newBuffer, fBuffer + fDataStart, fDataEnd - fDataStart); 158550d2417SBruno G. Albuquerque } 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