| /* | |
| Licensed to the Apache Software Foundation (ASF) under one | |
| or more contributor license agreements. See the NOTICE file | |
| distributed with this work for additional information | |
| regarding copyright ownership. The ASF licenses this file | |
| to you under the Apache License, Version 2.0 (the | |
| "License"); you may not use this file except in compliance | |
| with the License. You may obtain a copy of the License at | |
| http://www.apache.org/licenses/LICENSE-2.0 | |
| Unless required by applicable law or agreed to in writing, software | |
| distributed under the License is distributed on an "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| See the License for the specific language governing permissions and | |
| limitations under the License. | |
| */ | |
| #include "cripts/Lulu.hpp" | |
| #include "cripts/Preamble.hpp" | |
| namespace cripts | |
| { | |
| std::unordered_map<cripts::string_view, const Records *> Records::_gRecords; | |
| Records::Records(const cripts::string_view name) | |
| { | |
| TSOverridableConfigKey key; | |
| TSRecordDataType type; | |
| if (TSHttpTxnConfigFind(name.data(), name.size(), &key, &type) == TS_SUCCESS) { | |
| _name = name; | |
| _key = key; | |
| _type = type; | |
| } else { | |
| CFatal("[Records]: Invalid configuration variable '%.*s'", static_cast<int>(name.size()), name.data()); | |
| } | |
| } | |
| Records::ValueType | |
| Records::_get(const cripts::Context *context) const | |
| { | |
| TSAssert(context->state.txnp); | |
| switch (_type) { | |
| case TS_RECORDDATATYPE_INT: { | |
| TSMgmtInt i; | |
| if (TSHttpTxnConfigIntGet(context->state.txnp, _key, &i) == TS_SUCCESS) { | |
| return i; | |
| } | |
| } break; | |
| case TS_RECORDDATATYPE_FLOAT: { | |
| TSMgmtFloat f; | |
| if (TSHttpTxnConfigFloatGet(context->state.txnp, _key, &f) == TS_SUCCESS) { | |
| return f; | |
| } | |
| } break; | |
| case TS_RECORDDATATYPE_STRING: { | |
| return std::string{GetSV(context)}; | |
| } break; | |
| default: | |
| CFatal("[Records]: Invalid configuration type"); | |
| return 0; | |
| } | |
| return 0; | |
| } | |
| const cripts::string_view | |
| Records::GetSV(const cripts::Context *context) const | |
| { | |
| TSAssert(context->state.txnp); | |
| switch (_type) { | |
| case TS_RECORDDATATYPE_STRING: { | |
| const char *s = nullptr; | |
| int len = 0; | |
| if (TSHttpTxnConfigStringGet(context->state.txnp, _key, &s, &len) == TS_SUCCESS) { | |
| return {s, len}; | |
| } | |
| } break; | |
| default: | |
| CFatal("[Records]: Invalid configuration type for GetSV()"); | |
| break; | |
| } | |
| return {}; | |
| } | |
| bool | |
| Records::_set(const cripts::Context *context, const ValueType &value) const | |
| { | |
| TSAssert(context->state.txnp); | |
| switch (_type) { | |
| case TS_RECORDDATATYPE_INT: { | |
| TSMgmtInt i = std::get<TSMgmtInt>(value); | |
| if (TSHttpTxnConfigIntSet(context->state.txnp, _key, i) != TS_SUCCESS) { | |
| TSError("Failed to set integer configuration '%s'", _name.c_str()); | |
| return false; | |
| } | |
| CDebug("Set integer configuration '{}' to {}", _name.c_str(), i); | |
| } break; | |
| case TS_RECORDDATATYPE_FLOAT: { | |
| TSMgmtFloat f = std::get<TSMgmtFloat>(value); | |
| if (TSHttpTxnConfigFloatSet(context->state.txnp, _key, f) != TS_SUCCESS) { | |
| TSError("Failed to set float configuration '%s'", _name.c_str()); | |
| return false; | |
| } | |
| CDebug("Set float configuration '{}' to {}", _name.c_str(), f); | |
| } break; | |
| case TS_RECORDDATATYPE_STRING: { | |
| auto &str = std::get<std::string>(value); | |
| SetSV(context, {str.data(), str.size()}); | |
| } break; | |
| default: | |
| CFatal("[Records]: Invalid configuration type"); | |
| return false; | |
| } | |
| return true; // Success | |
| } | |
| bool | |
| Records::SetSV(const cripts::Context *context, const cripts::string_view value) const | |
| { | |
| TSAssert(context->state.txnp); | |
| switch (_type) { | |
| case TS_RECORDDATATYPE_STRING: { | |
| if (TSHttpTxnConfigStringSet(context->state.txnp, _key, value.data(), value.size()) != TS_SUCCESS) { | |
| TSError("Failed to set string configuration '%s'", _name.c_str()); | |
| return false; | |
| } | |
| CDebug("Set string configuration '{}' to '{}'", _name.c_str(), value); | |
| } break; | |
| default: | |
| CFatal("[Records]: Invalid configuration type for setSV()"); | |
| return false; | |
| } | |
| return true; // Success | |
| } | |
| // Static members for the records "cache" | |
| void | |
| Records::Add(const Records *rec) | |
| { | |
| CAssert(rec->Loaded()); | |
| auto it = _gRecords.find(rec->Name()); | |
| CAssert(it == _gRecords.end()); | |
| _gRecords[rec->Name()] = rec; | |
| } | |
| const Records * | |
| Records::Lookup(const cripts::string_view name) | |
| { | |
| auto it = _gRecords.find(name); | |
| if (it != _gRecords.end()) { | |
| CAssert(it->second->Loaded()); | |
| return it->second; | |
| } | |
| return nullptr; | |
| } | |
| } // namespace cripts |