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 /*!
34 	\file oess_2/tlv/h/basic_string.hpp
35 	\brief ����� %oess_2::tlv::basic_string_tlv_t.
36 */
37 
38 #if !defined( _OESS_2__TLV__BASIC_STRING_HPP_ )
39 #define _OESS_2__TLV__BASIC_STRING_HPP_
40 
41 #include <oess_2/tlv/h/declspec.hpp>
42 
43 #include <string>
44 #include <vector>
45 
46 #include <oess_2/defs/h/ex.hpp>
47 
48 #include <oess_2/io/h/bin_data_size.hpp>
49 
50 #include <oess_2/tlv/h/base.hpp>
51 #include <oess_2/tlv/h/default_processors.hpp>
52 #include <oess_2/tlv/h/errno.hpp>
53 
54 namespace oess_2
55 {
56 
57 namespace tlv
58 {
59 
60 //
61 // basic_string_tlv_t
62 //
63 
64 //! TLV ��� ������������ �������� std::basic_string.
65 /*!
66  * ���� Length �������� ����� ������, ���������� ��
67  * ������ ��������� ������������� ������ �������
68  * (�.�. ��� oess_2::char_t ����� ������).
69  *
70  * ��� ������ ������ ����������� � �������� ������
71  * ������ ���� Tag � ������� ���� Length.
72  *
73  * \par v.1.4.0-b2.2
74  * ��� ���� ��������� ������� "�������������� ��������". ��������
75  * ��������� ������������ ��� ����, ���� ��� ���� ��������� ��
76  * �������� ������ � tlv_unpack() ��� ���� ��� ���� ���������
77  * ����������� set_value().
78  *
79  * ������� ��������� � ��������������� �������� �������� �
80  * ������������� ����������.
81  *
82  * ��������� �������������� �������� ����� � ������� ������
83  * tlv_is_defined(). �������� �������� � �������������� �����
84  * � ������� ������ tlv_reset().
85  *
86  * ���� �������� �� ����������, �� ����� tlv_pack() ������ ��
87  * ���������� � �������� �����, � ����� tlv_size() ���������� 0.
88  *
89  */
90 template< class Tag_type,
91 	class Char = oess_2::char_t,
92 	class Tag_processor = default_tag_processor_t< Tag_type >,
93 	class Length_processor = default_length_processor_t< Tag_type > >
94 class	basic_string_tlv_t :
95 	public tlv_base_t
96 {
97 	public :
98 		//! ������� ��� std::basic_string< Char >.
99 		typedef std::basic_string< Char > string_type_t;
100 
101 		//! ������� ��� string_type_t.
102 		typedef string_type_t	value_type_t;
103 
104 		//! ������� ��� basic_string_tlv_t< Tag_type, Char,
105 		//! Tag_processor, Length_processor >.
106 		typedef basic_string_tlv_t< Tag_type, Char,
107 				Tag_processor, Length_processor >
108 			self_t;
109 
110 	private :
111 		//! �������� ���� Tag.
112 		Tag_processor	m_tag;
113 
114 		//! ���������� ���� Length.
115 		Length_processor	m_length;
116 
117 		//! �������� ���� Value.
118 		string_type_t	m_value;
119 
120 		//! ������� ����, ��� TLV ����� ��������.
121 		/*!
122 		 * \since v.1.4.0-b2.2
123 		 */
124 		bool	m_is_defined;
125 
126 	public :
127 		//! ����������� ������ �������� ���� Value.
128 		/*!
129 		 * \since v.1.4.0-b2.2
130 		 * �������� ��������� ��������������.
131 		 */
basic_string_tlv_t(Tag_type id)132 		basic_string_tlv_t( Tag_type id )
133 			:	m_tag( id )
134 			,	m_is_defined( false )
135 		{
136 		}
137 
138 		//! ���������� �������� ���� Value.
139 		/*!
140 		 * \par v.1.4.0-b2.2
141 		 * �������� ��������� ������������.
142 		 */
basic_string_tlv_t(Tag_type id,const string_type_t & value)143 		basic_string_tlv_t(
144 			Tag_type id,
145 			const string_type_t & value )
146 			:	m_tag( id )
147 			,	m_value( value )
148 			,	m_is_defined( true )
149 		{
150 		}
151 
~basic_string_tlv_t()152 		virtual ~basic_string_tlv_t()
153 		{
154 		}
155 
156 		//! �������� ������� �������� ���� Value.
157 		/*!
158 		 * \throw oess_2::logic_ex_t ��� ������� ��������� �
159 		 * ��������������� ��������.
160 		 */
161 		const string_type_t &
query_value() const162 		query_value() const
163 		{
164 			if( !m_is_defined )
165 				OESS_THROW_LOGIC( err::c_undefined_value,
166 						"unable to access undefined TLV value" );
167 
168 			return m_value;
169 		}
170 
171 		//! ���������� �������� ���� Value.
172 		/*!
173 		 * \par v.1.4.0-b2.2
174 		 * ����� ������ ����� ������ �������� ��������� ������������.
175 		 */
176 		void
set_value(const string_type_t & value)177 		set_value(
178 			//! ����� �������� ��� ���� Value.
179 			const string_type_t & value )
180 		{
181 			m_value = value;
182 			m_is_defined = true;
183 		}
184 
185 		//! �������� �������� ���� Tag.
186 		virtual default_tag_type_t
tlv_tag() const187 		tlv_tag() const
188 		{
189 			return m_tag.query_tag();
190 		}
191 
192 		//! ���������� ����, ������� ���������
193 		//! ��� ������������� ����� TLV (� ������ Tag, Length,
194 		//! Value).
195 		virtual size_t
tlv_size() const196 		tlv_size() const
197 		{
198 			if( m_is_defined )
199 				{
200 					size_t length = m_value.length() *
201 						oess_2::io::bin_data_size_t< Char >::image_size;
202 					length += m_length.tlv_length_size( length );
203 					length += m_tag.tlv_tag_size();
204 
205 					return length;
206 				}
207 			else
208 				return 0;
209 		}
210 
211 		//! ���������� ����� Length � Value �� �������� ������.
212 		/*!
213 			���� ���� Length �������� ����, �� �� ������
214 			������ �� �����������, � ���� Value �����
215 			������������� ������ ��������.
216 		*/
217 		virtual void
tlv_unpack(oess_2::io::istream_t & s,default_tag_type_t)218 		tlv_unpack(
219 			//! �����, � ������� ������� �������� �����
220 			//! �������������� ������ ����� Length � Value.
221 			oess_2::io::istream_t & s,
222 			//! � ������ ������ ������������.
223 			default_tag_type_t )
224 		{
225 			size_t length;
226 			m_length.tlv_unpack_length( s, length );
227 			if( length )
228 			{
229 				std::vector< Char > tmp( length );
230 				s.read( &tmp[ 0 ], length );
231 
232 				m_value.assign( &tmp[ 0 ], length );
233 			}
234 			else
235 				// � VC++ 6.0 � ������ basic_string ��� ������ clear!
236 				m_value.erase( m_value.begin(), m_value.end() );
237 
238 			// �������� ��������� ������������ ����� ���������� ��
239 			// �������� ������.
240 			m_is_defined = true;
241 		}
242 
243 		//! ������ TLV � �������� �����.
244 		/*!
245 			������������ ��� ���� (Tag, Length, Value).
246 			���� ����� Value ����� 0, �� ������������ ������
247 			Tag � ������� �������� ���� Length.
248 
249 			\par v.1.4.0-b2.2
250 			������ ������������ ������, ���� �� ����� ������������
251 			��������.
252 		*/
253 		virtual void
tlv_pack(oess_2::io::ostream_t & s) const254 		tlv_pack(
255 			//! �����, � ������� ������� �������� �����
256 			//! �������������� ������ TLV.
257 			oess_2::io::ostream_t & s ) const
258 		{
259 			if( m_is_defined )
260 			{
261 				size_t length = m_value.length() *
262 					oess_2::io::bin_data_size_t< Char >::image_size;
263 
264 				m_tag.tlv_pack_tag( s );
265 				m_length.tlv_pack_length( s, length );
266 				if( length )
267 					s.write( m_value.data(), m_value.length() );
268 			}
269 		}
270 
271 		/*!
272 		 * \since v.1.4.0-b2.2
273 		 * \brief ��������� �������� �������������� �������.
274 		 */
275 		bool
tlv_is_defined() const276 		tlv_is_defined() const
277 		{
278 			return m_is_defined;
279 		}
280 
281 		/*!
282 		 * \since v.1.4.0-b2.2
283 		 * \brief ����� �������� �������������� �������.
284 		 */
285 		void
tlv_reset()286 		tlv_reset()
287 		{
288 			m_is_defined = false;
289 		}
290 };
291 
292 } /* namespace tlv */
293 
294 } /* namespace oess_2 */
295 
296 #endif
297 
298