mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-04 13:54:25 +08:00
Changed handling of numbers witth a leading plus character
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
Version 10.0.3
|
||||
- Clear pdbx_nonpoly_scheme before filling it in reconstruction
|
||||
- Changed handling of numbers with a preceding plus character,
|
||||
these are now stored as strings to avoid inadvertently
|
||||
mutilating phone numbers.
|
||||
|
||||
Version 10.0.2
|
||||
- Fixed regression in reconstruction introduced in 10.0.1
|
||||
|
||||
@@ -331,8 +331,11 @@ class item_value
|
||||
case TEXT:
|
||||
{
|
||||
auto sv = m_data.sv();
|
||||
auto sp = sv.data();
|
||||
if (*sp == '+')
|
||||
++sp;
|
||||
int64_t v;
|
||||
auto &&[ptr, ec] = from_chars(sv.data(), sv.data() + sv.length(), v);
|
||||
auto &&[ptr, ec] = from_chars(sp, sv.data() + sv.length(), v);
|
||||
if (ec != std::errc{})
|
||||
throw std::system_error(std::make_error_code(ec));
|
||||
if (ptr != sv.data() + sv.length())
|
||||
@@ -361,8 +364,11 @@ class item_value
|
||||
case TEXT:
|
||||
{
|
||||
auto sv = m_data.sv();
|
||||
auto sp = sv.data();
|
||||
if (*sp == '+')
|
||||
++sp;
|
||||
double v;
|
||||
auto &&[ptr, ec] = from_chars(sv.data(), sv.data() + sv.length(), v);
|
||||
auto &&[ptr, ec] = from_chars(sp, sv.data() + sv.length(), v);
|
||||
if (ec != std::errc{})
|
||||
throw std::system_error(std::make_error_code(ec));
|
||||
if (ptr != sv.data() + sv.length())
|
||||
|
||||
@@ -239,7 +239,12 @@ void item_value::cast_to_int()
|
||||
{
|
||||
auto s = sv();
|
||||
int64_t v;
|
||||
auto [ptr, ec] = cif::from_chars(s.data(), s.data() + s.size(), v);
|
||||
|
||||
auto sp = s.data();
|
||||
if (*sp == '+')
|
||||
++sp;
|
||||
|
||||
auto [ptr, ec] = cif::from_chars(sp, s.data() + s.size(), v);
|
||||
if (ec != std::errc{})
|
||||
throw std::system_error(std::make_error_code(ec), "attempt to cast value to integer failed");
|
||||
if (ptr != s.data() + s.size())
|
||||
|
||||
@@ -635,9 +635,18 @@ sac_parser::CIFToken sac_parser::get_next_token()
|
||||
|
||||
if (result == CIFToken::VALUE_NUMERIC_INTEGER)
|
||||
{
|
||||
auto [ptr, ec] = from_chars(m_token_buffer.data(), m_token_buffer.data() + m_token_buffer.size(), m_token_value_int);
|
||||
if (ec != std::errc{})
|
||||
error("Invalid integer value: " + std::make_error_code(ec).message());
|
||||
// Avoid interpreting phone numbers as integers, TODO: check if this is an issue
|
||||
if (m_token_buffer.front() == '+')
|
||||
{
|
||||
result = CIFToken::VALUE_CHARSTRING;
|
||||
m_token_value = std::string_view(m_token_buffer.data(), m_token_buffer.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto [ptr, ec] = from_chars(m_token_buffer.data(), m_token_buffer.data() + m_token_buffer.size(), m_token_value_int);
|
||||
if (ec != std::errc{})
|
||||
error("Invalid integer value: " + std::make_error_code(ec).message());
|
||||
}
|
||||
}
|
||||
else if (result == CIFToken::VALUE_NUMERIC_FLOAT)
|
||||
{
|
||||
|
||||
@@ -3664,5 +3664,37 @@ HETATM 2 O O . HOH A 1 . ? 10.518 -1.781 0 1 37.22 ? O HOH 2 D 1
|
||||
)");
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
TEST_CASE("number-test-1")
|
||||
{
|
||||
auto data = R"(data_test
|
||||
_pdbx_contact_author.id 1
|
||||
_pdbx_contact_author.name_mi +98765432109
|
||||
)"_cf;
|
||||
|
||||
auto &db = data.front();
|
||||
db.load_dictionary("mmcif_pdbx.dic");
|
||||
|
||||
auto r = db["pdbx_contact_author"].front();
|
||||
CHECK(r["name_mi"].str() == "+98765432109");
|
||||
CHECK(r["name_mi"].get<int64_t>() == 98765432109);
|
||||
CHECK(r["name_mi"].get<double>() == 98765432109.0);
|
||||
}
|
||||
|
||||
TEST_CASE("number-test-2")
|
||||
{
|
||||
auto data = R"(data_test
|
||||
_pdbx_contact_author.id 1
|
||||
_pdbx_contact_author.name_mi '+98765432109'
|
||||
)"_cf;
|
||||
|
||||
auto &db = data.front();
|
||||
db.load_dictionary("mmcif_pdbx.dic");
|
||||
|
||||
auto r = db["pdbx_contact_author"].front();
|
||||
CHECK(r["name_mi"].str() == "+98765432109");
|
||||
CHECK(r["name_mi"].get<int64_t>() == 98765432109);
|
||||
CHECK(r["name_mi"].get<double>() == 98765432109.0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user