只有一个头文件.
/* CMemoryStream 学过Delphi和BCB的同学懂的. 只要引用这个头文件即可. */ #pragma once #include <Windows.h> enum SEEK_ORIGIN { SO_BEGINNING??? = 0, SO_CURRENT????? = 1, SO_END????????? = 2 }; class CMemoryStream { public: explicit CMemoryStream(int nMemoryDelta = DEFAULT_MEMORY_DELTA):m_nCapacity(0),?? ?m_pMemory(NULL),m_nSize(0),?? ?m_nPosition(0) { SetMemoryDelta(nMemoryDelta); } ~CMemoryStream() { Clear(); } int Seek(int nOffset, SEEK_ORIGIN nSeekOrigin) { switch (nSeekOrigin) { case SO_BEGINNING: m_nPosition = (int)nOffset; break; case SO_CURRENT: m_nPosition += (int)nOffset; break; case SO_END: m_nPosition = m_nSize + (int)nOffset; break; } return m_nPosition; } public: enum { DEFAULT_MEMORY_DELTA = 1024 }; // 默认内存步长 enum { MIN_MEMORY_DELTA = 256 };????? // 最小内存步长 private: char* m_pMemory;????? // 缓冲区指针 int?? m_nSize;??????? // 当前流的大小 int?? m_nPosition;??? // 当前位置 int?? m_nCapacity;??? // 缓冲区大小.真正大大小.包含给未来分配的长度 int?? m_nMemoryDelta; // 增长的步长 private: void? SetPointer(void *pMemory, int nSize) { m_pMemory = (char*)pMemory; m_nSize = nSize; } void? SetMemoryDelta(int nNewMemoryDelta) { if (nNewMemoryDelta != DEFAULT_MEMORY_DELTA) { if (nNewMemoryDelta < MIN_MEMORY_DELTA) nNewMemoryDelta = MIN_MEMORY_DELTA; //? 2^N for (int i = sizeof(int) * 8 - 1; i >= 0; i--) if (((1 << i) & nNewMemoryDelta) != 0) { nNewMemoryDelta &= (1 << i); break; } } m_nMemoryDelta = nNewMemoryDelta; } void? SetCapacity(int nNewCapacity) { SetPointer(Realloc(nNewCapacity), m_nSize); m_nCapacity = nNewCapacity; } char* Realloc(int& nNewCapacity) { char* pResult; if (nNewCapacity > 0 && nNewCapacity != m_nSize) nNewCapacity = (nNewCapacity + (m_nMemoryDelta - 1)) & ~(m_nMemoryDelta - 1); pResult = m_pMemory; if (nNewCapacity != m_nCapacity) { if (nNewCapacity == 0) { free(m_pMemory); pResult = NULL; } else { if (m_nCapacity == 0) pResult = (char*)malloc(nNewCapacity); else pResult = (char*)realloc(m_pMemory, nNewCapacity); } } return pResult; } public: int GetPosition() const { return const_cast<CMemoryStream&>(*this).Seek(0, SO_CURRENT); } void SetPosition(int nPos) { Seek(nPos, SO_BEGINNING); } void* GetMemory() { return m_pMemory; } void* GetCurrentPtr() {return m_pMemory + m_nPosition; } int Read(void *pBuffer, int nCount) { int nResult = 0; if (m_nPosition >= 0 && nCount >= 0) { nResult = m_nSize - m_nPosition; if (nResult > 0) { if (nResult > nCount) nResult = nCount; memmove(pBuffer, m_pMemory + (DWORD)m_nPosition, nResult); m_nPosition += nResult; } } return nResult; } int Write(const void *pBuffer, int nCount) { int nResult = 0; int nPos; if (m_nPosition >= 0 && nCount >= 0) { nPos = m_nPosition + nCount; if (nPos > 0) { if (nPos > m_nSize) { if (nPos > m_nCapacity) SetCapacity(nPos); m_nSize = nPos; } memmove(m_pMemory + (DWORD)m_nPosition, pBuffer, nCount); m_nPosition = nPos; nResult = nCount; } } return nResult; } BOOL ReadBuffer(void *pBuffer, int nCount) { if (nCount != 0 && Read(pBuffer, nCount) != nCount) return FALSE; else return TRUE; } BOOL WriteBuffer(void *pBuffer, int nCount) { if (nCount != 0 && Write(pBuffer, nCount) != nCount) return FALSE; else return TRUE; } int GetSize() const { int nPos, nResult; nPos = const_cast<CMemoryStream&>(*this).Seek(0, SO_CURRENT); nResult = const_cast<CMemoryStream&>(*this).Seek(0, SO_END); const_cast<CMemoryStream&>(*this).Seek(nPos, SO_BEGINNING); return nResult; } void SetSize(int nSize) { int nOldPos = m_nPosition; SetCapacity((int)nSize); m_nSize = (int)nSize; if (nOldPos > nSize) Seek(0, SO_END); } void Clear() { SetCapacity(0); m_nSize = 0; m_nPosition = 0; } void Zero() { m_nSize = 0; m_nPosition = 0; } };