21 #include "eckit/filesystem/PathName.h"
22 #include "eckit/utils/StringTools.h"
23 #include "eckit/types/Types.h"
24 #include "eckit/utils/Translator.h"
29 using namespace eckit;
31 typedef StringTools
S;
35 TextReaderIterator::TextReaderIterator(
TextReader &owner)
40 delimiter_(owner.delimiter()),
59 delimiter_(owner.delimiter()),
66 in_ =
new std::ifstream(pathName.localPath());
77 size_t leftBracket (
c.find(
'['));
78 size_t rightBracket (
c.find(
']'));
80 if ( !(leftBracket != std::string::npos && rightBracket != std::string::npos))
81 throw UserError(std::string(
"Error parsing bitfield definition. Should be like: bitfield_column_name:BITFIELD[a:1;b:3] was: '") +
c +
"'");
83 std::string s(
c.substr(leftBracket + 1, rightBracket - leftBracket - 1));
87 eckit::sql::FieldNames names;
88 eckit::sql::Sizes sizes;
90 size_t numberOfBits = 0;
91 std::vector<std::string> bs(S::split(
";", s));
95 for (
size_t i = 0;
i < bs.size(); ++
i)
97 std::vector<std::string> v(S::split(
":", bs[
i]));
102 throw UserError(
"Bitfields definition parse error");
104 if (std::find(names.begin(), names.end(), v[0]) != names.end())
105 throw UserError(
"Names of fields must be unique within one bitfield");
107 names.push_back(v[0]);
109 int size = atoi(v[1].c_str());
111 if ( !(v.size() > 0) )
112 throw UserError(
"Size of a bitfield must be positive and larger than zero");
114 numberOfBits += size;
115 sizes.push_back(size);
119 if (numberOfBits > 31) {
120 throw UserError(
"Bitfields can have up to 31 bits only currently");
123 return eckit::sql::BitfieldDef(make_pair(names, sizes));
129 std::getline(*
in_, header);
133 std::ostream& L(Log::info());
135 L <<
"TextReaderIterator::parseHeader: columns: " <<
columns << std::endl;
136 L <<
"TextReaderIterator::parseHeader: delimiter: '" <<
delimiter_ <<
"'" << std::endl;
137 L <<
"TextReaderIterator::parseHeader: header: '" << header <<
"'" << std::endl;
141 Log::debug() <<
"TextReaderIterator::parseHeader: column " <<
i <<
" '" <<
columns[
i] <<
"'" << std::endl;
142 std::vector<std::string> column (S::split(
":",
columns[
i]));
143 if (column.size() < 2)
144 throw UserError(std::string(
"Column '") +
columns[
i] +
"': format should be NAME \":\" TYPE");
146 const std::string columnName (
S::trim(column[0]));
147 const std::string columnType (S::upper(S::join(
":", std::vector<std::string>(column.begin() + 1, column.end()))));
149 if (! S::startsWith(columnType,
"BITFIELD"))
151 Log::debug() <<
"TextReaderIterator::parseHeader: adding column " <<
columns_.size() <<
" '" << columnName <<
"' : "
152 << columnType << std::endl;
157 Log::debug() <<
"TextReaderIterator::parseHeader: adding BITFIELD " <<
columns_.size() <<
" '" <<
columns[
i] << std::endl;
184 for (
size_t i = 0;
i <
columns().size();
i++) {
201 std::getline(*
in_, line);
203 std::vector<std::string> values(S::split(
delimiter_, line));
205 size_t nCols = values.size();
208 ASSERT(nCols ==
columns().size());
210 for(
size_t i = 0;
i < nCols; ++
i)
212 const std::string& v (
S::trim(values[
i]));
213 if (S::upper(v) ==
"NULL") {
221 std::string unquoted = S::unQuote(v);
222 size_t charlen = unquoted.length();
223 size_t lenDoubles = charlen > 0 ? (((charlen - 1) / 8) + 1): 1;
228 if (lenDoubles >
columns_[
i]->dataSizeDoubles()) {
231 columns_[
i]->dataSizeDoubles(lenDoubles);
243 lenDoubles =
columns_[
i]->dataSizeDoubles();
245 ::memcpy(buf, &unquoted[0], charlen);
246 ::memset(buf + charlen, 0, (lenDoubles *
sizeof(
double)) - charlen);
264 throw SeriousBug(
"Unexpected type in column", Here());
core::MetaData & columns()
static eckit::sql::BitfieldDef parseBitfields(const std::string &)
bool operator!=(const TextReaderIterator &other)
size_t rowDataSizeDoubles_
const double * data() const
std::string trim(const std::string &str)