00001 #include <boost/test/auto_unit_test.hpp>
00002
00003 #include <test/testsuite.hh>
00004 #include <utilmm/configfile/configset.hh>
00005 #include <typelib/pluginmanager.hh>
00006 #include <typelib/importer.hh>
00007 #include <typelib/typemodel.hh>
00008 #include <typelib/registry.hh>
00009 #include <typelib/value.hh>
00010 #include <typelib/memory_layout.hh>
00011
00012
00013 #include <typelib/value_ops.hh>
00014 #include <test/test_cimport.1>
00015 #include <string.h>
00016
00017 using namespace Typelib;
00018 using namespace std;
00019
00020 BOOST_AUTO_TEST_CASE( test_layout_simple )
00021 {
00022
00023 Registry registry;
00024 PluginManager::self manager;
00025 auto_ptr<Importer> importer(manager->importer("tlb"));
00026 utilmm::config_set config;
00027 BOOST_REQUIRE_NO_THROW( importer->load(TEST_DATA_PATH("test_cimport.tlb"), config, registry) );
00028
00029
00030 {
00031 Type const& type = *registry.get("/A");
00032 MemoryLayout ops = Typelib::layout_of(type);
00033
00034 BOOST_REQUIRE_EQUAL(2U, ops.size());
00035 BOOST_REQUIRE_EQUAL(MemLayout::FLAG_MEMCPY, ops[0]);
00036 A data;
00037 BOOST_REQUIRE_EQUAL(offsetof(A, d) + sizeof(data.d), ops[1]);
00038 }
00039
00040
00041 {
00042 Type const& type = *registry.build("/char[100]");
00043 MemoryLayout ops = Typelib::layout_of(type);
00044
00045 BOOST_REQUIRE_EQUAL(2U, ops.size());
00046 BOOST_REQUIRE_EQUAL(MemLayout::FLAG_MEMCPY, ops[0]);
00047 BOOST_REQUIRE_EQUAL(100U, ops[1]);
00048 }
00049
00050
00051 {
00052 Type const& type = *registry.get("/B");
00053 MemoryLayout ops = Typelib::layout_of(type);
00054
00055 BOOST_REQUIRE_EQUAL(2U, ops.size());
00056 BOOST_REQUIRE_EQUAL(MemLayout::FLAG_MEMCPY, ops[0]);
00057 B data;
00058 BOOST_REQUIRE_EQUAL(offsetof(B, z) + sizeof(data.z), ops[1]);
00059 }
00060
00061
00062 {
00063 Type const& type = *registry.get("TestMultiDimArray");
00064 MemoryLayout ops = Typelib::layout_of(type);
00065
00066 BOOST_REQUIRE_EQUAL(2U, ops.size());
00067 BOOST_REQUIRE_EQUAL(MemLayout::FLAG_MEMCPY, ops[0]);
00068 BOOST_REQUIRE_EQUAL(type.getSize(), ops[1]);
00069 }
00070
00071
00072
00073 {
00074 Type const& type = *registry.get("/C");
00075 BOOST_CHECK_THROW(Typelib::layout_of(type), Typelib::NoLayout);
00076
00077 MemoryLayout ops = Typelib::layout_of(type, true);
00078 BOOST_REQUIRE_EQUAL(2, ops.size());
00079 BOOST_REQUIRE_EQUAL(MemLayout::FLAG_MEMCPY, ops[0]);
00080 C data;
00081 BOOST_REQUIRE_EQUAL(offsetof(C, z) + sizeof(data.z), ops[1]);
00082 }
00083
00084
00085 {
00086 OpaqueType type("test_opaque", 10);
00087 BOOST_CHECK_THROW(Typelib::layout_of(type), Typelib::NoLayout);
00088 }
00089 }
00090
00091 BOOST_AUTO_TEST_CASE(test_layout_arrays)
00092 {
00093
00094 Registry registry;
00095 PluginManager::self manager;
00096 auto_ptr<Importer> importer(manager->importer("tlb"));
00097 utilmm::config_set config;
00098 BOOST_REQUIRE_NO_THROW( importer->load(TEST_DATA_PATH("test_cimport.tlb"), config, registry) );
00099
00100 {
00101 Type const& type = *registry.get("/Arrays");
00102 Compound const& str = static_cast<Compound const&>(*registry.get("/NS1/Test"));
00103 BOOST_REQUIRE(str.getSize() != str.getField("b")->getOffset() + str.getField("b")->getType().getSize());
00104
00105 Type const& v_str = *registry.get("/std/vector</NS1/Test>");
00106 Type const& v_double = *registry.get("/std/vector</double>");
00107 MemoryLayout ops = Typelib::layout_of(type);
00108
00109 StdCollections test;
00110
00111 Arrays arrays_v;
00112 size_t expected[] = {
00113 MemLayout::FLAG_MEMCPY,
00114 reinterpret_cast<uint8_t*>(&arrays_v.a_v_numeric) - reinterpret_cast<uint8_t*>(&arrays_v),
00115 MemLayout::FLAG_ARRAY,
00116 10,
00117 MemLayout::FLAG_CONTAINER,
00118 reinterpret_cast<size_t>(&v_double),
00119 MemLayout::FLAG_MEMCPY,
00120 sizeof(double),
00121 MemLayout::FLAG_END,
00122 MemLayout::FLAG_END,
00123 MemLayout::FLAG_MEMCPY,
00124 reinterpret_cast<uint8_t*>(&arrays_v.a_v_struct[0]) - reinterpret_cast<uint8_t*>(&arrays_v.padding3),
00125 MemLayout::FLAG_ARRAY,
00126 10,
00127 MemLayout::FLAG_CONTAINER,
00128 reinterpret_cast<size_t>(&v_str),
00129 MemLayout::FLAG_MEMCPY,
00130 sizeof(NS1::Test),
00131 MemLayout::FLAG_END,
00132 MemLayout::FLAG_END,
00133 MemLayout::FLAG_MEMCPY,
00134 sizeof(char)
00135 };
00136
00137 for (size_t i = 0; i < ops.size(); ++i)
00138 if (expected[i] != ops[i])
00139 {
00140 Typelib::display(cerr, ops.begin(), ops.end());
00141 std::cerr << "error at index " << i << std::endl;
00142 BOOST_REQUIRE_EQUAL(expected[i], ops[i]);
00143 }
00144
00145
00146 size_t expected_size = sizeof(expected) / sizeof(size_t);
00147 BOOST_REQUIRE_EQUAL(expected_size, ops.size());
00148 }
00149 }
00150
00151 BOOST_AUTO_TEST_CASE(test_layout_containers)
00152 {
00153
00154 Registry registry;
00155 PluginManager::self manager;
00156 auto_ptr<Importer> importer(manager->importer("tlb"));
00157 utilmm::config_set config;
00158 BOOST_REQUIRE_NO_THROW( importer->load(TEST_DATA_PATH("test_cimport.tlb"), config, registry) );
00159
00160 {
00161 Type const& type = *registry.get("/Collections");
00162 Compound const& str = static_cast<Compound const&>(*registry.get("/NS1/Test"));
00163 BOOST_REQUIRE(str.getSize() != str.getField("b")->getOffset() + str.getField("b")->getType().getSize());
00164
00165 Type const& v_str = *registry.get("/std/vector</NS1/Test>");
00166 Type const& v_v_str = *registry.get("/std/vector</std/vector</NS1/Test>>");
00167 Type const& v_double = *registry.get("/std/vector</double>");
00168 Type const& v_v_double = *registry.get("/std/vector</std/vector</double>>");
00169 MemoryLayout ops = Typelib::layout_of(type);
00170
00171 Collections value;
00172
00173 size_t expected[] = {
00174 MemLayout::FLAG_CONTAINER,
00175 reinterpret_cast<size_t>(&v_double),
00176 MemLayout::FLAG_MEMCPY,
00177 sizeof(double),
00178 MemLayout::FLAG_END,
00179 MemLayout::FLAG_MEMCPY,
00180 reinterpret_cast<uint8_t*>(&value.v_struct) - reinterpret_cast<uint8_t*>(&value.padding1),
00181 MemLayout::FLAG_CONTAINER,
00182 reinterpret_cast<size_t>(&v_str),
00183 MemLayout::FLAG_MEMCPY,
00184 sizeof(NS1::Test),
00185 MemLayout::FLAG_END,
00186 MemLayout::FLAG_MEMCPY,
00187 reinterpret_cast<uint8_t*>(&value.v_v_numeric) - reinterpret_cast<uint8_t*>(&value.padding2),
00188 MemLayout::FLAG_CONTAINER,
00189 reinterpret_cast<size_t>(&v_v_double),
00190 MemLayout::FLAG_CONTAINER,
00191 reinterpret_cast<size_t>(&v_double),
00192 MemLayout::FLAG_MEMCPY,
00193 sizeof(double),
00194 MemLayout::FLAG_END,
00195 MemLayout::FLAG_END,
00196 MemLayout::FLAG_MEMCPY,
00197 reinterpret_cast<uint8_t*>(&value.v_v_struct) - reinterpret_cast<uint8_t*>(&value.padding3),
00198 MemLayout::FLAG_CONTAINER,
00199 reinterpret_cast<size_t>(&v_v_str),
00200 MemLayout::FLAG_CONTAINER,
00201 reinterpret_cast<size_t>(&v_str),
00202 MemLayout::FLAG_MEMCPY,
00203 sizeof(NS1::Test),
00204 MemLayout::FLAG_END,
00205 MemLayout::FLAG_END,
00206 MemLayout::FLAG_MEMCPY,
00207 sizeof(char)
00208 };
00209
00210 for (size_t i = 0; i < ops.size(); ++i)
00211 if (expected[i] != ops[i])
00212 {
00213 Typelib::display(cerr, ops.begin(), ops.end());
00214 std::cerr << "error at index " << i << std::endl;
00215 BOOST_REQUIRE_EQUAL(expected[i], ops[i]);
00216 }
00217
00218
00219 size_t expected_size = sizeof(expected) / sizeof(size_t);
00220 BOOST_REQUIRE_EQUAL(expected_size, ops.size());
00221 }
00222 }
00223