blob: 1e3fd67e7f8fbc9891a3321893af07fe0f685ff1 [file] [log] [blame]
/**
*
* 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 "utils/ParsingUtils.h"
namespace org::apache::nifi::minifi::parsing {
nonstd::expected<bool, std::error_code> parseBool(const std::string_view input) {
if (utils::string::equalsIgnoreCase(input, "true")) { return true; }
if (utils::string::equalsIgnoreCase(input, "false")) { return false; }
return nonstd::make_unexpected(core::ParsingErrorCode::GeneralParsingError);
}
namespace {
std::optional<uint64_t> getUnitMultiplier(const std::string_view unit_str) {
if (unit_str.empty()) { return 1; }
static std::map<std::string_view, int64_t, std::less<>> unit_map{
{"B", 1},
{"K", 1_KB},
{"M", 1_MB},
{"G", 1_GB},
{"T", 1_TB},
{"P", 1_PB},
{"KB", 1_KiB},
{"MB", 1_MiB},
{"GB", 1_GiB},
{"TB", 1_TiB},
{"PB", 1_PiB},
{"KIB", 1_KiB},
{"MIB", 1_MiB},
{"GIB", 1_GiB},
{"TIB", 1_TiB},
{"PIB", 1_PiB},
};
const auto unit_multiplier = unit_map.find(unit_str);
if (unit_multiplier != unit_map.end()) { return unit_multiplier->second; }
return std::nullopt;
}
} // namespace
nonstd::expected<uint64_t, std::error_code> parseDataSizeMinMax(const std::string_view input, const uint64_t minimum, const uint64_t maximum) {
const auto trimmed_input = utils::string::trim(input);
const auto split_pos = trimmed_input.find_first_not_of("0123456789");
if (split_pos == std::string_view::npos) {
return parseIntegral<uint64_t>(trimmed_input);
}
const auto num_str = trimmed_input.substr(0, split_pos);
const std::string unit_str = utils::string::toUpper(std::string{trimmed_input.substr(split_pos, trimmed_input.size() - split_pos)});
nonstd::expected<uint64_t, std::error_code> num_part = parseIntegral<uint64_t>(num_str);
if (!num_part) { return nonstd::make_unexpected(num_part.error()); }
const auto unit_multiplier = getUnitMultiplier(utils::string::trim(unit_str));
if (!unit_multiplier) { return nonstd::make_unexpected(core::ParsingErrorCode::GeneralParsingError); }
uint64_t result = *num_part * *unit_multiplier;
gsl_Assert(unit_multiplier != 0);
if ((result / *unit_multiplier) != *num_part) {
return nonstd::make_unexpected(core::ParsingErrorCode::OverflowError);
}
if (result < minimum) { return nonstd::make_unexpected(core::ParsingErrorCode::SmallerThanMinimum); }
if (result > maximum) { return nonstd::make_unexpected(core::ParsingErrorCode::LargerThanMaximum); }
return result;
}
nonstd::expected<uint64_t, std::error_code> parseDataSize(const std::string_view input) {
return parseDataSizeMinMax(input, std::numeric_limits<uint64_t>::min(), std::numeric_limits<uint64_t>::max());
}
nonstd::expected<uint32_t, std::error_code> parseUnixOctalPermissions(const std::string_view input) {
uint32_t result = 0U;
if (input.size() == 9U) {
/* Probably rwxrwxrwx formatted */
for (size_t i = 0; i < 3; i++) {
if (input[i * 3] == 'r') {
result |= 04 << ((2 - i) * 3);
} else if (input[i * 3] != '-') {
return nonstd::make_unexpected(core::ParsingErrorCode::GeneralParsingError);
}
if (input[i * 3 + 1] == 'w') {
result |= 02 << ((2 - i) * 3);
} else if (input[i * 3 + 1] != '-') {
return nonstd::make_unexpected(core::ParsingErrorCode::GeneralParsingError);
}
if (input[i * 3 + 2] == 'x') {
result |= 01 << ((2 - i) * 3);
} else if (input[i * 3 + 2] != '-') {
return nonstd::make_unexpected(core::ParsingErrorCode::GeneralParsingError);
}
}
} else {
/* Probably octal */
try {
size_t pos = 0U;
result = std::stoul(std::string{input}, &pos, 8);
if (pos != input.size()) {
return nonstd::make_unexpected(core::ParsingErrorCode::GeneralParsingError);
}
if ((result & ~static_cast<uint32_t>(0777)) != 0U) {
return nonstd::make_unexpected(core::ParsingErrorCode::GeneralParsingError);
}
} catch (...) {
return nonstd::make_unexpected(core::ParsingErrorCode::GeneralParsingError);
}
}
return result;
}
nonstd::expected<float, std::error_code> parseFloat(std::string_view input) {
try {
return std::stof(std::string{input});
} catch(const std::exception&) {
return nonstd::make_unexpected(core::ParsingErrorCode::GeneralParsingError);
}
}
} // namespace org::apache::nifi::minifi::parsing