Skip to content

Commit 85c48dc

Browse files
author
Matt Godbolt
committed
Tidy up the index parsing
1 parent 8074c58 commit 85c48dc

File tree

2 files changed

+55
-24
lines changed

2 files changed

+55
-24
lines changed

src/IndexParser.cpp

+52-23
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,96 @@
66
#include <fstream>
77
#include <stdexcept>
88

9-
void IndexParser::buildIndexes(Index::Builder *builder, ConsoleLog& log) {
9+
void IndexParser::buildIndexes(Index::Builder *builder, ConsoleLog &log) {
1010
std::ifstream in(fileName_, std::ifstream::in);
1111
std::string contents((std::istreambuf_iterator<char>(in)),
1212
std::istreambuf_iterator<char>());
13-
cJSON * root = cJSON_Parse(contents.c_str());
14-
if(root == nullptr) {
13+
cJSON *root = cJSON_Parse(contents.c_str());
14+
if (root == nullptr) {
1515
throw std::runtime_error("Could not parse the json config file. "
1616
"Careful, this is a strict parser.");
1717
}
1818
if (!cJSON_HasObjectItem(root, "indexes")) {
1919
throw std::runtime_error("No indexes to be found in the config file.");
2020
}
21-
cJSON* indexes = cJSON_GetObjectItem(root,"indexes");
21+
cJSON *indexes = cJSON_GetObjectItem(root, "indexes");
2222
auto arraySize = cJSON_GetArraySize(indexes);
23-
for (int i =0; i < arraySize; i++) {
23+
for (int i = 0; i < arraySize; i++) {
2424
parseIndex(cJSON_GetArrayItem(indexes, i), builder, log);
2525
}
2626
}
2727

28-
void IndexParser::parseIndex(cJSON *index, Index::Builder *builder, ConsoleLog& log) {
28+
void IndexParser::parseIndex(cJSON *index, Index::Builder *builder,
29+
ConsoleLog &log) {
2930
if (!cJSON_HasObjectItem(index, "type")) {
30-
throw std::runtime_error("All indexes must have a type field, i.e. Regex, Field, ");
31+
throw std::runtime_error(
32+
"All indexes must have a type field, i.e. Regex, Field, ");
3133
}
3234
std::string indexName = "default";
3335
if (cJSON_HasObjectItem(index, "name")) {
3436
indexName = cJSON_GetObjectItem(index, "name")->valuestring;
3537
}
3638
std::string type = cJSON_GetObjectItem(index, "type")->valuestring;
3739
Index::IndexConfig config{};
38-
config.numeric = cJSON_GetObjectItem(index, "numeric") && strcmp("true", cJSON_GetObjectItem(index, "numeric")->string);
39-
config.unique = cJSON_GetObjectItem(index, "unique") && strcmp("true", cJSON_GetObjectItem(index, "unique")->string);
40-
config.sparse = cJSON_GetObjectItem(index, "sparse") && strcmp("true", cJSON_GetObjectItem(index, "sparse")->string);
41-
config.indexLineOffsets = cJSON_GetObjectItem(index, "indexLineOffsets") && strcmp("true", cJSON_GetObjectItem(index, "indexLineOffsets")->string);
40+
config.numeric = getBoolean(index, "numeric");
41+
config.unique = getBoolean(index, "unique");
42+
config.sparse = getBoolean(index, "sparse");
43+
config.indexLineOffsets = getBoolean(index, "indexLineOffsets");
4244

43-
// TODO: if anything is missing here we segfault
4445
if (type == "regex") {
45-
std::string regex = cJSON_GetObjectItem(index, "regex")->valuestring;
46+
auto regex = getOrThrowStr(index, "regex");
4647
if (cJSON_HasObjectItem(index, "capture")) {
4748
uint capture = cJSON_GetObjectItem(index, "capture")->valueint;
4849
builder->addIndexer(indexName, regex, config,
49-
std::unique_ptr<LineIndexer>(new RegExpIndexer(regex, capture)));
50+
std::unique_ptr<LineIndexer>(
51+
new RegExpIndexer(regex, capture)));
5052
} else {
5153
builder->addIndexer(indexName, regex, config,
52-
std::unique_ptr<LineIndexer>(new RegExpIndexer(regex)));
54+
std::unique_ptr<LineIndexer>(
55+
new RegExpIndexer(regex)));
5356
}
5457
} else if (type == "field") {
55-
std::string delimiter = cJSON_GetObjectItem(index, "delimiter")->valuestring;
56-
uint fieldNum = cJSON_GetObjectItem(index, "fieldNum")->valueint;
58+
auto delimiter = getOrThrowStr(index, "delimiter");
59+
auto fieldNum = getOrThrowUint(index, "fieldNum");
5760
std::ostringstream name;
5861
name << "Field " << fieldNum << " delimited by '"
59-
<< delimiter << "'";
62+
<< delimiter << "'";
6063
builder->addIndexer(indexName, name.str(), config,
61-
std::unique_ptr<LineIndexer>(new FieldIndexer(delimiter, fieldNum)));
64+
std::unique_ptr<LineIndexer>(
65+
new FieldIndexer(delimiter, fieldNum)));
6266
} else if (type == "pipe") {
63-
std::string pipeCommand = cJSON_GetObjectItem(index, "command")->valuestring;
64-
std::string delimiter = cJSON_GetObjectItem(index, "delimiter")->valuestring;
67+
auto pipeCommand = getOrThrowStr(index, "command");
68+
auto delimiter = getOrThrowStr(index, "delimiter");
6569

6670
builder->addIndexer(indexName, pipeCommand, config, std::move(
67-
std::unique_ptr<LineIndexer>(new ExternalIndexer(log,
68-
pipeCommand, delimiter))));
71+
std::unique_ptr<LineIndexer>(new ExternalIndexer(log,
72+
pipeCommand,
73+
delimiter))));
6974
} else {
7075
throw std::runtime_error("unknown index " + type);
7176
}
7277
}
78+
79+
bool IndexParser::getBoolean(cJSON *index, const char *field) const {
80+
return cJSON_GetObjectItem(index, field)
81+
&& strcmp("true", cJSON_GetObjectItem(index, field)->string);
82+
}
83+
84+
std::string IndexParser::getOrThrowStr(cJSON *index, const char *field) const {
85+
auto *item = cJSON_GetObjectItem(index, field);
86+
if (!item)
87+
throw std::runtime_error("Could not parse the json config file. Field '"
88+
+ std::string(field) + "' was missing");
89+
return item->valuestring;
90+
}
91+
92+
unsigned IndexParser::getOrThrowUint(cJSON *index, const char *field) const {
93+
auto *item = cJSON_GetObjectItem(index, field);
94+
if (!item)
95+
throw std::runtime_error("Could not parse the json config file. Field '"
96+
+ std::string(field) + "' was missing");
97+
if (item->valueint < 0)
98+
throw std::runtime_error("Could not parse the json config file. Field '"
99+
+ std::string(field) + "' was negative");
100+
return static_cast<unsigned>(item->valueint);
101+
}

src/IndexParser.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,7 @@ class IndexParser {
1818

1919
private:
2020
void parseIndex(cJSON *index, Index::Builder* builder, ConsoleLog& log);
21-
void parse(const char *p, Index::Builder* builder, ConsoleLog& log);
21+
bool getBoolean(cJSON *index, const char *field) const;
22+
std::string getOrThrowStr(cJSON *index, const char *field) const;
23+
unsigned getOrThrowUint(cJSON *index, const char *field) const;
2224
};

0 commit comments

Comments
 (0)