00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "CStreamBuffer.h"
00016
00017
00018
00019
00020
00021 const UInt32 CStreamBuffer::kChunkSize = 4096;
00022
00023 CStreamBuffer::CStreamBuffer() :
00024 m_size(0),
00025 m_headUsed(0)
00026 {
00027
00028 }
00029
00030 CStreamBuffer::~CStreamBuffer()
00031 {
00032
00033 }
00034
00035 const void*
00036 CStreamBuffer::peek(UInt32 n)
00037 {
00038 assert(n <= m_size);
00039
00040
00041
00042 if (n == 0) {
00043 return NULL;
00044 }
00045
00046
00047 ChunkList::iterator head = m_chunks.begin();
00048 head->reserve(n + m_headUsed);
00049
00050
00051 ChunkList::iterator scan = head;
00052 ++scan;
00053 while (head->size() - m_headUsed < n && scan != m_chunks.end()) {
00054 head->insert(head->end(), scan->begin(), scan->end());
00055 scan = m_chunks.erase(scan);
00056 }
00057
00058 return reinterpret_cast<const void*>(&(head->begin()[m_headUsed]));
00059 }
00060
00061 void
00062 CStreamBuffer::pop(UInt32 n)
00063 {
00064
00065 if (n >= m_size) {
00066 m_size = 0;
00067 m_headUsed = 0;
00068 m_chunks.clear();
00069 return;
00070 }
00071
00072
00073 m_size -= n;
00074
00075
00076 ChunkList::iterator scan = m_chunks.begin();
00077 assert(scan != m_chunks.end());
00078 while (scan->size() - m_headUsed <= n) {
00079 n -= scan->size() - m_headUsed;
00080 m_headUsed = 0;
00081 scan = m_chunks.erase(scan);
00082 assert(scan != m_chunks.end());
00083 }
00084
00085
00086 if (n > 0) {
00087 m_headUsed += n;
00088 }
00089 }
00090
00091 void
00092 CStreamBuffer::write(const void* vdata, UInt32 n)
00093 {
00094 assert(vdata != NULL);
00095
00096
00097 if (n == 0) {
00098 return;
00099 }
00100 m_size += n;
00101
00102
00103 const UInt8* data = reinterpret_cast<const UInt8*>(vdata);
00104
00105
00106 ChunkList::iterator scan = m_chunks.end();
00107 if (scan != m_chunks.begin()) {
00108 --scan;
00109 if (scan->size() >= kChunkSize) {
00110 ++scan;
00111 }
00112 }
00113 if (scan == m_chunks.end()) {
00114 scan = m_chunks.insert(scan, Chunk());
00115 }
00116
00117
00118 while (n > 0) {
00119
00120 assert(scan->size() <= kChunkSize);
00121 UInt32 count = kChunkSize - scan->size();
00122 if (count > n)
00123 count = n;
00124
00125
00126 scan->insert(scan->end(), data, data + count);
00127 n -= count;
00128 data += count;
00129
00130
00131 if (n > 0) {
00132 ++scan;
00133 scan = m_chunks.insert(scan, Chunk());
00134 }
00135 }
00136 }
00137
00138 UInt32
00139 CStreamBuffer::getSize() const
00140 {
00141 return m_size;
00142 }