test_memory_layout.cc
Go to the documentation of this file.
00001 #include <boost/test/auto_unit_test.hpp>
00002 
00003 #include <test/testsuite.hh>
00004 #include <typelib/utilmm/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     // Get the test file into repository
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     /* Check a simple structure with alignment issues */
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     /* Check handling of simple arrays */
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     /* Check a structure with arrays */
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     /* Check a multidimensional array */
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     // Check a structure with pointer. Must throw by default, but accept if the
00072     // accept_pointers flag is set, in which case FLAG_MEMCPY is used for it.
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     // Check an opaque type
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     // Get the test file into repository
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         // Check that we have all the operations that we need
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     // Get the test file into repository
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         // Check that we have all the operations that we need
00219         size_t expected_size = sizeof(expected) / sizeof(size_t);
00220         BOOST_REQUIRE_EQUAL(expected_size, ops.size());
00221     }
00222 }
00223 


typelib
Author(s): Sylvain Joyeux/sylvain.joyeux@m4x.org
autogenerated on Sat Jun 8 2019 18:49:22