2019-08-19 19:19:58 +08:00
|
|
|
|
#ifndef HGL_IO_DATA_INPUT_STREAM_INCLUDE
|
|
|
|
|
#define HGL_IO_DATA_INPUT_STREAM_INCLUDE
|
|
|
|
|
|
|
|
|
|
#include<hgl/io/InputStream.h>
|
2020-09-03 15:52:46 +08:00
|
|
|
|
#include<hgl/type/String.h>
|
2019-08-19 19:19:58 +08:00
|
|
|
|
#include<hgl/math/Vector.h>
|
|
|
|
|
namespace hgl
|
|
|
|
|
{
|
|
|
|
|
namespace io
|
|
|
|
|
{
|
|
|
|
|
class InputStream;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 格式数据输入流基类
|
|
|
|
|
*/
|
|
|
|
|
class DataInputStream ///格式数据输入流基类
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
InputStream *in;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
DataInputStream(InputStream *is)
|
|
|
|
|
{
|
|
|
|
|
in=is;
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-21 11:54:11 +08:00
|
|
|
|
virtual ~DataInputStream()=default;
|
2019-08-19 19:19:58 +08:00
|
|
|
|
|
|
|
|
|
virtual void Use(InputStream *is)
|
|
|
|
|
{
|
|
|
|
|
in=is;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual int64 Read(void *buf,int64 size)
|
|
|
|
|
{
|
|
|
|
|
if(!buf||size<0)return(-1);
|
|
|
|
|
|
|
|
|
|
return(in?in->Read(buf,size):-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual int64 Peek(void *buf,int64 size)
|
|
|
|
|
{
|
|
|
|
|
if(!buf||size<0)return(-1);
|
|
|
|
|
|
|
|
|
|
return(in?in->Peek(buf,size):-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual int64 ReadFully(void *buf,int64 size)
|
|
|
|
|
{
|
|
|
|
|
if(!buf||size<0)return(-1);
|
|
|
|
|
|
|
|
|
|
return(in?in->ReadFully(buf,size):-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual int64 Seek(int64 offset,SeekOrigin so=SeekOrigin::Begin)
|
|
|
|
|
{
|
|
|
|
|
return(in?in->Seek(offset,so):-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual int64 Skip(int64 size) ///<跳过指定字节不访问
|
|
|
|
|
{
|
|
|
|
|
return(in?in->Skip(size):-1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual bool CanRestart ()const{return in?in->CanRestart():false;} ///<是否可以复位
|
|
|
|
|
virtual bool CanSeek ()const{return in?in->CanSeek ():false;} ///<是否可以定位
|
|
|
|
|
virtual bool CanSize ()const{return in?in->CanSize ():false;} ///<是否可以取得尺寸
|
|
|
|
|
virtual bool CanPeek ()const{return in?in->CanPeek ():false;} ///<是否可以预览数据
|
|
|
|
|
|
|
|
|
|
virtual bool Restart ()const{return in?in->Restart ():false;} ///<复位访问指针
|
|
|
|
|
virtual int64 Tell ()const{return in?in->Tell ():-1;} ///<返回当前访问位置
|
|
|
|
|
virtual int64 GetSize ()const{return in?in->GetSize ():-1;} ///<取得流长度
|
|
|
|
|
virtual int64 Available ()const{return in?in->Available ():-1;} ///<剩下的可以不受阻塞读取的字节数
|
|
|
|
|
|
|
|
|
|
template<typename T> bool ReadNumber(T &value);
|
|
|
|
|
|
|
|
|
|
#define STREAM_READ(type,name) virtual bool Read##name(type &value) \
|
|
|
|
|
{ \
|
|
|
|
|
return Read(value); \
|
|
|
|
|
} \
|
|
|
|
|
\
|
|
|
|
|
virtual int64 Read##name(type *data,const int64 count) \
|
|
|
|
|
{ \
|
|
|
|
|
if(count<=0)return(count); \
|
|
|
|
|
if(!data)return(-1); \
|
|
|
|
|
\
|
|
|
|
|
return ReadArrays(data,count); \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
STREAM_READ(char, Char );
|
|
|
|
|
STREAM_READ(bool, Bool );
|
|
|
|
|
STREAM_READ(int8, Int8 );
|
|
|
|
|
STREAM_READ(uint8, Uint8 );
|
|
|
|
|
|
|
|
|
|
#undef STREAM_READ
|
|
|
|
|
|
|
|
|
|
#define STREAM_READ(type,name) virtual bool Read##name(type &)=0; \
|
|
|
|
|
virtual int64 Read##name(type *,const int64)=0;
|
|
|
|
|
|
|
|
|
|
STREAM_READ(int16, Int16 );
|
|
|
|
|
STREAM_READ(int32, Int32 );
|
|
|
|
|
STREAM_READ(int64, Int64 );
|
|
|
|
|
|
|
|
|
|
STREAM_READ(uint16, Uint16 );
|
|
|
|
|
STREAM_READ(uint32, Uint32 );
|
|
|
|
|
STREAM_READ(uint64, Uint64 );
|
|
|
|
|
|
|
|
|
|
STREAM_READ(u16char, UTF16Char);
|
|
|
|
|
STREAM_READ(float, Float );
|
|
|
|
|
STREAM_READ(double, Double );
|
|
|
|
|
|
|
|
|
|
#undef STREAM_READ
|
|
|
|
|
|
|
|
|
|
bool Read(Vector2f &vec){return ReadFloat((float *)&vec,2)==2;}
|
|
|
|
|
bool Read(Vector3f &vec){return ReadFloat((float *)&vec,3)==3;}
|
|
|
|
|
bool Read(Vector4f &vec){return ReadFloat((float *)&vec,4)==4;}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 自适应类型数据读取</p>
|
|
|
|
|
* 请在多平台混用的情况下不要使用此函数,以免造成不同平台数据实质结构不一致的情况
|
|
|
|
|
*/
|
|
|
|
|
template<typename T> bool Read(T &data)
|
|
|
|
|
{
|
|
|
|
|
return(ReadFully(&data,sizeof(T))==sizeof(T));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 自适应类型数据阵列读取</p>
|
|
|
|
|
* 请在多平台混用的情况下不要使用此函数,以免造成不同平台数据实质结构不一致的情况
|
|
|
|
|
* @param data 数据存放区
|
|
|
|
|
* @param count 数据个数
|
|
|
|
|
* @return 实质读入的数据个数
|
|
|
|
|
* @return <0 出错
|
|
|
|
|
*/
|
|
|
|
|
template<typename T> int64 ReadArrays(T *data,int64 count)
|
|
|
|
|
{
|
|
|
|
|
if(count<=0)return(count);
|
|
|
|
|
if(!data)return(-1);
|
|
|
|
|
|
|
|
|
|
return ReadFully(data,count*sizeof(T))/sizeof(T);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 自定义类型数据阵列读取</p>
|
|
|
|
|
* 请在多平台混用的情况下不要使用此函数,以免造成不同平台数据实质结构不一致的情况
|
|
|
|
|
* @param count 数据个数
|
|
|
|
|
* @param alloc_count 分配数据个数(默认-1)
|
|
|
|
|
* @return 实质读入的数据指针,请使用delete[]释放
|
|
|
|
|
* @return NULL 出错
|
|
|
|
|
*/
|
|
|
|
|
template<typename T> T *ReadArrays(int64 count)
|
|
|
|
|
{
|
|
|
|
|
if(count<=0)return(nullptr);
|
|
|
|
|
|
|
|
|
|
T *data=new T[count];
|
|
|
|
|
|
|
|
|
|
if(data==0)
|
|
|
|
|
return(nullptr);
|
|
|
|
|
|
|
|
|
|
if(ReadArrays(data,count)!=count)
|
|
|
|
|
{
|
|
|
|
|
delete[] data;
|
|
|
|
|
return(nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual bool ReadUTF16LEChars(u16char *,uint); ///<读取utf16-le格式字符阵列到u16char *
|
|
|
|
|
virtual bool ReadUTF16BEChars(u16char *,uint); ///<读取utf16-be格式字符阵列到u16char *
|
|
|
|
|
|
|
|
|
|
//32bit str-length
|
2024-12-24 22:39:02 +08:00
|
|
|
|
virtual bool ReadU8String (char *, uint max_len=0); ///<读取utf8格式字符串(前缀四字节的字符串字节长度)
|
|
|
|
|
virtual bool ReadU8String (U8String &, uint max_len=0); ///<读取utf8格式字符串(前缀四字节的字符串字节长度)
|
|
|
|
|
virtual bool ReadU8String (U16String &, uint max_len=0); ///<读取utf8格式字符串(前缀四字节的字符串字节长度)
|
2019-08-19 19:19:58 +08:00
|
|
|
|
|
|
|
|
|
virtual bool ReadUTF16LEString (u16char *, uint max_len=0);
|
|
|
|
|
virtual bool ReadUTF16BEString (u16char *, uint max_len=0);
|
|
|
|
|
|
2024-12-24 22:39:02 +08:00
|
|
|
|
virtual bool ReadUTF16LEString (U16String &, uint max_len=0); ///<读取utf16-le格式字符串(前缀四字节的字符串字节长度)
|
|
|
|
|
virtual bool ReadUTF16BEString (U16String &, uint max_len=0); ///<读取utf16-be格式字符串(前缀四字节的字符串字节长度)
|
2019-08-19 19:19:58 +08:00
|
|
|
|
|
|
|
|
|
//16bit str-length
|
|
|
|
|
virtual bool ReadUTF8ShortString (char *, uint max_len=0);
|
2024-12-24 22:39:02 +08:00
|
|
|
|
virtual bool ReadUTF8ShortString (U8String &, uint max_len=0); ///<读取utf8格式字符串(前缀2字节的字符串字节长度)
|
|
|
|
|
virtual bool ReadUTF8ShortString (U16String &, uint max_len=0); ///<读取utf8格式字符串(前缀2字节的字符串字节长度)
|
2019-08-19 19:19:58 +08:00
|
|
|
|
|
|
|
|
|
virtual bool ReadUTF16LEShortString (u16char *, uint max_len=0);
|
|
|
|
|
virtual bool ReadUTF16BEShortString (u16char *, uint max_len=0);
|
|
|
|
|
|
2024-12-24 22:39:02 +08:00
|
|
|
|
virtual bool ReadUTF16LEShortString (U16String &, uint max_len=0); ///<读取utf16-le格式字符串(前缀2字节的字符串字节长度)
|
|
|
|
|
virtual bool ReadUTF16BEShortString (U16String &, uint max_len=0); ///<读取utf16-be格式字符串(前缀2字节的字符串字节长度)
|
2019-08-19 19:19:58 +08:00
|
|
|
|
|
|
|
|
|
//8bit str-length
|
|
|
|
|
virtual bool ReadUTF8TinyString (char *, uint max_len=0);
|
2024-12-24 22:39:02 +08:00
|
|
|
|
virtual bool ReadUTF8TinyString (U8String &, uint max_len=0); ///<读取utf8格式字符串(前缀1字节的字符串字节长度)
|
|
|
|
|
virtual bool ReadUTF8TinyString (U16String &, uint max_len=0); ///<读取utf8格式字符串(前缀1字节的字符串字节长度)
|
2019-08-19 19:19:58 +08:00
|
|
|
|
|
|
|
|
|
virtual bool ReadUTF16LETinyString (u16char *, uint max_len=0);
|
|
|
|
|
virtual bool ReadUTF16BETinyString (u16char *, uint max_len=0);
|
|
|
|
|
|
2024-12-24 22:39:02 +08:00
|
|
|
|
virtual bool ReadUTF16LETinyString (U16String &, uint max_len=0); ///<读取utf16-le格式字符串(前缀1字节的字符串字节长度)
|
|
|
|
|
virtual bool ReadUTF16BETinyString (U16String &, uint max_len=0); ///<读取utf16-be格式字符串(前缀1字节的字符串字节长度)
|
2019-08-19 19:19:58 +08:00
|
|
|
|
};//class DataInputStream
|
|
|
|
|
|
|
|
|
|
template<> bool inline DataInputStream::ReadNumber<int8>(int8 &value){return ReadInt8(value);}
|
|
|
|
|
template<> bool inline DataInputStream::ReadNumber<uint8>(uint8 &value){return ReadUint8(value);}
|
|
|
|
|
|
|
|
|
|
#define DIS_READ_NUMBER(type,name) template<> bool inline DataInputStream::ReadNumber<type>(type &value){return Read##name(value);}
|
|
|
|
|
|
|
|
|
|
DIS_READ_NUMBER(int16, Int16 );
|
|
|
|
|
DIS_READ_NUMBER(int32, Int32 );
|
|
|
|
|
DIS_READ_NUMBER(int64, Int64 );
|
|
|
|
|
|
|
|
|
|
DIS_READ_NUMBER(uint16, Uint16 );
|
|
|
|
|
DIS_READ_NUMBER(uint32, Uint32 );
|
|
|
|
|
DIS_READ_NUMBER(uint64, Uint64 );
|
|
|
|
|
|
|
|
|
|
DIS_READ_NUMBER(u16char, UTF16Char);
|
|
|
|
|
DIS_READ_NUMBER(float, Float );
|
|
|
|
|
DIS_READ_NUMBER(double, Double );
|
|
|
|
|
|
|
|
|
|
#undef DIS_READ_NUMBER
|
|
|
|
|
}//namespace io
|
|
|
|
|
}//namespace hgl
|
|
|
|
|
#include<hgl/io/EndianDataInputStream.h>
|
|
|
|
|
#endif//HGL_IO_DATA_INPUT_STREAM_INCLUDE
|