|
6 | 6 | #include <fstream>
|
7 | 7 | #include <stdexcept>
|
8 | 8 |
|
9 |
| -void IndexParser::buildIndexes(Index::Builder *builder, ConsoleLog& log) { |
| 9 | +void IndexParser::buildIndexes(Index::Builder *builder, ConsoleLog &log) { |
10 | 10 | std::ifstream in(fileName_, std::ifstream::in);
|
11 | 11 | std::string contents((std::istreambuf_iterator<char>(in)),
|
12 | 12 | 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) { |
15 | 15 | throw std::runtime_error("Could not parse the json config file. "
|
16 | 16 | "Careful, this is a strict parser.");
|
17 | 17 | }
|
18 | 18 | if (!cJSON_HasObjectItem(root, "indexes")) {
|
19 | 19 | throw std::runtime_error("No indexes to be found in the config file.");
|
20 | 20 | }
|
21 |
| - cJSON* indexes = cJSON_GetObjectItem(root,"indexes"); |
| 21 | + cJSON *indexes = cJSON_GetObjectItem(root, "indexes"); |
22 | 22 | auto arraySize = cJSON_GetArraySize(indexes);
|
23 |
| - for (int i =0; i < arraySize; i++) { |
| 23 | + for (int i = 0; i < arraySize; i++) { |
24 | 24 | parseIndex(cJSON_GetArrayItem(indexes, i), builder, log);
|
25 | 25 | }
|
26 | 26 | }
|
27 | 27 |
|
28 |
| -void IndexParser::parseIndex(cJSON *index, Index::Builder *builder, ConsoleLog& log) { |
| 28 | +void IndexParser::parseIndex(cJSON *index, Index::Builder *builder, |
| 29 | + ConsoleLog &log) { |
29 | 30 | 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, "); |
31 | 33 | }
|
32 | 34 | std::string indexName = "default";
|
33 | 35 | if (cJSON_HasObjectItem(index, "name")) {
|
34 | 36 | indexName = cJSON_GetObjectItem(index, "name")->valuestring;
|
35 | 37 | }
|
36 | 38 | std::string type = cJSON_GetObjectItem(index, "type")->valuestring;
|
37 | 39 | 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"); |
42 | 44 |
|
43 |
| - // TODO: if anything is missing here we segfault |
44 | 45 | if (type == "regex") {
|
45 |
| - std::string regex = cJSON_GetObjectItem(index, "regex")->valuestring; |
| 46 | + auto regex = getOrThrowStr(index, "regex"); |
46 | 47 | if (cJSON_HasObjectItem(index, "capture")) {
|
47 | 48 | uint capture = cJSON_GetObjectItem(index, "capture")->valueint;
|
48 | 49 | builder->addIndexer(indexName, regex, config,
|
49 |
| - std::unique_ptr<LineIndexer>(new RegExpIndexer(regex, capture))); |
| 50 | + std::unique_ptr<LineIndexer>( |
| 51 | + new RegExpIndexer(regex, capture))); |
50 | 52 | } else {
|
51 | 53 | builder->addIndexer(indexName, regex, config,
|
52 |
| - std::unique_ptr<LineIndexer>(new RegExpIndexer(regex))); |
| 54 | + std::unique_ptr<LineIndexer>( |
| 55 | + new RegExpIndexer(regex))); |
53 | 56 | }
|
54 | 57 | } 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"); |
57 | 60 | std::ostringstream name;
|
58 | 61 | name << "Field " << fieldNum << " delimited by '"
|
59 |
| - << delimiter << "'"; |
| 62 | + << delimiter << "'"; |
60 | 63 | 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))); |
62 | 66 | } 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"); |
65 | 69 |
|
66 | 70 | 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)))); |
69 | 74 | } else {
|
70 | 75 | throw std::runtime_error("unknown index " + type);
|
71 | 76 | }
|
72 | 77 | }
|
| 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 | +} |
0 commit comments