Parse an inline key=value config pair.
| 79 | |
| 80 | // Parse an inline key=value config pair. |
| 81 | bool |
| 82 | RemapConfigs::parse_inline(const char *arg) |
| 83 | { |
| 84 | const char *sep; |
| 85 | std::string key; |
| 86 | std::string value; |
| 87 | |
| 88 | TSOverridableConfigKey name; |
| 89 | TSRecordDataType type; |
| 90 | |
| 91 | // Each token should be a configuration variable then a value, separated by '='. |
| 92 | sep = strchr(arg, '='); |
| 93 | if (sep == nullptr) { |
| 94 | return false; |
| 95 | } |
| 96 | |
| 97 | key = std::string(arg, std::distance(arg, sep)); |
| 98 | value = std::string(sep + 1, std::distance(sep + 1, arg + strlen(arg))); |
| 99 | |
| 100 | if (TSHttpTxnConfigFind(key.c_str(), -1 /* len */, &name, &type) != TS_SUCCESS) { |
| 101 | TSWarning("[%s] Invalid configuration variable '%s'", PLUGIN_NAME, key.c_str()); |
| 102 | return true; |
| 103 | } |
| 104 | |
| 105 | switch (type) { |
| 106 | case TS_RECORDDATATYPE_INT: |
| 107 | _items[_current]._data.rec_int = strtoll(value.c_str(), nullptr, 10); |
| 108 | break; |
| 109 | case TS_RECORDDATATYPE_STRING: |
| 110 | if (strcmp(value.c_str(), "NULL") == 0) { |
| 111 | _items[_current]._data.rec_string = nullptr; |
| 112 | _items[_current]._data_len = 0; |
| 113 | } else { |
| 114 | _items[_current]._data.rec_string = TSstrdup(value.c_str()); |
| 115 | _items[_current]._data_len = value.size(); |
| 116 | } |
| 117 | break; |
| 118 | case TS_RECORDDATATYPE_FLOAT: |
| 119 | _items[_current]._data.rec_float = strtof(value.c_str(), nullptr); |
| 120 | break; |
| 121 | default: |
| 122 | TSError("[%s] Configuration variable '%s' is of an unsupported type", PLUGIN_NAME, key.c_str()); |
| 123 | return false; |
| 124 | } |
| 125 | |
| 126 | _items[_current]._name = name; |
| 127 | _items[_current]._type = type; |
| 128 | ++_current; |
| 129 | return true; |
| 130 | } |
| 131 | |
| 132 | namespace |
| 133 | { |
no test coverage detected