15 #include "lcf/reader_lcf.h"
20 std::string LcfReader::error_str;
22 LcfReader::LcfReader(std::istream& filestream, std::string encoding)
24 , encoder(std::move(encoding))
26 offset = filestream.tellg();
29 size_t LcfReader::Read0(
void *ptr,
size_t size,
size_t nmemb) {
34 stream.read(
reinterpret_cast<char*
>(ptr), size*nmemb);
35 auto bytes_read = stream.gcount();
37 size_t result = bytes_read / size;
39 if (result != nmemb && !Eof()) {
40 perror(
"Reading error: ");
46 void LcfReader::Read(
void *ptr,
size_t size,
size_t nmemb) {
48 Read0(ptr, size, nmemb);
50 if (Read0(ptr, size, nmemb) != nmemb) {
51 fprintf(stderr,
"Read error at %" PRIu32
". The file is probably corrupted\n", Tell());
57 void LcfReader::Read<bool>(
bool& ref) {
62 void LcfReader::Read<int8_t>(int8_t& ref) {
67 void LcfReader::Read<uint8_t>(uint8_t& ref) {
72 void LcfReader::Read<int16_t>(int16_t& ref) {
78 void LcfReader::Read<uint32_t>(uint32_t& ref) {
83 int LcfReader::ReadInt() {
85 unsigned char temp = 0;
89 if (Read0(&temp, 1, 1) == 0) {
96 fprintf(stderr,
"Invalid compressed integer at %" PRIu32
"\n", Tell());
99 }
while (temp & 0x80);
101 return loops > 5 ? 0 : value;
104 uint64_t LcfReader::ReadUInt64() {
106 unsigned char temp = 0;
110 if (Read0(&temp, 1, 1) == 0) {
114 value |=
static_cast<uint64_t
>(temp & 0x7F);
117 fprintf(stderr,
"Invalid compressed integer at %" PRIu32
"\n", Tell());
120 }
while (temp & 0x80);
122 return loops > 9 ? 0 : value;
126 void LcfReader::Read<int32_t>(int32_t& ref) {
131 void LcfReader::Read<double>(
double& ref) {
137 void LcfReader::Read<bool>(std::vector<bool>& buffer,
size_t size) {
140 for (
unsigned i = 0; i < size; ++i) {
143 buffer.push_back(val > 0);
148 void LcfReader::Read<uint8_t>(std::vector<uint8_t>& buffer,
size_t size) {
151 for (
unsigned int i = 0; i < size; ++i) {
154 buffer.push_back(val);
159 void LcfReader::Read<int16_t>(std::vector<int16_t>& buffer,
size_t size) {
161 size_t items = size / 2;
162 for (
unsigned int i = 0; i < items; ++i) {
166 buffer.push_back(val);
169 Seek(1, FromCurrent);
175 void LcfReader::Read<int32_t>(std::vector<int32_t>& buffer,
size_t size) {
177 size_t items = size / 4;
178 for (
unsigned int i = 0; i < items; ++i) {
182 buffer.push_back(val);
185 Seek(size % 4, FromCurrent);
191 void LcfReader::Read<uint32_t>(std::vector<uint32_t>& buffer,
size_t size) {
193 size_t items = size / 4;
194 for (
unsigned int i = 0; i < items; ++i) {
198 buffer.push_back(val);
201 Seek(size % 4, FromCurrent);
206 void LcfReader::ReadBits(DBBitArray& buffer,
size_t size) {
207 buffer = DBBitArray(size);
208 for (
size_t i = 0; i < size; ++i) {
210 Read(&val,
sizeof(val), 1);
211 buffer[i] =
static_cast<bool>(val);
215 void LcfReader::ReadString(std::string& ref,
size_t size) {
217 Read((size > 0 ? &ref.front():
nullptr), 1, size);
221 void LcfReader::ReadString(DBString& ref,
size_t size) {
222 auto& tmp = StrBuffer();
223 ReadString(tmp, size);
227 bool LcfReader::IsOk()
const {
228 return stream.good() && encoder.IsOk();
231 bool LcfReader::Eof()
const {
235 void LcfReader::Seek(
size_t pos, SeekMode mode) {
236 constexpr
auto fast_seek_size = 32;
238 case LcfReader::FromStart:
239 stream.seekg(pos, std::ios_base::beg);
240 offset = stream.tellg();
242 case LcfReader::FromCurrent:
243 if (pos <= fast_seek_size) {
246 char buf[fast_seek_size];
247 stream.read(buf, pos);
248 offset += stream.gcount();
250 stream.seekg(pos, std::ios_base::cur);
251 offset = stream.tellg();
254 case LcfReader::FromEnd:
255 stream.seekg(pos, std::ios_base::end);
256 offset = stream.tellg();
259 assert(
false &&
"Invalid SeekMode");
263 uint32_t LcfReader::Tell() {
274 int LcfReader::Peek() {
275 return stream.peek();
278 void LcfReader::Skip(
const struct LcfReader::Chunk& chunk_info,
const char* where) {
279 fprintf(stderr,
"Skipped Chunk %02X (%" PRIu32
" byte) in lcf at %" PRIX32
" (%s)\n",
280 chunk_info.ID, chunk_info.length, Tell(), where);
282 for (uint32_t i = 0; i < chunk_info.length; ++i) {
284 LcfReader::Read(
byte);
285 fprintf(stderr,
"%02X ",
byte);
286 if ((i+1) % 16 == 0) {
287 fprintf(stderr,
"\n");
293 fprintf(stderr,
"\n");
296 void LcfReader::SetError(
const char* fmt, ...) {
301 vsprintf(str, fmt, args);
309 const std::string& LcfReader::GetError() {
313 void LcfReader::Encode(std::string& str) {
317 int LcfReader::IntSize(
unsigned int x) {
326 int LcfReader::UInt64Size(uint64_t x) {
335 #ifdef WORDS_BIGENDIAN
336 void LcfReader::SwapByteOrder(uint16_t& us)
342 void LcfReader::SwapByteOrder(uint32_t& ui)
345 ((ui<<8) & 0x00FF0000) |
346 ((ui>>8) & 0x0000FF00) |
350 void LcfReader::SwapByteOrder(
double& d)
352 char *p =
reinterpret_cast<char*
>(&d);
353 std::swap(p[0], p[7]);
354 std::swap(p[1], p[6]);
355 std::swap(p[2], p[5]);
356 std::swap(p[3], p[4]);
359 void LcfReader::SwapByteOrder(uint16_t& ) {}
360 void LcfReader::SwapByteOrder(uint32_t& ) {}
361 void LcfReader::SwapByteOrder(
double& ) {}
364 void LcfReader::SwapByteOrder(int16_t& s)
366 SwapByteOrder((uint16_t&) s);
369 void LcfReader::SwapByteOrder(int32_t& s)
371 SwapByteOrder((uint32_t&) s);