f23d5cd8d09061310a484c195d1deb1c8de2da63
[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(const ::std::vector<uint8_t>& vector):
16         m_vect(vector),
17         m_offset(0)
18 {
19 }
20 CDeserialiser::CDeserialiser(::std::vector<uint8_t>&& vector):
21         m_vect(vector),
22         m_offset(0)
23 {
24 }
25 CDeserialiser& CDeserialiser::operator=(const CDeserialiser& x)
26 {
27         m_vect = x.m_vect;
28         m_offset = x.m_offset;
29 }
30
31 bool CDeserialiser::IsConsumed() const
32 {
33         return m_offset == m_vect.size();
34 }
35
36 ::uint8_t CDeserialiser::ReadU8()
37 {
38         RangeCheck("CDeserialiser::ReadU8", 1);
39         uint8_t rv = m_vect[m_offset];
40         m_offset ++;
41         return rv;
42 }
43
44 ::uint16_t CDeserialiser::ReadU16()
45 {
46         RangeCheck("CDeserialiser::ReadU16", 2);
47         uint16_t rv = m_vect[m_offset] | ((uint16_t)m_vect[m_offset+1] << 8);
48         m_offset += 2;
49         return rv;
50 }
51
52 ::int16_t CDeserialiser::ReadS16()
53 {
54         uint16_t rv_u = ReadU16();
55         if( rv_u < 0x8000 )
56                 return rv_u;
57         else
58                 return ~rv_u + 1;
59 }
60
61 const ::std::vector<uint8_t> CDeserialiser::ReadBuffer()
62 {
63         RangeCheck("CDeserialiser::ReadBuffer(len)", 2);
64         size_t  size = ReadU16();
65         
66         auto range_start = m_vect.begin() + int(m_offset);
67         ::std::vector<uint8_t> ret( range_start, range_start + int(size) );
68         m_offset += size;
69         return ret;
70 }
71
72 const ::std::string CDeserialiser::ReadString()
73 {
74         RangeCheck("CDeserialiser::ReadString(len)", 1);
75         uint8_t len = ReadU8();
76         
77         RangeCheck("CDeserialiser::ReadString(data)", len);
78         ::std::string ret( reinterpret_cast<const char*>(m_vect.data()+m_offset), len );
79         m_offset += len;
80         return ret;
81 }
82
83 void CDeserialiser::RangeCheck(const char *Method, size_t bytes) throw(::std::out_of_range)
84 {
85         if( m_offset + bytes > m_vect.size() ) {
86                 ::_SysDebug("%s - out of range %i+%i >= %i", Method, m_offset, bytes, m_vect.size());
87                 throw ::std::out_of_range(Method);
88         }
89 }
90
91 CSerialiser::CSerialiser()
92 {
93 }
94
95 void CSerialiser::WriteU8(::uint8_t Value)
96 {
97         m_data.push_back(Value);
98 }
99
100 void CSerialiser::WriteU16(::uint16_t Value)
101 {
102         m_data.push_back(Value & 0xFF);
103         m_data.push_back(Value >> 8);
104 }
105
106 void CSerialiser::WriteS16(::int16_t Value)
107 {
108         if( Value < 0 )
109         {
110                 ::uint16_t rawval = 0x10000 - (::int32_t)Value;
111                 WriteU16(rawval);
112         }
113         else
114         {
115                 WriteU16(Value);
116         }
117 }
118
119 void CSerialiser::WriteBuffer(size_t n, const void* val)
120 {
121         const uint8_t*  val8 = static_cast<const uint8_t*>(val);
122         if( n > 0xFFFF )
123                 throw ::std::length_error("CSerialiser::WriteBuffer");
124         m_data.reserve( m_data.size() + 2 + n );
125         WriteU16(n);
126         for( size_t i = 0; i < n; i ++ )
127                 m_data.push_back(val8[i]);
128 }
129
130 void CSerialiser::WriteString(const char* val, size_t n)
131 {
132         if( n > 0xFF )
133                 throw ::std::length_error("CSerialiser::WriteString");
134         m_data.reserve( m_data.size() + 1 + n );
135         WriteU8(n);
136         for( size_t i = 0; i < n; i ++ )
137                 m_data.push_back(val[i]);
138 }
139
140 void CSerialiser::WriteSub(const CSerialiser& val)
141 {
142         // TODO: Append reference to sub-buffer contents
143         m_data.reserve( m_data.size() + val.m_data.size() );
144         for( auto byte : val.m_data )
145                 m_data.push_back( byte );
146 }
147
148 const ::std::vector<uint8_t>& CSerialiser::Compact()
149 {
150         return m_data;
151 }
152
153 };      // namespace AxWin
154

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