2 * Acess2 Networking Stack
3 * - By John Hodge (thePowersGang)
6 * - Scatter-gather handling
9 #include "include/buffer.h"
29 tIPStackBuffer *IPStack_Buffer_CreateBuffer(int MaxBuffers)
33 ret = malloc( sizeof(*ret) + MaxBuffers * sizeof(ret->SubBuffers[0]) );
34 ret->MaxSubBufffers = MaxBuffers;
37 memset(ret->SubBuffers, 0, MaxBuffers * sizeof(ret->SubBuffers[0]));
41 void IPStack_Buffer_ClearBuffer(tIPStackBuffer *Buffer)
43 for( int i = 0; i < Buffer->nSubBuffers; i ++ )
45 if( Buffer->SubBuffers[i].Cb == NULL )
47 Buffer->SubBuffers[i].Cb(
48 Buffer->SubBuffers[i].CbArg,
49 Buffer->SubBuffers[i].PreLength,
50 Buffer->SubBuffers[i].PostLength,
51 Buffer->SubBuffers[i].Data
54 // TODO: Fire callbacks?
55 Buffer->nSubBuffers = 0;
58 void IPStack_Buffer_DestroyBuffer(tIPStackBuffer *Buffer)
60 IPStack_Buffer_ClearBuffer(Buffer);
61 Buffer->MaxSubBufffers = 0;
65 void IPStack_Buffer_AppendSubBuffer(tIPStackBuffer *Buffer,
66 size_t HeaderLen, size_t FooterLen, const void *Data,
67 tIPStackBufferCb Cb, void *Arg
70 if( Buffer->nSubBuffers == Buffer->MaxSubBufffers ) {
72 Log_Error("IPStack", "Buffer %p only had %i sub-buffers allocated, which was not enough",
73 Buffer, Buffer->MaxSubBufffers);
77 int index = Buffer->nSubBuffers++;
78 Buffer->TotalLength += HeaderLen + FooterLen;
80 Buffer->SubBuffers[index].Data = Data;
81 Buffer->SubBuffers[index].PreLength = HeaderLen;
82 Buffer->SubBuffers[index].PostLength = FooterLen;
83 Buffer->SubBuffers[index].Cb = Cb;
84 Buffer->SubBuffers[index].CbArg = Arg;
87 size_t IPStack_Buffer_GetLength(tIPStackBuffer *Buffer)
89 return Buffer->TotalLength;
92 size_t IPStack_Buffer_GetData(tIPStackBuffer *Buffer, void *Dest, size_t MaxBytes)
95 size_t rem_space = MaxBytes;
98 for( int i = Buffer->nSubBuffers; i -- && rem_space != 0; )
100 len = MIN(Buffer->SubBuffers[i].PreLength, rem_space);
102 Buffer->SubBuffers[i].Data,
108 for( int i = 0; i < Buffer->nSubBuffers && rem_space; i ++ )
110 if( Buffer->SubBuffers[i].PostLength == 0 )
113 len = MIN(Buffer->SubBuffers[i].PostLength, rem_space);
115 (Uint8*)Buffer->SubBuffers[i].Data + Buffer->SubBuffers[i].PreLength,
122 return MaxBytes - rem_space;
125 void *IPStack_Buffer_CompactBuffer(tIPStackBuffer *Buffer, size_t *Length)
129 ret = malloc(Buffer->TotalLength);
135 *Length = Buffer->TotalLength;
137 IPStack_Buffer_GetData(Buffer, ret, Buffer->TotalLength);
142 int IPStack_Buffer_GetBuffer(tIPStackBuffer *Buffer, int Index, size_t *Length, const void **DataPtr)
144 if( Index == -1 ) Index = 0;
146 if( Index >= Buffer->nSubBuffers*2 ) {
150 if( Index >= Buffer->nSubBuffers )
153 Index -= Buffer->nSubBuffers;
155 // Bit of a hack to avoid multiple calls which return a zero length
156 while( !Buffer->SubBuffers[Index].PostLength )
158 if( Index++ == Buffer->nSubBuffers )
162 *DataPtr = (Uint8*)Buffer->SubBuffers[Index].Data + Buffer->SubBuffers[Index].PreLength;
163 *Length = Buffer->SubBuffers[Index].PostLength;
165 return (Index + 1) + Buffer->nSubBuffers;
170 Index = Buffer->nSubBuffers - Index - 1;
172 *DataPtr = Buffer->SubBuffers[Index].Data;
173 *Length = Buffer->SubBuffers[Index].PreLength;