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 14 ChainBuffer::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 22 ChainBuffer::~ChainBuffer() 23 { 24 _Destroy(); 25 } 26 27 // DetachNext 28 ChainBuffer * 29 ChainBuffer::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 44 void 45 ChainBuffer::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 59 void 60 ChainBuffer::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 74 void 75 ChainBuffer::_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 86 void 87 ChainBuffer::_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