headers/bsd: Add sys/queue.h.
[haiku.git] / src / system / boot / loader / net / ChainBuffer.cpp
blob5d2e036f97d0841223cef5d951a2fa1ebdcb53c7
1 /*
2 * Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
4 */
6 #include <boot/net/ChainBuffer.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include <util/kernel_cpp.h>
13 // constructor
14 ChainBuffer::ChainBuffer(void *data, uint32 size, ChainBuffer *next,
15 bool freeData)
17 _Init(data, size, next,
18 CHAIN_BUFFER_ON_STACK | (freeData ? CHAIN_BUFFER_FREE_DATA : 0));
21 // destructor
22 ChainBuffer::~ChainBuffer()
24 _Destroy();
27 // DetachNext
28 ChainBuffer *
29 ChainBuffer::DetachNext()
31 if (!fNext)
32 return NULL;
34 ChainBuffer *next = fNext;
36 fNext = NULL;
37 next->fFlags |= CHAIN_BUFFER_HEAD;
38 fTotalSize = fSize;
40 return next;
43 // Append
44 void
45 ChainBuffer::Append(ChainBuffer *next)
47 if (!next)
48 return;
50 if (fNext)
51 fNext->Append(next);
52 else
53 fNext = next;
55 fTotalSize = fSize + fNext->fTotalSize;
58 // Flatten
59 void
60 ChainBuffer::Flatten(void *_buffer) const
62 if (uint8 *buffer = (uint8*)_buffer) {
63 if (fData && fSize > 0) {
64 memcpy(buffer, fData, fSize);
65 buffer += fSize;
68 if (fNext)
69 fNext->Flatten(buffer);
73 // _Init
74 void
75 ChainBuffer::_Init(void *data, uint32 size, ChainBuffer *next, uint32 flags)
77 fFlags = flags | CHAIN_BUFFER_HEAD;
78 fSize = size;
79 fTotalSize = fSize;
80 fData = data;
81 fNext = NULL;
82 Append(next);
85 // _Destroy
86 void
87 ChainBuffer::_Destroy()
89 ChainBuffer *next = fNext;
90 fNext = NULL;
91 if ((fFlags & CHAIN_BUFFER_FREE_DATA) && fData) {
92 free(fData);
93 fData = NULL;
96 if (!(fFlags & CHAIN_BUFFER_EMBEDDED_DATA))
97 fSize = 0;
98 fTotalSize = fSize;
100 if (next) {
101 if (next->fFlags & CHAIN_BUFFER_ON_STACK)
102 next->_Destroy();
103 else
104 delete next;