mirror of https://github.com/KLayout/klayout.git
660 lines
18 KiB
C++
660 lines
18 KiB
C++
|
|
/*
|
|
|
|
KLayout Layout Viewer
|
|
Copyright (C) 2006-2022 Matthias Koefferlein
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
#include "tlXMLParser.h"
|
|
#include "tlUnitTest.h"
|
|
|
|
#if defined(HAVE_QT) || defined(HAVE_EXPAT)
|
|
|
|
#include <sstream>
|
|
#include <cmath>
|
|
|
|
|
|
struct Child {
|
|
Child () : txt (""), d(-1), live(true) { }
|
|
~Child () { tl_assert (live); live = false; }
|
|
std::string txt;
|
|
double d;
|
|
bool live;
|
|
bool operator== (const Child &x) const { return txt == x.txt && fabs (d - x.d) < 1e-9 && children == x.children; }
|
|
std::vector<Child> children;
|
|
std::vector<Child>::const_iterator begin_children() const { return children.begin (); }
|
|
std::vector<Child>::const_iterator end_children() const { return children.end (); }
|
|
void add_child (const Child &c) { children.push_back (c); }
|
|
void add_child_ptr (Child *c) { children.push_back (*c); delete c; }
|
|
};
|
|
|
|
struct Root {
|
|
long m;
|
|
unsigned int mi;
|
|
std::vector<double> m_subs;
|
|
std::vector<int> m_isubs;
|
|
std::vector<Child> m_children;
|
|
Child m_child;
|
|
|
|
Root () : m(0), mi(0) { }
|
|
|
|
bool operator== (const Root &x) const { return m == x.m &&
|
|
mi == x.mi && m_subs == x.m_subs &&
|
|
m_isubs == x.m_isubs && m_children == x.m_children
|
|
&& m_child == x.m_child; }
|
|
|
|
int get_mi () const { return mi; }
|
|
void set_mi (int i) { mi = i; }
|
|
void add_sub (const double &s) {
|
|
m_subs.push_back (s);
|
|
}
|
|
void add_isub (const int &s) {
|
|
m_isubs.push_back (s);
|
|
}
|
|
std::vector<double>::const_iterator begin_subs () const {
|
|
return m_subs.begin ();
|
|
}
|
|
std::vector<double>::const_iterator end_subs () const {
|
|
return m_subs.end ();
|
|
}
|
|
std::vector<int>::const_iterator begin_isubs () const {
|
|
return m_isubs.begin ();
|
|
}
|
|
std::vector<int>::const_iterator end_isubs () const {
|
|
return m_isubs.end ();
|
|
}
|
|
void add_child_ptr (Child *c) {
|
|
m_children.push_back (*c);
|
|
delete c;
|
|
}
|
|
void add_child (const Child &c) {
|
|
m_children.push_back (c);
|
|
}
|
|
std::vector<Child>::const_iterator begin_children () const {
|
|
return m_children.begin ();
|
|
}
|
|
std::vector<Child>::const_iterator end_children () const {
|
|
return m_children.end ();
|
|
}
|
|
void set_child (const Child &child) { m_child = child; }
|
|
const Child &get_child () const { return m_child; }
|
|
};
|
|
|
|
TEST (1)
|
|
{
|
|
tl::XMLStringSource s ("<?xml version=\"1.0\"?>\n"
|
|
"<root>"
|
|
" <member>"
|
|
" 10"
|
|
" </member>"
|
|
" <imember>21</imember>"
|
|
" <sub>1.0</sub>"
|
|
" <isub>-100</isub>"
|
|
" <sub>-2.5</sub>"
|
|
" <child><t> Text </t><d>2.5</d><d>1e-3</d></child>"
|
|
" <child><t>T2</t></child>"
|
|
" <c><t>Single child</t></c>"
|
|
"</root>");
|
|
|
|
Root root;
|
|
|
|
tl::XMLStruct<Root> structure ("root",
|
|
tl::make_member (&Root::begin_subs, &Root::end_subs, &Root::add_sub, "sub") +
|
|
tl::make_member (&Root::begin_isubs, &Root::end_isubs, &Root::add_isub, "isub") +
|
|
tl::make_element (&Root::begin_children, &Root::end_children, &Root::add_child, "child",
|
|
tl::make_member (&Child::txt, "t") +
|
|
tl::make_member (&Child::d, "d")
|
|
) +
|
|
tl::make_element (&Root::get_child, &Root::set_child, "c",
|
|
tl::make_member (&Child::txt, "t") +
|
|
tl::make_member (&Child::d, "d")
|
|
) +
|
|
tl::make_member (&Root::m, "member") +
|
|
tl::make_member (&Root::get_mi, &Root::set_mi, "imember")
|
|
);
|
|
|
|
std::string error;
|
|
try {
|
|
structure.parse (s, root);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (root.m_subs.size (), size_t (2));
|
|
EXPECT_EQ (root.m_subs [0], 1.0);
|
|
EXPECT_EQ (root.m_subs [1], -2.5);
|
|
EXPECT_EQ (root.m_isubs.size (), size_t (1));
|
|
EXPECT_EQ (root.m_isubs [0], -100);
|
|
EXPECT_EQ (root.m, 10);
|
|
EXPECT_EQ (root.mi, (unsigned int) 21);
|
|
EXPECT_EQ (root.m_children.size (), size_t (2));
|
|
EXPECT_EQ (root.m_children [0].txt, " Text ");
|
|
EXPECT_EQ (fabs (root.m_children [0].d - 0.001) < 1e-12, true);
|
|
EXPECT_EQ (root.m_children [1].txt, "T2");
|
|
EXPECT_EQ (root.m_children [1].d, -1.0);
|
|
EXPECT_EQ (root.m_child.txt, "Single child");
|
|
EXPECT_EQ (root.m_child.d, -1.0);
|
|
|
|
// write ..
|
|
tl::OutputStringStream out;
|
|
tl::OutputStream os (out);
|
|
structure.write (os, root);
|
|
|
|
// and read again.
|
|
tl::XMLStringSource s2 (out.string ());
|
|
|
|
Root rsave (root);
|
|
root = Root ();
|
|
|
|
try {
|
|
structure.parse (s2, root);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (root == rsave, true);
|
|
}
|
|
|
|
TEST (5)
|
|
{
|
|
tl::XMLStringSource s ("<?xml version=\"1.0\"?>\n"
|
|
"<root>"
|
|
" <member>1</member>"
|
|
"</ruut>");
|
|
|
|
Root root;
|
|
|
|
tl::XMLStruct<Root> structure ("root",
|
|
tl::make_member (&Root::m, "member")
|
|
);
|
|
|
|
std::string error;
|
|
try {
|
|
structure.parse (s, root);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
#if !defined (HAVE_EXPAT)
|
|
EXPECT_EQ (error, "XML parser error: tag mismatch in line 2, column 33");
|
|
#else
|
|
EXPECT_EQ (error, "XML parser error: mismatched tag in line 2, column 28");
|
|
#endif
|
|
}
|
|
|
|
TEST (6)
|
|
{
|
|
tl::XMLStringSource s ("<?xml version=\"1.0\"?>\n"
|
|
"<root>"
|
|
" <member>1a</member>"
|
|
"</root>");
|
|
|
|
Root root;
|
|
|
|
tl::XMLStruct<Root> structure ("root",
|
|
tl::make_member (&Root::m, "member")
|
|
);
|
|
|
|
std::string error;
|
|
try {
|
|
structure.parse (s, root);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
#if !defined (HAVE_EXPAT)
|
|
EXPECT_EQ (error, "XML parser error: Unexpected text after numeric value: '...a' in line 2, column 27");
|
|
#else
|
|
// expat delivers cdata at beginning of closing tag
|
|
EXPECT_EQ (error, "XML parser error: Unexpected text after numeric value: '...a' in line 2, column 18");
|
|
#endif
|
|
}
|
|
|
|
TEST (7)
|
|
{
|
|
std::string tmp_file = tl::TestBase::tmp_file ("tmp_tlXMLParser_7.xml");
|
|
|
|
FILE *f = fopen (tmp_file.c_str (), "w");
|
|
tl_assert (f != NULL);
|
|
|
|
fprintf (f,
|
|
"<?xml version=\"1.0\"?>\n"
|
|
"<root>\n"
|
|
" <member>\n"
|
|
" 10\n"
|
|
" </member>\n"
|
|
" <sub>1.0</sub>\n"
|
|
" <isub>-100</isub>\n"
|
|
" <sub>-2.5</sub>\n"
|
|
" <child><t> Text </t><d>2.5</d><d>1e-3</d></child>\n"
|
|
" <child><t>T2</t></child>\n"
|
|
"</root>\n");
|
|
fclose (f);
|
|
|
|
tl::XMLFileSource s (tmp_file.c_str ());
|
|
|
|
Root root;
|
|
|
|
tl::XMLStruct<Root> structure ("root",
|
|
tl::make_member (&Root::add_sub, "sub") +
|
|
tl::make_member (&Root::add_isub, "isub") +
|
|
tl::make_element (&Root::add_child, "child",
|
|
tl::make_member (&Child::txt, "t") +
|
|
tl::make_member (&Child::d, "d")
|
|
) +
|
|
tl::make_member (&Root::m, "member")
|
|
);
|
|
|
|
std::string error;
|
|
try {
|
|
structure.parse (s, root);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (root.m_subs.size (), size_t (2));
|
|
EXPECT_EQ (root.m_subs [0], 1.0);
|
|
EXPECT_EQ (root.m_subs [1], -2.5);
|
|
EXPECT_EQ (root.m_isubs.size (), size_t (1));
|
|
EXPECT_EQ (root.m_isubs [0], -100);
|
|
EXPECT_EQ (root.m, 10);
|
|
EXPECT_EQ (root.m_children.size (), size_t (2));
|
|
EXPECT_EQ (root.m_children [0].txt, " Text ");
|
|
EXPECT_EQ (fabs (root.m_children [0].d - 0.001) < 1e-12, true);
|
|
EXPECT_EQ (root.m_children [1].txt, "T2");
|
|
EXPECT_EQ (root.m_children [1].d, -1.0);
|
|
}
|
|
|
|
TEST (7a)
|
|
{
|
|
std::string tmp_file = tl::TestBase::tmp_file ("tmp_tlXMLParser_7a.xml");
|
|
|
|
FILE *f = fopen (tmp_file.c_str (), "w");
|
|
tl_assert (f != NULL);
|
|
|
|
fprintf (f,
|
|
"<?xml version=\"1.0\"?>\n"
|
|
"<root>\n"
|
|
" <member>\n"
|
|
" 10\n"
|
|
" </member>\n"
|
|
" <sub>1.0</sub>\n"
|
|
" <isub>-100</isub>\n"
|
|
" <sub>-2.5</sub>\n"
|
|
" <child><t> Text </t><d>2.5</d><d>1e-3</d></child>\n"
|
|
" <child><t>T2</t></child>\n"
|
|
"</root>\n");
|
|
fclose (f);
|
|
|
|
tl::XMLFileSource s (tmp_file.c_str ());
|
|
|
|
Root root;
|
|
|
|
tl::XMLStruct<Root> structure ("root",
|
|
tl::make_member (&Root::add_sub, "sub") +
|
|
tl::make_member (&Root::add_isub, "isub") +
|
|
tl::make_element (&Root::add_child_ptr, "child",
|
|
tl::make_member (&Child::txt, "t") +
|
|
tl::make_member (&Child::d, "d")
|
|
) +
|
|
tl::make_member (&Root::m, "member")
|
|
);
|
|
|
|
std::string error;
|
|
try {
|
|
structure.parse (s, root);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (root.m_subs.size (), size_t (2));
|
|
EXPECT_EQ (root.m_subs [0], 1.0);
|
|
EXPECT_EQ (root.m_subs [1], -2.5);
|
|
EXPECT_EQ (root.m_isubs.size (), size_t (1));
|
|
EXPECT_EQ (root.m_isubs [0], -100);
|
|
EXPECT_EQ (root.m, 10);
|
|
EXPECT_EQ (root.m_children.size (), size_t (2));
|
|
EXPECT_EQ (root.m_children [0].txt, " Text ");
|
|
EXPECT_EQ (fabs (root.m_children [0].d - 0.001) < 1e-12, true);
|
|
EXPECT_EQ (root.m_children [1].txt, "T2");
|
|
EXPECT_EQ (root.m_children [1].d, -1.0);
|
|
}
|
|
|
|
TEST (8)
|
|
{
|
|
std::string tmp_file = tl::TestBase::tmp_file ("tmp_tlXMLParser_8.xml");
|
|
|
|
FILE *f = fopen (tmp_file.c_str (), "w");
|
|
tl_assert (f != NULL);
|
|
|
|
fprintf (f,
|
|
"<?xml version=\"1.0\"?>\n"
|
|
"<root>\n"
|
|
" <member>\n"
|
|
" 10\n"
|
|
" </member>\n"
|
|
" <child><t> Text </t>\n"
|
|
" <child><t>C1</t></child>\n"
|
|
" <child><t>c2</t><child><t>d2</t><d>-1.25</d></child></child>\n"
|
|
" <d>2.5</d><d>125e-3</d></child>\n"
|
|
" <child><t>T2</t></child>\n"
|
|
"</root>\n");
|
|
fclose (f);
|
|
|
|
tl::XMLFileSource s (tmp_file.c_str ());
|
|
|
|
Root root;
|
|
|
|
tl::XMLElementList child_struct =
|
|
tl::make_member (&Child::txt, "t") +
|
|
tl::make_member (&Child::d, "d") +
|
|
tl::make_element (&Child::begin_children, &Child::end_children, &Child::add_child, "child", &child_struct);
|
|
|
|
tl::XMLStruct<Root> structure ("root",
|
|
tl::make_element (&Root::begin_children, &Root::end_children, &Root::add_child, "child", &child_struct) +
|
|
tl::make_member (&Root::m, "member")
|
|
);
|
|
|
|
std::string error;
|
|
try {
|
|
structure.parse (s, root);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
// write ..
|
|
tl::OutputStringStream out;
|
|
tl::OutputStream os (out);
|
|
structure.write (os, root);
|
|
std::string xml = out.string ();
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (root.m, 10);
|
|
EXPECT_EQ (root.m_children.size (), size_t (2));
|
|
EXPECT_EQ (root.m_children [0].txt, " Text ");
|
|
EXPECT_EQ (fabs (root.m_children [0].d - 0.125) < 1e-12, true);
|
|
EXPECT_EQ (root.m_children [0].children.size (), size_t (2));
|
|
EXPECT_EQ (root.m_children [0].children [0].txt, "C1");
|
|
EXPECT_EQ (root.m_children [0].children [1].txt, "c2");
|
|
EXPECT_EQ (root.m_children [0].children [1].children.size (), size_t (1));
|
|
EXPECT_EQ (root.m_children [0].children [1].children [0].txt, "d2");
|
|
EXPECT_EQ (root.m_children [1].txt, "T2");
|
|
EXPECT_EQ (root.m_children [1].d, -1.0);
|
|
|
|
tl::XMLStringSource xml_src (xml);
|
|
Root root2;
|
|
try {
|
|
structure.parse (xml_src, root2);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (root == root2, true);
|
|
|
|
}
|
|
|
|
TEST (8a)
|
|
{
|
|
std::string tmp_file = tl::TestBase::tmp_file ("tmp_tlXMLParser_8a.xml");
|
|
|
|
FILE *f = fopen (tmp_file.c_str (), "w");
|
|
tl_assert (f != NULL);
|
|
|
|
fprintf (f,
|
|
"<?xml version=\"1.0\"?>\n"
|
|
"<root>\n"
|
|
" <member>\n"
|
|
" 10\n"
|
|
" </member>\n"
|
|
" <child><t> Text </t>\n"
|
|
" <child><t>C1</t></child>\n"
|
|
" <child><t>c2</t><child><t>d2</t><d>-1.25</d></child></child>\n"
|
|
" <d>2.5</d><d>125e-3</d></child>\n"
|
|
" <child><t>T2</t></child>\n"
|
|
"</root>\n");
|
|
fclose (f);
|
|
|
|
tl::XMLFileSource s (tmp_file.c_str ());
|
|
|
|
Root root;
|
|
|
|
tl::XMLElementList child_struct =
|
|
tl::make_member (&Child::txt, "t") +
|
|
tl::make_member (&Child::d, "d") +
|
|
tl::make_element (&Child::begin_children, &Child::end_children, &Child::add_child_ptr, "child", &child_struct);
|
|
|
|
tl::XMLStruct<Root> structure ("root",
|
|
tl::make_element (&Root::begin_children, &Root::end_children, &Root::add_child_ptr, "child", &child_struct) +
|
|
tl::make_member (&Root::m, "member")
|
|
);
|
|
|
|
std::string error;
|
|
try {
|
|
structure.parse (s, root);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
// write ..
|
|
tl::OutputStringStream out;
|
|
tl::OutputStream os (out);
|
|
structure.write (os, root);
|
|
std::string xml = out.string ();
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (root.m, 10);
|
|
EXPECT_EQ (root.m_children.size (), size_t (2));
|
|
EXPECT_EQ (root.m_children [0].txt, " Text ");
|
|
EXPECT_EQ (fabs (root.m_children [0].d - 0.125) < 1e-12, true);
|
|
EXPECT_EQ (root.m_children [0].children.size (), size_t (2));
|
|
EXPECT_EQ (root.m_children [0].children [0].txt, "C1");
|
|
EXPECT_EQ (root.m_children [0].children [1].txt, "c2");
|
|
EXPECT_EQ (root.m_children [0].children [1].children.size (), size_t (1));
|
|
EXPECT_EQ (root.m_children [0].children [1].children [0].txt, "d2");
|
|
EXPECT_EQ (root.m_children [1].txt, "T2");
|
|
EXPECT_EQ (root.m_children [1].d, -1.0);
|
|
|
|
tl::XMLStringSource xml_src (xml);
|
|
Root root2;
|
|
try {
|
|
structure.parse (xml_src, root2);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (root == root2, true);
|
|
|
|
}
|
|
|
|
TEST (9)
|
|
{
|
|
// unknown elements shall be ignored.
|
|
std::string x =
|
|
"<?xml version=\"1.0\"?>\n"
|
|
"<root>\n"
|
|
" <member>\n"
|
|
" 10\n"
|
|
" </member>\n"
|
|
" <unknown-member>15</unknown-member>\n"
|
|
" <unknown-child><t>blabla</t>\n"
|
|
" <child><t>C1</t></child>\n"
|
|
" <child><t>c2</t><child><t>d2</t><d>-1.25</d><unknown-data>blabla</unknown-data></child></child>\n"
|
|
" <d>2.5</d><d>125e-3</d>\n"
|
|
" <unknown-data>2.5</unknown-data>\n"
|
|
" </unknown-child>\n"
|
|
" <child><t> Text </t>\n"
|
|
" <child><t>C1</t></child>\n"
|
|
" <child><t>c2</t><child><t>d2</t><d>-1.25</d><unknown-data>blabal</unknown-data></child></child>\n"
|
|
" <d>2.5</d><d>125e-3</d>\n"
|
|
" <unknown-data>2.5</unknown-data>\n"
|
|
" </child>\n"
|
|
" <unknown-child><t>TT</t></unknown-child>\n"
|
|
" <child><t>T2</t></child>\n"
|
|
"</root>\n";
|
|
|
|
tl::XMLStringSource s (x);
|
|
|
|
Root root;
|
|
|
|
tl::XMLElementList child_struct =
|
|
tl::make_member (&Child::txt, "t") +
|
|
tl::make_member (&Child::d, "d") +
|
|
tl::make_element (&Child::begin_children, &Child::end_children, &Child::add_child_ptr, "child", &child_struct);
|
|
|
|
tl::XMLStruct<Root> structure ("root",
|
|
tl::make_element (&Root::begin_children, &Root::end_children, &Root::add_child_ptr, "child", &child_struct) +
|
|
tl::make_member (&Root::m, "member")
|
|
);
|
|
|
|
std::string error;
|
|
try {
|
|
structure.parse (s, root);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (root.m, 10);
|
|
EXPECT_EQ (root.m_children.size (), size_t (2));
|
|
EXPECT_EQ (root.m_children [0].txt, " Text ");
|
|
EXPECT_EQ (fabs (root.m_children [0].d - 0.125) < 1e-12, true);
|
|
EXPECT_EQ (root.m_children [0].children.size (), size_t (2));
|
|
EXPECT_EQ (root.m_children [0].children [0].txt, "C1");
|
|
EXPECT_EQ (root.m_children [0].children [1].txt, "c2");
|
|
EXPECT_EQ (root.m_children [0].children [1].children.size (), size_t (1));
|
|
EXPECT_EQ (root.m_children [0].children [1].children [0].txt, "d2");
|
|
EXPECT_EQ (root.m_children [1].txt, "T2");
|
|
EXPECT_EQ (root.m_children [1].d, -1.0);
|
|
}
|
|
|
|
TEST (10)
|
|
{
|
|
// UTF8 encoding
|
|
std::string x =
|
|
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
|
"<child><t>H\xc3\xa4llo</t>\n"
|
|
"</child>\n";
|
|
|
|
tl::XMLStringSource s (x);
|
|
|
|
Child child;
|
|
|
|
tl::XMLStruct<Child> child_struct ("child", tl::make_member (&Child::txt, "t"));
|
|
|
|
std::string error;
|
|
try {
|
|
child_struct.parse (s, child);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (child.txt, "H\xc3\xa4llo");
|
|
}
|
|
|
|
#if defined(HAVE_EXPAT) || QT_VERSION < 0x60000 // #QTBUG-98656 (XML reader does not read encoding properly)
|
|
TEST (11)
|
|
{
|
|
// iso8859-1 encoding
|
|
std::string x =
|
|
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
|
|
"<child><t>H\xe4llo</t>\n"
|
|
"</child>\n";
|
|
|
|
tl::XMLStringSource s (x);
|
|
|
|
Child child;
|
|
|
|
tl::XMLStruct<Child> child_struct ("child", tl::make_member (&Child::txt, "t"));
|
|
|
|
std::string error;
|
|
try {
|
|
child_struct.parse (s, child);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (child.txt, "H\xc3\xa4llo");
|
|
}
|
|
#endif
|
|
|
|
TEST (12)
|
|
{
|
|
// UTF8 encoding
|
|
std::string x =
|
|
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
|
"<child><t>H\xc3\xa4llo</t>\n"
|
|
"</child>\n";
|
|
|
|
tl::InputMemoryStream ms (x.c_str (), x.size ());
|
|
tl::InputStream is (ms);
|
|
tl::XMLStreamSource s (is);
|
|
|
|
Child child;
|
|
|
|
tl::XMLStruct<Child> child_struct ("child", tl::make_member (&Child::txt, "t"));
|
|
|
|
std::string error;
|
|
try {
|
|
child_struct.parse (s, child);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (child.txt, "H\xc3\xa4llo");
|
|
}
|
|
|
|
#if defined(HAVE_EXPAT) || QT_VERSION < 0x60000 // #QTBUG-98656 (XML reader does not read encoding properly)
|
|
TEST (13)
|
|
{
|
|
// iso8859 encoding
|
|
std::string x =
|
|
"<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n"
|
|
"<child><t>H\xe4llo</t>\n"
|
|
"</child>\n";
|
|
|
|
tl::InputMemoryStream ms (x.c_str (), x.size ());
|
|
tl::InputStream is (ms);
|
|
tl::XMLStreamSource s (is);
|
|
|
|
Child child;
|
|
|
|
tl::XMLStruct<Child> child_struct ("child", tl::make_member (&Child::txt, "t"));
|
|
|
|
std::string error;
|
|
try {
|
|
child_struct.parse (s, child);
|
|
} catch (tl::XMLException &ex) {
|
|
error = ex.msg ();
|
|
}
|
|
|
|
EXPECT_EQ (error, "");
|
|
EXPECT_EQ (child.txt, "H\xc3\xa4llo");
|
|
}
|
|
#endif
|
|
|
|
#endif
|