mirror of
https://github.com/lighttransport/tinyusdz.git
synced 2026-01-18 01:11:17 +01:00
use tinyusdz::str::parse_int
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
all:
|
||||
clang++-17 -O2 -g -stdlib=libc++ parse_int.cc -o parse_int
|
||||
clang++ -O2 -g -stdlib=libc++ parse_int.cc -o parse_int ../../src/tiny-string.cc
|
||||
|
||||
clean:
|
||||
rm -f parse_int a.out
|
||||
@@ -9,4 +9,4 @@ test: all
|
||||
./parse_int 1000000 1 4
|
||||
./parse_int 1000000 1 8
|
||||
|
||||
.PHONY: all clean test
|
||||
.PHONY: all clean test
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <random>
|
||||
#include <charconv>
|
||||
|
||||
#include "../../src/tiny-string.hh"
|
||||
|
||||
std::string gen_intarray(size_t n, bool delim_at_end) {
|
||||
std::stringstream ss;
|
||||
std::random_device rd;
|
||||
@@ -333,8 +335,8 @@ bool do_parse(
|
||||
|
||||
while ((j = cnt++) < results.size()) {
|
||||
int64_t val;
|
||||
auto answer = std::from_chars(spans[j].p_begin, spans[j].p_begin + spans[j].length, val);
|
||||
if (answer.ec != std::errc()) {
|
||||
tinyusdz::tstring_view ts(spans[j].p_begin, size_t(spans[j].length));
|
||||
if (!tinyusdz::str::parse_int64(ts, &val)) {
|
||||
parse_failed = true;
|
||||
}
|
||||
|
||||
@@ -355,8 +357,8 @@ bool do_parse(
|
||||
} else {
|
||||
for (size_t i = 0; i < spans.size(); i++) {
|
||||
int64_t val;
|
||||
auto answer = std::from_chars(spans[i].p_begin, spans[i].p_begin + spans[i].length, val);
|
||||
if (answer.ec != std::errc()) {
|
||||
tinyusdz::tstring_view ts(spans[i].p_begin, size_t(spans[i].length));
|
||||
if (!tinyusdz::str::parse_int64(ts, &val)) {
|
||||
std::cerr << "parsing failure\n";
|
||||
return false;
|
||||
}
|
||||
@@ -416,4 +418,4 @@ int main(int argc, char **argv) {
|
||||
do_parse(nthreads, lex_results, parse_results);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -400,7 +400,7 @@ bool parse_int64(const tstring_view &sv, int64_t *ret) {
|
||||
if (str[i] < '0' || str[i] > '9') {
|
||||
return false;
|
||||
}
|
||||
result = result * 10 + (str[i] - '0');
|
||||
result = result * 10ull + uint64_t(str[i] - '0');
|
||||
|
||||
// Check for overflow
|
||||
if (negative && result > static_cast<uint64_t>(std::numeric_limits<int64_t>::max()) + 1) {
|
||||
@@ -437,7 +437,7 @@ bool parse_uint(const tstring_view &sv, uint32_t *ret) {
|
||||
if (str[i] < '0' || str[i] > '9') {
|
||||
return false;
|
||||
}
|
||||
result = result * 10 + (str[i] - '0');
|
||||
result = result * 10 + uint64_t(str[i] - '0');
|
||||
|
||||
// Check for overflow
|
||||
if (result > std::numeric_limits<uint32_t>::max()) {
|
||||
@@ -473,11 +473,11 @@ bool parse_uint64(const tstring_view &sv, uint64_t *ret) {
|
||||
}
|
||||
|
||||
// Check for overflow before multiplication
|
||||
if (result > (std::numeric_limits<uint64_t>::max() - (str[i] - '0')) / 10) {
|
||||
if (result > (std::numeric_limits<uint64_t>::max() - uint64_t(str[i] - '0')) / 10) {
|
||||
return false;
|
||||
}
|
||||
|
||||
result = result * 10 + (str[i] - '0');
|
||||
result = result * 10 + uint64_t(str[i] - '0');
|
||||
}
|
||||
|
||||
*ret = result;
|
||||
@@ -714,7 +714,7 @@ bool parse_int_arary(const tstring_view &sv, std::vector<int32_t> *result, const
|
||||
p++;
|
||||
}
|
||||
|
||||
if (p == num_start) {
|
||||
if (p <= num_start) {
|
||||
return false; // No number found
|
||||
}
|
||||
|
||||
@@ -722,7 +722,7 @@ bool parse_int_arary(const tstring_view &sv, std::vector<int32_t> *result, const
|
||||
int32_t value;
|
||||
tstring_view num_view(num_start);
|
||||
// Create a temporary view with the correct length
|
||||
size_t num_len = p - num_start;
|
||||
size_t num_len = size_t(p - num_start);
|
||||
std::string num_str(num_start, num_len);
|
||||
tstring_view temp_view(num_str.c_str());
|
||||
if (!parse_int(temp_view, &value)) {
|
||||
|
||||
@@ -171,6 +171,11 @@ struct tstring_view {
|
||||
_s = s;
|
||||
}
|
||||
|
||||
constexpr tstring_view(const char *s, size_t n) {
|
||||
_len = n;
|
||||
_s = s;
|
||||
}
|
||||
|
||||
tstring_view(const std::string &s) : tstring_view(s.c_str()) {
|
||||
}
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ TEST_LIST = {
|
||||
{ "ioutil_test", ioutil_test },
|
||||
{ "strutil_test", strutil_test },
|
||||
{ "tinystring_test", tinystring_test },
|
||||
{ "parse_int_test", parse_int_test },
|
||||
{ "timesamples_test", timesamples_test },
|
||||
#if defined(TINYUSDZ_WITH_PXR_COMPAT_API)
|
||||
{ "pxr_compat_api_test", pxr_compat_api_test },
|
||||
|
||||
@@ -66,3 +66,134 @@ void tinystring_test(void) {
|
||||
TEST_CHECK(v4.ends_with(v2));
|
||||
|
||||
}
|
||||
|
||||
void parse_int_test(void) {
|
||||
using namespace tinyusdz::str;
|
||||
|
||||
int32_t result;
|
||||
|
||||
// Basic positive numbers
|
||||
{
|
||||
tstring_view sv("123");
|
||||
TEST_CHECK(parse_int(sv, &result));
|
||||
TEST_CHECK(result == 123);
|
||||
}
|
||||
|
||||
// Basic negative numbers
|
||||
{
|
||||
tstring_view sv("-456");
|
||||
TEST_CHECK(parse_int(sv, &result));
|
||||
TEST_CHECK(result == -456);
|
||||
}
|
||||
|
||||
// Zero
|
||||
{
|
||||
tstring_view sv("0");
|
||||
TEST_CHECK(parse_int(sv, &result));
|
||||
TEST_CHECK(result == 0);
|
||||
}
|
||||
|
||||
// Positive sign
|
||||
{
|
||||
tstring_view sv("+789");
|
||||
TEST_CHECK(parse_int(sv, &result));
|
||||
TEST_CHECK(result == 789);
|
||||
}
|
||||
|
||||
// Maximum int32_t value
|
||||
{
|
||||
tstring_view sv("2147483647");
|
||||
TEST_CHECK(parse_int(sv, &result));
|
||||
TEST_CHECK(result == 2147483647);
|
||||
}
|
||||
|
||||
// Minimum int32_t value
|
||||
{
|
||||
tstring_view sv("-2147483648");
|
||||
TEST_CHECK(parse_int(sv, &result));
|
||||
TEST_CHECK(result == -2147483648);
|
||||
}
|
||||
|
||||
// Empty string
|
||||
{
|
||||
tstring_view sv("");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
// Just a sign
|
||||
{
|
||||
tstring_view sv("-");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
{
|
||||
tstring_view sv("+");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
// Non-numeric characters
|
||||
{
|
||||
tstring_view sv("123a");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
{
|
||||
tstring_view sv("a123");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
{
|
||||
tstring_view sv("12.3");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
// Overflow cases
|
||||
{
|
||||
tstring_view sv("2147483648"); // INT32_MAX + 1
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
{
|
||||
tstring_view sv("-2147483649"); // INT32_MIN - 1
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
// Very large numbers
|
||||
{
|
||||
tstring_view sv("999999999999999999");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
{
|
||||
tstring_view sv("-999999999999999999");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
// Leading/trailing spaces (should fail since parse_int doesn't handle whitespace)
|
||||
{
|
||||
tstring_view sv(" 123");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
{
|
||||
tstring_view sv("123 ");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
// Multiple signs
|
||||
{
|
||||
tstring_view sv("++123");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
{
|
||||
tstring_view sv("--123");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
{
|
||||
tstring_view sv("+-123");
|
||||
TEST_CHECK(!parse_int(sv, &result));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
|
||||
void strutil_test(void);
|
||||
void tinystring_test(void);
|
||||
void parse_int_test(void);
|
||||
|
||||
Reference in New Issue
Block a user