From 5cc7cbc3704ec255eb5d0ac53b2cc0fcb1221d63 Mon Sep 17 00:00:00 2001 From: Dominick Allen Date: Wed, 23 Oct 2024 13:21:10 -0500 Subject: String conversion and parsing format spec. --- source/fud_string_convert.cpp | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 source/fud_string_convert.cpp (limited to 'source/fud_string_convert.cpp') diff --git a/source/fud_string_convert.cpp b/source/fud_string_convert.cpp new file mode 100644 index 0000000..428ab36 --- /dev/null +++ b/source/fud_string_convert.cpp @@ -0,0 +1,110 @@ +/* + * libfud + * Copyright 2024 Dominick Allen + * + * Licensed 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 "fud_string_convert.hpp" + +namespace fud::impl { + +FudStatus checkPlusSigned(StringView& view, size_t& skipIndex) +{ + auto isPlusSigned = view.data()[0] == '+'; + if (isPlusSigned && view.length() == 1) { + return FudStatus::ArgumentInvalid; + } + if (isPlusSigned) { + view.advanceUnsafe(); + skipIndex++; + } + return FudStatus::Success; +} + +Result checkNegative(StringView& view, size_t& skipIndex) +{ + bool isNegative = view.data()[0] == '-'; + if (isNegative && view.length() == 1) { + return FudStatus::ArgumentInvalid; + } + if (isNegative) { + skipIndex += 1; + view.advanceUnsafe(); + } + return isNegative; +} + +Result determineRadix(StringView input, size_t& index) +{ + if (input.length() < 1) { + return FudStatus::ArgumentInvalid; + } + + if (input.length() == 1 && input.data()[0] == '0') { + return Radix::Octal; + } + + if (input.length() == 1) { + return Radix::Decimal; + } + + if (input.data()[0] == '0' && (input.data()[1] == 'x' || input.data()[1] == 'X')) { + index += 2; + return Radix::Hexadecimal; + } + + if (input.data()[0] == '0') { + auto nextChar = input.data()[1]; + auto nextVal = AsciiLookup[nextChar]; + if (nextVal >= 0 && nextVal < static_cast(Radix::Octal)) { + return Radix::Octal; + } + if (nextVal >= static_cast(Radix::Octal)) { + return FudStatus::ArgumentInvalid; + } + } + + return Radix::Decimal; +} + +Result getRadix(StringView& view, size_t& skipIndex, Option specifiedRadixOption) +{ + if (specifiedRadixOption.isNone()) { + size_t radixIndex = 0; + auto status = determineRadix(view, radixIndex); + if (status.isOkay()) { + skipIndex += radixIndex; + view.advanceUnsafe(radixIndex); + return static_cast(status.takeOkay()); + } + return status.takeError(); + } + + auto radix = specifiedRadixOption.value(); + if (radix == static_cast(Radix::Hexadecimal) && view.length() > 2 && + (view.data()[1] == 'x' || view.data()[1] == 'X')) { + skipIndex += 2; + view.advanceUnsafe(2); + } else if (radix == static_cast(Radix::Binary) && view.length() > 2 && view.data()[1] == 'b') { + skipIndex += 2; + view.advanceUnsafe(2); + } else if (radix == static_cast(Radix::Octal) && view.length() > 2 && view.data()[1] == '0') { + skipIndex += 2; + view.advanceUnsafe(2); + } + + return radix; +} + +} // namespace fud::impl -- cgit v1.2.3