source: icGREP/icgrep-devel/icgrep/lz4/lz4_frame_decoder.cpp @ 6173

Last change on this file since 6173 was 6137, checked in by xwa163, 14 months ago
  1. LZ4 ScanMatch? pipeline
  2. Refactor LZ4 Generator
  3. Adjust some naming
File size: 2.4 KB
Line 
1/*
2 *  Copyright (c) 2017 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icgrep is a trademark of International Characters.
5 */
6
7#include <iostream>
8#include <fstream>
9
10#include <lz4/lz4_frame_decoder.h>
11
12namespace {
13
14
15// Little-endian.
16const uint32_t magicNumber = 0x184D2204;
17}
18
19LZ4FrameDecoder::LZ4FrameDecoder() {
20
21}
22
23LZ4FrameDecoder::LZ4FrameDecoder(const std::string & filename) {
24    this->init(filename);
25}
26
27void LZ4FrameDecoder::init(const std::string &filename) {
28    const size_t minFilesize = this->getMinFileSize();
29
30    std::ifstream f(filename, std::ios::binary | std::ios::ate);
31    if (f.fail()) {
32        return;
33    }
34    mFilesize = f.tellg();
35    if (mFilesize < minFilesize) {
36        return;
37    }
38
39    // Verify magic number (assuming little-endian).
40    f.seekg(0);
41    uint32_t magic;
42    f.read(reinterpret_cast<char*>(&magic), 4);
43    if (magic != magicNumber) {
44        return;
45    }
46
47    // Decode FD to get its length and whether checksum is used.
48    if (!decodeFrameDescriptor(f)) {
49        return;
50    }
51
52    mBlocksStart = 4 + mFDLength;       // MagicNb & FD
53    long long blocksEnd = mFilesize - this->endMarkSize() - (mHasContentChecksum ? this->contentChecksumSize() : 0);      // EndMark & checksum
54    if (blocksEnd > 0 && mBlocksStart <= static_cast<size_t>(blocksEnd)) {
55        mBlocksLength = blocksEnd - mBlocksStart;
56        mValid = true;
57    }
58}
59
60bool LZ4FrameDecoder::decodeFrameDescriptor(std::ifstream & f) {
61    const size_t minFilesize = this->getMinFileSize();
62
63    char flag, blockDescriptor, headerChecksum;
64    f.get(flag);
65    f.get(blockDescriptor);
66    mHasContentChecksum = (flag >> 2) & 1;
67    bool hasContentSize = (flag >> 3) & 1;
68    mHasBlockChecksum = (flag >> 4) & 1;
69
70    // Version number.
71    if ((flag >> 6) != 1) {
72        return false;
73    }
74
75    if (mFilesize < minFilesize +
76            (mHasContentChecksum ? this->contentChecksumSize() : 0) +
77            (hasContentSize ? 8 : 0)
78       ) {
79        return false;
80    }
81
82    if (hasContentSize) {
83        mFDLength = 1 + 1 + 8 + 1;      //  flag, BD, content size, HC
84        // Skip content size.
85        f.seekg(8, std::ios::cur);
86    } else {
87        mFDLength = 3;
88    }
89    f.get(headerChecksum);
90    return true;
91}
92
93size_t LZ4FrameDecoder::endMarkSize() const {
94    return 4;
95}
96
97size_t LZ4FrameDecoder::contentChecksumSize() const {
98    return 4;
99}
100
Note: See TracBrowser for help on using the repository browser.