1/* 2 * Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6#include <boot/net/ChainBuffer.h> 7 8#include <stdlib.h> 9#include <string.h> 10 11#include <util/kernel_cpp.h> 12 13// constructor 14ChainBuffer::ChainBuffer(void *data, uint32 size, ChainBuffer *next, 15 bool freeData) 16{ 17 _Init(data, size, next, 18 CHAIN_BUFFER_ON_STACK | (freeData ? CHAIN_BUFFER_FREE_DATA : 0)); 19} 20 21// destructor 22ChainBuffer::~ChainBuffer() 23{ 24 _Destroy(); 25} 26 27// DetachNext 28ChainBuffer * 29ChainBuffer::DetachNext() 30{ 31 if (!fNext) 32 return NULL; 33 34 ChainBuffer *next = fNext; 35 36 fNext = NULL; 37 next->fFlags |= CHAIN_BUFFER_HEAD; 38 fTotalSize = fSize; 39 40 return next; 41} 42 43// Append 44void 45ChainBuffer::Append(ChainBuffer *next) 46{ 47 if (!next) 48 return; 49 50 if (fNext) 51 fNext->Append(next); 52 else 53 fNext = next; 54 55 fTotalSize = fSize + fNext->fTotalSize; 56} 57 58// Flatten 59void 60ChainBuffer::Flatten(void *_buffer) const 61{ 62 if (uint8 *buffer = (uint8*)_buffer) { 63 if (fData && fSize > 0) { 64 memcpy(buffer, fData, fSize); 65 buffer += fSize; 66 } 67 68 if (fNext) 69 fNext->Flatten(buffer); 70 } 71} 72 73// _Init 74void 75ChainBuffer::_Init(void *data, uint32 size, ChainBuffer *next, uint32 flags) 76{ 77 fFlags = flags | CHAIN_BUFFER_HEAD; 78 fSize = size; 79 fTotalSize = fSize; 80 fData = data; 81 fNext = NULL; 82 Append(next); 83} 84 85// _Destroy 86void 87ChainBuffer::_Destroy() 88{ 89 ChainBuffer *next = fNext; 90 fNext = NULL; 91 if ((fFlags & CHAIN_BUFFER_FREE_DATA) && fData) { 92 free(fData); 93 fData = NULL; 94 } 95 96 if (!(fFlags & CHAIN_BUFFER_EMBEDDED_DATA)) 97 fSize = 0; 98 fTotalSize = fSize; 99 100 if (next) { 101 if (next->fFlags & CHAIN_BUFFER_ON_STACK) 102 next->_Destroy(); 103 else 104 delete next; 105 } 106} 107