2023-07-27 18:51:51 +08:00
|
|
|
#pragma once
|
|
|
|
#include<hgl/io/FileInputStream.h>
|
|
|
|
#include<hgl/io/TextInputStream.h>
|
|
|
|
#include<hgl/util/csv/CSVFieldSplite.h>
|
|
|
|
|
|
|
|
namespace hgl
|
|
|
|
{
|
|
|
|
namespace util
|
|
|
|
{
|
|
|
|
template<typename T> class CSVParseCallback
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
virtual bool OnLine(util::CSVFieldSplite<T> &csv)=0;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename T> class CSVTextParse:public io::TextInputStream::ParseCallback<T>
|
|
|
|
{
|
|
|
|
util::CSVFieldSplite<T> splite;
|
|
|
|
|
|
|
|
CSVParseCallback<T> *callback;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
CSVTextParse(CSVParseCallback<T> *pcb)
|
|
|
|
{
|
|
|
|
callback=pcb;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OnLine(const T *text,const int length) override
|
|
|
|
{
|
|
|
|
if(!text||!*text||length<=0)
|
2023-07-28 18:14:01 +08:00
|
|
|
return(true);
|
2023-07-27 18:51:51 +08:00
|
|
|
|
|
|
|
splite.Start(text,length);
|
|
|
|
|
2023-07-28 18:14:01 +08:00
|
|
|
return callback->OnLine(splite);
|
2023-07-27 18:51:51 +08:00
|
|
|
}
|
|
|
|
};//class CSVTextParse
|
|
|
|
|
|
|
|
template<typename T> inline bool ParseCSV(io::InputStream *is,CSVParseCallback<T> *pcb)
|
|
|
|
{
|
|
|
|
io::TextInputStream tis(is);
|
|
|
|
|
|
|
|
CSVTextParse<T> parse(pcb);
|
|
|
|
|
|
|
|
tis.SetParseCallback<T>(&parse);
|
|
|
|
|
2023-07-28 18:14:01 +08:00
|
|
|
return tis.Run()>0;
|
2023-07-27 18:51:51 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename T> inline bool ParseCSVFile(const OSString &filename,CSVParseCallback<T> *pcb)
|
|
|
|
{
|
2023-07-27 18:57:17 +08:00
|
|
|
io::OpenFileInputStream fis(filename);
|
2023-07-27 18:51:51 +08:00
|
|
|
|
2023-07-27 18:57:17 +08:00
|
|
|
if(!fis)
|
2023-07-27 18:51:51 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return ParseCSV<T>(fis,pcb);
|
|
|
|
}
|
|
|
|
}//namespace util
|
|
|
|
}//namespace hgl
|