237 lines
3.8 KiB
C
237 lines
3.8 KiB
C
|
#ifndef HGL_IO_MEMORY_OUTPUT_STREAM_INCLUDE
|
|||
|
#define HGL_IO_MEMORY_OUTPUT_STREAM_INCLUDE
|
|||
|
|
|||
|
#include<hgl/type/MemBlock.h>
|
|||
|
#include<hgl/io/OutputStream.h>
|
|||
|
namespace hgl
|
|||
|
{
|
|||
|
namespace io
|
|||
|
{
|
|||
|
/**
|
|||
|
* 内存数据输出流,将数据输出到一个内存块中。
|
|||
|
*/
|
|||
|
class MemoryOutputStream:public OutputStream ///内存数据输出流
|
|||
|
{
|
|||
|
protected:
|
|||
|
|
|||
|
uint8 *buf;
|
|||
|
|
|||
|
size_t max_size;
|
|||
|
size_t buf_size;
|
|||
|
size_t cur_pos;
|
|||
|
|
|||
|
bool one;
|
|||
|
|
|||
|
public:
|
|||
|
|
|||
|
MemoryOutputStream()
|
|||
|
{
|
|||
|
buf=0;
|
|||
|
max_size=0;
|
|||
|
buf_size=0;
|
|||
|
cur_pos=0;
|
|||
|
one=false;
|
|||
|
}
|
|||
|
|
|||
|
virtual ~MemoryOutputStream()
|
|||
|
{
|
|||
|
Close();
|
|||
|
}
|
|||
|
|
|||
|
void *GetData()const{return buf;}
|
|||
|
|
|||
|
/**
|
|||
|
* 创建一个当前流数据的内存拷贝,此函数需用户自行delete[]
|
|||
|
* @param len 存放数据长度的指针
|
|||
|
* @return 创建好的内存拷贝
|
|||
|
*/
|
|||
|
void *CreateCopyData(int *len)const
|
|||
|
{
|
|||
|
if(buf_size<=0)
|
|||
|
return(nullptr);
|
|||
|
|
|||
|
uint8 *data=new uint8[buf_size+1];
|
|||
|
memcpy(data,buf,buf_size);
|
|||
|
data[buf_size]=0;
|
|||
|
|
|||
|
if(len)
|
|||
|
*len=buf_size;
|
|||
|
|
|||
|
return data;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 关联一个数据区到当前输出流
|
|||
|
* @param ptr 数据指针
|
|||
|
* @param size 数据长度字节数
|
|||
|
* @param one_instance 是否仅此一份实例(如果是,将由MemoryOutputStream类负责释放)
|
|||
|
* @return 是否成功
|
|||
|
*/
|
|||
|
bool Link(void *ptr,size_t size,bool one_instance=false)
|
|||
|
{
|
|||
|
if(!ptr||!size)
|
|||
|
return(false);
|
|||
|
|
|||
|
buf=(uint8 *)ptr;
|
|||
|
buf_size=size;
|
|||
|
max_size=size;
|
|||
|
cur_pos=0;
|
|||
|
|
|||
|
one=one_instance;
|
|||
|
|
|||
|
return(true);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* 更新关联的数据区长度,不复位cur_pos
|
|||
|
* @param ptr 数据指针
|
|||
|
* @param size 数据长度字节数
|
|||
|
* @return 是否成功
|
|||
|
*/
|
|||
|
bool Update(void *ptr,size_t size)
|
|||
|
{
|
|||
|
if(!ptr||!size)
|
|||
|
return(false);
|
|||
|
|
|||
|
buf=(uint8 *)ptr;
|
|||
|
buf_size=size;
|
|||
|
max_size=0;
|
|||
|
|
|||
|
return(true);
|
|||
|
}
|
|||
|
|
|||
|
void Unlink()
|
|||
|
{
|
|||
|
buf=0;
|
|||
|
buf_size=0;
|
|||
|
max_size=0;
|
|||
|
}
|
|||
|
|
|||
|
bool Create(int64 size)
|
|||
|
{
|
|||
|
Close();
|
|||
|
|
|||
|
if(size<=0)
|
|||
|
return(false);
|
|||
|
|
|||
|
buf=(uint8 *)hgl_malloc(size);
|
|||
|
|
|||
|
if(!buf)
|
|||
|
return(false);
|
|||
|
|
|||
|
one=true;
|
|||
|
cur_pos=0;
|
|||
|
buf_size=size;
|
|||
|
max_size=size;
|
|||
|
|
|||
|
return(true);
|
|||
|
}
|
|||
|
|
|||
|
void Close() override
|
|||
|
{
|
|||
|
if(buf)
|
|||
|
{
|
|||
|
if(one)
|
|||
|
hgl_free(buf);
|
|||
|
|
|||
|
buf=0;
|
|||
|
}
|
|||
|
|
|||
|
buf_size=0;
|
|||
|
max_size=0;
|
|||
|
}
|
|||
|
|
|||
|
void ClearData()
|
|||
|
{
|
|||
|
cur_pos=0;
|
|||
|
buf_size=0;
|
|||
|
}
|
|||
|
|
|||
|
int64 Write(const void *ptr,int64 size) override
|
|||
|
{
|
|||
|
if(!ptr||size<0)
|
|||
|
return(-1);
|
|||
|
|
|||
|
if(!buf)
|
|||
|
{
|
|||
|
if(!Create(size))
|
|||
|
return(-1);
|
|||
|
}
|
|||
|
|
|||
|
if(cur_pos+size>buf_size)
|
|||
|
{
|
|||
|
if(one)
|
|||
|
{
|
|||
|
buf_size=cur_pos+size;
|
|||
|
|
|||
|
if(buf_size>max_size)
|
|||
|
{
|
|||
|
max_size=power_to_2(buf_size);
|
|||
|
|
|||
|
buf=(uint8 *)hgl_realloc(buf,max_size);
|
|||
|
}
|
|||
|
}
|
|||
|
else
|
|||
|
size=buf_size-cur_pos;
|
|||
|
}
|
|||
|
|
|||
|
if(size<=0)
|
|||
|
return(0);
|
|||
|
|
|||
|
memcpy(buf+cur_pos,ptr,size);
|
|||
|
|
|||
|
cur_pos+=size;
|
|||
|
|
|||
|
return size;
|
|||
|
}
|
|||
|
|
|||
|
bool CanRestart()const override{return true;}
|
|||
|
bool CanSeek()const override{return true;}
|
|||
|
bool CanSize()const override{return true;}
|
|||
|
|
|||
|
bool Restart() override
|
|||
|
{
|
|||
|
cur_pos=0;
|
|||
|
return(true);
|
|||
|
}
|
|||
|
|
|||
|
int64 Seek(int64 off,SeekOrigin so=soBegin) override
|
|||
|
{
|
|||
|
if(!CanSeek())return(-1);
|
|||
|
|
|||
|
if(so==soCurrent)
|
|||
|
{
|
|||
|
off+=cur_pos;
|
|||
|
}
|
|||
|
else
|
|||
|
if(so==soEnd)
|
|||
|
{
|
|||
|
off+=buf_size;
|
|||
|
}
|
|||
|
|
|||
|
if(off<0||off>=buf_size)
|
|||
|
return(-1);
|
|||
|
|
|||
|
cur_pos=off;
|
|||
|
return cur_pos;
|
|||
|
}
|
|||
|
|
|||
|
int64 Tell()const override
|
|||
|
{
|
|||
|
return cur_pos;
|
|||
|
}
|
|||
|
|
|||
|
int64 GetSize()const override
|
|||
|
{
|
|||
|
return buf_size;
|
|||
|
}
|
|||
|
|
|||
|
int64 Available()const override
|
|||
|
{
|
|||
|
return buf_size-cur_pos;
|
|||
|
}
|
|||
|
};//class MemoryOutputStream
|
|||
|
}//namespace io
|
|||
|
}//namespace hgl
|
|||
|
#endif//HGL_IO_MEMORY_OUTPUT_STREAM_INCLUDE
|