Merge branch 'develop' of https://github.com/BigSeb/cereal into BigSeb-develop

This commit is contained in:
Shane Grant 2015-12-22 14:44:37 -08:00
commit 61429d2292
2 changed files with 52 additions and 5 deletions

View File

@ -232,19 +232,22 @@ namespace cereal
itsOS.clear(); itsOS.seekp( 0, std::ios::beg );
itsOS << value << std::ends;
const auto strValue = itsOS.str();
auto strValue = itsOS.str();
// itsOS.str() may contains data from previous calls after the first '\0' that was just inserted
// and this data is counted in the length call. We make sure to remove that section so that the
// whitespace validation is done properly
strValue.resize(std::strlen(strValue.c_str()));
// If the first or last character is a whitespace, add xml:space attribute
// the string always contains a '\0' added by std::ends, so the last character is at len-2 and an 'empty'
// string has a length of 1 or lower
const auto len = strValue.length();
if ( len > 1 && ( xml_detail::isWhitespace( strValue[0] ) || xml_detail::isWhitespace( strValue[len - 2] ) ) )
if ( len > 0 && ( xml_detail::isWhitespace( strValue[0] ) || xml_detail::isWhitespace( strValue[len - 1] ) ) )
{
itsNodes.top().node->append_attribute( itsXML.allocate_attribute( "xml:space", "preserve" ) );
}
// allocate strings for all of the data in the XML object
auto dataPtr = itsXML.allocate_string( itsOS.str().c_str(), itsOS.str().length() + 1 );
auto dataPtr = itsXML.allocate_string(strValue.c_str(), strValue.length() + 1 );
// insert into the XML
itsNodes.top().node->append_node( itsXML.allocate_node( rapidxml::node_data, nullptr, dataPtr ) );

View File

@ -225,3 +225,47 @@ BOOST_AUTO_TEST_CASE( xml_char_issue109 )
test_ws_in_out<cereal::XMLInputArchive, cereal::XMLOutputArchive>( char( chars[i] ) );
}
}
template <class IArchive, class OArchive, class Out, size_t Nb, class In = Out>
void test_ws_in_out_array(Out const (&o_a_value_with_ws)[Nb])
{
std::ostringstream os;
{
OArchive oar(os);
for (const auto& o_value_with_ws : o_a_value_with_ws)
{
oar(o_value_with_ws);
}
}
In i_a_value_with_ws[Nb];
std::istringstream is(os.str());
{
IArchive iar(is);
for (In& i_value_with_ws : i_a_value_with_ws)
{
iar(i_value_with_ws);
}
}
for (size_t uiIndex = 0; uiIndex < Nb; ++uiIndex)
{
BOOST_CHECK_EQUAL(i_a_value_with_ws[uiIndex], o_a_value_with_ws[uiIndex]);
}
}
BOOST_AUTO_TEST_CASE(xml_string_issue_consecutive_calls)
{
std::string strings[] = {
"some text",
" some text",
" some text ",
"Long text without ws at the end",
"some text ",
" some text",
" some text ",
};
test_ws_in_out_array<cereal::XMLInputArchive, cereal::XMLOutputArchive>(strings);
}