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
ChainBuffer(void * data,uint32 size,ChainBuffer * next,bool freeData)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
~ChainBuffer()22 ChainBuffer::~ChainBuffer()
23 {
24 _Destroy();
25 }
26
27 // DetachNext
28 ChainBuffer *
DetachNext()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
Append(ChainBuffer * next)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
Flatten(void * _buffer) const60 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
_Init(void * data,uint32 size,ChainBuffer * next,uint32 flags)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
_Destroy()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