Usermode/AxWin4 - PushData implemented
[tpg/acess2.git] / Usermode / Applications / axwin4_src / Common / serialisation.cpp
1 /*
2  * Acess2 GUI v4
3  * - By John Hodge (thePowersGang) 
4  *
5  * serialisation.cpp
6  * - IPC Serialisation
7  */
8 #include <serialisation.hpp>
9 #include <cstddef>
10 #include <stdexcept>
11 #include <acess/sys.h>  // SysDebug
12
13 namespace AxWin {
14
15 CDeserialiser::CDeserialiser(size_t Length, const uint8_t *Buffer):
16         m_length(Length),
17         m_data(Buffer),
18         m_offset(0)
19 {
20 }
21
22 bool CDeserialiser::IsConsumed() const
23 {
24         return m_offset == m_length;
25 }
26
27 ::uint8_t CDeserialiser::ReadU8()
28 {
29         RangeCheck("CDeserialiser::ReadU8", 1);
30         uint8_t rv = m_data[m_offset];
31         m_offset ++;
32         return rv;
33 }
34
35 ::uint16_t CDeserialiser::ReadU16()
36 {
37         RangeCheck("CDeserialiser::ReadU16", 2);
38         uint16_t rv = m_data[m_offset] | ((uint16_t)m_data[m_offset+1] << 8);
39         m_offset += 2;
40         return rv;
41 }
42
43 ::int16_t CDeserialiser::ReadS16()
44 {
45         uint16_t rv_u = ReadU16();
46         if( rv_u < 0x8000 )
47                 return rv_u;
48         else
49                 return ~rv_u + 1;
50 }
51
52 const ::std::vector<uint8_t> CDeserialiser::ReadBuffer()
53 {
54         RangeCheck("CDeserialiser::ReadBuffer(len)", 2);
55         size_t  size = ReadU16();
56         
57         ::std::vector<uint8_t> ret( size );
58         for( size_t i = 0; i < size; i ++ )
59                 ret[i] = m_data[m_offset++];
60         return ret;
61 }
62
63 const ::std::string CDeserialiser::ReadString()
64 {
65         RangeCheck("CDeserialiser::ReadString(len)", 1);
66         uint8_t len = m_data[m_offset];
67         m_offset ++;
68         
69         RangeCheck("CDeserialiser::ReadString(data)", len);
70         ::std::string ret( reinterpret_cast<const char*>(m_data+m_offset), len );
71         m_offset += len;
72         return ret;
73 }
74
75 void CDeserialiser::RangeCheck(const char *Method, size_t bytes) throw(::std::out_of_range)
76 {
77         if( m_offset + bytes > m_length ) {
78                 ::_SysDebug("%s - out of range %i+%i >= %i", Method, m_offset, bytes, m_length);
79                 throw ::std::out_of_range(Method);
80         }
81 }
82
83 CSerialiser::CSerialiser()
84 {
85 }
86
87 void CSerialiser::WriteU8(::uint8_t Value)
88 {
89         m_data.push_back(Value);
90 }
91
92 void CSerialiser::WriteU16(::uint16_t Value)
93 {
94         m_data.push_back(Value & 0xFF);
95         m_data.push_back(Value >> 8);
96 }
97
98 void CSerialiser::WriteS16(::int16_t Value)
99 {
100         if( Value < 0 )
101         {
102                 ::uint16_t rawval = 0x10000 - (::int32_t)Value;
103                 WriteU16(rawval);
104         }
105         else
106         {
107                 WriteU16(Value);
108         }
109 }
110
111 void CSerialiser::WriteBuffer(size_t n, const void* val)
112 {
113         const uint8_t*  val8 = static_cast<const uint8_t*>(val);
114         if( n > 0xFFFF )
115                 throw ::std::length_error("CSerialiser::WriteBuffer");
116         m_data.reserve( m_data.size() + 2 + n );
117         WriteU16(n);
118         for( size_t i = 0; i < n; i ++ )
119                 m_data.push_back(val8[i]);
120 }
121
122 void CSerialiser::WriteString(const char* val, size_t n)
123 {
124         if( n > 0xFF )
125                 throw ::std::length_error("CSerialiser::WriteString");
126         m_data.reserve( m_data.size() + 1 + n );
127         WriteU8(n);
128         for( size_t i = 0; i < n; i ++ )
129                 m_data.push_back(val[i]);
130 }
131
132 void CSerialiser::WriteSub(const CSerialiser& val)
133 {
134         // TODO: Append reference to sub-buffer contents
135         m_data.reserve( m_data.size() + val.m_data.size() );
136         for( auto byte : val.m_data )
137                 m_data.push_back( byte );
138 }
139
140 const ::std::vector<uint8_t>& CSerialiser::Compact()
141 {
142         return m_data;
143 }
144
145 };      // namespace AxWin
146

UCC git Repository :: git.ucc.asn.au