/* * Copyright (C) 2018 The Android Open Source Project * * 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 "lang_id/common/lite_strings/numbers.h" #include #include #include namespace libtextclassifier3 { namespace mobile { // Returns true if the characters that start at address ptr (inclusive) and stop // at the first '\0' consist of only whitespaces, as determined by isspace(). // Note: this function returns false if ptr is nullptr. static bool OnlyWhitespaces(const char *ptr) { if (ptr == nullptr) { return false; } for (; *ptr != '\0'; ++ptr) { if (!isspace(*ptr)) { return false; } } return true; } bool LiteAtoi(const char *c_str, int *value) { if (c_str == nullptr) { return false; } // Short version of man strtol: // // strtol parses some optional whitespaces, an optional +/- sign, and next a // succession of digits. If it finds some digits, it sets temp to point to // the first character after that succession of digits and returns the parsed // integer. // // If there were no digits at all, strtol() sets temp to be c_str (the start // address) and returns 0. char *temp = nullptr; const long int parsed_value = strtol(c_str, &temp, 0); // NOLINT // Check for overflow. Note: to simplify the code, we assume that LONG_MIN / // LONG_MAX means that strtol encountered an overflow (normally, in that case, // one should also inspect errno). Hence, we maybe give up the possibility to // parse one extreme value on each side (min/max). That should be ok. if ((parsed_value == LONG_MIN) || (parsed_value == LONG_MAX) || (parsed_value < INT_MIN) || (parsed_value > INT_MAX)) { return false; } *value = static_cast(parsed_value); // First part of the expression below means that the input string contained at // least one digit. The other part checks that what remains after the number // (if anything) consists only of whitespaces. return (temp != c_str) && OnlyWhitespaces(temp); } bool LiteAtof(const char *c_str, float *value) { if (c_str == nullptr) { return false; } // strtof is similar to strtol, see more detailed comments inside LiteAtoi. char *temp = nullptr; *value = strtof(c_str, &temp); return (temp != c_str) && OnlyWhitespaces(temp); } } // namespace mobile } // namespace nlp_saft