openMSX
GZFileAdapter.cc
Go to the documentation of this file.
1 #include "GZFileAdapter.hh"
2 #include "ZlibInflate.hh"
3 #include "FileException.hh"
4 
5 namespace openmsx {
6 
7 constexpr uint8_t ASCII_FLAG = 0x01; // bit 0 set: file probably ascii text
8 constexpr uint8_t HEAD_CRC = 0x02; // bit 1 set: header CRC present
9 constexpr uint8_t EXTRA_FIELD = 0x04; // bit 2 set: extra field present
10 constexpr uint8_t ORIG_NAME = 0x08; // bit 3 set: original file name present
11 constexpr uint8_t COMMENT = 0x10; // bit 4 set: file comment present
12 constexpr uint8_t RESERVED = 0xE0; // bits 5..7: reserved
13 
14 
15 GZFileAdapter::GZFileAdapter(std::unique_ptr<FileBase> file_)
16  : CompressedFileAdapter(std::move(file_))
17 {
18 }
19 
20 static bool skipHeader(ZlibInflate& zlib, std::string& originalName)
21 {
22  // check magic bytes
23  if (zlib.get16LE() != 0x8B1F) {
24  return false;
25  }
26 
27  uint8_t method = zlib.getByte();
28  uint8_t flags = zlib.getByte();
29  if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
30  return false;
31  }
32 
33  // Discard time, xflags and OS code:
34  zlib.skip(6);
35 
36  if ((flags & EXTRA_FIELD) != 0) {
37  // skip the extra field
38  int len = zlib.get16LE();
39  zlib.skip(len);
40  }
41  if ((flags & ORIG_NAME) != 0) {
42  // get the original file name
43  originalName = zlib.getCString();
44  }
45  if ((flags & COMMENT) != 0) {
46  // skip the .gz file comment
47  zlib.getCString();
48  }
49  if ((flags & HEAD_CRC) != 0) {
50  // skip the header crc
51  zlib.skip(2);
52  }
53  return true;
54 }
55 
56 void GZFileAdapter::decompress(FileBase& f, Decompressed& d)
57 {
58  ZlibInflate zlib(f.mmap());
59  if (!skipHeader(zlib, d.originalName)) {
60  throw FileException("Not a gzip header");
61  }
62  d.size = zlib.inflate(d.buf);
63 }
64 
65 } // namespace openmsx
GZFileAdapter(std::unique_ptr< FileBase > file)
constexpr uint8_t ASCII_FLAG
Definition: GZFileAdapter.cc:7
constexpr uint8_t ORIG_NAME
STL namespace.
constexpr uint8_t COMMENT
std::string getCString()
Definition: ZlibInflate.cc:73
constexpr uint8_t RESERVED
constexpr uint8_t HEAD_CRC
Definition: GZFileAdapter.cc:8
void skip(size_t num)
Definition: ZlibInflate.cc:31
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
virtual span< uint8_t > mmap()
Definition: FileBase.cc:10
constexpr uint8_t EXTRA_FIELD
Definition: GZFileAdapter.cc:9
size_t inflate(MemBuffer< uint8_t > &output, size_t sizeHint=65536)
Definition: ZlibInflate.cc:82