src/cripts/Configs.cc (129 lines of code) (raw):

/* 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