#include "UtilityCommon.h" #include "RingBufferEx.h" namespace util { RingBufferEx::RingBufferEx(int bufferSize) : m_pBuffer(NULL), m_BufferSize(bufferSize), m_Head(0), m_Tail(0) { assert( bufferSize >= 0 ); if (bufferSize > 0) { Init( bufferSize ); } } RingBufferEx::~RingBufferEx() { Release(); } void RingBufferEx::Init( int bufferSize ) { assert( bufferSize > 0 ); assert( m_pBuffer==NULL ); m_pBuffer = new BYTE [bufferSize]; m_BufferSize = bufferSize; m_Head = 0; m_Tail = 0; } void RingBufferEx::Release() { SAFE_DELETE_ARRAY( m_pBuffer ); m_BufferSize = 0; m_Head = 0; m_Tail = 0; } void RingBufferEx::Recycle() { m_Head = 0; m_Tail = 0; } // ³»ºÎ ¹öÆÛ¿¡´Ù°¡ pBuffer¸¦ memcpy int RingBufferEx::Write( const BYTE * pBuffer, int len ) { // TailµÚ¿¡´Ù°¡ pBuffer¸¦ len¸¸Å­ Ãß°¡ÇØ¾ß Çϴµ¥.. // ÀÏ´Ü.. buffer°¡ ºÎÁ·ÇÏ¸é ³¶ÆÐ! if ( GetFreeSize() < len ) { // HooooooooooooT // oooooooTHooooo return -1; } if (m_Head <= m_Tail) { // ......HT...... // ....HooooT.... // tail µÚÂÊÀ» ¾²°í.. int rightFreeSize = m_BufferSize - m_Tail; // 0¹øÂ° ÀÚ¸®°¡ ºñ¾îÀÖÀ¸¹Ç·Î ³¡±îÁö ä¿öµµ µÈ´Ù.(tail -1 ¾ÈÇØÁ൵ µÈ´Ù.) int writeLen = min( rightFreeSize, len ); memcpy( m_pBuffer+m_Tail, pBuffer, writeLen ); m_Tail = ( m_Tail + writeLen ) % m_BufferSize; // ¾µ°Ô ³²¾ÒÀ¸¸é ¾ÕÂʺÎÅÍ ¾´´Ù. int remainLen = len - writeLen; if (remainLen > 0) { assert( m_Tail == 0 ); // ¾µ°Ô ³²Àº °æ¿ì´Â tailÀº 0ÀÌ µÈ´Ù. memcpy( m_pBuffer, pBuffer+writeLen, remainLen ); m_Tail = remainLen; } } else { // T............H // T........Hoooo // ooooT........H // ooooT....Hoooo // HoooooooooT... // FreeSize´Â üũÇßÀ¸¹Ç·Î tailºÎÅÍ ¸¾²¯ ¾²¸é µÈ´Ù. memcpy( m_pBuffer+m_Tail, pBuffer, len ); m_Tail += len; } return len; } // ³»ºÎ ¹öÆÛ¿¡¼­ pBuffer·Î memcpy int RingBufferEx::Read( BYTE * pBuffer, int len ) { if ( GetDataSize() < len ) { // lenÀÌ Å©¸é ¾Æ¿¹ ½ÇÆÐ·Î ó¸®ÇÑ´Ù. return -1; } if (m_Head < m_Tail) { // HooooooooooooT // ......HT...... // ....HooooT.... // HoooooooooT... // dataSize´Â À§¿¡¼­ üũÇßÀ¸¹Ç·Î ÃæºÐÇÏ´Ù. memcpy( pBuffer, m_pBuffer+m_Head, len ); m_Head += len; } else { // oooooooTHooooo // T............H // T........Hoooo // ooooT........H // ooooT....Hoooo // headºÎÅÍ ³¡±îÁö? int writeLen = min( len, m_BufferSize-m_Head ); memcpy( pBuffer, m_pBuffer+m_Head, writeLen ); m_Head = (m_Head + writeLen) % m_BufferSize; // ¾ÆÁ÷ ´õ ½á¾ßµÇ¸é ¾ÕÂʺÎÅÍ ¾´´Ù. int remainLen = len - writeLen; if (remainLen > 0) { assert( m_Head == 0 ); memcpy( pBuffer+writeLen, m_pBuffer, remainLen ); m_Head += remainLen; } } return len; } // ³»ºÎ ¹öÆÛ¿¡¼­ pBuffer·Î memcpy, ´Ü ³»ºÎ head, tailÀº º¯È­ÇÏÁö ¾Ê´Â´Ù. int RingBufferEx::Peek( BYTE * pBuffer, int len ) { if ( GetDataSize() < len ) { // lenÀÌ Å©¸é ¾Æ¿¹ ½ÇÆÐ·Î ó¸®ÇÑ´Ù. return -1; } if (m_Head < m_Tail) { // HooooooooooooT // ......HT...... // ....HooooT.... // HoooooooooT... // dataSize´Â À§¿¡¼­ üũÇßÀ¸¹Ç·Î ÃæºÐÇÏ´Ù. memcpy( pBuffer, m_pBuffer+m_Head, len ); } else { // oooooooTHooooo // T............H // T........Hoooo // ooooT........H // ooooT....Hoooo // headºÎÅÍ ³¡±îÁö? int writeLen = min( len, m_BufferSize-m_Head ); memcpy( pBuffer, m_pBuffer+m_Head, writeLen ); // ¾ÆÁ÷ ´õ ½á¾ßµÇ¸é ¾ÕÂʺÎÅÍ ¾´´Ù. int remainLen = len - writeLen; if (remainLen > 0) { memcpy( pBuffer+writeLen, m_pBuffer, remainLen ); } } return len; } // head, tailÀÇ À§Ä¡¸¸ À̵¿½ÃŲ´Ù. int RingBufferEx::Skip( int len ) { if ( GetDataSize() < len ) { // lenÀÌ Å©¸é ¾Æ¿¹ ½ÇÆÐ·Î ó¸®ÇÑ´Ù. return -1; } m_Head = (m_Head + len) % m_BufferSize; return len; } BYTE * RingBufferEx::GetContigousPtr(OUT int & size) const { if (m_Head <= m_Tail) { size = m_Tail - m_Head; return (m_pBuffer+m_Head); } else { size = m_BufferSize-m_Head; return (m_pBuffer+m_Head); } } }