const void* StreamBuffer::peek(UInt32 n) { assert(n <= m_size); // if requesting no data then return NULL so we don't try to access // an empty list. if (n == 0) { return NULL; } // reserve space in first chunk ChunkList::iterator head = m_chunks.begin(); head->reserve(n + m_headUsed); // consolidate chunks into the first chunk until it has n bytes ChunkList::iterator scan = head; ++scan; while (head->size() - m_headUsed < n && scan != m_chunks.end()) { head->insert(head->end(), scan->begin(), scan->end()); scan = m_chunks.erase(scan); } return reinterpret_cast<const void*>(&(head->begin()[m_headUsed])); }
void StreamBuffer::write(const void* vdata, UInt32 n) { assert(vdata != NULL); // ignore if no data, otherwise update size if (n == 0) { return; } m_size += n; // cast data to bytes const UInt8* data = reinterpret_cast<const UInt8*>(vdata); // point to last chunk if it has space, otherwise append an empty chunk ChunkList::iterator scan = m_chunks.end(); if (scan != m_chunks.begin()) { --scan; if (scan->size() >= kChunkSize) { ++scan; } } if (scan == m_chunks.end()) { scan = m_chunks.insert(scan, Chunk()); } // append data in chunks while (n > 0) { // choose number of bytes for next chunk assert(scan->size() <= kChunkSize); UInt32 count = kChunkSize - (UInt32)scan->size(); if (count > n) count = n; // transfer data scan->insert(scan->end(), data, data + count); n -= count; data += count; // append another empty chunk if we're not done yet if (n > 0) { ++scan; scan = m_chunks.insert(scan, Chunk()); } } }