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 /********************************************************************
35 purpose: Converts data types into a buffer stream for sending
36 via a network/writing to file.
37 *********************************************************************/
41 #include "./KDefines.h"
42 #include "./KEncodersDecoders.h"
43 #include "./Extras/KUtils.h"
48 class KDIS_EXPORT KDataStream
52 Endian m_MachineEndian
;
56 std::vector
<KUOCTET
> m_vBuffer
;
57 KUINT16 m_ui16CurrentWritePos
;
61 // All DIS data is sent in Big Endian format
62 KDataStream( Endian NetworkEndian
= Big_Endian
);
64 KDataStream( const KOCTET
* SerialData
, KUINT16 DataSize
, Endian NetworkEndian
= Big_Endian
);
68 //************************************
69 // FullName: KDIS::KDataStream::GetMachineEndian
70 // Description: Returns the machine endian. Calculated automatically.
71 //************************************
72 Endian
GetMachineEndian() const;
74 //************************************
75 // FullName: KDIS::KDataStream::GetNetWorkEndian
76 // Description: Returns the network endian, set by user in
77 // constructor, Big_Endian by default.
78 //************************************
79 Endian
GetNetWorkEndian() const;
81 //************************************
82 // FullName: KDIS::KDataStream::GetBufferSize
83 // Description: Returns current buffer size in Octets/Bytes
84 //************************************
85 KUINT16
GetBufferSize() const;
87 //************************************
88 // FullName: KDIS::KDataStream::CopyIntoBuffer
89 // Description: Copy the stream into an Octet buffer,
90 // Returns total bytes copied into buffer.
91 // Throws exception if the buffer is too small.
92 // Parameter: KOCTET * Buffer
93 // Parameter: KUINT16 BufferSize
94 // Parameter: KUINT16 WritePos - Where to start writing into the buffer
95 //************************************
96 KUINT16
CopyIntoBuffer( KOCTET
* Buffer
, KUINT16 BufferSize
, KUINT16 WritePos
= 0 ) const ;
98 //************************************
99 // FullName: KDIS::KDataStream::CopyFromBuffer
100 // Description: Copy data from a buffer/array into the data stream
101 // Parameter: KOCTET * SerialData
102 // Parameter: KUINT16 DataSize
103 // Parameter: Endian NetworkEndian = Big_Endian
104 //************************************
105 void CopyFromBuffer( const KOCTET
* SerialData
, KUINT16 DataSize
, Endian NetworkEndian
= Big_Endian
);
107 //************************************
108 // FullName: KDIS::KDataStream::GetBufferPtr
109 // Description: Returns a pointer to the buffer.
110 // This is a more efficient way of sending data than using CopyIntoBuffer.
111 //************************************
112 const KOCTET
* GetBufferPtr() const;
114 //************************************
115 // FullName: KDIS::KDataStream::GetBuffer
116 // Description: Returns a constant reference to the internal buffer.
117 // Useful if you need lower-level access to the data.
118 //************************************
119 const std::vector
<KUOCTET
> & GetBuffer() const;
121 //************************************
122 // FullName: KDIS::KDataStream::ResetWritePosition
123 // Description: Moves the write position back to the start of the buffer.
124 //************************************
125 void ResetWritePosition();
127 //************************************
128 // FullName: KDIS::KDataStream::SetCurrentWritePosition
129 // KDIS::KDataStream::GetCurrentWritePosition
130 // Description: The write position is the current position in the buffer that we are reading data from.
131 // Using these 2 functions it is possible to "peak" at data and then restore the buffers
132 // write position. For example if we wanted to read the next 4 bytes to determine what the
133 // next data type is we could peak and then reset the write position back by 4 so that the
134 // data can be re-read by the data types decode function.
135 // Parameter: KUINT16 WP
136 //************************************
137 void SetCurrentWritePosition( KUINT16 WP
);
138 KUINT16
GetCurrentWritePosition() const;
140 //************************************
141 // FullName: KDIS::KDataStream::Clear
142 // Description: Clears contents
143 //************************************
146 //************************************
147 // FullName: KDIS::KDataStream::GetAsString
148 // Description: Returns string representation of the stream, values are in hex.
149 //************************************
150 KString
GetAsString() const;
152 //************************************
153 // FullName: KDIS::KDataStream::GetAsString
154 // Description: Read a string of hex octets and convert into
156 // This function works in conjunction with GetAsString, each PDU could be saved to a
157 // file and then read back in using this function. Good for debugging or logging data.
158 // Parameter: const KString & S
159 //************************************
160 void ReadFromString( const KString
& S
);
162 //************************************
163 // FullName: KDIS::KDataStream<Type>::Write
164 // Description: Write data into stream.
165 // Parameter: Type T, KUOCTET V, KOCTET V
166 //************************************
168 void Write( Type T
);
169 void Write( KUOCTET V
);
170 void Write( KOCTET V
);
172 //************************************
173 // FullName: KDIS::KDataStream<Type>::Write
174 // Description: Read data from stream.
175 // Parameter: Type & T, KUOCTET & V, KOCTET & V
176 //************************************
178 void Read( Type
& T
);
179 void Read( KUOCTET
& V
);
180 void Read( KOCTET
& V
);
184 KDataStream
& operator << ( Type T
);
185 KDataStream
& operator << ( KDataStream val
);
189 KDataStream
& operator >> ( Type
& T
);
191 KBOOL
operator == ( const KDataStream
& Value
) const;
192 KBOOL
operator != ( const KDataStream
& Value
) const;
195 //////////////////////////////////////////////////////////////////////////
196 // Template Operators
197 //////////////////////////////////////////////////////////////////////////
200 void KDataStream::Write( Type T
)
203 if( m_MachineEndian
== m_NetEndian
)bSwapBytes
= false;
204 else bSwapBytes
= true;
206 NetToDataType
<Type
> OctArray( T
, bSwapBytes
);
208 for( KUINT8 i
= 0; i
< sizeof T
; ++i
)
210 m_vBuffer
.push_back( OctArray
.m_Octs
[i
] );
214 //////////////////////////////////////////////////////////////////////////
217 void KDataStream::Read( Type
& T
)
219 NetToDataType
<Type
> OctArray( T
, false );
221 // Copy octets into data type
222 if (m_vBuffer
.size() < m_ui16CurrentWritePos
+ sizeof T
) { throw KException(INVALID_DATA
); } //James Wing Nov 2016
223 for( KUINT8 i
= 0; i
< sizeof T
; ++i
, ++m_ui16CurrentWritePos
)
225 OctArray
.m_Octs
[i
] = m_vBuffer
[m_ui16CurrentWritePos
];
228 if( m_MachineEndian
!= m_NetEndian
)
230 OctArray
.SwapBytes();
233 T
= OctArray
.m_Value
;
236 //////////////////////////////////////////////////////////////////////////
239 KDataStream
& KDataStream::operator<<( Type T
)
245 //////////////////////////////////////////////////////////////////////////
248 KDataStream
& KDataStream::operator>>( Type
& T
)
254 //////////////////////////////////////////////////////////////////////////
256 } // END namespace KDIS