#ifndef MEMORYBLOCK_H
#define MEMORYBLOCK_H
#include "odbclib.h"
#include <cstdlib>
using std::min;
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,bool = true) throw(runtime_error);
template<typename T>
T getValue(size_t offset = 0) const
{
//TODO:may cross memory boundary
T *p = (T *)((byte*)m_buffer + offset);
return *p;
}
template<typename T>
MemoryBlock& setValue(T const& t,size_t offset = 0)
{
memcpy((byte*)m_buffer + offset,(void const*)&t,min(sizeof(T),m_size));
return *this;
}
template<typename T,size_t N>
MemoryBlock& setValue(T const (&t)[N],size_t offset = 0)
{
T * p = (T *)((byte*)m_buffer + offset);
T * end = (T *)((byte*)m_buffer + m_size);
int i = 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(size_t)const;
template<> MemoryBlock& MemoryBlock::setValue<string>(string const&,size_t);
}
#endif
#include "odbclib.h"
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,bool preserve) throw(runtime_error)
{
byte* newAddr = (byte*)::realloc(m_buffer,sz);
if(!newAddr)
throw runtime_error("realloc failed!");
if((void*)newAddr != m_buffer && preserve)
memcpy(newAddr,m_buffer,sz < m_size ? sz : m_size);
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(size_t offset)const
{
byte *lastByte = (byte*)m_buffer + m_size - 1;
byte data = *lastByte;
*lastByte = byte(0);
string s((char const*)((byte*)m_buffer + offset));
*lastByte = data;
return s;
}
template<>
MemoryBlock& MemoryBlock::setValue<string>(string const& s,size_t offset)
{
long len;
if((len = m_size - offset - 1) < 0)
return *this;
len = std::min<long>(s.size(),len);
memcpy((byte*)m_buffer + offset,s.data(),len);
*((byte*)m_buffer + offset + len) = byte(0);
return *this;
}
}
给getValue,setValue添加了默认参数 ,表示从第几个字节开始提取数据,值得注意的是 在头文件中声明类成员模板特化版本的时候并没有写上默认参数的值
分享到:
相关推荐
例如下面的类模板A,只有在模板参数是char*时才需要特化成员函数func(),但其他的成员函数都不需要特化: 1 template 2 struct A 3 { 4 // 其他成员函数a 5 // 其他成员函数b 6 // …… 7 void f
我们知道在C++模板编程中如果我们特化或是偏特化某个模板类, 我们需要重写整个模板类中的所有函数, 但是这些代码通常是非常相似的, 甚至在某些情况下可能只有一两个函数会不一样,其他函数都是一样的。...
7.2.5 成员函数模板 7.2.6 友元函数模板 7.3 模板源代码组织 7.4 标准复数库 7.5 标准ualarray库 7.5.1 ualarray类型 7.5.2 分段数组 7.5.3 广义分段数组 7.5.4 掩码数组和间接数组 7.6 ...
16.6 模板特化 564 16.6.1 函数模板的特化 565 16.6.2 类模板的特化 567 16.6.3 特化成员而不特化类 569 16.6.4 类模板的部分特化 570 16.7 重载与函数模板 570 小结 573 术语 574 第五部分 高级主题 第17章 用于...
一组新的多维数组模板类 by chen3feng(RoachCock@smth) email: chen3feng@163.com, chen3fengx@163.com, chen3fengx@hotmail.com [引言] 在C/C++开发中,多维数组是一个让很多人感到棘手的问题.原因...
模板的特化(具体化) .pdf 前置加加重载(1).pdf 前置加加重载pdf 國浅拷贝与深拷贝.pdf 输入输出函数重载(1).pdf 输入输出函数重载pdf 画委托构造函数.pdf 析构函数.pdf 虛表.pdf 网虛函数和多态.pdf 网虚析构函数....
8.8 模板特化 8.9 小结 8.10 问题 第9章 重用 9.1 发现和获得 9.2 健壮性 9.3 内存管理 9.4 可选的内存分配方案 9.5 传递参数给operator new 9.6 管理外部资源 9.7 寻找有关内存的bug 9.8 名字冲突 9.9 性能 9.10 ...
2.1 函数模板 25 2.2 类模板 27 2.3 模板完全特化 28 2.4 函数模板重载 30 2.5 类模板继承 30 2.6 本章小结 31 第3章 C++ I/O流技术 32 3.1 I/O流类 32 3.2 标准输入输出 34 3.3 文件输入输出 ...
4.3.3 模板特化大小 4.4 运行时间 4.4.1 内联(inlning) 4.4.2 虚函数 4.4.3 返回引用 4.5 空闲存储空间(free-store)和堆栈空间(stack space) 4.5.1 使用高效的算法 4.5.2 尽可能快地释放空闲资源 ...
2.1 函数模板 25 2.2 类模板 27 2.3 模板完全特化 28 2.4 函数模板重载 30 2.5 类模板继承 30 2.6 本章小结 31 第3章 C++ I/O流技术 32 3.1 I/O流类 32 3.2 标准输入输出 34 3.3 文件输入输出 ...
2.1 函数模板 25 2.2 类模板 27 2.3 模板完全特化 28 2.4 函数模板重载 30 2.5 类模板继承 30 2.6 本章小结 31 第3章 C++ I/O流技术 32 3.1 I/O流类 32 3.2 标准输入输出 34 3.3 文件输入输出 ...
条款15 指向类成员的指针井非指针........................ …............. …........ 攀... 零......40 条款16 指向成员函数的指针井非指针……星.....………..................... …............. 43 条款17 ...