1 /*
2 
3 Copyright (c) 2002-2008, Yauheni Akhotnikau
4 Copyright (c) 2008-2013, The SObjectizer Project
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 - Redistributions of source code must retain the above copyright notice, this
11 list of conditions and the following disclaimer.
12 
13 - Redistributions in binary form must reproduce the above copyright notice, this
14 list of conditions and the following disclaimer in the documentation and/or
15 other materials provided with the distribution.
16 
17 - The name of the author may not be used to endorse or promote products derived
18 from this software without specific prior written permission.
19 
20 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
21 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
23 EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
25 OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
28 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
29 OF SUCH DAMAGE.
30 
31 */
32 
33 #include <iostream>
34 #include <exception>
35 #include <map>
36 
37 #include <oess_2/io/h/mem_buf.hpp>
38 
39 #include <oess_2/stdsn/h/serializable.hpp>
40 #include <oess_2/stdsn/h/shptr.hpp>
41 #include <oess_2/stdsn/h/inout_templ.hpp>
42 #include <oess_2/stdsn/h/ent_std.hpp>
43 
44 class	my_t :
45 	public oess_2::stdsn::serializable_t
46 {
47 	OESS_SERIALIZER( my_t )
48 	private :
49 		static int	m_global_counter;
50 
51 		int	m_ordinal;
52 	public :
my_t()53 		my_t()
54 			:	m_ordinal( ++m_global_counter )
55 		{
56 			std::cout << m_ordinal << " my_t::my_t()" << std::endl;
57 		}
~my_t()58 		virtual ~my_t()
59 		{
60 			std::cout << m_ordinal << " my_t::~my_t()" << std::endl;
61 		}
62 
63 		void
say() const64 		say() const
65 		{
66 			std::cout << m_ordinal << " my_t::say()" << std::endl;
67 		}
68 
69 		my_t *
clone() const70 		clone() const
71 			{
72 				return new my_t();
73 			}
74 
75 		int
ordinal() const76 		ordinal() const
77 			{
78 				return m_ordinal;
79 			}
80 };
81 
82 int	my_t::m_global_counter = 0;
83 
84 class	my_ptr_t
85 	:	public oess_2::stdsn::shptr_t
86 {
87 	typedef oess_2::stdsn::shptr_t shptr_base_type_t;
88 
89 	OESS_SERIALIZER( my_ptr_t )
90 	OESS_2_SHPTR_IFACE( my_ptr_t, my_t, shptr_base_type_t )
91 
92 	protected :
93 
94 		virtual void
95 		oess_shptr_assign( const oess_2::stdsn::shptr_t & o );
96 };
97 
98 void
oess_shptr_assign(const oess_2::stdsn::shptr_t & o)99 my_ptr_t::oess_shptr_assign( const oess_2::stdsn::shptr_t & o )
100 {
101 
102 	// ������ �� ����, ��� ����� ���� ��������� ������
103 	// �� ������ ������.
104 	// ����� �������� ����� ����������, ����
105 	// ������������ ����������� ��� ��������, �����������
106 	// � �������� ����.
107 	try
108 	{
109 		const my_ptr_t & what =
110 			dynamic_cast< const my_ptr_t & >( o );
111 		if( &what != this )
112 		{
113 			// ����������� ������ ������ �� �����.
114 			oess_reset( ( what.get() ? what->clone() : 0 ) );
115 		}
116 	}
117 	catch( ... )
118 	{
119 		// � ���� ������ ���������� ��������
120 		// ����������� �� �������� ������.
121 		base_type_t::oess_shptr_assign( o );
122 	}
123 }
124 
125 bool
operator <(const my_ptr_t & o1,const my_ptr_t & o2)126 operator<( const my_ptr_t & o1, const my_ptr_t & o2 )
127 {
128 	return ( o1->ordinal() < o2->ordinal() );
129 }
130 
131 class	my_cont_t :
132 	public oess_2::stdsn::serializable_t
133 {
134 	OESS_SERIALIZER( my_cont_t )
135 	private :
136 		typedef std::multimap< my_ptr_t, int > cont_t;
137 		cont_t	m_cont;
138 
139 	public :
my_cont_t()140 		my_cont_t()
141 		{
142 		}
~my_cont_t()143 		virtual ~my_cont_t()
144 		{
145 		}
146 
147 		void
show() const148 		show() const
149 		{
150 			for( cont_t::const_iterator
151 					it = m_cont.begin(),
152 					it_end = m_cont.end();
153 				it != it_end; ++it )
154 			{
155 				(*it).first->say();
156 			}
157 		}
158 
159 		void
add(const my_ptr_t & o)160 		add( const my_ptr_t & o )
161 		{
162 			static int i = 0;
163 			m_cont.insert( cont_t::value_type( o, ++i ) );
164 		}
165 };
166 
167 #include "main.ddl.cpp"
168 
169 void
do_test()170 do_test()
171 {
172 	oess_2::io::mem_buf_t buf;
173 
174 	{
175 		my_ptr_t ptr( new my_t() );
176 		oess_2::stdsn::shptr_t empty;
177 		my_ptr_t ptr2( ptr );
178 		my_ptr_t ptr3;
179 		ptr3 = ptr2;
180 
181 		my_t * p = ptr.get();
182 		if( p )
183 			p->say();
184 		p = ptr2.get();
185 		if( p )
186 		{
187 			p->say();
188 			ptr2->say();
189 			(*ptr2).say();
190 		}
191 
192 		oess_2::stdsn::oent_std_t oent( buf );
193 		oent << ptr << empty << ptr2;
194 		my_cont_t my_cont;
195 		my_cont.add( ptr );
196 		my_cont.add( ptr2 );
197 		my_cont.add( ptr3 );
198 		my_cont.show();
199 
200 		oent << my_cont;
201 	}
202 
203 	std::cout << "buf size: " << buf.size() << std::endl;
204 
205 	{
206 		buf.set_pos( 0 );
207 		my_ptr_t ptr;
208 		my_cont_t cont;
209 
210 		oess_2::stdsn::ient_std_t ient( buf , my_repository_details::repository );
211 
212 		while( !buf.eof() )
213 		{
214 			ient >> ptr;
215 			if( ptr.get() )
216 				ptr->say();
217 			else
218 				std::cout << "empty pointer" << std::endl;
219 
220 			ient >> ptr;
221 			if( ptr.get() )
222 				ptr->say();
223 			else
224 				std::cout << "empty pointer" << std::endl;
225 
226 			ient >> ptr;
227 			if( ptr.get() )
228 				ptr->say();
229 			else
230 				std::cout << "empty pointer" << std::endl;
231 
232 			ient >> cont;
233 			cont.show();
234 		}
235 	}
236 }
237 
238 int
main(int,char **)239 main( int, char ** )
240 {
241 	try
242 	{
243 		do_test();
244 
245 		return 0;
246 	}
247 	catch( std::exception & x )
248 	{
249 		std::cerr << x.what() << std::endl;
250 	}
251 
252 	return 2;
253 }
254 
255