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