45 class ReadStreamCSV : 
public ReadStream {
 
   47     ReadStreamCSV(std::istream& 
file, 
const std::map<std::string, std::string>& rwOperation,
 
   72         if (!getline(
file, line)) {
 
   76         if (!line.empty() && line.back() == 
'\r') {
 
   77             line = line.substr(0, line.length() - 1);
 
   83         size_t columnsFilled = 0;
 
   84         for (uint32_t column = 0; columnsFilled < 
arity; column++) {
 
   85             size_t charactersRead = 0;
 
   86             std::string element = 
nextElement(line, start, end);
 
   97                         charactersRead = element.size();
 
  120                     default: 
fatal(
"invalid type attribute: `%c`", ty[0]);
 
  123                 if (charactersRead != element.size()) {
 
  124                     throw std::invalid_argument(
 
  125                             "Expected: " + 
delimiter + 
" or \\n. Got: " + element[charactersRead]);
 
  128                 std::stringstream errorMessage;
 
  129                 errorMessage << 
"Error converting <" + element + 
"> in column " << column + 1 << 
" in line " 
  131                 throw std::invalid_argument(errorMessage.str());
 
  144         assert(element.size() > 0);
 
  151         } 
else if (
isPrefix(
"0x", element)) {
 
  159     std::string 
nextElement(
const std::string& line, 
size_t& start, 
size_t& end) {
 
  164             int record_parens = 0;
 
  165             size_t next_delimiter = line.find(
delimiter, start);
 
  168             while (end < std::min(next_delimiter, line.length()) || record_parens != 0) {
 
  170                 if (line[end] == 
'[') {
 
  172                 } 
else if (line[end] == 
']') {
 
  177                 if (record_parens < 0) {
 
  185                 if (end == next_delimiter && record_parens != 0) {
 
  186                     next_delimiter = line.find(
delimiter, end);
 
  191             if (record_parens != 0) {
 
  192                 std::stringstream errorMessage;
 
  193                 errorMessage << 
"Unbalanced record parenthesis " << 
lineNumber << 
"; ";
 
  194                 throw std::invalid_argument(errorMessage.str());
 
  197             end = std::min(line.find(
delimiter, start), line.length());
 
  202             std::stringstream errorMessage;
 
  203             errorMessage << 
"Values missing in line " << 
lineNumber << 
"; ";
 
  204             throw std::invalid_argument(errorMessage.str());
 
  207         element = line.substr(start, end - start);
 
  214             const std::map<std::string, std::string>& rwOperation, 
const unsigned arity_)
 const {
 
  215         std::string columnString = 
getOr(rwOperation, 
"columns", 
"");
 
  216         std::map<int, int> inputColumnMap;
 
  218         if (!columnString.empty()) {
 
  219             std::istringstream iss(columnString);
 
  222             while (std::getline(iss, mapping, 
':')) {
 
  223                 inputColumnMap[stoi(mapping)] = index++;
 
  225             if (inputColumnMap.size() < arity_) {
 
  226                 throw std::invalid_argument(
"Invalid column set was given: <" + columnString + 
">");
 
  229             while (inputColumnMap.size() < arity_) {
 
  230                 int size = 
static_cast<int>(inputColumnMap.size());
 
  234         return inputColumnMap;
 
  251             throw std::invalid_argument(
"Cannot open fact file " + 
baseName + 
"\n");
 
  254         if (
getOr(rwOperation, 
"headers", 
"false") == 
"true") {
 
  269         } 
catch (std::exception& 
e) {
 
  270             std::stringstream errorMessage;
 
  271             errorMessage << 
e.what();
 
  272             errorMessage << 
"cannot parse fact file " << 
baseName << 
"!\n";
 
  273             throw std::invalid_argument(errorMessage.str());
 
  287     static std::string 
getFileName(
const std::map<std::string, std::string>& rwOperation) {
 
  288         auto name = 
getOr(rwOperation, 
"filename", rwOperation.at(
"name") + 
".facts");
 
  289         if (name.front() != 
'/') {
 
  290             name = 
getOr(rwOperation, 
"fact-dir", 
".") + 
"/" + name;
 
  307         return mk<ReadStreamCSV>(std::cin, rwOperation, symbolTable, recordTable);
 
  310     const std::string& 
getName()
 const override {
 
  311         static const std::string name = 
"stdin";
 
  321         return mk<ReadFileCSV>(rwOperation, symbolTable, recordTable);
 
  324     const std::string& 
getName()
 const override {
 
  325         static const std::string name = 
"file";