]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/serialization/test/test_dll_plugin.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / serialization / test / test_dll_plugin.cpp
1 /////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
2 // test_dll_plugin.cpp
3
4 // (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
5 // Use, modification and distribution is subject to the Boost Software
6 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
8
9 // should pass compilation and execution
10
11 // Note this test creates, serializes, and destroys
12 // a class instance while knowing nothing more than its
13 // exported class ID (GUID) and a base class from which
14 // it is derived. This is referred to as a "plugin"
15 // since the same program could, without recompilation,
16 // manipulate any number of derived types - even those
17 // which have not been yet been created.
18
19 #include <fstream>
20
21 #include <cstdio> // remove
22 #include <boost/config.hpp>
23 #if defined(BOOST_NO_STDC_NAMESPACE)
24 namespace std{
25 using ::remove;
26 }
27 #endif
28
29 #include <boost/archive/archive_exception.hpp>
30
31 // for now, only test with simple text and polymorphic archive
32 #include "test_tools.hpp"
33
34 #include <boost/serialization/base_object.hpp>
35 #include <boost/serialization/export.hpp>
36 #include <boost/serialization/type_info_implementation.hpp>
37 #include <boost/serialization/access.hpp>
38 #include <boost/serialization/void_cast.hpp>
39 #include <boost/serialization/extended_type_info.hpp>
40
41 #include "polymorphic_base.hpp"
42
43 // declare and implement a derived class in our own executable
44 class polymorphic_derived1 : public polymorphic_base
45 {
46 friend class boost::serialization::access;
47 template<class Archive>
48 void serialize(Archive &ar, const unsigned int /* file_version */){
49 ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(polymorphic_base);
50 }
51 const char * get_key() const{
52 return
53 boost::serialization::type_info_implementation<
54 polymorphic_derived1
55 >::type::get_const_instance().get_key();
56 }
57 public:
58 virtual ~polymorphic_derived1(){}
59 };
60
61 // This class is derived from polymorphic_base which uses the no_rtti system
62 // rather than the typeid system. This system uses the exported name as the
63 // type identifier key. This MUST be exported!!!
64 BOOST_CLASS_EXPORT(polymorphic_derived1)
65
66 // MWerks users can do this to make their code work
67 BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(polymorphic_base, polymorphic_derived1)
68
69 // save exported polymorphic class
70 void save_exported(const char *testfile)
71 {
72 test_ostream os(testfile, TEST_STREAM_FLAGS);
73 test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
74
75 polymorphic_base *rb1 = new polymorphic_derived1;
76
77 // get the eti record for the exported type "polymorphic_derived2"
78 boost::serialization::extended_type_info const * const d2_eti =
79 boost::serialization::extended_type_info::find(
80 "polymorphic_derived2"
81 );
82 assert(NULL != d2_eti);
83
84 // create a new instance of the type referred to by this record.
85 // in this example, we happen to know that the class constructor
86 // takes no arguments.
87 void const * const rd2 = d2_eti->construct();
88 assert(NULL != rd2);
89
90 // transform the pointer to a pointer to the base class
91 polymorphic_base const * const rb2
92 = static_cast<polymorphic_base const *>(
93 boost::serialization::void_upcast(
94 * d2_eti,
95 boost::serialization::type_info_implementation<polymorphic_base>
96 ::type::get_const_instance(),
97 rd2
98 )
99 );
100
101 // export will permit correct serialization
102 // through a pointer to a base class
103 oa << BOOST_SERIALIZATION_NVP(rb1);
104 oa << BOOST_SERIALIZATION_NVP(rb2);
105
106 // don't need these any more - don't leak memory
107 delete rb1;
108 // note delete original handle - not runtime cast one !!!
109 //delete rb2;
110 d2_eti->destroy(rd2);
111 }
112
113 // save exported polymorphic class
114 void load_exported(const char *testfile)
115 {
116 test_istream is(testfile, TEST_STREAM_FLAGS);
117 test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
118
119 polymorphic_base *rb1 = NULL;
120 polymorphic_base *rb2 = NULL;
121
122 // export will permit correct serialization
123 // through a pointer to a base class
124 ia >> BOOST_SERIALIZATION_NVP(rb1);
125
126 BOOST_CHECK_MESSAGE(
127 boost::serialization::type_info_implementation<polymorphic_derived1>
128 ::type::get_const_instance()
129 ==
130 * boost::serialization::type_info_implementation<polymorphic_base>
131 ::type::get_const_instance().get_derived_extended_type_info(*rb1),
132 "restored pointer b1 not of correct type"
133 );
134 ia >> BOOST_SERIALIZATION_NVP(rb2);
135
136 // get the eti record for the exported type "polymorphic_derived2"
137 boost::serialization::extended_type_info const * const d2_eti =
138 boost::serialization::extended_type_info::find(
139 "polymorphic_derived2"
140 );
141 assert(NULL != d2_eti);
142
143 BOOST_CHECK_MESSAGE(
144 * d2_eti
145 ==
146 * boost::serialization::type_info_implementation<polymorphic_base>
147 ::type::get_const_instance().get_derived_extended_type_info(*rb2),
148 "restored pointer b2 not of correct type"
149 );
150
151 delete rb1;
152 delete rb2;
153 }
154
155 #ifdef BOOST_WINDOWS
156
157 #define WIN32_LEAN_AND_MEAN
158 #include <TCHAR.H>
159 #include <windows.h>
160
161 int
162 test_main( int /* argc */, char* /* argv */[] )
163 {
164 const char * testfile = boost::archive::tmpnam(NULL);
165 BOOST_REQUIRE(NULL != testfile);
166
167 HINSTANCE hDLL; // Handle to DLL
168 hDLL = LoadLibrary(_T("plugin_polymorphic_derived2.dll"));
169 BOOST_CHECK_MESSAGE(
170 (0 != hDLL),
171 "Failed to find/load plugin_polymorphic_derived2"
172 );
173 if(0 == hDLL)
174 return EXIT_FAILURE;
175
176 save_exported(testfile);
177 load_exported(testfile);
178 FreeLibrary(hDLL);
179
180 std::remove(testfile);
181 return EXIT_SUCCESS;
182 }
183
184 #else // presume *nix
185
186 #include <dlfcn.h>
187
188 int
189 test_main( int /* argc */, char* /* argv */[] )
190 {
191 const char * testfile = boost::archive::tmpnam(NULL);
192 BOOST_REQUIRE(NULL != testfile);
193
194 void * hDLL; // Handle to DLL
195 hDLL = dlopen("plugin_polymorphic_derived2.so", RTLD_NOW | RTLD_GLOBAL);
196 BOOST_CHECK_MESSAGE((0 != hDLL), "Failed to find/load plugin_polymorphic_derived2" );
197 if(0 == hDLL)
198 return EXIT_FAILURE;
199
200 save_exported(testfile);
201 load_exported(testfile);
202 dlclose(hDLL);
203
204 std::remove(testfile);
205 return EXIT_SUCCESS;
206 }
207
208 #endif
209
210 // EOF