X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;ds=sidebyside;f=KernelLand%2FModules%2FIPStack%2Fbuffer.c;h=2555a6359d3b8a7ee214192aad8edef04a5e7f40;hb=3f9b3f4cb91ce4ada9c892e6f2a3c69dbb9debd6;hp=9151c1c1a20b9104941b19ead440f4671bbf4c91;hpb=849329d50395b44ac97c5b5145fc2df0749eace2;p=tpg%2Facess2.git diff --git a/KernelLand/Modules/IPStack/buffer.c b/KernelLand/Modules/IPStack/buffer.c index 9151c1c1..2555a635 100644 --- a/KernelLand/Modules/IPStack/buffer.c +++ b/KernelLand/Modules/IPStack/buffer.c @@ -14,11 +14,15 @@ struct sIPStackBuffer int MaxSubBufffers; int nSubBuffers; size_t TotalLength; + tMutex lBufferLock; + struct _subbuffer { const void *Data; size_t PreLength; size_t PostLength; + tIPStackBufferCb Cb; + void *CbArg; // TODO: Callbacks? } SubBuffers[]; }; @@ -32,18 +36,45 @@ tIPStackBuffer *IPStack_Buffer_CreateBuffer(int MaxBuffers) ret->MaxSubBufffers = MaxBuffers; ret->nSubBuffers = 0; ret->TotalLength = 0; + memset(&ret->lBufferLock, 0, sizeof(ret->lBufferLock)); memset(ret->SubBuffers, 0, MaxBuffers * sizeof(ret->SubBuffers[0])); return ret; } +void IPStack_Buffer_ClearBuffer(tIPStackBuffer *Buffer) +{ + IPStack_Buffer_LockBuffer(Buffer); + for( int i = 0; i < Buffer->nSubBuffers; i ++ ) + { + if( Buffer->SubBuffers[i].Cb == NULL ) + continue ; + Buffer->SubBuffers[i].Cb( + Buffer->SubBuffers[i].CbArg, + Buffer->SubBuffers[i].PreLength, + Buffer->SubBuffers[i].PostLength, + Buffer->SubBuffers[i].Data + ); + } + Buffer->nSubBuffers = 0; + IPStack_Buffer_UnlockBuffer(Buffer); +} + void IPStack_Buffer_DestroyBuffer(tIPStackBuffer *Buffer) { - // TODO: Fire callbacks? + IPStack_Buffer_ClearBuffer(Buffer); Buffer->MaxSubBufffers = 0; - Buffer->nSubBuffers = 0; free(Buffer); } +void IPStack_Buffer_LockBuffer(tIPStackBuffer *Buffer) +{ + Mutex_Acquire(&Buffer->lBufferLock); +} +void IPStack_Buffer_UnlockBuffer(tIPStackBuffer *Buffer) +{ + Mutex_Release(&Buffer->lBufferLock); +} + void IPStack_Buffer_AppendSubBuffer(tIPStackBuffer *Buffer, size_t HeaderLen, size_t FooterLen, const void *Data, tIPStackBufferCb Cb, void *Arg @@ -62,6 +93,8 @@ void IPStack_Buffer_AppendSubBuffer(tIPStackBuffer *Buffer, Buffer->SubBuffers[index].Data = Data; Buffer->SubBuffers[index].PreLength = HeaderLen; Buffer->SubBuffers[index].PostLength = FooterLen; + Buffer->SubBuffers[index].Cb = Cb; + Buffer->SubBuffers[index].CbArg = Arg; } size_t IPStack_Buffer_GetLength(tIPStackBuffer *Buffer) @@ -69,9 +102,43 @@ size_t IPStack_Buffer_GetLength(tIPStackBuffer *Buffer) return Buffer->TotalLength; } +size_t IPStack_Buffer_GetData(tIPStackBuffer *Buffer, void *Dest, size_t MaxBytes) +{ + Uint8 *dest = Dest; + size_t rem_space = MaxBytes; + size_t len; + + for( int i = Buffer->nSubBuffers; i -- && rem_space != 0; ) + { + len = MIN(Buffer->SubBuffers[i].PreLength, rem_space); + memcpy(dest, + Buffer->SubBuffers[i].Data, + len + ); + dest += len; + rem_space -= len; + } + for( int i = 0; i < Buffer->nSubBuffers && rem_space; i ++ ) + { + if( Buffer->SubBuffers[i].PostLength == 0 ) + continue ; + + len = MIN(Buffer->SubBuffers[i].PostLength, rem_space); + memcpy(dest, + (Uint8*)Buffer->SubBuffers[i].Data + Buffer->SubBuffers[i].PreLength, + len + ); + dest += len; + rem_space -= len; + } + + return MaxBytes - rem_space; +} + void *IPStack_Buffer_CompactBuffer(tIPStackBuffer *Buffer, size_t *Length) { void *ret; + ret = malloc(Buffer->TotalLength); if(!ret) { *Length = 0; @@ -79,27 +146,9 @@ void *IPStack_Buffer_CompactBuffer(tIPStackBuffer *Buffer, size_t *Length) } *Length = Buffer->TotalLength; - - Uint8 *dest = ret; - for( int i = Buffer->nSubBuffers; i --; ) - { - memcpy(dest, - Buffer->SubBuffers[i].Data, - Buffer->SubBuffers[i].PreLength - ); - dest += Buffer->SubBuffers[i].PreLength; - } - for( int i = 0; i < Buffer->nSubBuffers; i ++ ) - { - if( Buffer->SubBuffers[i].PostLength ) - { - memcpy(dest, - (Uint8*)Buffer->SubBuffers[i].Data + Buffer->SubBuffers[i].PreLength, - Buffer->SubBuffers[i].PostLength - ); - dest += Buffer->SubBuffers[i].PreLength; - } - } + + IPStack_Buffer_GetData(Buffer, ret, Buffer->TotalLength); + return ret; } @@ -111,7 +160,7 @@ int IPStack_Buffer_GetBuffer(tIPStackBuffer *Buffer, int Index, size_t *Length, return -1; } - if( Index > Buffer->nSubBuffers ) + if( Index >= Buffer->nSubBuffers ) { // Appended buffers Index -= Buffer->nSubBuffers; @@ -130,11 +179,12 @@ int IPStack_Buffer_GetBuffer(tIPStackBuffer *Buffer, int Index, size_t *Length, } else { - Index = Buffer->nSubBuffers - Index; + int rv = Index + 1; + Index = Buffer->nSubBuffers - Index - 1; // Prepended buffers *DataPtr = Buffer->SubBuffers[Index].Data; *Length = Buffer->SubBuffers[Index].PreLength; - return Buffer->nSubBuffers - (Index - 1); + return rv; } }