Add QUtil::is_long_long

This commit is contained in:
Jay Berkenbilt 2022-05-15 14:56:04 -04:00
parent 173b944ef8
commit 60ec94a7c3
5 changed files with 52 additions and 0 deletions

View File

@ -1,3 +1,8 @@
2022-05-15 Jay Berkenbilt <ejb@ql.org>
* Add QUtil::is_long_long to test whether a string can be
converted to a long long and back without loss of information.
2022-05-04 Jay Berkenbilt <ejb@ql.org>
* JSON: add a new "blob" type that takes a function to write data

View File

@ -65,6 +65,13 @@ namespace QUtil
QPDF_DLL
unsigned int string_to_uint(char const* str);
// Returns true if this exactly represents a long long. The
// determination is made by converting the string to a long long,
// then converting the result back to a string, and then comparing
// that result with the original string.
QPDF_DLL
bool is_long_long(char const* str);
// Pipeline's write method wants unsigned char*, but we often have
// some other type of string. These methods do combinations of
// const_cast and reinterpret_cast to give us an unsigned char*.

View File

@ -467,6 +467,19 @@ QUtil::string_to_uint(char const* str)
return QIntC::to_uint(string_to_ull(str));
}
bool
QUtil::is_long_long(char const* str)
{
try {
auto i1 = string_to_ll(str);
std::string s1 = int_to_string(i1);
return str == s1;
} catch (std::exception&) {
// overflow or other error
}
return false;
}
unsigned char*
QUtil::unsigned_char_pointer(std::string const& str)
{

View File

@ -129,3 +129,5 @@ delete file
D:20210209144925-05'00'
D:20210210011925+05'30'
D:20210209191925Z
---- is_long_long
done

View File

@ -676,6 +676,29 @@ timestamp_test()
QUtil::qpdf_time_to_pdf_time(QUtil::get_current_qpdf_time())));
}
void
is_long_long_test()
{
auto check = [](char const* s, bool v) {
if (QUtil::is_long_long(s) != v) {
std::cout << "failed: " << s << std::endl;
}
};
check("12312312", true);
check("12312312.34", false);
check("-12312312", true);
check("-12312312.34", false);
check("1e2", false);
check("9223372036854775807", true);
check("9223372036854775808", false);
check("-9223372036854775808", true);
check("-9223372036854775809", false);
check("123123123123123123123123123123123123", false);
check("potato", false);
check("0123", false);
std::cout << "done" << std::endl;
}
int
main(int argc, char* argv[])
{
@ -710,6 +733,8 @@ main(int argc, char* argv[])
rename_delete_test();
std::cout << "---- timestamp" << std::endl;
timestamp_test();
std::cout << "---- is_long_long" << std::endl;
is_long_long_test();
} catch (std::exception& e) {
std::cout << "unexpected exception: " << e.what() << std::endl;
}