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 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 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 DynamicBuffer::~DynamicBuffer() 35550d2417SBruno G. Albuquerque { 36550d2417SBruno G. Albuquerque delete[] fBuffer; 37550d2417SBruno G. Albuquerque fBufferSize = 0; 38550d2417SBruno G. Albuquerque fDataStart = 0; 39550d2417SBruno G. Albuquerque fDataEnd = 0; 40550d2417SBruno G. Albuquerque } 41550d2417SBruno G. Albuquerque 42550d2417SBruno G. Albuquerque 43a12096e5SBruno G. Albuquerque DynamicBuffer::DynamicBuffer(const DynamicBuffer& buffer) : 44a12096e5SBruno G. Albuquerque fBuffer(NULL), 45a12096e5SBruno G. Albuquerque fBufferSize(0), 46a12096e5SBruno G. Albuquerque fDataStart(0), 47a12096e5SBruno G. Albuquerque fDataEnd(0), 48a12096e5SBruno G. Albuquerque fInit(B_NO_INIT) 49a12096e5SBruno G. Albuquerque { 50a12096e5SBruno G. Albuquerque fInit = buffer.fInit; 51a12096e5SBruno G. Albuquerque if (fInit == B_OK) { 52a12096e5SBruno G. Albuquerque status_t result = _GrowToFit(buffer.fBufferSize, true); 53a12096e5SBruno G. Albuquerque if (result == B_OK) { 54a12096e5SBruno G. Albuquerque memcpy(fBuffer, buffer.fBuffer, fBufferSize); 55a12096e5SBruno G. Albuquerque fDataStart = buffer.fDataStart; 56a12096e5SBruno G. Albuquerque fDataEnd = buffer.fDataEnd; 57a12096e5SBruno G. Albuquerque } else 58a12096e5SBruno G. Albuquerque fInit = result; 59a12096e5SBruno G. Albuquerque } 60a12096e5SBruno G. Albuquerque } 61a12096e5SBruno G. Albuquerque 62a12096e5SBruno G. Albuquerque 63550d2417SBruno G. Albuquerque status_t 64550d2417SBruno G. Albuquerque DynamicBuffer::InitCheck() const 65550d2417SBruno G. Albuquerque { 66550d2417SBruno G. Albuquerque return fInit; 67550d2417SBruno G. Albuquerque } 68550d2417SBruno G. Albuquerque 69550d2417SBruno G. Albuquerque 70a05da9f4SIngo Weinhold status_t 71*739f15e1SIngo Weinhold DynamicBuffer::Write(const void* data, size_t size) 72550d2417SBruno G. Albuquerque { 73550d2417SBruno G. Albuquerque if (fInit != B_OK) 74550d2417SBruno G. Albuquerque return fInit; 75550d2417SBruno G. Albuquerque 76c98ce75fSBruno G. Albuquerque status_t result = _GrowToFit(size); 77550d2417SBruno G. Albuquerque if (result != B_OK) 78550d2417SBruno G. Albuquerque return result; 79550d2417SBruno G. Albuquerque 80c98ce75fSBruno G. Albuquerque memcpy(fBuffer + fDataEnd, data, size); 81c98ce75fSBruno G. Albuquerque fDataEnd += size; 82550d2417SBruno G. Albuquerque 83a05da9f4SIngo Weinhold return B_OK; 84550d2417SBruno G. Albuquerque } 85550d2417SBruno G. Albuquerque 86550d2417SBruno G. Albuquerque 87*739f15e1SIngo Weinhold ssize_t 88*739f15e1SIngo Weinhold DynamicBuffer::Read(void* data, size_t size) 89550d2417SBruno G. Albuquerque { 90550d2417SBruno G. Albuquerque if (fInit != B_OK) 91550d2417SBruno G. Albuquerque return fInit; 92550d2417SBruno G. Albuquerque 93*739f15e1SIngo Weinhold if (size > Size()) 94*739f15e1SIngo Weinhold size = Size(); 95550d2417SBruno G. Albuquerque 96b93465f1SBruno G. Albuquerque memcpy(data, fBuffer + fDataStart, size); 97c98ce75fSBruno G. Albuquerque fDataStart += size; 98550d2417SBruno G. Albuquerque 99550d2417SBruno G. Albuquerque if (fDataStart == fDataEnd) 100550d2417SBruno G. Albuquerque fDataStart = fDataEnd = 0; 101550d2417SBruno G. Albuquerque 102*739f15e1SIngo Weinhold return size; 103550d2417SBruno G. Albuquerque } 104550d2417SBruno G. Albuquerque 105550d2417SBruno G. Albuquerque 106550d2417SBruno G. Albuquerque unsigned char* 107550d2417SBruno G. Albuquerque DynamicBuffer::Data() const 108550d2417SBruno G. Albuquerque { 109550d2417SBruno G. Albuquerque return fBuffer + fDataStart; 110550d2417SBruno G. Albuquerque } 111550d2417SBruno G. Albuquerque 112550d2417SBruno G. Albuquerque 113550d2417SBruno G. Albuquerque size_t 114550d2417SBruno G. Albuquerque DynamicBuffer::Size() const 115550d2417SBruno G. Albuquerque { 116b37fa18bSPhilippe Houdoin return fDataEnd - fDataStart; 117550d2417SBruno G. Albuquerque } 118550d2417SBruno G. Albuquerque 119550d2417SBruno G. Albuquerque 120550d2417SBruno G. Albuquerque size_t 121550d2417SBruno G. Albuquerque DynamicBuffer::BytesRemaining() const 122550d2417SBruno G. Albuquerque { 123b37fa18bSPhilippe Houdoin return fBufferSize - fDataEnd; 124550d2417SBruno G. Albuquerque } 125550d2417SBruno G. Albuquerque 126550d2417SBruno G. Albuquerque 127550d2417SBruno G. Albuquerque void 128550d2417SBruno G. Albuquerque DynamicBuffer::PrintToStream() 129550d2417SBruno G. Albuquerque { 130550d2417SBruno G. Albuquerque printf("Current buffer size : %ld\n", fBufferSize); 131550d2417SBruno G. Albuquerque printf("Data start position : %ld\n", fDataStart); 132550d2417SBruno G. Albuquerque printf("Data end position : %ld\n", fDataEnd); 133550d2417SBruno G. Albuquerque printf("Bytes wasted : %ld\n", fDataStart); 134550d2417SBruno G. Albuquerque printf("Bytes available : %ld\n", fBufferSize - fDataEnd); 135550d2417SBruno G. Albuquerque } 136550d2417SBruno G. Albuquerque 137550d2417SBruno G. Albuquerque 138550d2417SBruno G. Albuquerque status_t 139a12096e5SBruno G. Albuquerque DynamicBuffer::_GrowToFit(size_t size, bool exact) 140550d2417SBruno G. Albuquerque { 141b93465f1SBruno G. Albuquerque if (size <= fBufferSize - fDataEnd) 142550d2417SBruno G. Albuquerque return B_OK; 143550d2417SBruno G. Albuquerque 144a12096e5SBruno G. Albuquerque size_t newSize; 145a12096e5SBruno G. Albuquerque if (!exact) 146a12096e5SBruno G. Albuquerque newSize = (fBufferSize + size) * 2; 147a12096e5SBruno G. Albuquerque else 148a12096e5SBruno G. Albuquerque newSize = size; 149550d2417SBruno G. Albuquerque 150c98ce75fSBruno G. Albuquerque unsigned char* newBuffer = new (std::nothrow) unsigned char[newSize]; 151550d2417SBruno G. Albuquerque if (newBuffer == NULL) 152550d2417SBruno G. Albuquerque return B_NO_MEMORY; 153550d2417SBruno G. Albuquerque 154754bbf48SJérôme Duval if (fDataStart != fDataEnd) 155550d2417SBruno G. Albuquerque memcpy(newBuffer, fBuffer + fDataStart, fDataEnd - fDataStart); 156550d2417SBruno G. Albuquerque 157550d2417SBruno G. Albuquerque delete[] fBuffer; 158550d2417SBruno G. Albuquerque fBuffer = newBuffer; 159550d2417SBruno G. Albuquerque fDataEnd -= fDataStart; 160550d2417SBruno G. Albuquerque fDataStart = 0; 161550d2417SBruno G. Albuquerque fBufferSize = newSize; 162550d2417SBruno G. Albuquerque 163550d2417SBruno G. Albuquerque return B_OK; 164550d2417SBruno G. Albuquerque } 165