Remove old changelog
[KDIS.git] / src / KDataStream.cpp
blobce9aaeb9405de8561aa55d1ba39762a2e0eb92ea
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 "KDIS/KDataStream.hpp"
32 using namespace KDIS;
33 using namespace KDIS::UTILS;
34 using namespace std;
36 //////////////////////////////////////////////////////////////////////////
37 // public:
38 //////////////////////////////////////////////////////////////////////////
40 KDataStream::KDataStream(Endian Network_Endian /*= Big_Endian*/)
41 : m_NetEndian(Network_Endian), m_ui16CurrentWritePos(0) {
42 if (IsMachineBigEndian() == true) {
43 m_MachineEndian = Big_Endian;
44 } else {
45 m_MachineEndian = Little_Endian;
49 //////////////////////////////////////////////////////////////////////////
51 KDataStream::KDataStream(const KOCTET* SerialData, KUINT16 DataSize,
52 Endian Network_Endian /*= Big_Endian */)
53 : m_NetEndian(Network_Endian), m_ui16CurrentWritePos(0) {
54 // Copy Data into vector
55 for (KUINT16 i = 0; i < DataSize; ++i) {
56 m_vBuffer.push_back(SerialData[i]);
59 if (IsMachineBigEndian() == true) {
60 m_MachineEndian = Big_Endian;
61 } else {
62 m_MachineEndian = Little_Endian;
66 //////////////////////////////////////////////////////////////////////////
68 KDataStream::~KDataStream() {}
70 //////////////////////////////////////////////////////////////////////////
72 Endian KDataStream::GetMachineEndian() const { return m_MachineEndian; }
74 //////////////////////////////////////////////////////////////////////////
76 Endian KDataStream::GetNetWorkEndian() const { return m_NetEndian; }
78 //////////////////////////////////////////////////////////////////////////
80 KUINT16 KDataStream::GetBufferSize() const {
81 // Since the return type is unsigned, if the result is < 0, it returns a large
82 // positive value (undesired).
83 // Example: (unsigned short)(8 - 16) = 65528, but (int)(8 - 16) = -8
84 // Non-breaking fix: // Throw instead of erroneously returning large +#
85 if ((KINT16)(m_vBuffer.size() - m_ui16CurrentWritePos) < 0) {
86 throw KException(
87 BUFFER_TOO_SMALL); // an alternate fix would be to return zero (0)
89 return (m_vBuffer.size() - m_ui16CurrentWritePos);
92 //////////////////////////////////////////////////////////////////////////
94 KUINT16 KDataStream::CopyIntoBuffer(KOCTET* Buffer, KUINT16 BufferSize,
95 KUINT16 WritePos /*= 0*/) const {
96 if ((KINT16)(BufferSize - WritePos) < (KUINT16)m_vBuffer.size()) {
97 throw KException(BUFFER_TOO_SMALL);
100 vector<KUOCTET>::const_iterator citr = m_vBuffer.begin();
101 vector<KUOCTET>::const_iterator citrEnd = m_vBuffer.end();
103 KUINT16 CurrentWritePos = WritePos;
105 for (; citr != citrEnd; ++citr, ++CurrentWritePos) {
106 Buffer[CurrentWritePos] = *citr;
109 return m_vBuffer.size();
112 //////////////////////////////////////////////////////////////////////////
114 void KDataStream::CopyFromBuffer(const KOCTET* SerialData, KUINT16 DataSize,
115 Endian NetworkEndian /*= Big_Endian*/) {
116 // Copy Data into vector
117 for (KUINT16 i = 0; i < DataSize; ++i) {
118 m_vBuffer.push_back(SerialData[i]);
122 //////////////////////////////////////////////////////////////////////////
124 const KOCTET* KDataStream::GetBufferPtr() const {
125 return (const KOCTET*)&m_vBuffer[0];
128 //////////////////////////////////////////////////////////////////////////
130 const vector<KUOCTET>& KDataStream::GetBuffer() const { return m_vBuffer; }
132 //////////////////////////////////////////////////////////////////////////
134 void KDataStream::ResetWritePosition() { m_ui16CurrentWritePos = 0; }
136 //////////////////////////////////////////////////////////////////////////
138 void KDataStream::SetCurrentWritePosition(KUINT16 WP) {
139 if (WP > m_vBuffer.size()) {
140 throw KException(INVALID_DATA);
141 } // James Wing -- Oct 2016 -- disallow advancing write position beyond end
142 // of buffer in spite of defective PDU size indicator telling us to --
143 // never trust the data.
144 m_ui16CurrentWritePos = WP;
147 //////////////////////////////////////////////////////////////////////////
149 KUINT16 KDataStream::GetCurrentWritePosition() const {
150 return m_ui16CurrentWritePos;
153 //////////////////////////////////////////////////////////////////////////
155 void KDataStream::Clear() {
156 m_vBuffer.clear();
157 m_ui16CurrentWritePos = 0;
160 //////////////////////////////////////////////////////////////////////////
162 KString KDataStream::GetAsString() const {
163 KStringStream ss;
165 vector<KUOCTET>::const_iterator citr = m_vBuffer.begin();
166 vector<KUOCTET>::const_iterator citrEnd = m_vBuffer.end();
168 for (; citr != citrEnd; ++citr) {
169 // If less than 10 add a zero so that each octet has the same 2 digit
170 // representation.
171 if (*citr < 10) ss << "0";
173 ss << hex << (KUINT16)*citr << " ";
176 return ss.str();
179 //////////////////////////////////////////////////////////////////////////
181 void KDataStream::ReadFromString(const KString& S) {
182 KStringStream ss(S);
184 KUINT16 o;
185 while (ss >> hex >> o) {
186 m_vBuffer.push_back(o);
190 //////////////////////////////////////////////////////////////////////////
192 void KDataStream::Write(KUOCTET V) { m_vBuffer.push_back(V); }
194 //////////////////////////////////////////////////////////////////////////
196 void KDataStream::Write(KOCTET V) { m_vBuffer.push_back(V); }
198 //////////////////////////////////////////////////////////////////////////
200 void KDataStream::Read(KUOCTET& V) {
201 if (m_ui16CurrentWritePos >= m_vBuffer.size()) {
202 throw KException(INVALID_DATA);
203 } // James Wing Nov 2016
204 V = m_vBuffer[m_ui16CurrentWritePos++];
207 //////////////////////////////////////////////////////////////////////////
209 void KDataStream::Read(KOCTET& V) {
210 if (m_ui16CurrentWritePos >= m_vBuffer.size()) {
211 throw KException(INVALID_DATA);
212 } // James Wing Nov 2016
213 V = m_vBuffer[m_ui16CurrentWritePos++];
216 //////////////////////////////////////////////////////////////////////////
218 KDataStream& KDataStream::operator<<(KDataStream val) {
219 vector<KUOCTET>::const_iterator citr = val.m_vBuffer.begin();
220 vector<KUOCTET>::const_iterator citrEnd = val.m_vBuffer.end();
222 // Copy data into the buffer OCTET by OCTET
223 for (; citr != citrEnd; ++citr) {
224 m_vBuffer.push_back(*citr);
227 return *this;
230 //////////////////////////////////////////////////////////////////////////
232 KBOOL KDataStream::operator==(const KDataStream& Value) const {
233 if (m_vBuffer != Value.m_vBuffer) return false;
234 return true;
237 //////////////////////////////////////////////////////////////////////////
239 KBOOL KDataStream::operator!=(const KDataStream& Value) const {
240 return !(*this == Value);
243 //////////////////////////////////////////////////////////////////////////