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 *********************************************************************/
39 #ifndef KDIS_KDATASTREAM_HPP_
40 #define KDIS_KDATASTREAM_HPP_
44 #include "KDIS/Extras/KUtils.hpp"
45 #include "KDIS/KDefines.hpp"
46 #include "KDIS/KEncodersDecoders.hpp"
50 class KDIS_EXPORT KDataStream
{
52 Endian m_MachineEndian
;
56 std::vector
<KUOCTET
> m_vBuffer
;
57 KUINT16 m_ui16CurrentWritePos
;
60 // All DIS data is sent in Big Endian format
61 explicit KDataStream(Endian NetworkEndian
= Big_Endian
);
63 KDataStream(const KOCTET
* SerialData
, KUINT16 DataSize
,
64 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
,
97 KUINT16 WritePos
= 0) const;
99 //************************************
100 // FullName: KDIS::KDataStream::CopyFromBuffer
101 // Description: Copy data from a buffer/array into the data stream
102 // Parameter: KOCTET * SerialData
103 // Parameter: KUINT16 DataSize
104 // Parameter: Endian NetworkEndian = Big_Endian
105 //************************************
106 void CopyFromBuffer(const KOCTET
* SerialData
, KUINT16 DataSize
,
107 Endian NetworkEndian
= Big_Endian
);
109 //************************************
110 // FullName: KDIS::KDataStream::GetBufferPtr
111 // Description: Returns a pointer to the buffer.
112 // This is a more efficient way of sending data than using
114 //************************************
115 const KOCTET
* GetBufferPtr() const;
117 //************************************
118 // FullName: KDIS::KDataStream::GetBuffer
119 // Description: Returns a constant reference to the internal buffer.
120 // Useful if you need lower-level access to the data.
121 //************************************
122 const std::vector
<KUOCTET
>& GetBuffer() const;
124 //************************************
125 // FullName: KDIS::KDataStream::ResetWritePosition
126 // Description: Moves the write position back to the start of the buffer.
127 //************************************
128 void ResetWritePosition();
130 //************************************
131 // FullName: KDIS::KDataStream::SetCurrentWritePosition
132 // KDIS::KDataStream::GetCurrentWritePosition
133 // Description: The write position is the current position in the buffer that
134 // we are reading data from.
135 // Using these 2 functions it is possible to "peak" at data and
136 // then restore the buffers write position. For example if we
137 // wanted to read the next 4 bytes to determine what the next
138 // data type is we could peak and then reset the write position
139 // back by 4 so that the data can be re-read by the data types
141 // Parameter: KUINT16 WP
142 //************************************
143 void SetCurrentWritePosition(KUINT16 WP
);
144 KUINT16
GetCurrentWritePosition() const;
146 //************************************
147 // FullName: KDIS::KDataStream::Clear
148 // Description: Clears contents
149 //************************************
152 //************************************
153 // FullName: KDIS::KDataStream::GetAsString
154 // Description: Returns string representation of the stream, values are in
156 //************************************
157 KString
GetAsString() const;
159 //************************************
160 // FullName: KDIS::KDataStream::GetAsString
161 // Description: Read a string of hex octets and convert into
163 // This function works in conjunction with GetAsString, each PDU
164 // could be saved to a file and then read back in using this
165 // function. Good for debugging or logging data.
166 // Parameter: const KString & S
167 //************************************
168 void ReadFromString(const KString
& S
);
170 //************************************
171 // FullName: KDIS::KDataStream<Type>::Write
172 // Description: Write data into stream.
173 // Parameter: Type T, KUOCTET V, KOCTET V
174 //************************************
175 template <class Type
>
177 void Write(KUOCTET V
);
178 void Write(KOCTET V
);
180 //************************************
181 // FullName: KDIS::KDataStream<Type>::Write
182 // Description: Read data from stream.
183 // Parameter: Type & T, KUOCTET & V, KOCTET & V
184 //************************************
185 template <class Type
>
187 void Read(KUOCTET
& V
);
188 void Read(KOCTET
& V
);
191 template <class Type
>
192 KDataStream
& operator<<(Type T
);
193 KDataStream
& operator<<(KDataStream val
);
196 template <class Type
>
197 KDataStream
& operator>>(Type
& T
);
199 KBOOL
operator==(const KDataStream
& Value
) const;
200 KBOOL
operator!=(const KDataStream
& Value
) const;
203 //////////////////////////////////////////////////////////////////////////
204 // Template Operators
205 //////////////////////////////////////////////////////////////////////////
207 template <class Type
>
208 void KDataStream::Write(Type T
) {
210 if (m_MachineEndian
== m_NetEndian
)
215 NetToDataType
<Type
> OctArray(T
, bSwapBytes
);
217 for (KUINT8 i
= 0; i
< sizeof T
; ++i
) {
218 m_vBuffer
.push_back(OctArray
.m_Octs
[i
]);
222 //////////////////////////////////////////////////////////////////////////
224 template <class Type
>
225 void KDataStream::Read(Type
& T
) {
226 NetToDataType
<Type
> OctArray(T
, false);
228 // Copy octets into data type
229 if (m_vBuffer
.size() < m_ui16CurrentWritePos
+ sizeof T
) {
230 throw KException(INVALID_DATA
);
231 } // James Wing Nov 2016
232 for (KUINT8 i
= 0; i
< sizeof T
; ++i
, ++m_ui16CurrentWritePos
) {
233 OctArray
.m_Octs
[i
] = m_vBuffer
[m_ui16CurrentWritePos
];
236 if (m_MachineEndian
!= m_NetEndian
) {
237 OctArray
.SwapBytes();
240 T
= OctArray
.m_Value
;
243 //////////////////////////////////////////////////////////////////////////
245 template <class Type
>
246 KDataStream
& KDataStream::operator<<(Type T
) {
251 //////////////////////////////////////////////////////////////////////////
253 template <class Type
>
254 KDataStream
& KDataStream::operator>>(Type
& T
) {
259 //////////////////////////////////////////////////////////////////////////
261 } // END namespace KDIS
263 #endif // KDIS_KDATASTREAM_HPP_