diff --git a/BufferCore.cpp b/BufferCore.cpp index 3f4eb68..e1bfb4f 100644 --- a/BufferCore.cpp +++ b/BufferCore.cpp @@ -17,14 +17,20 @@ //--------------------------------------------------------------------------- -CBuffer::CBuffer( int BufferSize ) : BufSize( BufferSize ) +/***** Rolling Buffer *****/ + +CRollingBuffer::CRollingBuffer( int BufferSize ) : BufSize( BufferSize ) { // Create Buffer - if (BufSize) { + if (BufSize) + { + // Create Buffer Buffer = (char *)malloc( BufSize+1 ); OutBuffer = (char *)malloc( BufSize+1 ); + OutBuffer[0] = 0; } else { + // No buffers created Buffer = NULL; OutBuffer = NULL; } @@ -36,7 +42,7 @@ CBuffer::CBuffer( int BufferSize ) : BufSize( BufferSize ) } //--------------------------------------------------------------------------- -CBuffer::~CBuffer() +CRollingBuffer::~CRollingBuffer() { // Destroy Buffer if (Buffer) { @@ -48,51 +54,92 @@ CBuffer::~CBuffer() } //--------------------------------------------------------------------------- -// Over write existing buffer with new data -int CBuffer::Set( const char * Data, int Len ) +// Clear all data from buffer +int CRollingBuffer::Reset() { - // Validate data - if (!Data || !Len) { - return 0; - } - else if (Len == -1) { - Len = strlen( Data ); - } + int BytesCleared = 0; - if (Len <= BufSize) { - memcpy( Buffer, Data, Len ); - BufStart = 0; - BufEnd = Len; - BufLen = Len; - } - else { - memcpy( Buffer, &Data[Len-BufSize], BufSize ); - BufStart = 0; - BufEnd = 0; - BufLen = BufSize; - } - return BufLen; + // Clear buffer + BytesCleared = BufLen; + + // Reset pointers + BufStart = 0; + BufEnd = 0; + BufLen = 0; + + return BytesCleared; } //--------------------------------------------------------------------------- -// Return "stitched" buffer data in temporary buffer -int CBuffer::Peek( char ** Data, int PeekPos, int MaxLen ) +// Return specific character for current rolling data +char CRollingBuffer::PeekChar( int Pos ) +{ + char CharValue = 0; + + // Validate buffer and Pos + if (!BufLen || (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; - // Check if any data - if (!BufLen || !MaxLen) { + // Validate + if (!BufLen || !Data || (PeekPos >= BufLen)) { *Data = NULL; return 0; } - // Validate start position - if (PeekPos >= BufLen) { + // 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 (!BufLen || !*Data || !MaxLen || (PeekPos < 0) || (PeekPos > BufLen)) { *Data = NULL; return 0; } - else if (BufStart + StartPos < BufSize) { + + // Get buffer start position + if (BufStart + StartPos < BufSize) { StartPos = BufStart + PeekPos; } else { @@ -113,6 +160,8 @@ int CBuffer::Peek( char ** Data, int PeekPos, int MaxLen ) 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 @@ -122,25 +171,20 @@ int CBuffer::Peek( char ** Data, int PeekPos, int MaxLen ) //--------------------------------------------------------------------------- // Return "stitched" buffer data in temporary buffer -int CBuffer::PeekCopy( char ** Data, int PeekPos, int MaxLen ) +// 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 (!BufLen || !MaxLen) { - if (*Data) - (*Data)[0] = 0; + if (!BufLen || !*Data || !MaxLen || (PeekPos < 0) || (PeekPos > BufLen)) { + if (*Data) (*Data)[0] = 0; return 0; } - // Validate start position - if (PeekPos >= BufLen) { - if (*Data) - (*Data)[0] = 0; - return 0; - } - else if (BufStart + StartPos < BufSize) { + // Get start position + if (BufStart + StartPos < BufSize) { StartPos = BufStart + PeekPos; } else { @@ -171,7 +215,72 @@ int CBuffer::PeekCopy( char ** Data, int PeekPos, int MaxLen ) } //--------------------------------------------------------------------------- -int CBuffer::Clear( int ClearLen ) +// 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 (!BufLen || !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; + 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; @@ -193,40 +302,29 @@ int CBuffer::Clear( int ClearLen ) return BytesCleared; } - -//--------------------------------------------------------------------------- - -int CBuffer::Reset() -{ - int BytesCleared = 0; - - // Clear all data - BytesCleared = BufLen; - BufStart = 0; - BufEnd = 0; - BufLen = 0; - - return BytesCleared; -} //--------------------------------------------------------------------------- // Add bytes to end of buffer -// Return "stitched" buffer data in temporary buffer -int CBuffer::Push( const char * Data, int Len ) +// 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 BytesPushed = 0; + int TotalPushed = 0; int BufRemain = 0; - int DataRemain = Len; + int DataRemain; // Validate Buffer and Len - if (!BufSize || !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 (TotalPushed < Len) { @@ -247,7 +345,7 @@ int CBuffer::Push( const char * Data, int Len ) BufEnd = 0; } if (BufLen > BufSize) { - // Head is caught up with tail, move tail up + // Head has caught up with tail, move tail up BufLen = BufSize; BufStart = BufEnd; } @@ -259,14 +357,12 @@ int CBuffer::Push( const char * Data, int Len ) // Read first-in bytes from buffer // Return "stitched" buffer data in temporary buffer -int CBuffer::Pop( char ** Data, int MaxLen ) +int CRollingBuffer::Pop( char ** Data, int MaxLen ) { int BytesWritten = 0; - // Read data + // Read & clear data BytesWritten = Peek( Data, MaxLen ); - - // Clear bytes Clear( BytesWritten ); // Return temp buffer @@ -275,15 +371,13 @@ int CBuffer::Pop( char ** Data, int MaxLen ) //--------------------------------------------------------------------------- // Read first-in bytes from buffer -// Return "stitched" buffer data in temporary buffer -int CBuffer::PopCopy( char ** Data, int MaxLen ) +// Return "stitched" buffer data copied to pointer which if created if NULL +int CRollingBuffer::PopCopy( char ** Data, int MaxLen ) { int BytesWritten = 0; - // Read data + // Copy & clear data BytesWritten = PeekCopy( Data, MaxLen ); - - // Clear bytes Clear( BytesWritten ); // Return temp buffer @@ -292,7 +386,7 @@ int CBuffer::PopCopy( char ** Data, int MaxLen ) //--------------------------------------------------------------------------- // Read File descriptor directly into rolling buffer -int CBuffer::ReadFromFD( int Handle, int MaxRead ) +int CRollingBuffer::ReadFromFD( int Handle, int MaxRead, bool Overwrite ) { int BytesRead = 0; int TotalRead = 0; @@ -305,7 +399,12 @@ int CBuffer::ReadFromFD( int Handle, int MaxRead ) } // Read file descriptor into buffer - DataRemain = (MaxRead == -1)? BufSize : MaxRead; + if (Overwrite && (MaxRead > BufLen)) { + DataRemain = MaxRead; + } + else { + DataRemain = BufLen; + } while (DataRemain) { // Read from file descriptor @@ -335,7 +434,7 @@ int CBuffer::ReadFromFD( int Handle, int MaxRead ) //--------------------------------------------------------------------------- // Write given number of bytes directly from buffer to File descriptor -int CBuffer::WriteToFD( int Handle, int MaxLen ) +int CRollingBuffer::WriteToFD( int Handle, int MaxLen ) { int BytesWritten = 0; int TotalWritten = 0; @@ -375,37 +474,146 @@ int CBuffer::WriteToFD( int Handle, int MaxLen ) } //--------------------------------------------------------------------------- -// Return specific character for current rolling data -char CBuffer::PeekChar( int Pos, bool ClearChar ) -{ - char CharValue = 0; +/***** Shifting Buffer *****/ + +CShiftBuffer::CShiftBuffer( int BufferSize ) : BufSize( BufferSize ) +{ + // Create Buffer + if (BufSize) + { + // Create Buffer + Buffer = (char *)malloc( BufSize+1 ); + Buffer[0] = 0; + + OutBuffer = (char *)malloc( BufSize+1 ); + } + else { + // No buffers created + Buffer = NULL; + OutBuffer = NULL; + } + + // Set vars + BufLen = 0; +} +//--------------------------------------------------------------------------- + +CShiftBuffer::~CShiftBuffer() +{ + // Destroy Buffer + if (Buffer) { + free( Buffer ); + } + if (OutBuffer) { + free( OutBuffer ); + } +} +//--------------------------------------------------------------------------- + +// Clear all data from buffer +int CShiftBuffer::Reset() +{ + int BytesCleared = 0; + + // Reset buffer + BytesCleared = BufLen; + BufLen = 0; + Buffer[0] = 0; + + return BytesCleared; +} +//--------------------------------------------------------------------------- + +// Return specific character for current rolling data +char CShiftBuffer::PeekChar( int Pos ) +{ // Validate buffer and Pos - if (!BufLen) { + if (!BufLen || (Pos < 0) || (Pos > BufLen)) { return 0; } - // Get char - if (BufStart + Pos < BufSize) { - CharValue = Buffer[ BufStart+Pos ]; - } - else { - CharValue = Buffer[ BufStart+Pos-BufSize ]; - } - - // Clear Char - if (ClearChar && (Pos == 0)) { - BufStart++; - BufLen--; - } - // Return char - return CharValue; + return Buffer[Pos]; +} +//--------------------------------------------------------------------------- + +// Return pointer direct to buffer +// Return number of contiguous chars (cannot rollover) +int CShiftBuffer::PeekDirect( char ** Data, int PeekPos ) +{ + // Validate + if (!BufLen || !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 (!BufLen || !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, 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 (!BufLen || !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 CBuffer::FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int StartPos ) +bool CShiftBuffer::FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int StartPos ) { char * CheckPos = NULL; char * CheckLimit = NULL; @@ -425,8 +633,8 @@ bool CBuffer::FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int } // Get Search start point and limit - CheckPos = (BufStart + StartPos < BufSize)? &Buffer[ BufStart+StartPos ] : &Buffer[ (BufStart+StartPos)-BufSize ]; - CheckLimit = &Buffer[BufSize-1]; + CheckPos = &Buffer[StartPos]; + CheckLimit = &Buffer[BufLen-1]; // Set Match start point and limit MatchPos = (char*)SearchStr; @@ -438,12 +646,15 @@ bool CBuffer::FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int { // Check if char match if (*CheckPos == *MatchPos) { - if (MatchPos == MatchLimit) + if (MatchPos == MatchLimit) { // Full match found + FoundPos -= SearchLen; return true; - else + } + else { // Next char to match MatchPos++; + } } else { // Reset match point @@ -453,7 +664,7 @@ bool CBuffer::FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int // Next char FoundPos++; if (CheckPos == CheckLimit) { - CheckPos = Buffer; // Roll-over, Start at beginning of buffer + break; } else { CheckPos++; } @@ -464,3 +675,179 @@ bool CBuffer::FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int 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 + BytesCleared = BufLen; + BufLen = 0; + Buffer[0] = 0; + } + else { + // Shift remaining data + BytesCleared = ClearLen; + memcpy( Buffer, &Buffer[ClearLen], BufLen-ClearLen ); // Shift remaining old data left + BufLen -= ClearLen; + Buffer[BufLen] = 0; + } + + 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 first-in bytes from buffer +// Return "stitched" buffer data in temporary buffer +int CShiftBuffer::Pop( char ** Data, int MaxLen ) +{ + int BytesWritten = 0; + + // Read and clear bytes + BytesWritten = Peek( Data, MaxLen ); + Clear( BytesWritten ); + + return BytesWritten; +} +//--------------------------------------------------------------------------- + +// Read first-in bytes from buffer +// Return "stitched" buffer data copied to pointer which if created if NULL +int CShiftBuffer::PopCopy( char ** Data, int MaxLen ) +{ + int BytesWritten = 0; + + // Copy and clear bytes + BytesWritten = PeekCopy( Data, MaxLen ); + Clear( BytesWritten ); + + // Return temp buffer + return BytesWritten; +} +//--------------------------------------------------------------------------- + +// Read File descriptor directly into buffer +int CShiftBuffer::ReadFromFD( int Handle, int MaxRead ) +{ + int BytesRead = 0; + int TotalRead = 0; + int DataRemain = 0; + + // Check if buffer created + if (!BufSize) { + return 0; + } + + // Read file descriptor into buffer + DataRemain = (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; + } + 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; +} +//--------------------------------------------------------------------------- + + diff --git a/BufferCore.h b/BufferCore.h index 70800b2..c8415a5 100644 --- a/BufferCore.h +++ b/BufferCore.h @@ -16,51 +16,115 @@ //--------------------------------------------------------------------------- -class CBuffer +/** Shift and Rolling buffer class + * + * Shifting buffer: + * Data is either set at start of buffer or appended to buffer + * Start of buffered data is always at beginning of buffer + * Never rolls over (option to over overwrite if data longer than buffer) + * Shifts unsused data to left when clearing used data + * Always zero terminates buffer + * Can look directly at buffer + * + * Rolling buffer: + * Data is continuosly assigned to buffer + * Start of buffer is tracked by references (can be anywhere) + * Data rolls over to start of buffer if end of buffer reached (option to overwrite start) + * Data is never shifted/moved inside buffer, only references are adjusted + * Never zero terminates buffer + * Can only look at data by copying (stitching) to another buffer + */ + +class CRollingBuffer { private: // Buffer Definition - char * Buffer; // Memory allocated to buffer - const int BufSize; // Size of allocated buffer + char * Buffer; // Memory allocated to buffer + const int BufSize; // Size of allocated buffer + int BufLen; // Total unread characters in buffer + + // Temporary output buffer + char * OutBuffer; // Temporary output buffer for "stitched" (rollover) data // Buffer pointers - int BufStart; // First unread characters on buffer + int BufStart; // First unread characters in buffer int BufEnd; // Next write position for new data (End of unread data + 1) - int BufLen; // Total unread characters on buffer + +public: + // Life Cycle + CRollingBuffer( int BufferSize ); + virtual ~CRollingBuffer(); + + // Direct Operations + int Reset(); // Clear buffer and reset all pointers to start of buffer + + // Reading from buffer + char PeekChar( int Pos = 0 ); // Return one character from buffer (do not remove from buffer + int PeekDirect( char ** Data, int PeekPos = 0 ); // Return contiguous data pointer direct to buffer (continguous data couont returned) + int Peek( char ** Data, int PeekPos = 0, int MaxLen = -1 ); // Return stiched data copied to temporary output buffer + int PeekCopy( char ** Data, int PeekPos = 0, int MaxLen = -1 ); // Return stiched data copied to supplied pointer (create if not exist) + + bool FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int StartPos = 0 ); // Search buffer directly + + // Change data on buffer + virtual int Push( bool Overwrite, const char * Data, int Len = -1 ); + virtual int Clear( int ClearLen = -1 ); + + virtual int Pop( char ** Data, int MaxLen = -1 ); + virtual int PopCopy( char ** Data, int MaxLen = -1 ); + + // File operations + virtual int ReadFromFD( int Handle, int MaxRead = -1, bool Overwrite = false ); + virtual int WriteToFD( int Handle, int MaxWrite = -1 ); + + // Miscellaneous + int Size() { return BufSize; }; + int Len() { return BufLen; }; +}; +//--------------------------------------------------------------------------- + +class CShiftBuffer +{ +private: + // Buffer Definition + char * Buffer; // Memory allocated to buffer + const int BufSize; // Size of allocated buffer + int BufLen; // Total unread characters in buffer // Temporary output buffer char * OutBuffer; // Temporary output buffer for "stitched" (rollover) data public: // Life Cycle - CBuffer( int BufferSize ); - ~CBuffer(); + CShiftBuffer( int BufferSize ); + virtual ~CShiftBuffer(); // Direct Operations - int Reset(); - int Set( const char * Data, int Len = -1 ); - int Peek( char ** Data, int PeekPos = 0, int MaxLen = -1 ); - int PeekCopy( char ** Data, int PeekPos = 0, int MaxLen = -1 ); - int Clear( int ClearLen = -1 ); + int Reset(); // Clear buffer and reset all pointers to start of buffer - // FiFo operations - int Push( const char * Data, int Len = -1 ); - int Pop( char ** Data, int MaxLen = -1 ); - int PopCopy( char ** Data, int MaxLen = -1 ); + // Reading from buffer + char PeekChar( int Pos = 0 ); // Return one character from buffer (do not remove from buffer + int PeekDirect( char ** Data, int PeekPos = 0 ); // Return contiguous data pointer direct to buffer (continguous data couont returned) + int Peek( char ** Data, int PeekPos = 0, int MaxLen = -1 ); // Return stiched data copied to temporary output buffer + int PeekCopy( char ** Data, int PeekPos = 0, int MaxLen = -1 ); // Return stiched data copied to supplied pointer (create if not exist) + + bool FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int StartPos = 0 ); // Search buffer directly + + // Chagne data on buffer + virtual int Push( bool Overwrite, const char * Data, int Len = -1 ); + virtual int Clear( int ClearLen = -1 ); + + virtual int Pop( char ** Data, int MaxLen = -1 ); + virtual int PopCopy( char ** Data, int MaxLen = -1 ); // File operations - int ReadFromFD( int Handle, int MaxRead = -1 ); - int WriteToFD( int Handle, int MaxWrite = -1 ); - - // Character Operations - char PeekChar( int Pos = 0, bool ClearChar = false ); - bool FindStr( const char * SearchStr, int SearchLen, int &FoundPos, int StartPos = 0 ); + virtual int ReadFromFD( int Handle, int MaxRead = -1 ); + virtual int WriteToFD( int Handle, int MaxWrite = -1 ); // Miscellaneous - inline int Size() { return BufSize; }; - inline int Len() { return BufLen; }; + int Size() { return BufSize; }; + int Len() { return BufLen; }; }; - //--------------------------------------------------------------------------- #endif /* REDACORE_BUFFERCORE_H_ */ diff --git a/SelectableCore.cpp b/SelectableCore.cpp index 6ecef1a..55a6462 100644 --- a/SelectableCore.cpp +++ b/SelectableCore.cpp @@ -299,7 +299,7 @@ bool CSelectableCore::SetBuffers( THandle * Handle, int InBufSize, int OutBufSiz Handle->InBuffer = NULL; } if (InBufSize) { - Handle->InBuffer = new CBuffer( InBufSize ); + Handle->InBuffer = (CRollingBuffer*) new CRollingBuffer( InBufSize ); } // Output Buffer @@ -308,7 +308,7 @@ bool CSelectableCore::SetBuffers( THandle * Handle, int InBufSize, int OutBufSiz Handle->OutBuffer = NULL; } if (OutBufSize) { - Handle->OutBuffer = new CBuffer( OutBufSize ); + Handle->OutBuffer = (CRollingBuffer*) new CRollingBuffer( OutBufSize ); } // Set Input Timeout @@ -1060,7 +1060,7 @@ bool CSelectableCore::ProcessBuffer( THandle * Handle, bool Force ) while (Handle->InBuffer->FindStr( Handle->InMarker, Handle->InMarkerLen, Pos )) { // Show Packet - Len = Handle->InBuffer->Peek( &Data, 0, Pos+1 ); + Len = Handle->InBuffer->Peek( &Data, 0, Pos+Handle->InMarkerLen+1 ); if (Log) Log->Output( DebugLevel, dlHigh, OutputDisplay, Data, Len, "%s: Handle '%s' - IN-M:", Name, Handle->Name ); // Write buffer to Outputs @@ -1181,7 +1181,7 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len if (ChildHandle->OutBuffer) { // Write to buffer - BytesWritten = ChildHandle->OutBuffer->Push( Data, Len ); + BytesWritten = ChildHandle->OutBuffer->Push( true, Data, Len ); // Add to select write list if (BytesWritten) { @@ -1210,7 +1210,7 @@ int CSelectableCore::Input( const char * ChannelName, const char * Data, int Len if (Handle->OutBuffer) { // Write to buffer - BytesWritten = Handle->OutBuffer->Push( Data, Len ); + BytesWritten = Handle->OutBuffer->Push( true, Data, Len ); // Add to select write list if (BytesWritten) { diff --git a/SelectableCore.h b/SelectableCore.h index 49a4e9c..a6451a4 100644 --- a/SelectableCore.h +++ b/SelectableCore.h @@ -92,8 +92,8 @@ struct SHandle { bool KeepAlive; // Socket keep alive // Buffers - CBuffer * InBuffer; - CBuffer * OutBuffer; + CRollingBuffer * InBuffer; + CRollingBuffer * OutBuffer; // Input Markers char * InMarker;