#include "csv.h"
#include <vector>
#include <string.h>
#include <algorithm>
using namespace std;
Csv::Csv()
{
mHasStringKeyMap = false;
}
Csv::~Csv()
{
}
Csv* Csv::CreateAndLoad(string filename)
{
// 打开文件
FILE* fp = fopen(filename.c_str(),"r");
if(fp == NULL)
{
printf("ICsv::CreateAndLoad fopen failed, filename=%s",filename.c_str());
return NULL;
}
// 获取文件大小后,读取
int size = fileSize(fp);
char* buffer = new char[size];
int bytes = 0;
while(bytes<size)
{
int ret = fread(buffer+bytes, 1,size-bytes, fp);
if(ret==0)
{
break;
}
bytes += ret;
}
// 初始化到csv对象中
Csv* pCsv = new Csv();
pCsv->InitWithBuffer(buffer);
delete []buffer;
return pCsv;
}
void Csv::Delete(Csv*&p)
{
delete p;
p = NULL;
}
void Csv::MapToVec()
{
int i = 0,j = 0;
m_StringVec.clear();
// 取出第一行
std::vector<std::string> firstline;
firstline.push_back(m_CSVName);
for (StringMap::iterator it = m_StringKeyMap.begin();it != m_StringKeyMap.end();it++)
{
for (std::map<std::string,std::string>::iterator jt = it->second.begin();jt!=it->second.end();jt++)
{
if (std::find(firstline.begin(),firstline.end(),jt->first) == firstline.end())
{
firstline.push_back(jt->first);
}
}
}
m_StringVec.push_back(firstline);
for (StringMap::iterator it = m_StringKeyMap.begin();it != m_StringKeyMap.end();it++)
{
if (it->first!=firstline.front())
{
std::vector<std::string> vecLine;
std::map<std::string,std::string>& strline = it->second;
for (std::map<std::string,std::string>::iterator jt = strline.begin();jt!=strline.end();jt++)
{
vecLine.push_back(jt->second);
}
if (std::find(vecLine.begin(),vecLine.end(),it->first)==vecLine.end())
{
vecLine.insert(vecLine.begin(),it->first);
}
m_StringVec.push_back(vecLine);
}
}
}
unsigned int Csv::GetParamNum(const char* ptext,char Delim )
{
size_t sz = strlen(ptext)+1;
const char* pstart = ptext;
static const char* nullStr ="";
unsigned int ret=0;
if (ptext[0]==0)
{
return ret;
}
for (unsigned int n = 0;n < sz; n++)
{
if (ptext[n] == Delim )
{
ret++;
pstart = &ptext[n+1];
}
}
ret++;
return ret;
}
bool Csv::InitWithBuffer(const char* text)
{
m_StringVec.clear();
m_buffer = text;
unsigned long dwsize = 0;
dwsize = m_buffer.size();
if (dwsize<=0)
{
return false;
}
char* buffer = (char*)m_buffer.c_str();
if ( buffer && dwsize )
{
bool bquote = false;
unsigned int uiIndex = 0;
bool bnewline = false;
char* pstartline = buffer ;
// 取得所有行和列;
//printf("--------begin:%s---------------\n",csvfile);
for (unsigned int n = 0,sz = 1;n < dwsize; n++,sz++)
{
if (buffer[n]=='"')
{
bquote=!bquote;
}
if (!bquote && (buffer[n]== '\n'))
{
buffer[n] = 0;
if (buffer[n-1] == '\r')
{
buffer[n-1] =0;
}
//printf("%s\n",pstartline);
std::vector<std::string> coltext;
Split(pstartline,coltext,',');
m_StringVec.push_back( coltext );
if (n+1<dwsize)
{
pstartline = &buffer[n+1];
}
}
}
for (unsigned int i =0;i<m_StringVec.size();i++)
{
if (m_StringVec[i].size()<m_StringVec[0].size())
{
m_StringVec[i].resize(m_StringVec[0].size(),"");
}
}
this->InitStringKeyMap();
return true;
}
return false;
}
void Csv::SetFilePath(string path)
{
m_CSVName = path;
}
/*
=====================================
Csv::SaveCSV
=====================================
*/
bool Csv::SaveCSV(const char* path)
{
std::string buff;
for (unsigned int i = 0;i<m_StringVec.size();i++)
{
for (unsigned int j = 0;j <m_StringVec[i].size();j++)
{
buff += m_StringVec[i][j];
if (j!=m_StringVec[i].size()-1)
{
buff +=",";
}
}
buff+="\n";
}
if (path == NULL)
{
path = m_CSVName.c_str();
}
return true;
}
long Csv::Clear()
{
m_StringVec.clear();
m_StringKeyMap.clear();
// m_buffer.UnInit();
return 0;
}
/*
=====================================
Csv::InitStringKeyMap
// 创建一个以字符串作为索引的表
// 该方法有明显的性能损耗
=====================================
*/
void Csv::InitStringKeyMap()
{
vector<string> colkey ;
if (!m_StringVec.empty())
{
colkey = m_StringVec.at(0);
}
for (unsigned int i = 0;i<m_StringVec.size();i++)
{
vector<string> linetext = m_StringVec.at(i);
std::map<string,string> str_key_coltext;
for (unsigned int j = 0;j < colkey.size();j++)
{
if (j >= linetext.size()){break;}
str_key_coltext[colkey[j]] = linetext[j];
}
m_StringKeyMap[linetext[0] ] = str_key_coltext;
}
mHasStringKeyMap = true;
}
/*
=====================================
Csv::GetCsvMap
返回表,以第一列的值作为表的行索引,以第一行的值作为后序各行的列索引
=====================================
*/
std::map<string,map<string,string> > & Csv::GetMapMap()
{
if (m_StringKeyMap.empty())
{
this->InitStringKeyMap();
}
return m_StringKeyMap;
}
/*
=====================================
Csv::GetStringVec
=====================================
*/
std::vector< std::vector< std::string> > &Csv::GetVecVec()
{
return m_StringVec;
}
std::vector< std::map<std::string,std::string> > & Csv::GetVecMap()
{
static std::vector< std::map<std::string,std::string> > ret;
return ret;
}
/*
=====================================
Csv::GetParam
=====================================
*/
const char* Csv::GetParam( const char* uiLine, const char* uiCol, int index /*= 0*/,char Delim /*='|'*/ )
{
const char* buffer = this->GetString(uiLine,uiCol);
char* start = (char*)buffer;
int sz = strlen(buffer);
static string ret ;
for (int i = 0 , n = 0; i<sz+1 ;i++)
{
if (buffer[i] == Delim || buffer [i] == 0)
{
if (n == index )
{
ret = string(start,&buffer[i]-start);
return ret.c_str();
}
else if(buffer[i+1])
{
start = (char*)&buffer[i+1];
}
n ++;
}
}
return ret.c_str();
}
const char* Csv::GetParam(const char* input, int index ,char Delim )
{
int sz = strlen(input)+1;
const char* buffer = input;
const char* start = buffer;
static string ret = "";
for (int i = 0 , n = 0; i<sz+1 ;i++)
{
if (buffer[i] == Delim || buffer [i] == 0)
{
if ( n == index )
{
ret = std::string(start,&buffer[i]-start);
break;
}
else if(buffer[i+1])
{
start = (char*)&buffer[i+1];
}
n ++;
}
}
return ret.c_str();
}
/*
=====================================
Csv::GetInt
=====================================
*/
long int Csv::GetInt( unsigned int uiLine, unsigned int uiCol )
{
const char* str = this->GetString(uiLine,uiCol);
if (str)
{
return atol(str);
}
else
{
return 0;
}
}
/*
=====================================
Csv::GetInt
=====================================
*/
long int Csv::GetInt( const char* usLine, const char* usCol )
{
const char* str = this->GetString(usLine,usCol);
if (str)
{
return atol(str);
}
else
{
return 0;;
}
}
long int Csv::GetInt (unsigned int uiLine, const char* usCol)
{
const char* buffer = this->GetData(uiLine,usCol);
return atol(buffer);
}
long int Csv::GetInt( unsigned int uiLine, const char* usCol,int index /*= 0*/,char Delim /*='|'*/ )
{
char* buffer = (char*)this->GetData(uiLine,usCol);
const char* ret = GetParam(buffer,index,Delim);
return atol(ret);
}
/*
=====================================
Csv::GetFloat
=====================================
*/
double Csv::GetFloat( unsigned int uiLine, unsigned int uiCol )
{
const char* str = this->GetString(uiLine,uiCol);
if (str)
{
return atof(str);
}
else
{
return 0.0f;
}
}
double Csv::GetFloat(unsigned int uiLine,