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

Last change on this file since 5706 was 5706, checked in by nmedfort, 12 months ago

First stage of MultiBlockKernel? and pipeline restructuring

File size: 2.1 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 {
13const size_t minFilesize = 
14    4 +         // Magic number
15    3 +         // Frame descriptor (3-11 bytes)
16    4;          // End mark
17
18// Little-endian.
19const uint32_t magicNumber = 0x184D2204;
20}
21
22LZ4FrameDecoder::LZ4FrameDecoder(const std::string & filename) {
23    std::ifstream f(filename, std::ios::binary | std::ios::ate);
24    if (f.fail()) {
25        return;
26    }
27    mFilesize = f.tellg();
28    if (mFilesize < minFilesize) {
29        return;
30    }
31
32    // Verify magic number (assuming little-endian).
33    f.seekg(0);
34    uint32_t magic;
35    f.read(reinterpret_cast<char*>(&magic), 4);
36    if (magic != magicNumber) {
37        return;
38    }
39
40    // Decode FD to get its length and whether checksum is used.
41    if (!decodeFrameDescriptor(f)) {
42        return;
43    }
44
45    mBlocksStart = 4 + mFDLength;       // MagicNb & FD
46    long long blocksEnd = mFilesize - 4 - (mHasContentChecksum ? 4 : 0);      // EndMark & checksum
47    if (blocksEnd > 0 && mBlocksStart <= static_cast<size_t>(blocksEnd)) {
48        mBlocksLength = blocksEnd - mBlocksStart;
49        mValid = true;
50    }
51}
52
53bool LZ4FrameDecoder::decodeFrameDescriptor(std::ifstream & f) {
54    char flag, blockDescriptor, headerChecksum;
55    f.get(flag);
56    f.get(blockDescriptor);
57    mHasContentChecksum = (flag >> 2) & 1;
58    bool hasContentSize = (flag >> 3) & 1;
59    mHasBlockChecksum = (flag >> 4) & 1;
60
61    // Version number.
62    if ((flag >> 6) != 1) {
63        return false;
64    }
65
66    if (mFilesize < minFilesize +
67            (mHasContentChecksum ? 4 : 0) +
68            (hasContentSize ? 8 : 0)
69       ) {
70        return false;
71    }
72
73    if (hasContentSize) {
74        mFDLength = 1 + 1 + 8 + 1;      //  flag, BD, content size, HC
75        // Skip content size.
76        f.seekg(8, std::ios::cur);
77    } else {
78        mFDLength = 3;
79    }
80    f.get(headerChecksum);
81    return true;
82}
Note: See TracBrowser for help on using the repository browser.