//header file namespace odbclib { class MemoryBlock { public: typedef unsigned char byte; explicit MemoryBlock(size_t = 0xff) throw(runtime_error); MemoryBlock(MemoryBlock const&) throw(runtime_error); virtual ~MemoryBlock(); MemoryBlock& initBlock(byte); void const* getRawBlock() const; void* getRawBlock(); void writeRawBlock(void const*,size_t); size_t getSize()const; MemoryBlock& setSize(size_t) throw(runtime_error); template<typename T> T getValue() const { //TODO:may cross memory boundary T *p = (T *)m_buffer; return *p; } template<typename T> MemoryBlock& setValue(T const& t) { initBlock(0); memcpy(m_buffer,(void const*)&t,min(sizeof(T),m_size)); return *this; } template<typename T,size_t N> MemoryBlock& setValue(T const (&t)[N]) { T * p = (T *)m_buffer; T * end = (T *)((byte*)m_buffer + m_size); int i = 0; initBlock(0); while(end - p > 0) memcpy(p++,&t[i++],sizeof(T)); return *this; } private: void * m_buffer; size_t m_size; }; template<> string MemoryBlock::getValue()const; template<> MemoryBlock& MemoryBlock::setValue<string>(string const&); }
//source file namespace odbclib { MemoryBlock::MemoryBlock(size_t sz) throw(runtime_error) :m_buffer(0), m_size(0) { m_buffer = (byte*)::malloc(sz); if(!m_buffer) throw runtime_error("malloc failed!"); m_size = sz; } MemoryBlock::MemoryBlock(MemoryBlock const& other) throw(runtime_error) :m_buffer(0), m_size(0) { m_buffer = (byte*)::malloc(other.m_size); if(!m_buffer) throw runtime_error("malloc failed!"); m_size = other.m_size; memcpy(m_buffer,(void*)other.m_buffer,m_size); } MemoryBlock::~MemoryBlock() { ::free(m_buffer); m_buffer = (void*)0; m_size = 0u; } void const* MemoryBlock::getRawBlock() const{return (void*)m_buffer;} void* MemoryBlock::getRawBlock(){return (void*)m_buffer;} void MemoryBlock::writeRawBlock(void const* mem,size_t memsz) { memcpy(m_buffer,mem,min(memsz,m_size)); } size_t MemoryBlock::getSize()const{return m_size;} MemoryBlock& MemoryBlock::setSize(size_t sz) throw(runtime_error) { byte* newAddr = (byte*)::realloc(m_buffer,sz); if(!newAddr) throw runtime_error("realloc failed!"); m_buffer = newAddr; m_size = sz; return *this; } MemoryBlock& MemoryBlock::initBlock(byte data) { memset(m_buffer,data,m_size); return *this; } template<> string MemoryBlock::getValue()const { byte *lastByte = (byte*)m_buffer + m_size - 1; byte data = *lastByte; *lastByte = byte(0); string s((char const*)m_buffer); *lastByte = data; return s; } template<> MemoryBlock& MemoryBlock::setValue<string>(string const& s) { initBlock(0); memcpy(m_buffer,s.data(),min(s.size(),m_size)); *((byte*)m_buffer + m_size - 1) = byte(0); return *this; } }
通过 vc 2010 , g++ 4.5.2