/* * 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 FudError{FudStatus::ArgumentInvalid}; } if (isNegative) { skipIndex += 1; view.advanceUnsafe(); } return Okay{isNegative}; } Result determineRadix(StringView input, size_t& index) { if (input.length() < 1) { return FudError{FudStatus::ArgumentInvalid}; } if (input.length() == 1 && input.data()[0] == '0') { return Okay{Radix::Octal}; } if (input.length() == 1) { return Okay{Radix::Decimal}; } if (input.data()[0] == '0' && (input.data()[1] == 'x' || input.data()[1] == 'X')) { index += 2; return Okay{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 Okay{Radix::Octal}; } if (nextVal >= static_cast(Radix::Octal)) { return FudError{FudStatus::ArgumentInvalid}; } } return Okay{Radix::Decimal}; } Result getRadix(StringView& view, size_t& skipIndex, Option specifiedRadixOption) { using RetType = Result; if (specifiedRadixOption.isNone()) { size_t radixIndex = 0; auto status = determineRadix(view, radixIndex); if (status.isOkay()) { skipIndex += radixIndex; view.advanceUnsafe(radixIndex); return RetType::okay(static_cast(status.takeOkay())); } return RetType::error(status); } 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 RetType::okay(radix); } } // namespace fud::impl