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