1 /* 2 * Copyright 2009, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Bruno Albuquerque, bga@bug-br.org.br 7 */ 8 9 #include "DynamicBuffer.h" 10 11 #include <Errors.h> 12 #include <SupportDefs.h> 13 14 15 DynamicBuffer::DynamicBuffer(size_t _initialSize) : 16 fBuffer(NULL), 17 fBufferSize(0), 18 fDataStart(0), 19 fDataEnd(0), 20 fInit(B_NO_INIT) 21 { 22 if (_initialSize > 0) { 23 fBuffer = new unsigned char[_initialSize]; 24 if (fBuffer != NULL) { 25 fBufferSize = _initialSize; 26 fInit = B_OK; 27 } 28 } 29 } 30 31 32 DynamicBuffer::~DynamicBuffer() 33 { 34 delete[] fBuffer; 35 fBufferSize = 0; 36 fDataStart = 0; 37 fDataEnd = 0; 38 } 39 40 41 status_t 42 DynamicBuffer::InitCheck() const 43 { 44 return fInit; 45 } 46 47 48 status_t 49 DynamicBuffer::Insert(const void* _data, size_t _size) 50 { 51 if (fInit != B_OK) 52 return fInit; 53 54 status_t result = _GrowToFit(_size); 55 if (result != B_OK) 56 return result; 57 58 memcpy(fBuffer + fDataEnd, _data, _size); 59 fDataEnd += _size; 60 61 return B_OK; 62 } 63 64 65 status_t 66 DynamicBuffer::Remove(void* _data, size_t _size) 67 { 68 if (fInit != B_OK) 69 return fInit; 70 71 if (fDataStart + _size > fDataEnd) 72 return B_BUFFER_OVERFLOW; 73 74 memcpy(_data, fBuffer + fDataStart, _size); 75 fDataStart += _size; 76 77 if (fDataStart == fDataEnd) 78 fDataStart = fDataEnd = 0; 79 80 return B_OK; 81 } 82 83 84 unsigned char* 85 DynamicBuffer::Data() const 86 { 87 return fBuffer + fDataStart; 88 } 89 90 91 size_t 92 DynamicBuffer::Size() const 93 { 94 return fBufferSize; 95 } 96 97 98 size_t 99 DynamicBuffer::BytesRemaining() const 100 { 101 return fDataEnd - fDataStart; 102 } 103 104 105 void 106 DynamicBuffer::PrintToStream() 107 { 108 printf("Current buffer size : %ld\n", fBufferSize); 109 printf("Data start position : %ld\n", fDataStart); 110 printf("Data end position : %ld\n", fDataEnd); 111 printf("Bytes wasted : %ld\n", fDataStart); 112 printf("Bytes available : %ld\n", fBufferSize - fDataEnd); 113 } 114 115 116 status_t 117 DynamicBuffer::_GrowToFit(size_t _size) 118 { 119 if (_size <= fBufferSize - fDataEnd) 120 return B_OK; 121 122 size_t newSize = (fBufferSize + _size) * 2; 123 124 unsigned char* newBuffer = new unsigned char[newSize]; 125 if (newBuffer == NULL) 126 return B_NO_MEMORY; 127 128 if (fDataStart != fDataEnd) { 129 memcpy(newBuffer, fBuffer + fDataStart, fDataEnd - fDataStart); 130 } 131 132 delete[] fBuffer; 133 fBuffer = newBuffer; 134 fDataEnd -= fDataStart; 135 fDataStart = 0; 136 fBufferSize = newSize; 137 138 return B_OK; 139 } 140