139 lines
3.3 KiB
C++
139 lines
3.3 KiB
C++
#include<hgl/io/TextInputStream.h>
|
||
|
||
namespace hgl
|
||
{
|
||
namespace io
|
||
{
|
||
TextInputStream::TextInputStream(InputStream *i,const int buf_size)
|
||
{
|
||
input_stream=i;
|
||
buffer_size=buf_size;
|
||
buffer=new uint8[buffer_size];
|
||
cur_buf_size=0;
|
||
|
||
stream_pos=0;
|
||
stream_size=input_stream->Available();
|
||
|
||
bom=ByteOrderMask::NONE;
|
||
callback=nullptr;
|
||
}
|
||
|
||
template<typename T> int TextInputStream::Parse(const T *p)
|
||
{
|
||
const T *sp=(const T *)p;
|
||
const T *end=(const T *)(buffer+cur_buf_size);
|
||
|
||
int line_count=0;
|
||
|
||
while(p<end)
|
||
{
|
||
if(*p=='\n')
|
||
{
|
||
callback->OnLine(sp,p-sp,true);
|
||
++line_count;
|
||
++p;
|
||
sp=p;
|
||
}
|
||
else
|
||
if(*p=='\r')
|
||
{
|
||
++p;
|
||
if(*p=='\n')
|
||
{
|
||
callback->OnLine(sp,p-sp-1,true);
|
||
++line_count;
|
||
++p;
|
||
sp=p;
|
||
}
|
||
}
|
||
else
|
||
++p;
|
||
}
|
||
|
||
if(sp<end)
|
||
{
|
||
callback->OnLine(sp,end-sp,false);
|
||
++line_count;
|
||
}
|
||
|
||
return line_count;
|
||
}
|
||
|
||
int TextInputStream::TextBlockParse()
|
||
{
|
||
uint8 *p=buffer;
|
||
|
||
if(stream_pos==0) //×ʼ£¬ÄǼì²âÒ»ÏÂBOMÍ·
|
||
{
|
||
if(cur_buf_size>=2)
|
||
{
|
||
bom=CheckBOM(p);
|
||
|
||
const BOMFileHeader *bfh=GetBOM(bom);
|
||
|
||
if(bfh)
|
||
{
|
||
if(bfh->size==cur_buf_size)
|
||
return(0);
|
||
|
||
p+=bfh->size;
|
||
}
|
||
}
|
||
}
|
||
|
||
if(bom==ByteOrderMask::UTF16LE||bom==ByteOrderMask::UTF16BE)
|
||
return Parse<u16char>((u16char *)p);
|
||
else
|
||
if(bom==ByteOrderMask::UTF32LE||bom==ByteOrderMask::UTF32BE)
|
||
return Parse<u32char>((u32char *)p);
|
||
else
|
||
return Parse<char>((char *)p);
|
||
}
|
||
|
||
int TextInputStream::Run(ParseCallback *pc)
|
||
{
|
||
if(!pc)return(-2);
|
||
if(!input_stream)return(-1);
|
||
|
||
callback=pc;
|
||
|
||
int64 read_size;
|
||
|
||
int result;
|
||
int line_count=0;
|
||
|
||
while(stream_pos<stream_size)
|
||
{
|
||
read_size=stream_size-stream_pos;
|
||
|
||
if(read_size>buffer_size)
|
||
read_size=buffer_size;
|
||
|
||
cur_buf_size=input_stream->Read(buffer,read_size);
|
||
|
||
if(cur_buf_size!=read_size)
|
||
{
|
||
callback->OnReadError();
|
||
return(-1);
|
||
}
|
||
|
||
result=TextBlockParse();
|
||
|
||
if(result<0)
|
||
{
|
||
callback->OnReadError();
|
||
return(result);
|
||
}
|
||
|
||
line_count+=result;
|
||
|
||
stream_pos+=cur_buf_size;
|
||
}
|
||
|
||
callback->OnEnd();
|
||
|
||
return line_count;
|
||
}
|
||
}//namespace io
|
||
}//namespace hgl
|