将内存模拟成C++流的方法
如何将一个 内存 模拟成一个C++流,
把一个内存new出来后,在这段内存上面建立一个 C++ 的istream类.以后所有的操作都可以对这个istream类进行.
这样做有很多好处,比如,你的资源分析器可以接受一个istream指针,这个istream可能是一个fstream.也可能是你从zip文件中解出到内存后,从内存构造的一个istream.
具体做法是,从basic_streambuf里派生一个类,
这里只介绍一个简单的支持输出的streambuf.如果谁完善了它,或者实现了一个支持各种特性,输入输出,block buffer等功能的时候,麻烦也告诉我一下.不胜感激.
#ifndef __MEM_STREAM_BUFFER_H__
#define __MEM_STREAM_BUFFER_H__
/*
提供 C++ 标准库的扩展。支持从一段内存上建立一个istream类。
作者: 潘李亮 2004 - 10 - 25
Xheartblue 2004-10-25
本代码为免费代码,可以只有使用和修改。
但是你得保留本声明和作者名字。
*/
#include <streambuf>
namespace std
{
template <typename _CharT, typename _CharTrait = char_traits<_CharT> >
class mem_streambuf : public basic_streambuf<_CharT,_CharTrait>
{
public: //类型的定义
typedef _CharT streambuf_type;
typedef _CharT char_type;
typedef int int_type;
typedef typename std::streampos pos_type;
typedef typename std::streamsize off_type;
protected:
size_t m_bufLen;
char_type* m_buffer;
bool m_bIsAllocInner;
public:
//构造函数
mem_streambuf(char_type* buf,size_t len)
{
set_buf(buf,len);
}
mem_streambuf()
{
m_buffer = NULL;
m_bufLen = 0;
m_bIsAllocInner = false;
}
mem_streambuf(size_t len)
{
m_buffer = NULL;
m_bufLen = 0;
m_bIsAllocInner = false;
alloc_buf(len);
_init();
}
~mem_streambuf()
{
dealloc_buf();
}
bool alloc_buf(int len)
{
dealloc_buf();
m_buffer = new char_type[len];
m_bIsAllocInner = true;
m_bufLen = len;
return true;
}
bool set_buf(char_type* buf,size_t len)
{
m_buffer = buf;
m_bufLen = len;
m_bIsAllocInner = false;
_init();
return true;
}
bool dealloc_buf()
{
if(m_bIsAllocInner)
{
delete [] m_buffer;
}
m_buffer = NULL;
m_bufLen = 0;
m_bIsAllocInner = false;
return true;
}
char_type* get_buf()
{
return m_buffer;
}
protected:
void _init()
{
setg(m_buffer,m_buffer,m_buffer+ m_bufLen);
setp(m_buffer,m_buffer,m_buffer+ m_bufLen);
}
};//endl class mem_streambuf;
template <typename _CharT , typename _CharTrait = char_traits<_CharT> >
class basic_imemstream : public basic_istream<_CharT,_CharTrait>
{
public:
typedef mem_streambuf<_CharT,_CharTrait> stream_type;
typedef _CharT char_type;
protected:
stream_type m_buffer;
public:
basic_imemstream(stream_type* buf): basic_istream<_CharT,_CharTrait>(buf)
{
}
basic_imemstream(char_type* buf,size_t len)
:m_buffer(buf,len),basic_istream<_CharT,_CharTrait>(&m_buffer)
{
}
basic_imemstream():m_buffer(),basic_istream<_CharT,_CharTrait>(&m_buffer)
{
}
basic_imemstream(int len)
:m_buffer(len),basic_istream<_CharT,_CharTrait>(&m_buffer)
{
}
void set_buf(char_type* buf,int len)
{
m_buffer.set_buf(buf,len);
}
char_type* get_buf()
{
return m_buffer.get_buf();
}
basic_streambuf<_CharT,_CharTrait>* rdbuf()
{
return &m_buffer;
}
void rdbuf(basic_streambuf<_CharT,_CharTrait>* buf)
本文地址:http://www.45fan.com/a/question/70052.html