Important Update:
- Library Clean up: - Removed all unused C/C++ libraries from source - First C/C++ libraries then redA libraries - Library changes: - renamed BufferCore -> CharBufferCore - added ItemBufferCore - CharBufferCore: - Derive RollingBuffer & ShiftBuffer from common class CharBuffer - CharBuffer is mostly a virtual class (interface)
This commit is contained in:
802
CharBufferCore.cpp
Normal file
802
CharBufferCore.cpp
Normal file
@@ -0,0 +1,802 @@
|
||||
/*
|
||||
* CharBufferCore.cpp
|
||||
*
|
||||
* Created on: 18 May 2016
|
||||
* Author: wentzelc
|
||||
*/
|
||||
|
||||
// Standard C/C++ Libraries
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
// redA Libraries
|
||||
#include "CharBufferCore.h"
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
/***** Char Buffer *****/
|
||||
|
||||
CCharBuffer::CCharBuffer( int BufferSize ) : BufSize( BufferSize )
|
||||
{
|
||||
// Create Buffer
|
||||
if (BufSize)
|
||||
{
|
||||
// Create Buffer
|
||||
Buffer = (char *)malloc( BufSize+1 );
|
||||
memset( Buffer, 0, BufSize+1 );
|
||||
|
||||
// Create temp output buffer big enough to handle all data
|
||||
OutBuffer = (char *)malloc( BufSize+1 );
|
||||
}
|
||||
else {
|
||||
// No buffers created
|
||||
Buffer = NULL;
|
||||
OutBuffer = NULL;
|
||||
}
|
||||
|
||||
// Set pointers
|
||||
BufLen = 0;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
CCharBuffer::~CCharBuffer()
|
||||
{
|
||||
// Destroy Buffer
|
||||
if (Buffer) {
|
||||
free( Buffer );
|
||||
}
|
||||
if (OutBuffer) {
|
||||
free( OutBuffer );
|
||||
}
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Clear all data from buffer
|
||||
int CCharBuffer::Reset()
|
||||
{
|
||||
int BytesCleared = 0;
|
||||
|
||||
// Reset buffer
|
||||
BytesCleared = BufLen;
|
||||
BufLen = 0;
|
||||
Buffer[0] = 0;
|
||||
|
||||
return BytesCleared;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Read first-in bytes from buffer
|
||||
// Return "stitched" buffer data in temporary buffer
|
||||
int CCharBuffer::Pop( char ** Data, int MaxLen )
|
||||
{
|
||||
int BytesWritten = 0;
|
||||
|
||||
// Read & clear data
|
||||
BytesWritten = Peek( Data, 0, MaxLen );
|
||||
Clear( BytesWritten );
|
||||
|
||||
// Return temp buffer
|
||||
return BytesWritten;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Read first-in bytes from buffer
|
||||
// Return "stitched" buffer data copied to pointer which if created if NULL
|
||||
int CCharBuffer::PopCopy( char ** Data, int MaxLen )
|
||||
{
|
||||
int BytesWritten = 0;
|
||||
|
||||
// Copy & clear data
|
||||
BytesWritten = PeekCopy( Data, 0, MaxLen );
|
||||
Clear( BytesWritten );
|
||||
|
||||
// Return temp buffer
|
||||
return BytesWritten;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/***** Rolling Buffer *****/
|
||||
|
||||
CRollingBuffer::CRollingBuffer( int BufferSize ) : CCharBuffer( BufferSize )
|
||||
{
|
||||
// Set pointers
|
||||
BufStart = 0;
|
||||
BufEnd = 0;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Clear all data from buffer
|
||||
int CRollingBuffer::Reset()
|
||||
{
|
||||
// Reset pointers
|
||||
BufStart = 0;
|
||||
BufEnd = 0;
|
||||
|
||||
return CCharBuffer::Reset();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Return specific character for current rolling data
|
||||
char CRollingBuffer::PeekChar( int Pos )
|
||||
{
|
||||
char CharValue = 0;
|
||||
|
||||
// Validate buffer and Pos
|
||||
if (!BufSize || (Pos < 0) || (Pos > BufLen)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get char
|
||||
if (BufStart + Pos < BufSize) {
|
||||
CharValue = Buffer[ BufStart+Pos ];
|
||||
}
|
||||
else {
|
||||
CharValue = Buffer[ BufStart+Pos-BufSize ];
|
||||
}
|
||||
|
||||
// Return char
|
||||
return CharValue;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Return pointer direct to buffer
|
||||
// Data is not removed from buffer
|
||||
// Return number of contiguous chars (cannot rollover)
|
||||
int CRollingBuffer::PeekDirect( char ** Data, int PeekPos )
|
||||
{
|
||||
int BytesReturned = 0;
|
||||
int StartPos = 0;
|
||||
|
||||
// Validate
|
||||
if (!BufSize || !Data || (PeekPos > BufLen)) {
|
||||
*Data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get reference
|
||||
if (BufStart + StartPos < BufSize) {
|
||||
StartPos = BufStart + PeekPos;
|
||||
BytesReturned = (StartPos + BufLen > BufSize)? BufSize - StartPos : BufLen;
|
||||
}
|
||||
else {
|
||||
StartPos = BufStart + PeekPos - BufSize;
|
||||
BytesReturned = (StartPos + BufLen > BufEnd) ? BufEnd - StartPos : BufLen;
|
||||
}
|
||||
|
||||
// Return buffer pointer
|
||||
*Data = &Buffer[StartPos];
|
||||
return BytesReturned;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Return "stitched" buffer data copied to pointer
|
||||
// Pointer is created if NULL passed
|
||||
// Data is not removed from buffer
|
||||
int CRollingBuffer::Peek( char ** Data, int PeekPos, int MaxLen )
|
||||
{
|
||||
int BytesReturned = 0;
|
||||
int StartPos = 0;
|
||||
|
||||
// Validate
|
||||
if (!BufSize || !Data || !MaxLen || (PeekPos < 0) || (PeekPos > BufLen)) {
|
||||
*Data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get buffer start position
|
||||
if (BufStart + StartPos < BufSize) {
|
||||
StartPos = BufStart + PeekPos;
|
||||
}
|
||||
else {
|
||||
StartPos = BufStart + PeekPos - BufSize;
|
||||
}
|
||||
|
||||
// Validate MaxLen
|
||||
if ((MaxLen == -1) || (MaxLen > BufSize)) {
|
||||
MaxLen = BufSize;
|
||||
}
|
||||
BytesReturned = (MaxLen > BufLen - PeekPos)? (BufLen - PeekPos) : MaxLen;
|
||||
|
||||
// Copy Data from Buffer
|
||||
if (StartPos + BytesReturned <= BufSize) {
|
||||
memcpy( OutBuffer, &Buffer[StartPos], BytesReturned );
|
||||
}
|
||||
else {
|
||||
memcpy( OutBuffer, &Buffer[StartPos], BufSize-StartPos ); // Copy from end of buffer
|
||||
memcpy( &OutBuffer[BufSize-StartPos], Buffer, (BytesReturned-(BufSize-StartPos)) ); // Copy rollover from start of buffer
|
||||
}
|
||||
|
||||
// Zero terminate
|
||||
OutBuffer[BytesReturned] = 0;
|
||||
|
||||
// Return Temp buffer
|
||||
*Data = OutBuffer;
|
||||
return BytesReturned;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Return "stitched" buffer data in temporary buffer
|
||||
// Data is not removed from buffer
|
||||
int CRollingBuffer::PeekCopy( char ** Data, int PeekPos, int MaxLen )
|
||||
{
|
||||
int BytesReturned = 0;
|
||||
int StartPos = 0;
|
||||
|
||||
// Check if any data
|
||||
if (!BufSize || !Data || !MaxLen || (PeekPos < 0) || (PeekPos > BufLen)) {
|
||||
if (*Data) (*Data)[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get start position
|
||||
if (BufStart + StartPos < BufSize) {
|
||||
StartPos = BufStart + PeekPos;
|
||||
}
|
||||
else {
|
||||
StartPos = BufStart + PeekPos - BufSize;
|
||||
}
|
||||
|
||||
// Validate MaxLen
|
||||
if ((MaxLen == -1) || (MaxLen > BufSize)) {
|
||||
MaxLen = BufSize;
|
||||
}
|
||||
BytesReturned = (MaxLen > BufLen - PeekPos)? (BufLen - PeekPos) : MaxLen;
|
||||
|
||||
// Allocate memory
|
||||
if (!*Data)
|
||||
*Data = (char*)malloc( BytesReturned + 1 );
|
||||
|
||||
// Copy Data from Buffer
|
||||
if (StartPos + BytesReturned <= BufSize) {
|
||||
memcpy( *Data, &Buffer[StartPos], BytesReturned );
|
||||
}
|
||||
else {
|
||||
memcpy( *Data, &Buffer[StartPos], BufSize-StartPos ); // Copy from end of buffer
|
||||
memcpy( &(*Data)[BufSize-StartPos], Buffer, (BytesReturned-(BufSize-StartPos)) ); // Copy rollover from start of buffer
|
||||
}
|
||||
(*Data)[BytesReturned] = 0;
|
||||
|
||||
return BytesReturned;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Look for first occurrence of character in buffer
|
||||
bool CRollingBuffer::FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int StartPos )
|
||||
{
|
||||
char * CheckPos = NULL;
|
||||
char * CheckLimit = NULL;
|
||||
char * MatchPos = NULL;
|
||||
char * MatchLimit = NULL;
|
||||
|
||||
// Check if buffer exists
|
||||
if (!BufSize || !SearchStr || !SearchLen) {
|
||||
FoundPos = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate start Pos
|
||||
if (StartPos >= BufLen) {
|
||||
FoundPos = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get Search start point and limit
|
||||
CheckPos = (BufStart + StartPos < BufSize)? &Buffer[ BufStart+StartPos ] : &Buffer[ (BufStart+StartPos)-BufSize ];
|
||||
CheckLimit = &Buffer[BufSize-1];
|
||||
|
||||
// Set Match start point and limit
|
||||
MatchPos = (char*)SearchStr;
|
||||
MatchLimit = (char*)&SearchStr[SearchLen-1];
|
||||
|
||||
// Search for char
|
||||
FoundPos = StartPos;
|
||||
while (FoundPos < BufLen)
|
||||
{
|
||||
// Check if char match
|
||||
if (*CheckPos == *MatchPos) {
|
||||
if (MatchPos == MatchLimit) {
|
||||
// Full match found
|
||||
FoundPos -= SearchLen-1;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// Next char to match
|
||||
MatchPos++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Reset match point
|
||||
MatchPos = (char*)SearchStr;
|
||||
}
|
||||
|
||||
// Next char
|
||||
FoundPos++;
|
||||
if (CheckPos == CheckLimit) {
|
||||
CheckPos = Buffer; // Roll-over, Start at beginning of buffer
|
||||
} else {
|
||||
CheckPos++;
|
||||
}
|
||||
}
|
||||
|
||||
// Not Found
|
||||
FoundPos = -1;
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Remove data from start of buffer
|
||||
int CRollingBuffer::Clear( int ClearLen )
|
||||
{
|
||||
int BytesCleared;
|
||||
|
||||
// Validate ClearLen
|
||||
if (ClearLen == -1) {
|
||||
BytesCleared = BufLen;
|
||||
}
|
||||
else {
|
||||
BytesCleared = (ClearLen > BufLen)? BufLen : ClearLen;
|
||||
}
|
||||
|
||||
// Update Buffer pointers
|
||||
if (BufStart + BytesCleared < BufSize) {
|
||||
BufStart += BytesCleared;
|
||||
} else {
|
||||
BufStart = (BytesCleared-(BufSize-BufStart)); // Copy roll-over from start of buffer
|
||||
}
|
||||
BufLen -= BytesCleared;
|
||||
|
||||
return BytesCleared;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Add bytes to end of buffer
|
||||
// Perform roll over if requied
|
||||
// Option to overwrite existing data if longer than buffer length
|
||||
int CRollingBuffer::Push( bool Overwrite, const char * Data, int Len )
|
||||
{
|
||||
int BytesPushed = 0;
|
||||
int TotalPushed = 0;
|
||||
int BufRemain = 0;
|
||||
int DataRemain;
|
||||
|
||||
// Validate Buffer and Len
|
||||
if (!BufSize || !Data || !Len) {
|
||||
return 0;
|
||||
}
|
||||
else if (Len == -1) {
|
||||
Len = strlen( Data );
|
||||
}
|
||||
|
||||
// Prevent overwrite
|
||||
DataRemain = (!Overwrite && (Len > BufSize-BufLen))? BufSize-BufLen : Len;
|
||||
|
||||
// Read Data into buffer
|
||||
while (DataRemain)
|
||||
{
|
||||
// Read from file descriptor
|
||||
BufRemain = BufSize - BufEnd;
|
||||
BytesPushed = ((BufRemain > DataRemain)? DataRemain : BufRemain);
|
||||
memcpy( &Buffer[BufEnd], &Data[TotalPushed], BytesPushed );
|
||||
|
||||
// Update Data Pointers
|
||||
TotalPushed += BytesPushed;
|
||||
DataRemain -= BytesPushed;
|
||||
|
||||
// Update Buffer Pointers
|
||||
BufLen += BytesPushed;
|
||||
BufEnd += BytesPushed;
|
||||
if (BufEnd >= BufSize) {
|
||||
// Rolling over end of buffer, start at beginning
|
||||
BufEnd = 0;
|
||||
}
|
||||
if (BufLen > BufSize) {
|
||||
// Head has caught up with tail, move tail up
|
||||
BufLen = BufSize;
|
||||
BufStart = BufEnd;
|
||||
}
|
||||
}
|
||||
|
||||
return TotalPushed;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Read File descriptor directly into rolling buffer
|
||||
int CRollingBuffer::ReadFromFD( int Handle, int MaxRead, bool Overwrite )
|
||||
{
|
||||
int BytesRead = 0;
|
||||
int TotalRead = 0;
|
||||
int BufRemain = 0;
|
||||
int DataRemain = 0;
|
||||
|
||||
// Check if buffer created
|
||||
if (!BufSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read file descriptor into buffer
|
||||
if (MaxRead == -1)
|
||||
MaxRead = BufSize;
|
||||
DataRemain = ((!Overwrite && (MaxRead > BufSize-BufLen)))? BufSize-BufLen : MaxRead;
|
||||
while (DataRemain)
|
||||
{
|
||||
// Read from file descriptor
|
||||
BufRemain = BufSize - BufEnd;
|
||||
BytesRead = read( Handle, &Buffer[BufEnd], ((BufRemain > DataRemain)? DataRemain : BufRemain) );
|
||||
if (BytesRead <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Update Buffer Pointers
|
||||
DataRemain -= BytesRead;
|
||||
TotalRead += BytesRead;
|
||||
BufLen += BytesRead;
|
||||
BufEnd += BytesRead;
|
||||
if (BufEnd >= BufSize) {
|
||||
// Rolling over end of buffer, start at beginning
|
||||
BufEnd = 0;
|
||||
}
|
||||
if (BufLen > BufSize) {
|
||||
// Head is caught up with tail, move tail up
|
||||
BufLen = BufSize;
|
||||
BufStart = BufEnd;
|
||||
}
|
||||
}
|
||||
return TotalRead;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Write given number of bytes directly from buffer to File descriptor
|
||||
int CRollingBuffer::WriteToFD( int Handle, int MaxLen )
|
||||
{
|
||||
int BytesWritten = 0;
|
||||
int TotalWritten = 0;
|
||||
int BufRemain = 0;
|
||||
int DataRemain = 0;
|
||||
int ReadPos = 0;
|
||||
|
||||
// Check if buffer created
|
||||
if (!BufSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read Data into buffer
|
||||
ReadPos = BufStart;
|
||||
DataRemain = (MaxLen == -1)? BufLen : MaxLen;
|
||||
while (DataRemain)
|
||||
{
|
||||
// Read from file descriptor
|
||||
BufRemain = BufSize - ReadPos;
|
||||
BytesWritten = write( Handle, &Buffer[ReadPos], ((BufRemain > DataRemain)? DataRemain : BufRemain) );
|
||||
if (BytesWritten <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Update Data Pointers
|
||||
TotalWritten += BytesWritten;
|
||||
DataRemain -= BytesWritten;
|
||||
|
||||
// Update Buffer Pointers
|
||||
ReadPos += BytesWritten;
|
||||
if (ReadPos >= BufSize) {
|
||||
ReadPos = 0; // Rolling over end of buffer, start at beginning
|
||||
}
|
||||
}
|
||||
|
||||
return TotalWritten;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
/***** Shifting Buffer *****/
|
||||
|
||||
CShiftBuffer::CShiftBuffer( int BufferSize ) :
|
||||
CCharBuffer( BufferSize )
|
||||
{
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Return specific character for current rolling data
|
||||
char CShiftBuffer::PeekChar( int Pos )
|
||||
{
|
||||
// Validate buffer and Pos
|
||||
if (!BufSize || (Pos < 0) || (Pos > BufLen)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return char
|
||||
return Buffer[Pos];
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Return pointer direct to buffer
|
||||
// Return number of contiguous chars (cannot rollover)
|
||||
int CShiftBuffer::PeekDirect( char ** Data, int PeekPos )
|
||||
{
|
||||
// Validate
|
||||
if (!BufSize || !Data || (PeekPos > BufLen)) {
|
||||
*Data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return buffer pointer
|
||||
*Data = &Buffer[PeekPos];
|
||||
return (BufLen - PeekPos);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Copy data into temporary buffer
|
||||
int CShiftBuffer::Peek( char ** Data, int PeekPos, int MaxLen )
|
||||
{
|
||||
int BytesReturned = 0;
|
||||
|
||||
// Validate
|
||||
if (!BufSize || !Data || !MaxLen || (PeekPos < 0) || (PeekPos > BufLen)) {
|
||||
*Data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate bytes to return
|
||||
if ((MaxLen == -1) || (MaxLen > BufSize)) {
|
||||
MaxLen = BufSize;
|
||||
}
|
||||
BytesReturned = (MaxLen > BufLen - PeekPos)? (BufLen - PeekPos) : MaxLen;
|
||||
|
||||
// Copy Data from Buffer
|
||||
memcpy( OutBuffer, &Buffer[PeekPos], BytesReturned );
|
||||
OutBuffer[BytesReturned] = 0;
|
||||
|
||||
// Return Temp buffer
|
||||
*Data = OutBuffer;
|
||||
return BytesReturned;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Return "stitched" buffer data in temporary buffer
|
||||
// Data is not removed from buffer
|
||||
int CShiftBuffer::PeekCopy( char ** Data, int PeekPos, int MaxLen )
|
||||
{
|
||||
int BytesReturned = 0;
|
||||
int StartPos = 0;
|
||||
|
||||
// Check if any data
|
||||
if (!BufSize || !Data || !MaxLen || (PeekPos < 0) || (PeekPos > BufLen)) {
|
||||
if (*Data) (*Data)[0] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate bytes to return
|
||||
if ((MaxLen == -1) || (MaxLen > BufSize)) {
|
||||
MaxLen = BufSize;
|
||||
}
|
||||
BytesReturned = (MaxLen > BufLen - PeekPos)? (BufLen - PeekPos) : MaxLen;
|
||||
|
||||
// Allocate memory
|
||||
if (!*Data)
|
||||
*Data = (char*)malloc( BytesReturned + 1 );
|
||||
|
||||
// Copy Data from Buffer
|
||||
memcpy( *Data, &Buffer[StartPos], BytesReturned );
|
||||
(*Data)[BytesReturned] = 0;
|
||||
|
||||
return BytesReturned;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Look for first occurrence of character in buffer
|
||||
bool CShiftBuffer::FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int StartPos )
|
||||
{
|
||||
char * CheckPos = NULL;
|
||||
char * CheckLimit = NULL;
|
||||
char * MatchPos = NULL;
|
||||
char * MatchLimit = NULL;
|
||||
|
||||
// Check if buffer exists
|
||||
if (!BufSize || !SearchStr || !SearchLen) {
|
||||
FoundPos = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Validate start Pos
|
||||
if (StartPos >= BufLen) {
|
||||
FoundPos = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get Search start point and limit
|
||||
CheckPos = &Buffer[StartPos];
|
||||
CheckLimit = &Buffer[BufLen-1];
|
||||
|
||||
// Set Match start point and limit
|
||||
MatchPos = (char*)SearchStr;
|
||||
MatchLimit = (char*)&SearchStr[SearchLen-1];
|
||||
|
||||
// Search for char
|
||||
FoundPos = StartPos;
|
||||
while (FoundPos < BufLen)
|
||||
{
|
||||
// Check if char match
|
||||
if (*CheckPos == *MatchPos) {
|
||||
if (MatchPos == MatchLimit) {
|
||||
// Full match found
|
||||
FoundPos -= SearchLen-1;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// Next char to match
|
||||
MatchPos++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Reset match point
|
||||
MatchPos = (char*)SearchStr;
|
||||
}
|
||||
|
||||
// Next char
|
||||
FoundPos++;
|
||||
if (CheckPos == CheckLimit) {
|
||||
break;
|
||||
} else {
|
||||
CheckPos++;
|
||||
}
|
||||
}
|
||||
|
||||
// Not Found
|
||||
FoundPos = -1;
|
||||
return false;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Remove data from start of buffer
|
||||
int CShiftBuffer::Clear( int ClearLen )
|
||||
{
|
||||
int BytesCleared;
|
||||
|
||||
// Validate ClearLen
|
||||
if ((ClearLen == -1) || (ClearLen >= BufLen))
|
||||
{
|
||||
// Clear all data
|
||||
BufLen = 0;
|
||||
Buffer[0] = 0;
|
||||
BytesCleared = BufLen;
|
||||
}
|
||||
else {
|
||||
// Shift remaining data
|
||||
memmove( Buffer, &Buffer[ClearLen], BufLen-ClearLen ); // Shift remaining old data left
|
||||
BufLen -= ClearLen;
|
||||
Buffer[BufLen] = 0;
|
||||
BytesCleared = ClearLen;
|
||||
}
|
||||
|
||||
return BytesCleared;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Add bytes to end of buffer
|
||||
// Option to overwrite existing data if longer than buffer length
|
||||
int CShiftBuffer::Push( bool Overwrite, const char * Data, int Len )
|
||||
{
|
||||
int BytesPushed = 0;
|
||||
int BufRemain = 0;
|
||||
|
||||
// Validate Buffer and Len
|
||||
if (!BufSize || !Data || !Len) {
|
||||
return 0;
|
||||
}
|
||||
else if (Len == -1) {
|
||||
Len = strlen( Data );
|
||||
}
|
||||
|
||||
// Copy Data to buffer
|
||||
BufRemain = BufSize - BufLen;
|
||||
if (Overwrite && (Len > BufRemain))
|
||||
{
|
||||
if (Len < BufSize) {
|
||||
memcpy( Buffer, &Buffer[Len-BufRemain], BufLen-(Len-BufRemain) ); // Shift remaining old data left
|
||||
memcpy( &Buffer[BufSize-Len], Data, Len ); // Copy new data
|
||||
BytesPushed = Len;
|
||||
}
|
||||
else {
|
||||
memcpy( Buffer, &Data[Len-BufSize], BufSize ); // Copy last portion of new data
|
||||
BytesPushed = Len;
|
||||
}
|
||||
|
||||
// Update Pointers
|
||||
BufLen = BufSize;
|
||||
Buffer[BufLen] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Copy first portion of new data to buffer
|
||||
BytesPushed = (Len > BufRemain)? BufRemain : Len;
|
||||
memcpy( &Buffer[BufLen], Data, BytesPushed );
|
||||
|
||||
// Update Buffer Pointers
|
||||
BufLen += BytesPushed;
|
||||
Buffer[BufLen] = 0;
|
||||
}
|
||||
|
||||
return BytesPushed;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Read File descriptor directly into buffer
|
||||
int CShiftBuffer::ReadFromFD( int Handle, int MaxRead, bool Overwrite )
|
||||
{
|
||||
int BytesRead = 0;
|
||||
int TotalRead = 0;
|
||||
int DataRemain = 0;
|
||||
|
||||
// Check if buffer created
|
||||
if (!BufSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read file descriptor into buffer
|
||||
if (MaxRead == -1)
|
||||
MaxRead = BufSize;
|
||||
DataRemain = ((!Overwrite && (MaxRead > BufSize-BufLen)))? BufSize-BufLen : MaxRead;
|
||||
while (DataRemain)
|
||||
{
|
||||
// Read from file descriptor
|
||||
BytesRead = read( Handle, &Buffer[BufLen], DataRemain );
|
||||
if (BytesRead <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Update Buffer Pointers
|
||||
DataRemain -= BytesRead;
|
||||
TotalRead += BytesRead;
|
||||
BufLen += BytesRead;
|
||||
|
||||
// Zero terminate
|
||||
Buffer[BufLen] = 0;
|
||||
}
|
||||
return TotalRead;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Write given number of bytes directly from buffer to File descriptor
|
||||
int CShiftBuffer::WriteToFD( int Handle, int MaxLen )
|
||||
{
|
||||
int BytesWritten = 0;
|
||||
int TotalWritten = 0;
|
||||
int BufRemain = 0;
|
||||
int DataRemain = 0;
|
||||
int ReadPos = 0;
|
||||
|
||||
// Check if buffer created
|
||||
if (!BufSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Read Data into buffer
|
||||
ReadPos = 0;
|
||||
DataRemain = ((MaxLen == -1) || (MaxLen > BufLen))? BufLen : MaxLen;
|
||||
while (DataRemain)
|
||||
{
|
||||
// Read from file descriptor
|
||||
BufRemain = BufSize - ReadPos;
|
||||
BytesWritten = write( Handle, &Buffer[ReadPos], ((BufRemain > DataRemain)? DataRemain : BufRemain) );
|
||||
if (BytesWritten <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Update Data Pointers
|
||||
TotalWritten += BytesWritten;
|
||||
DataRemain -= BytesWritten;
|
||||
|
||||
// Update Buffer Pointers
|
||||
ReadPos += BytesWritten;
|
||||
if (ReadPos >= BufSize) {
|
||||
ReadPos = 0; // Rolling over end of buffer, start at beginning
|
||||
}
|
||||
}
|
||||
|
||||
return TotalWritten;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user