Merge pull request #5 from intothevoid/master
[KDIS.git] / KDIS / KDIS / DataTypes / VariableDatum.cpp
blob2d258dd734c9c2ee1e54fdaf99f8609025114735
1 /*********************************************************************
2 Copyright 2013 Karl Jones
3 All rights reserved.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 1. Redistributions of source code must retain the above copyright notice, this
9 list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 For Further Information Please Contact me at
26 Karljj1@yahoo.com
27 http://p.sf.net/kdis/UserGuide
28 *********************************************************************/
30 #include "./VariableDatum.h"
31 #include <math.h>
33 //////////////////////////////////////////////////////////////////////////
35 using namespace std;
36 using namespace KDIS;
37 using namespace DATA_TYPE;
38 using namespace ENUMS;
39 using namespace UTILS;
41 //////////////////////////////////////////////////////////////////////////
42 // Public:
43 //////////////////////////////////////////////////////////////////////////
45 VariableDatum::VariableDatum() :
46 m_ui32DatumLength( 0 ),
47 m_ui32DatumID( 0 )
51 //////////////////////////////////////////////////////////////////////////
53 VariableDatum::VariableDatum( DatumID ID, const KString & Value )
55 m_ui32DatumID = ID;
57 SetDatumValue( Value );
60 //////////////////////////////////////////////////////////////////////////
62 VariableDatum::VariableDatum( DatumID ID, const KOCTET* data, KUINT32 sizeInBits )
64 m_ui32DatumID = ID;
66 SetDatumValue( data, sizeInBits );
69 //////////////////////////////////////////////////////////////////////////
71 VariableDatum::VariableDatum( KDataStream & stream )
73 Decode( stream );
76 //////////////////////////////////////////////////////////////////////////
78 VariableDatum::~VariableDatum()
82 //////////////////////////////////////////////////////////////////////////
84 void VariableDatum::SetDatumID( DatumID ID )
86 m_ui32DatumID = ID;
89 //////////////////////////////////////////////////////////////////////////
91 DatumID VariableDatum::GetDatumID() const
93 return ( DatumID )m_ui32DatumID;
96 //////////////////////////////////////////////////////////////////////////
98 KUINT32 VariableDatum::GetDatumLength() const
100 return m_ui32DatumLength;
103 //////////////////////////////////////////////////////////////////////////
105 KUINT32 VariableDatum::GetPDULength() const
107 return VARIABLE_DATUM_SIZE + ( m_v8DatumValue.size() * 8 );
110 //////////////////////////////////////////////////////////////////////////
112 void VariableDatum::SetDatumValue( const KString & s )
114 SetDatumValue( s.c_str(), ( s.length() + 1 ) * 8 ); // +1 to allow for terminating NULL ...
117 //////////////////////////////////////////////////////////////////////////
119 void VariableDatum::SetDatumValue( const KOCTET * data, KUINT32 sizeInBits )
121 m_v8DatumValue.clear();
123 KUINT32 sizeInOctets = ceil( sizeInBits / 8.0 );
124 for( KUINT16 i = 0; i < sizeInOctets; )
126 DatumEntry de;
128 for( KUINT16 j = 0; j < 8 && i < sizeInOctets; ++j, ++i )
130 de.Buffer[j] = data[i];
132 m_v8DatumValue.push_back( de );
135 m_ui32DatumLength = sizeInBits;
138 //////////////////////////////////////////////////////////////////////////
140 void VariableDatum::GetDatumValueCopyIntoBuffer( KOCTET * Buffer, KUINT16 BufferSize ) const
142 KUINT32 sizeInOctets = ceil( m_ui32DatumLength / 8.0 );
144 if( BufferSize < sizeInOctets )throw KException( __FUNCTION__, BUFFER_TOO_SMALL );
146 // Copy the data into the buffer, octet by octet
147 vector<DatumEntry>::const_iterator citr = m_v8DatumValue.begin();
149 KUINT16 i = 0;
151 while( i < sizeInOctets )
153 for( KUINT16 j = 0; i < sizeInOctets && j < 8; ++j, ++i )
155 Buffer[i] = citr->Buffer[j];
157 ++citr;
161 //////////////////////////////////////////////////////////////////////////
163 KString VariableDatum::GetDatumValueAsKString() const
165 KStringStream ss;
167 vector<DatumEntry>::const_iterator citr = m_v8DatumValue.begin();
168 vector<DatumEntry>::const_iterator citrEnd = m_v8DatumValue.end();
170 KUINT32 i = 0;
172 KUINT32 ui32LengthInOctets = ceil(m_ui32DatumLength / 8.0);
174 while( citr != citrEnd )
176 for( KUINT16 j = 0; i < ui32LengthInOctets && j < 8; ++j, ++i )
178 ss << citr->Buffer[j];
180 ++citr;
183 return ss.str();
186 //////////////////////////////////////////////////////////////////////////
188 vector<KUINT64> VariableDatum::GetDatumValueAsKUINT64() const
190 KBOOL bSwapBytes = !IsMachineBigEndian();
192 vector<DatumEntry>::const_iterator citr = m_v8DatumValue.begin();
193 vector<DatumEntry>::const_iterator citrEnd = m_v8DatumValue.end();
195 vector<KUINT64> m_Return;
197 KUINT32 ui32CurrentPos = 0;
198 KUINT32 ui32LengthInOctets = ceil(m_ui32DatumLength / 8.0);
200 while( citr != citrEnd )
202 if( ( ui32LengthInOctets - ui32CurrentPos ) < 8 )break;
204 m_Return.push_back( NetToKUINT64( citr->Buffer, bSwapBytes ).m_Value );
206 ui32CurrentPos += 8;
209 return m_Return;
212 //////////////////////////////////////////////////////////////////////////
214 vector<KFLOAT64> VariableDatum::GetDatumValueAsKFLOAT64() const
216 KBOOL bSwapBytes = !IsMachineBigEndian();
218 vector<DatumEntry>::const_iterator citr = m_v8DatumValue.begin();
219 vector<DatumEntry>::const_iterator citrEnd = m_v8DatumValue.end();
221 vector<KFLOAT64> m_Return;
223 KUINT32 ui32CurrentPos = 0;
224 KUINT32 ui32LengthInOctets = ceil(m_ui32DatumLength / 8.0);
226 while( citr != citrEnd )
228 if( ( ui32LengthInOctets - ui32CurrentPos ) < 8 )break;
230 m_Return.push_back( NetToKFLOAT64( citr->Buffer, bSwapBytes ).m_Value );
232 ui32CurrentPos += 8;
235 return m_Return;
238 //////////////////////////////////////////////////////////////////////////
240 void VariableDatum::ClearDatumValue()
242 m_v8DatumValue.clear();
243 m_ui32DatumLength = 0;
246 //////////////////////////////////////////////////////////////////////////
248 KString VariableDatum::GetAsString() const
250 KStringStream ss;
252 // For now we return the datum value as a string.
253 ss << "Variable Datum:"
254 << "\n\tID: " << GetEnumAsStringDatumID( m_ui32DatumID )
255 << "\n\tLength: " << m_ui32DatumLength
256 << "\n\tValue(S): " << GetDatumValueAsKString()
257 << "\n";
259 return ss.str();
262 //////////////////////////////////////////////////////////////////////////
264 void VariableDatum::Decode( KDataStream & stream )
266 if( stream.GetBufferSize() < VARIABLE_DATUM_SIZE )throw KException( __FUNCTION__, NOT_ENOUGH_DATA_IN_BUFFER );
268 m_v8DatumValue.clear();
270 stream >> m_ui32DatumID
271 >> m_ui32DatumLength;
273 KUINT32 ui32LengthInOctets = ceil(ceil(m_ui32DatumLength / 8.0) / 8.0) * 8;
275 // Datum length is returned in bits, so we need to convert to octets
276 for( KUINT16 i = 0; i < ui32LengthInOctets; )
278 DatumEntry de;
280 for( KUINT16 j = 0; i < ui32LengthInOctets && j < 8; ++j, ++i )
282 KOCTET o;
283 stream >> o;
284 de.Buffer[j] = o;
286 m_v8DatumValue.push_back( de );
290 //////////////////////////////////////////////////////////////////////////
292 KDataStream VariableDatum::Encode() const
294 KDataStream stream;
296 VariableDatum::Encode( stream );
298 return stream;
301 //////////////////////////////////////////////////////////////////////////
303 void VariableDatum::Encode( KDataStream & stream ) const
305 stream << m_ui32DatumID
306 << m_ui32DatumLength;
308 vector<DatumEntry>::const_iterator citr = m_v8DatumValue.begin();
309 vector<DatumEntry>::const_iterator citrEnd = m_v8DatumValue.end();
311 while( citr != citrEnd )
313 for( KUINT16 i = 0; i < 8; ++i )
315 stream << citr->Buffer[i];
318 ++citr;
322 //////////////////////////////////////////////////////////////////////////
324 KBOOL VariableDatum::operator == ( const VariableDatum & Value ) const
326 if( m_ui32DatumID != Value.m_ui32DatumID ) return false;
327 if( m_ui32DatumLength != Value.m_ui32DatumLength ) return false;
329 vector<DatumEntry>::const_iterator citrThis = m_v8DatumValue.begin(),
330 citrOther = Value.m_v8DatumValue.begin();
332 while( citrThis != m_v8DatumValue.end() && citrOther != Value.m_v8DatumValue.end() )
334 if( memcmp( citrThis->Buffer, citrOther->Buffer, 8 ) != 0 )return false;
335 ++citrThis;
336 ++citrOther;
338 return true;
341 //////////////////////////////////////////////////////////////////////////
343 KBOOL VariableDatum::operator != ( const VariableDatum & Value ) const
345 return !( *this == Value );
348 //////////////////////////////////////////////////////////////////////////