17#include "lcf/reader_lcf.h"
23std::string LcfReader::error_str;
25LcfReader::LcfReader(std::istream& filestream, std::string encoding)
27 , encoder(std::move(encoding))
29 offset = filestream.tellg();
32size_t LcfReader::Read0(
void *ptr,
size_t size,
size_t nmemb) {
37 stream.read(
reinterpret_cast<char*
>(ptr), size*nmemb);
38 auto bytes_read = stream.gcount();
40 size_t result = bytes_read / size;
42 if (result != nmemb && !Eof()) {
43 perror(
"Reading error: ");
49void LcfReader::Read(
void *ptr,
size_t size,
size_t nmemb) {
51 Read0(ptr, size, nmemb);
53 if (Read0(ptr, size, nmemb) != nmemb) {
54 Log::Warning(
"Read error at %" PRIu32
". The file is probably corrupted", Tell());
60void LcfReader::Read<bool>(
bool& ref) {
65void LcfReader::Read<int8_t>(int8_t& ref) {
70void LcfReader::Read<uint8_t>(uint8_t& ref) {
75void LcfReader::Read<int16_t>(int16_t& ref) {
81void LcfReader::Read<uint32_t>(uint32_t& ref) {
86int LcfReader::ReadInt() {
88 unsigned char temp = 0;
92 if (Read0(&temp, 1, 1) == 0) {
99 Log::Warning(
"Invalid compressed integer at %" PRIu32
"", Tell());
102 }
while (temp & 0x80);
104 return loops > 5 ? 0 : value;
107uint64_t LcfReader::ReadUInt64() {
109 unsigned char temp = 0;
113 if (Read0(&temp, 1, 1) == 0) {
117 value |=
static_cast<uint64_t
>(temp & 0x7F);
120 Log::Warning(
"Invalid compressed integer at %" PRIu32
"", Tell());
123 }
while (temp & 0x80);
125 return loops > 9 ? 0 : value;
129void LcfReader::Read<int32_t>(int32_t& ref) {
134void LcfReader::Read<double>(
double& ref) {
140void LcfReader::Read<bool>(std::vector<bool>& buffer,
size_t size) {
143 for (
unsigned i = 0; i < size; ++i) {
146 buffer.push_back(val > 0);
151void LcfReader::Read<uint8_t>(std::vector<uint8_t>& buffer,
size_t size) {
154 for (
unsigned int i = 0; i < size; ++i) {
157 buffer.push_back(val);
162void LcfReader::Read<int16_t>(std::vector<int16_t>& buffer,
size_t size) {
164 size_t items = size / 2;
165 for (
unsigned int i = 0; i < items; ++i) {
169 buffer.push_back(val);
172 Seek(1, FromCurrent);
178void LcfReader::Read<int32_t>(std::vector<int32_t>& buffer,
size_t size) {
180 size_t items = size / 4;
181 for (
unsigned int i = 0; i < items; ++i) {
185 buffer.push_back(val);
188 Seek(size % 4, FromCurrent);
194void LcfReader::Read<uint32_t>(std::vector<uint32_t>& buffer,
size_t size) {
196 size_t items = size / 4;
197 for (
unsigned int i = 0; i < items; ++i) {
201 buffer.push_back(val);
204 Seek(size % 4, FromCurrent);
209void LcfReader::ReadBits(DBBitArray& buffer,
size_t size) {
210 buffer = DBBitArray(size);
211 for (
size_t i = 0; i < size; ++i) {
213 Read(&val,
sizeof(val), 1);
214 buffer[i] =
static_cast<bool>(val);
218void LcfReader::ReadString(std::string& ref,
size_t size) {
220 Read((size > 0 ? &ref.front(): nullptr), 1, size);
224void LcfReader::ReadString(DBString& ref,
size_t size) {
225 auto& tmp = StrBuffer();
226 ReadString(tmp, size);
230bool LcfReader::IsOk()
const {
231 return stream.good() && encoder.IsOk();
234bool LcfReader::Eof()
const {
238void LcfReader::Seek(
size_t pos, SeekMode mode) {
239 constexpr auto fast_seek_size = 32;
241 case LcfReader::FromStart:
242 stream.seekg(pos, std::ios_base::beg);
243 offset = stream.tellg();
245 case LcfReader::FromCurrent:
246 if (pos <= fast_seek_size) {
249 char buf[fast_seek_size];
250 stream.read(buf, pos);
251 offset += stream.gcount();
253 stream.seekg(pos, std::ios_base::cur);
254 offset = stream.tellg();
257 case LcfReader::FromEnd:
258 stream.seekg(pos, std::ios_base::end);
259 offset = stream.tellg();
262 assert(
false &&
"Invalid SeekMode");
266uint32_t LcfReader::Tell() {
277int LcfReader::Peek() {
278 return stream.peek();
281void LcfReader::Skip(
const struct LcfReader::Chunk& chunk_info,
const char* where) {
282 Log::Debug(
"Skipped Chunk %02X (%" PRIu32
" byte) in lcf at %" PRIX32
" (%s)",
283 chunk_info.ID, chunk_info.length, Tell(), where);
285 std::stringstream ss;
288 for (uint32_t i = 0; i < chunk_info.length; ++i) {
290 LcfReader::Read(
byte);
291 ss << std::setfill(
'0') << std::setw(2) << (int)
byte <<
" ";
292 if ((i+1) % 16 == 0) {
293 Log::Debug(
"%s", ss.str().c_str());
300 if (!ss.str().empty()) {
301 Log::Debug(
"%s", ss.str().c_str());
305void LcfReader::SetError(
const char* fmt, ...) {
310 vsprintf(str, fmt, args);
313 Log::Error(
"%s", error_str.c_str());
318const std::string& LcfReader::GetError() {
322void LcfReader::Encode(std::string& str) {
326int LcfReader::IntSize(
unsigned int x) {
335int LcfReader::UInt64Size(uint64_t x) {
344#ifdef WORDS_BIGENDIAN
345void LcfReader::SwapByteOrder(uint16_t& us)
351void LcfReader::SwapByteOrder(uint32_t& ui)
354 ((ui<<8) & 0x00FF0000) |
355 ((ui>>8) & 0x0000FF00) |
359void LcfReader::SwapByteOrder(
double& d)
361 char *p =
reinterpret_cast<char*
>(&d);
362 std::swap(p[0], p[7]);
363 std::swap(p[1], p[6]);
364 std::swap(p[2], p[5]);
365 std::swap(p[3], p[4]);
368void LcfReader::SwapByteOrder(uint16_t& ) {}
369void LcfReader::SwapByteOrder(uint32_t& ) {}
370void LcfReader::SwapByteOrder(
double& ) {}
373void LcfReader::SwapByteOrder(int16_t& s)
375 SwapByteOrder((uint16_t&) s);
378void LcfReader::SwapByteOrder(int32_t& s)
380 SwapByteOrder((uint32_t&) s);