-
Notifications
You must be signed in to change notification settings - Fork 0
/
csv.cpp
executable file
·133 lines (113 loc) · 4.88 KB
/
csv.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "csv.hpp"
#include "file.hpp"
#include "path.hpp"
#include "read_write.hpp"
#include "tinyInterpreter.hpp"
#include "../string/strEdit.hpp"
// erasing empty element(s) in the tail of vector
void eraseEmptyTail(std::vector<std::string>& inOut){
uint cols = inOut.size();
for(uint p=cols-1; p!=0; --p){
if(inOut[p].size()==0){ inOut.erase(inOut.begin()+p);
} else { break; }
}
}
// erasing empty element(s) in the tail of vector
void eraseEmptyTail(std::vector<std::vector<std::string>>& inOut){
uint rows = inOut.size();
for(uint p=rows-1; p!=0; --p){
if(inOut[p].size()==1 && inOut[p][0].size()==0){ inOut.erase(inOut.begin()+p);
} else { break; }
}
}
bool isEmpty(std::string& token, struct debugInformation& dbgInf){
if(token.size()!=0){
for(uint i=0; i<token.size(); ++i){
if(token[i]!=' '){ printf("ERROR: %s: Line(%u): There is a invalid value (%c) between ',' and '\"'.\n", dbgInf.FileName.c_str(), dbgInf.LineNum, token[i]); return false; }
}
}
return true;
}
bool go2comma(const uchar*& str, uint& r, struct debugInformation& dbgInf){
for(; str[r]!=0; ++r){
if(str[r]==','){ break; }
if(str[r]==0x0D && str[r+1]==0x0A){ ++r; break; } // Line feed code (Windows)
if(str[r]==0x0A){ break; } // Line feed code (Unix)
if(str[r]!=' '){ printf("ERROR: %s: Line(%u): There is a invalid value (%c) between '\"' and ','.\n", dbgInf.FileName.c_str(), dbgInf.LineNum, str[r]); return false; }
}
return true;
}
bool go2doubleQuotation(std::string& token, const uchar*& str, uint& r, struct debugInformation& dbgInf){
if(isEmpty(token, dbgInf)==false){ return false; }
++r;
for(; str[r]!=0; ++r){
if(str[r]=='"' && str[r+1]=='"'){ ++r; token += str[r]; continue; } // "" is treated as a escape of ".
if(str[r]=='"'){ ++r; if(go2comma(str, r, dbgInf)==false){ return false; } break; }
if(str[r]==0x0D && str[r+1]==0x0A){ ++r; } // Line feed code (Windows): ignore '0x0D'
if(str[r]==0x0A){ ++dbgInf.LineNum; } // Line feed code (Unix)
token += str[r]; // Both of the line feed codes (CR+LF or LF) are added as a LF.
}
if(str[r]==0){ printf("ERROR: %s: Line(%u): Command of '\"\"' is not closed. ('\"' is required).\n", dbgInf.FileName.c_str(), dbgInf.LineNum); return false; }
return true;
}
std::vector<std::string> getLine(bool& result, const uchar* str, uint& r, struct debugInformation& dbgInf){
result=true;
std::vector<std::string> line;
std::string token;
for(; str[r]!=0; ){
if(str[r]==' '){ if(token.size()==0){ ++r; continue; } } // skip ' ' just after ','
if(str[r]==','){
line.push_back(std::move(token));
token.clear();
++r;
continue;
}
if(str[r]=='"'){ if(go2doubleQuotation(token, str, r, dbgInf)==false){ result=false; return std::vector<std::string>(0); } continue; } // Command of '""'.
if(str[r]==0x0D && str[r+1]==0x0A){ r+=2; break; } // Line feed code (Windows)
if(str[r]==0x0A){ ++dbgInf.LineNum; ++r; break; } // Line feed code (Unix)
token += str[r];
++r;
}
line.push_back(std::move(token));
return line;
}
std::vector<std::vector<std::string>> sstd::csv2vvec(const char* pReadFile){
// r: read place
uint r=0;
// std::string str = sstd::read(pReadFile);
// ignoreBOM(str, r); // Ignore BOM (BOM: byte order mark)
std::string str = sstd::read_withoutBOM(pReadFile);
std::vector<std::vector<std::string>> ret;
struct debugInformation dbgInf;
dbgInf.FileName = sstd::path2fileName(pReadFile);
dbgInf.LineNum = 1;
bool result;
for(; str[r]!=0; ){
std::vector<std::string> line = getLine(result, (uchar*)&str[0], r, dbgInf);
eraseEmptyTail(line);
ret.push_back(std::move(line));
if(result==false){ return std::vector<std::vector<std::string>>(0); }
}
eraseEmptyTail(ret);
return ret;
}
std::vector<std::vector<std::string>> sstd::csv2vvec(const std::string& readFile){
return sstd::csv2vvec(readFile.c_str());
}
//-----
bool sstd::vvec2csv(const char* pSavePath, const std::vector<std::vector<std::string>>& vecCSV){
std::string str;
for(uint r=0; r<vecCSV.size(); ++r){
for(uint c=0; c<vecCSV[r].size(); ++c){
str += '\"' + vecCSV[r][c] + "\",";
}
str += '\n';
}
sstd::file fp;
if(!fp.fopen(pSavePath, "wb")){ return false; }
if(fp.fwrite(str.c_str(), sizeof(char), str.size())!=(size_t)str.size()){ return false; }
return true;
}
bool sstd::vvec2csv(const std::string& savePath, const std::vector<std::vector<std::string>>& vecCSV){
return sstd::vvec2csv(savePath.c_str(), vecCSV);
}