1
2
3
4
5
6 #include <soulng/util/BinaryReader.hpp>
7 #include <soulng/util/Unicode.hpp>
8 #include <soulng/util/Error.hpp>
9 #include <cstring>
10
11 namespace soulng { namespace util {
12
13 using namespace soulng::unicode;
14
15 BinaryReader::BinaryReader(const std::string& fileName_) :
16 fileName(fileName_), file(fileName), begin(reinterpret_cast<const uint8_t*>(file.Begin())), end(reinterpret_cast<const uint8_t*>(file.End())), pos(0)
17 {
18 }
19
20 BinaryReader::~BinaryReader()
21 {
22 }
23
24 bool BinaryReader::ReadBool()
25 {
26 uint8_t x = ReadByte();
27 return static_cast<bool>(x);
28 }
29
30 uint8_t BinaryReader::ReadByte()
31 {
32 CheckEof();
33 uint8_t x = *begin++;
34 ++pos;
35 return x;
36 }
37
38 int8_t BinaryReader::ReadSByte()
39 {
40 uint8_t x = ReadByte();
41 return static_cast<int8_t>(x);
42 }
43
44 uint16_t BinaryReader::ReadUShort()
45 {
46 uint8_t h = ReadByte();
47 uint8_t l = ReadByte();
48 return (static_cast<uint16_t>(h) << 8) | static_cast<uint16_t>(l);
49 }
50
51 int16_t BinaryReader::ReadShort()
52 {
53 uint16_t x = ReadUShort();
54 return static_cast<int16_t>(x);
55 }
56
57 uint32_t BinaryReader::ReadUInt()
58 {
59 uint8_t b0 = ReadByte();
60 uint8_t b1 = ReadByte();
61 uint8_t b2 = ReadByte();
62 uint8_t b3 = ReadByte();
63 return (static_cast<uint32_t>(b0) << 24) | (static_cast<uint32_t>(b1) << 16) | (static_cast<uint32_t>(b2) << 8) | static_cast<uint32_t>(b3);
64 }
65
66 int32_t BinaryReader::ReadInt()
67 {
68 uint32_t x = ReadUInt();
69 return static_cast<int32_t>(x);
70 }
71
72 uint64_t BinaryReader::ReadULong()
73 {
74 uint8_t b0 = ReadByte();
75 uint8_t b1 = ReadByte();
76 uint8_t b2 = ReadByte();
77 uint8_t b3 = ReadByte();
78 uint8_t b4 = ReadByte();
79 uint8_t b5 = ReadByte();
80 uint8_t b6 = ReadByte();
81 uint8_t b7 = ReadByte();
82 return (static_cast<uint64_t>(b0) << 56) | (static_cast<uint64_t>(b1) << 48) | (static_cast<uint64_t>(b2) << 40) | (static_cast<uint64_t>(b3) << 32) | (static_cast<uint64_t>(b4) << 24) |
83 (static_cast<uint64_t>(b5) << 16) | (static_cast<uint64_t>(b6) << 8) | static_cast<uint64_t>(b7);
84 }
85
86 int64_t BinaryReader::ReadLong()
87 {
88 uint64_t x = ReadULong();
89 return static_cast<int64_t>(x);
90 }
91
92 float BinaryReader::ReadFloat()
93 {
94 uint32_t x = ReadUInt();
95 return *reinterpret_cast<float*>(&x);
96 }
97
98 double BinaryReader::ReadDouble()
99 {
100 uint64_t x = ReadULong();
101 return *reinterpret_cast<double*>(&x);
102 }
103
104 char BinaryReader::ReadChar()
105 {
106 uint8_t x = ReadByte();
107 return static_cast<char>(x);
108 }
109
110 char16_t BinaryReader::ReadWChar()
111 {
112 uint16_t x = ReadUShort();
113 return static_cast<char16_t>(x);
114 }
115
116 char32_t BinaryReader::ReadUChar()
117 {
118 uint32_t x = ReadUInt();
119 return static_cast<char32_t>(x);
120 }
121
122 std::string BinaryReader::ReadUtf8String()
123 {
124 std::string s;
125 uint8_t x = ReadByte();
126 while (x != 0)
127 {
128 s.append(1, static_cast<char>(x));
129 x = ReadByte();
130 }
131 return s;
132 }
133
134 std::u16string BinaryReader::ReadUtf16String()
135 {
136 std::string s = ReadUtf8String();
137 return ToUtf16(s);
138 }
139
140 std::u32string BinaryReader::ReadUtf32String()
141 {
142 std::string s = ReadUtf8String();
143 return ToUtf32(s);
144 }
145
146 uint32_t BinaryReader::ReadULEB128UInt()
147 {
148 uint32_t result = 0;
149 uint32_t shift = 0;
150 while (true)
151 {
152 uint8_t b = ReadByte();
153 result |= ((b & 0x7F) << shift);
154 if ((b & 0x80) == 0) break;
155 shift += 7;
156 }
157 return result;
158 }
159
160 uint64_t BinaryReader::ReadULEB128ULong()
161 {
162 uint64_t result = 0;
163 uint64_t shift = 0;
164 while (true)
165 {
166 uint8_t b = ReadByte();
167 result |= ((b & 0x7F) << shift);
168 if ((b & 0x80) == 0) break;
169 shift += 7;
170 }
171 return result;
172 }
173
174 int32_t BinaryReader::ReadSLEB128Int()
175 {
176 int32_t result = 0;
177 int32_t shift = 0;
178 uint8_t b = 0;
179 do
180 {
181 b = ReadByte();
182 result |= (b & 0x7F) << shift;
183 shift += 7;
184 }
185 while ((b & 0x80) != 0);
186 if ((shift < 32) && (b & 0x40) != 0)
187 {
188 result |= ~int32_t(0) << shift;
189 }
190 return result;
191 }
192
193 int64_t BinaryReader::ReadSLEB128Long()
194 {
195 int64_t result = 0;
196 int64_t shift = 0;
197 uint8_t b = 0;
198 do
199 {
200 b = ReadByte();
201 result |= (b & 0x7F) << shift;
202 shift += 7;
203 }
204 while ((b & 0x80) != 0);
205 if ((shift < 64) && (b & 0x40) != 0)
206 {
207 result |= ~int64_t(0) << shift;
208 }
209 return result;
210 }
211
212 void BinaryReader::ReadUuid(boost::uuids::uuid& uuid)
213 {
214 for (boost::uuids::uuid::value_type& x : uuid)
215 {
216 x = ReadByte();
217 }
218 }
219
220 void BinaryReader::Skip(uint32_t size)
221 {
222 begin += size;
223 pos += size;
224 }
225
226 void BinaryReader::CheckEof()
227 {
228 if (begin == end)
229 {
230 throw std::runtime_error("unexpected end of file '" + fileName + "'");
231 }
232 }
233
234 } }