1 /*********************************************************************
2 Copyright 2013 Karl Jones
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
27 http://p.sf.net/kdis/UserGuide
28 *********************************************************************/
30 #include "./VariableDatum.h"
33 //////////////////////////////////////////////////////////////////////////
37 using namespace DATA_TYPE
;
38 using namespace ENUMS
;
39 using namespace UTILS
;
41 //////////////////////////////////////////////////////////////////////////
43 //////////////////////////////////////////////////////////////////////////
45 VariableDatum::VariableDatum() :
46 m_ui32DatumLength( 0 ),
51 //////////////////////////////////////////////////////////////////////////
53 VariableDatum::VariableDatum( DatumID ID
, const KString
& Value
)
57 SetDatumValue( Value
);
60 //////////////////////////////////////////////////////////////////////////
62 VariableDatum::VariableDatum( DatumID ID
, const KOCTET
* data
, KUINT32 sizeInBits
)
66 SetDatumValue( data
, sizeInBits
);
69 //////////////////////////////////////////////////////////////////////////
71 VariableDatum::VariableDatum( KDataStream
& stream
)
76 //////////////////////////////////////////////////////////////////////////
78 VariableDatum::~VariableDatum()
82 //////////////////////////////////////////////////////////////////////////
84 void VariableDatum::SetDatumID( DatumID 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
; )
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();
151 while( i
< sizeInOctets
)
153 for( KUINT16 j
= 0; i
< sizeInOctets
&& j
< 8; ++j
, ++i
)
155 Buffer
[i
] = citr
->Buffer
[j
];
161 //////////////////////////////////////////////////////////////////////////
163 KString
VariableDatum::GetDatumValueAsKString() const
167 vector
<DatumEntry
>::const_iterator citr
= m_v8DatumValue
.begin();
168 vector
<DatumEntry
>::const_iterator citrEnd
= m_v8DatumValue
.end();
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
];
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
);
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
);
238 //////////////////////////////////////////////////////////////////////////
240 void VariableDatum::ClearDatumValue()
242 m_v8DatumValue
.clear();
243 m_ui32DatumLength
= 0;
246 //////////////////////////////////////////////////////////////////////////
248 KString
VariableDatum::GetAsString() const
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()
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
; )
280 for( KUINT16 j
= 0; i
< ui32LengthInOctets
&& j
< 8; ++j
, ++i
)
286 m_v8DatumValue
.push_back( de
);
290 //////////////////////////////////////////////////////////////////////////
292 KDataStream
VariableDatum::Encode() const
296 VariableDatum::Encode( 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
];
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;
341 //////////////////////////////////////////////////////////////////////////
343 KBOOL
VariableDatum::operator != ( const VariableDatum
& Value
) const
345 return !( *this == Value
);
348 //////////////////////////////////////////////////////////////////////////