25typedef SSIZE_T ssize_t;
31static const bool sPlatformHasCR =
true;
33static const bool sPlatformHasCR =
false;
51 const long double pDefaultFloat =
52 std::numeric_limits<long double>::signaling_NaN(),
53 const long long pDefaultInteger = 0)
86 virtual const char *what()
const throw()
override {
return "unsupported conversion datatype"; }
104 : mConverterParams(pConverterParams)
113 void ToStr(
const T &pVal, std::string &pStr)
const
115 if (
typeid(T) ==
typeid(
int) ||
typeid(T) ==
typeid(
long) ||
116 typeid(T) ==
typeid(
long long) ||
typeid(T) ==
typeid(
unsigned) ||
117 typeid(T) ==
typeid(
unsigned long) ||
118 typeid(T) ==
typeid(
unsigned long long) ||
typeid(T) ==
typeid(
float) ||
119 typeid(T) ==
typeid(
double) ||
typeid(T) ==
typeid(
long double) ||
120 typeid(T) ==
typeid(
char))
122 std::ostringstream out;
137 void ToVal(
const std::string &pStr, T &pVal)
const
141 if (
typeid(T) ==
typeid(
int))
143 pVal =
static_cast<T
>(std::stoi(pStr));
146 else if (
typeid(T) ==
typeid(
long))
148 pVal =
static_cast<T
>(std::stol(pStr));
151 else if (
typeid(T) ==
typeid(
long long))
153 pVal =
static_cast<T
>(std::stoll(pStr));
156 else if (
typeid(T) ==
typeid(
unsigned))
158 pVal =
static_cast<T
>(std::stoul(pStr));
161 else if (
typeid(T) ==
typeid(
unsigned long))
163 pVal =
static_cast<T
>(std::stoul(pStr));
166 else if (
typeid(T) ==
typeid(
unsigned long long))
168 pVal =
static_cast<T
>(std::stoull(pStr));
187 if (
typeid(T) ==
typeid(
float))
189 pVal =
static_cast<T
>(std::stof(pStr));
192 else if (
typeid(T) ==
typeid(
double))
194 pVal =
static_cast<T
>(std::stod(pStr));
197 else if (
typeid(T) ==
typeid(
long double))
199 pVal =
static_cast<T
>(std::stold(pStr));
216 if (
typeid(T) ==
typeid(
char))
218 pVal =
static_cast<T
>(pStr[0]);
238 std::string &pStr)
const
250 std::string &pVal)
const
256using ConvFunc = std::function<void(
const std::string &pStr, T &pVal)>;
273 explicit LabelParams(
const int pColumnNameIdx = 0,
const int pRowNameIdx = -1)
307 const bool pHasCR = sPlatformHasCR,
308 const bool pQuotedLinebreaks =
false,
309 const bool pAutoQuote =
true)
356 const char pCommentPrefix =
'#',
357 const bool pSkipEmptyLines =
false)
395 explicit Document(
const std::string &pPath = std::string(),
400 : mPath(pPath), mLabelParams(pLabelParams), mSeparatorParams(pSeparatorParams),
401 mConverterParams(pConverterParams), mLineReaderParams(pLineReaderParams)
423 : mPath(), mLabelParams(pLabelParams), mSeparatorParams(pSeparatorParams),
424 mConverterParams(pConverterParams), mLineReaderParams(pLineReaderParams)
445 mLabelParams = pLabelParams;
446 mSeparatorParams = pSeparatorParams;
447 mConverterParams = pConverterParams;
448 mLineReaderParams = pLineReaderParams;
467 mLabelParams = pLabelParams;
468 mSeparatorParams = pSeparatorParams;
469 mConverterParams = pConverterParams;
470 mLineReaderParams = pLineReaderParams;
480 void Save(
const std::string &pPath = std::string())
493 void Save(std::ostream &pStream) { WriteCsv(pStream); }
502 mColumnNames.clear();
519 if (mColumnNames.find(pColumnName) != mColumnNames.end())
521 return mColumnNames.at(pColumnName) - (mLabelParams.
mRowNameIdx + 1);
532 template <
typename T>
535 const ssize_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
536 std::vector<T> column;
538 for (
auto itRow = mData.begin(); itRow != mData.end(); ++itRow)
540 if (std::distance(mData.begin(), itRow) > mLabelParams.
mColumnNameIdx)
543 converter.
ToVal(itRow->at(columnIdx), val);
544 column.push_back(val);
556 template <
typename T>
557 std::vector<T>
GetColumn(
const size_t pColumnIdx, ConvFunc<T> pToVal)
const
559 const ssize_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
560 std::vector<T> column;
561 for (
auto itRow = mData.begin(); itRow != mData.end(); ++itRow)
563 if (std::distance(mData.begin(), itRow) > mLabelParams.
mColumnNameIdx)
566 pToVal(itRow->at(columnIdx), val);
567 column.push_back(val);
578 template <
typename T>
579 std::vector<T>
GetColumn(
const std::string &pColumnName)
const
584 throw std::out_of_range(
"column not found: " + pColumnName);
595 template <
typename T>
596 std::vector<T>
GetColumn(
const std::string &pColumnName, ConvFunc<T> pToVal)
const
601 throw std::out_of_range(
"column not found: " + pColumnName);
611 template <
typename T>
612 void SetColumn(
const size_t pColumnIdx,
const std::vector<T> &pColumn)
614 const size_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
616 while (pColumn.size() + (mLabelParams.
mColumnNameIdx + 1) > GetDataRowCount())
618 std::vector<std::string> row;
619 row.resize(GetDataColumnCount());
620 mData.push_back(row);
623 if ((columnIdx + 1) > GetDataColumnCount())
625 for (
auto itRow = mData.begin(); itRow != mData.end(); ++itRow)
627 itRow->resize(columnIdx + 1 + (mLabelParams.
mRowNameIdx + 1));
632 for (
auto itRow = pColumn.begin(); itRow != pColumn.end(); ++itRow)
635 converter.
ToStr(*itRow, str);
637 .at(std::distance(pColumn.begin(), itRow) +
639 .at(columnIdx) = str;
648 template <
typename T>
649 void SetColumn(
const std::string &pColumnName,
const std::vector<T> &pColumn)
654 throw std::out_of_range(
"column not found: " + pColumnName);
665 const ssize_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
666 for (
auto itRow = mData.begin(); itRow != mData.end(); ++itRow)
668 itRow->erase(itRow->begin() + columnIdx);
681 throw std::out_of_range(
"column not found: " + pColumnName);
693 template <
typename T>
695 const std::vector<T> &pColumn = std::vector<T>(),
696 const std::string &pColumnName = std::string())
698 const size_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
700 std::vector<std::string> column;
703 column.resize(GetDataRowCount());
707 column.resize(pColumn.size() + (mLabelParams.
mColumnNameIdx + 1));
709 for (
auto itRow = pColumn.begin(); itRow != pColumn.end(); ++itRow)
712 converter.
ToStr(*itRow, str);
713 const size_t rowIdx = std::distance(pColumn.begin(), itRow) +
715 column.at(rowIdx) = str;
719 while (column.size() > GetDataRowCount())
721 std::vector<std::string> row;
722 const size_t columnCount =
724 GetDataColumnCount());
725 row.resize(columnCount);
726 mData.push_back(row);
729 for (
auto itRow = mData.begin(); itRow != mData.end(); ++itRow)
731 const size_t rowIdx = std::distance(mData.begin(), itRow);
732 itRow->insert(itRow->begin() + columnIdx, column.at(rowIdx));
735 if (!pColumnName.empty())
747 const ssize_t count =
748 static_cast<ssize_t
>((mData.size() > 0) ? mData.at(0).size() : 0) -
750 return (count >= 0) ? count : 0;
762 if (mRowNames.find(pRowName) != mRowNames.end())
764 return mRowNames.at(pRowName) - (mLabelParams.
mColumnNameIdx + 1);
775 template <
typename T>
776 std::vector<T>
GetRow(
const size_t pRowIdx)
const
778 const ssize_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
781 for (
auto itCol = mData.at(rowIdx).begin(); itCol != mData.at(rowIdx).end();
784 if (std::distance(mData.at(rowIdx).begin(), itCol) > mLabelParams.
mRowNameIdx)
787 converter.
ToVal(*itCol, val);
800 template <
typename T>
801 std::vector<T>
GetRow(
const size_t pRowIdx, ConvFunc<T> pToVal)
const
803 const ssize_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
806 for (
auto itCol = mData.at(rowIdx).begin(); itCol != mData.at(rowIdx).end();
809 if (std::distance(mData.at(rowIdx).begin(), itCol) > mLabelParams.
mRowNameIdx)
824 template <
typename T>
825 std::vector<T>
GetRow(
const std::string &pRowName)
const
830 throw std::out_of_range(
"row not found: " + pRowName);
841 template <
typename T>
842 std::vector<T>
GetRow(
const std::string &pRowName, ConvFunc<T> pToVal)
const
847 throw std::out_of_range(
"row not found: " + pRowName);
857 template <
typename T>
858 void SetRow(
const size_t pRowIdx,
const std::vector<T> &pRow)
860 const size_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
862 while ((rowIdx + 1) > GetDataRowCount())
864 std::vector<std::string> row;
865 row.resize(GetDataColumnCount());
866 mData.push_back(row);
869 if (pRow.size() > GetDataColumnCount())
871 for (
auto itRow = mData.begin(); itRow != mData.end(); ++itRow)
873 itRow->resize(pRow.size() + (mLabelParams.
mRowNameIdx + 1));
878 for (
auto itCol = pRow.begin(); itCol != pRow.end(); ++itCol)
881 converter.
ToStr(*itCol, str);
882 mData.at(rowIdx).at(std::distance(pRow.begin(), itCol) +
892 template <
typename T>
893 void SetRow(
const std::string &pRowName,
const std::vector<T> &pRow)
898 throw std::out_of_range(
"row not found: " + pRowName);
909 const ssize_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
910 mData.erase(mData.begin() + rowIdx);
922 throw std::out_of_range(
"row not found: " + pRowName);
934 template <
typename T>
935 void InsertRow(
const size_t pRowIdx,
const std::vector<T> &pRow = std::vector<T>(),
936 const std::string &pRowName = std::string())
938 const size_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
940 std::vector<std::string> row;
943 row.resize(GetDataColumnCount());
947 row.resize(pRow.size() + (mLabelParams.
mRowNameIdx + 1));
949 for (
auto itCol = pRow.begin(); itCol != pRow.end(); ++itCol)
952 converter.
ToStr(*itCol, str);
953 row.at(std::distance(pRow.begin(), itCol) +
958 while (rowIdx > GetDataRowCount())
960 std::vector<std::string> tempRow;
961 tempRow.resize(GetDataColumnCount());
962 mData.push_back(tempRow);
965 mData.insert(mData.begin() + rowIdx, row);
967 if (!pRowName.empty())
979 const ssize_t count =
980 static_cast<ssize_t
>(mData.size()) - (mLabelParams.
mColumnNameIdx + 1);
981 return (count >= 0) ? count : 0;
990 template <
typename T>
991 T
GetCell(
const size_t pColumnIdx,
const size_t pRowIdx)
const
993 const ssize_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
994 const ssize_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
998 converter.
ToVal(mData.at(rowIdx).at(columnIdx), val);
1009 template <
typename T>
1010 T
GetCell(
const size_t pColumnIdx,
const size_t pRowIdx, ConvFunc<T> pToVal)
const
1012 const ssize_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
1013 const ssize_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
1016 pToVal(mData.at(rowIdx).at(columnIdx), val);
1026 template <
typename T>
1027 T
GetCell(
const std::string &pColumnName,
const std::string &pRowName)
const
1032 throw std::out_of_range(
"column not found: " + pColumnName);
1035 const ssize_t rowIdx =
GetRowIdx(pRowName);
1038 throw std::out_of_range(
"row not found: " + pRowName);
1051 template <
typename T>
1052 T
GetCell(
const std::string &pColumnName,
const std::string &pRowName,
1053 ConvFunc<T> pToVal)
const
1058 throw std::out_of_range(
"column not found: " + pColumnName);
1061 const ssize_t rowIdx =
GetRowIdx(pRowName);
1064 throw std::out_of_range(
"row not found: " + pRowName);
1067 return GetCell<T>(columnIdx, rowIdx, pToVal);
1076 template <
typename T>
1077 T
GetCell(
const std::string &pColumnName,
const size_t pRowIdx)
const
1082 throw std::out_of_range(
"column not found: " + pColumnName);
1095 template <
typename T>
1096 T
GetCell(
const std::string &pColumnName,
const size_t pRowIdx,
1097 ConvFunc<T> pToVal)
const
1102 throw std::out_of_range(
"column not found: " + pColumnName);
1105 return GetCell<T>(columnIdx, pRowIdx, pToVal);
1114 template <
typename T>
1115 T
GetCell(
const size_t pColumnIdx,
const std::string &pRowName)
const
1117 const ssize_t rowIdx =
GetRowIdx(pRowName);
1120 throw std::out_of_range(
"row not found: " + pRowName);
1133 template <
typename T>
1134 T
GetCell(
const size_t pColumnIdx,
const std::string &pRowName,
1135 ConvFunc<T> pToVal)
const
1137 const ssize_t rowIdx =
GetRowIdx(pRowName);
1140 throw std::out_of_range(
"row not found: " + pRowName);
1143 return GetCell<T>(pColumnIdx, rowIdx, pToVal);
1152 template <
typename T>
1153 void SetCell(
const size_t pColumnIdx,
const size_t pRowIdx,
const T &pCell)
1155 const size_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
1156 const size_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
1158 while ((rowIdx + 1) > GetDataRowCount())
1160 std::vector<std::string> row;
1161 row.resize(GetDataColumnCount());
1162 mData.push_back(row);
1165 if ((columnIdx + 1) > GetDataColumnCount())
1167 for (
auto itRow = mData.begin(); itRow != mData.end(); ++itRow)
1169 itRow->resize(columnIdx + 1);
1175 converter.
ToStr(pCell, str);
1176 mData.at(rowIdx).at(columnIdx) = str;
1185 template <
typename T>
1186 void SetCell(
const std::string &pColumnName,
const std::string &pRowName,
1192 throw std::out_of_range(
"column not found: " + pColumnName);
1195 const ssize_t rowIdx =
GetRowIdx(pRowName);
1198 throw std::out_of_range(
"row not found: " + pRowName);
1211 const ssize_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
1214 throw std::out_of_range(
"column name row index < 0: " +
1228 const ssize_t columnIdx = pColumnIdx + (mLabelParams.
mRowNameIdx + 1);
1229 mColumnNames[pColumnName] = columnIdx;
1232 throw std::out_of_range(
"column name row index < 0: " +
1238 if (rowIdx >=
static_cast<int>(mData.size()))
1240 mData.resize(rowIdx + 1);
1242 auto &row = mData[rowIdx];
1243 if (columnIdx >=
static_cast<int>(row.size()))
1245 row.resize(columnIdx + 1);
1248 mData.at(mLabelParams.
mColumnNameIdx).at(columnIdx) = pColumnName;
1259 return std::vector<std::string>(
1265 return std::vector<std::string>();
1275 const ssize_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
1278 throw std::out_of_range(
"row name column index < 0: " +
1282 return mData.at(rowIdx).at(mLabelParams.
mRowNameIdx);
1292 const ssize_t rowIdx = pRowIdx + (mLabelParams.
mColumnNameIdx + 1);
1293 mRowNames[pRowName] = rowIdx;
1296 throw std::out_of_range(
"row name column index < 0: " +
1301 if (rowIdx >=
static_cast<int>(mData.size()))
1303 mData.resize(rowIdx + 1);
1305 auto &row = mData[rowIdx];
1306 if (mLabelParams.
mRowNameIdx >=
static_cast<int>(row.size()))
1311 mData.at(rowIdx).at(mLabelParams.
mRowNameIdx) = pRowName;
1320 std::vector<std::string> rownames;
1323 for (
auto itRow = mData.begin(); itRow != mData.end(); ++itRow)
1325 if (std::distance(mData.begin(), itRow) > mLabelParams.
mColumnNameIdx)
1327 rownames.push_back(itRow->at(mLabelParams.
mRowNameIdx));
1337 std::ifstream stream;
1338 stream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
1339 stream.open(mPath, std::ios::binary);
1343 void ReadCsv(std::istream &pStream)
1346 pStream.seekg(0, std::ios::end);
1347 std::streamsize length = pStream.tellg();
1348 pStream.seekg(0, std::ios::beg);
1351 std::vector<char> bom2b(2,
'\0');
1354 pStream.read(bom2b.data(), 2);
1355 pStream.seekg(0, std::ios::beg);
1358 static const std::vector<char> bomU16le = {
'\xff',
'\xfe' };
1359 static const std::vector<char> bomU16be = {
'\xfe',
'\xff' };
1360 if ((bom2b == bomU16le) || (bom2b == bomU16be))
1363 mIsLE = (bom2b == bomU16le);
1365 std::wifstream wstream;
1366 wstream.exceptions(std::wifstream::failbit | std::wifstream::badbit);
1367 wstream.open(mPath, std::ios::binary);
1371 std::locale(wstream.getloc(),
1372 new std::codecvt_utf16<
wchar_t, 0x10ffff,
1373 static_cast<std::codecvt_mode
>(
1374 std::consume_header |
1375 std::little_endian)>));
1379 wstream.imbue(std::locale(
1381 new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
1383 std::wstringstream wss;
1384 wss << wstream.rdbuf();
1385 std::string utf8 = ToString(wss.str());
1386 std::stringstream ss(utf8);
1387 ParseCsv(ss, utf8.size());
1395 std::vector<char> bom3b(3,
'\0');
1396 pStream.read(bom3b.data(), 3);
1397 static const std::vector<char> bomU8 = {
'\xef',
'\xbb',
'\xbf' };
1401 pStream.seekg(0, std::ios::beg);
1410 ParseCsv(pStream, length);
1414 void ParseCsv(std::istream &pStream, std::streamsize p_FileLength)
1416 const std::streamsize bufLength = 64 * 1024;
1417 std::vector<char> buffer(bufLength);
1418 std::vector<std::string> row;
1420 bool quoted =
false;
1424 while (p_FileLength > 0)
1426 std::streamsize readLength =
1427 std::min<std::streamsize>(p_FileLength, bufLength);
1428 pStream.read(buffer.data(), readLength);
1429 for (
int i = 0; i < readLength; ++i)
1431 if (buffer[i] ==
'"')
1433 if (cell.empty() || cell[0] ==
'"')
1439 else if (buffer[i] == mSeparatorParams.
mSeparator)
1443 row.push_back(Unquote(Trim(cell)));
1451 else if (buffer[i] ==
'\r')
1462 else if (buffer[i] ==
'\n')
1478 row.push_back(Unquote(Trim(cell)));
1481 !row.at(0).empty() &&
1488 mData.push_back(row);
1502 p_FileLength -= readLength;
1506 if (!cell.empty() || !row.empty())
1508 row.push_back(Unquote(Trim(cell)));
1510 mData.push_back(row);
1515 mSeparatorParams.
mHasCR = (cr > (lf / 2));
1519 (
static_cast<ssize_t
>(mData.size()) > mLabelParams.
mColumnNameIdx))
1524 mColumnNames[columnName] = i++;
1530 (
static_cast<ssize_t
>(mData.size()) > (mLabelParams.
mColumnNameIdx + 1)))
1533 for (
auto &dataRow : mData)
1535 if (
static_cast<ssize_t
>(dataRow.size()) > mLabelParams.
mRowNameIdx)
1537 mRowNames[dataRow[mLabelParams.
mRowNameIdx]] = i++;
1543 void WriteCsv()
const
1548 std::stringstream ss;
1550 std::string utf8 = ss.str();
1551 std::wstring wstr = ToWString(utf8);
1553 std::wofstream wstream;
1554 wstream.exceptions(std::wofstream::failbit | std::wofstream::badbit);
1555 wstream.open(mPath, std::ios::binary | std::ios::trunc);
1560 std::locale(wstream.getloc(),
1561 new std::codecvt_utf16<
wchar_t, 0x10ffff,
1562 static_cast<std::codecvt_mode
>(
1563 std::little_endian)>));
1567 wstream.imbue(std::locale(wstream.getloc(),
1568 new std::codecvt_utf16<wchar_t, 0x10ffff>));
1571 wstream << static_cast<wchar_t>(0xfeff);
1577 std::ofstream stream;
1578 stream.exceptions(std::ofstream::failbit | std::ofstream::badbit);
1579 stream.open(mPath, std::ios::binary | std::ios::trunc);
1584 void WriteCsv(std::ostream &pStream)
const
1586 for (
auto itr = mData.begin(); itr != mData.end(); ++itr)
1588 for (
auto itc = itr->begin(); itc != itr->end(); ++itc)
1591 ((itc->find(mSeparatorParams.
mSeparator) != std::string::npos) ||
1592 (itc->find(
' ') != std::string::npos)))
1595 std::string str = *itc;
1596 ReplaceString(str,
"\"",
"\"\"");
1598 pStream <<
"\"" << str <<
"\"";
1605 if (std::distance(itc, itr->end()) > 1)
1610 pStream << (mSeparatorParams.
mHasCR ?
"\r\n" :
"\n");
1614 size_t GetDataRowCount()
const {
return mData.size(); }
1616 size_t GetDataColumnCount()
const
1618 return (mData.size() > 0) ? mData.at(0).size() : 0;
1621 std::string Trim(
const std::string &pStr)
1623 if (mSeparatorParams.
mTrim)
1625 std::string str = pStr;
1628 str.erase(str.begin(), std::find_if(str.begin(), str.end(),
1629 [](
int ch) { return !isspace(ch); }));
1632 str.erase(std::find_if(str.rbegin(), str.rend(),
1633 [](
int ch) { return !isspace(ch); })
1645 std::string Unquote(
const std::string &pStr)
1647 if (mSeparatorParams.
mAutoQuote && (pStr.size() >= 2) && (pStr.front() ==
'"') &&
1648 (pStr.back() ==
'"'))
1651 std::string str = pStr.substr(1, pStr.size() - 2);
1654 ReplaceString(str,
"\"\"",
"\"");
1665#if defined(_MSC_VER)
1666#pragma warning(disable : 4996)
1668 static std::string ToString(
const std::wstring &pWStr)
1670 size_t len = std::wcstombs(
nullptr, pWStr.c_str(), 0) + 1;
1671 char *cstr =
new char[len];
1672 std::wcstombs(cstr, pWStr.c_str(), len);
1673 std::string str(cstr);
1678 static std::wstring ToWString(
const std::string &pStr)
1680 size_t len = 1 + mbstowcs(
nullptr, pStr.c_str(), 0);
1681 wchar_t *wcstr =
new wchar_t[len];
1682 std::mbstowcs(wcstr, pStr.c_str(), len);
1683 std::wstring wstr(wcstr);
1687#if defined(_MSC_VER)
1688#pragma warning(default : 4996)
1692 static void ReplaceString(std::string &pStr,
const std::string &pSearch,
1693 const std::string &pReplace)
1697 while ((pos = pStr.find(pSearch, pos)) != std::string::npos)
1699 pStr.replace(pos, pSearch.size(), pReplace);
1700 pos += pReplace.size();
1706 LabelParams mLabelParams;
1707 SeparatorParams mSeparatorParams;
1708 ConverterParams mConverterParams;
1709 LineReaderParams mLineReaderParams;
1710 std::vector<std::vector<std::string>> mData;
1711 std::map<std::string, size_t> mColumnNames;
1712 std::map<std::string, size_t> mRowNames;
1714 bool mIsUtf16 =
false;
Class providing conversion to/from numerical datatypes and strings.
void ToStr(const T &pVal, std::string &pStr) const
Converts numerical value to string representation.
void ToVal(const std::string &pStr, T &pVal) const
Converts string holding a numerical value to numerical datatype representation.
Converter(const ConverterParams &pConverterParams)
Constructor.
Class representing a CSV document.
std::vector< T > GetRow(const std::string &pRowName, ConvFunc< T > pToVal) const
Get row by name.
std::string GetRowName(const ssize_t pRowIdx)
Get row name.
ssize_t GetColumnIdx(const std::string &pColumnName) const
Get column index by name.
void SetRow(const std::string &pRowName, const std::vector< T > &pRow)
Set row by name.
std::vector< T > GetRow(const size_t pRowIdx, ConvFunc< T > pToVal) const
Get row by index.
T GetCell(const std::string &pColumnName, const std::string &pRowName) const
Get cell by name.
std::vector< T > GetColumn(const size_t pColumnIdx, ConvFunc< T > pToVal) const
Get column by index.
void RemoveColumn(const size_t pColumnIdx)
Remove column by index.
T GetCell(const size_t pColumnIdx, const std::string &pRowName) const
Get cell by column index and row name.
void Clear()
Clears loaded Document data.
std::vector< std::string > GetColumnNames()
Get column names.
Document(const std::string &pPath=std::string(), const LabelParams &pLabelParams=LabelParams(), const SeparatorParams &pSeparatorParams=SeparatorParams(), const ConverterParams &pConverterParams=ConverterParams(), const LineReaderParams &pLineReaderParams=LineReaderParams())
Constructor.
std::vector< T > GetColumn(const std::string &pColumnName) const
Get column by name.
void RemoveRow(const std::string &pRowName)
Remove row by name.
T GetCell(const size_t pColumnIdx, const size_t pRowIdx, ConvFunc< T > pToVal) const
Get cell by index.
void SetColumnName(size_t pColumnIdx, const std::string &pColumnName)
Set column name.
void SetRowName(size_t pRowIdx, const std::string &pRowName)
Set row name.
T GetCell(const size_t pColumnIdx, const size_t pRowIdx) const
Get cell by index.
std::vector< T > GetRow(const std::string &pRowName) const
Get row by name.
void SetRow(const size_t pRowIdx, const std::vector< T > &pRow)
Set row by index.
std::vector< T > GetColumn(const std::string &pColumnName, ConvFunc< T > pToVal) const
Get column by name.
std::vector< T > GetColumn(const size_t pColumnIdx) const
Get column by index.
std::vector< std::string > GetRowNames()
Get row names.
void Load(const std::string &pPath, const LabelParams &pLabelParams=LabelParams(), const SeparatorParams &pSeparatorParams=SeparatorParams(), const ConverterParams &pConverterParams=ConverterParams(), const LineReaderParams &pLineReaderParams=LineReaderParams())
Read Document data from file.
void InsertColumn(const size_t pColumnIdx, const std::vector< T > &pColumn=std::vector< T >(), const std::string &pColumnName=std::string())
Insert column at specified index.
void InsertRow(const size_t pRowIdx, const std::vector< T > &pRow=std::vector< T >(), const std::string &pRowName=std::string())
Insert row at specified index.
void SetCell(const size_t pColumnIdx, const size_t pRowIdx, const T &pCell)
Set cell by index.
T GetCell(const std::string &pColumnName, const size_t pRowIdx) const
Get cell by column name and row index.
void Save(const std::string &pPath=std::string())
Write Document data to file.
ssize_t GetRowIdx(const std::string &pRowName) const
Get row index by name.
T GetCell(const std::string &pColumnName, const std::string &pRowName, ConvFunc< T > pToVal) const
Get cell by name.
T GetCell(const size_t pColumnIdx, const std::string &pRowName, ConvFunc< T > pToVal) const
Get cell by column index and row name.
void Save(std::ostream &pStream)
Write Document data to stream.
void SetColumn(const std::string &pColumnName, const std::vector< T > &pColumn)
Set column by name.
void SetCell(const std::string &pColumnName, const std::string &pRowName, const T &pCell)
Set cell by name.
std::string GetColumnName(const ssize_t pColumnIdx)
Get column name.
void Load(std::istream &pStream, const LabelParams &pLabelParams=LabelParams(), const SeparatorParams &pSeparatorParams=SeparatorParams(), const ConverterParams &pConverterParams=ConverterParams(), const LineReaderParams &pLineReaderParams=LineReaderParams())
Read Document data from stream.
void RemoveColumn(const std::string &pColumnName)
Remove column by name.
void RemoveRow(const size_t pRowIdx)
Remove row by index.
Document(std::istream &pStream, const LabelParams &pLabelParams=LabelParams(), const SeparatorParams &pSeparatorParams=SeparatorParams(), const ConverterParams &pConverterParams=ConverterParams(), const LineReaderParams &pLineReaderParams=LineReaderParams())
Constructor.
void SetColumn(const size_t pColumnIdx, const std::vector< T > &pColumn)
Set column by index.
size_t GetColumnCount() const
Get number of data columns (excluding label columns).
T GetCell(const std::string &pColumnName, const size_t pRowIdx, ConvFunc< T > pToVal) const
Get cell by column name and row index.
size_t GetRowCount() const
Get number of data rows (excluding label rows).
std::vector< T > GetRow(const size_t pRowIdx) const
Get row by index.
Exception thrown when attempting to access Document data in a datatype which is not supported by the ...
Datastructure holding parameters controlling how invalid numbers (including empty strings) should be ...
long double mDefaultFloat
floating-point default value to represent invalid numbers.
long long mDefaultInteger
integer default value to represent invalid numbers.
bool mHasDefaultConverter
specifies if conversion of non-numerical strings shall be converted to a default numerical value,...
ConverterParams(const bool pHasDefaultConverter=false, const long double pDefaultFloat=std::numeric_limits< long double >::signaling_NaN(), const long long pDefaultInteger=0)
Constructor.
Datastructure holding parameters controlling which row and column should be treated as labels.
int mRowNameIdx
specifies the zero-based column index of the row labels.
LabelParams(const int pColumnNameIdx=0, const int pRowNameIdx=-1)
Constructor.
int mColumnNameIdx
specifies the zero-based row index of the column labels.
Datastructure holding parameters controlling how special line formats should be treated.
bool mSkipCommentLines
specifies whether to skip lines prefixed with mCommentPrefix.
char mCommentPrefix
specifies which prefix character to indicate a comment line.
bool mSkipEmptyLines
specifies whether to skip empty lines.
LineReaderParams(const bool pSkipCommentLines=false, const char pCommentPrefix='#', const bool pSkipEmptyLines=false)
Constructor.
Datastructure holding parameters controlling how the CSV data fields are separated.
bool mQuotedLinebreaks
specifies whether to allow line breaks in quoted text.
bool mTrim
specifies whether to trim leading and trailing spaces from cells read.
SeparatorParams(const char pSeparator=',', const bool pTrim=false, const bool pHasCR=sPlatformHasCR, const bool pQuotedLinebreaks=false, const bool pAutoQuote=true)
Constructor.
bool mHasCR
specifies whether new documents should use CR/LF instead of LF.
char mSeparator
specifies the column separator.
bool mAutoQuote
specifies whether to automatically dequote cell data.