source: icGREP/icgrep-devel/icgrep/lz4FrameDecoder.cpp @ 6020

Last change on this file since 6020 was 6020, checked in by xwa163, 3 months ago
  1. New version of lz4_swizzled_match_copy kernel with higher performance
  2. Adjust related pipeline code
  3. Remove legacy comments
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 <lz4FrameDecoder.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.