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
openmsx::ZlibInflate::getByte
uint8_t getByte()
Definition: ZlibInflate.cc:38
FileException.hh
openmsx::ZlibInflate
Definition: ZlibInflate.hh:12
openmsx::ZlibInflate::skip
void skip(size_t num)
Definition: ZlibInflate.cc:31
openmsx::ORIG_NAME
constexpr uint8_t ORIG_NAME
Definition: GZFileAdapter.cc:10
openmsx::RESERVED
constexpr uint8_t RESERVED
Definition: GZFileAdapter.cc:12
openmsx::COMMENT
constexpr uint8_t COMMENT
Definition: GZFileAdapter.cc:11
ZlibInflate.hh
openmsx::ZlibInflate::get16LE
unsigned get16LE()
Definition: ZlibInflate.cc:48
openmsx::HEAD_CRC
constexpr uint8_t HEAD_CRC
Definition: GZFileAdapter.cc:8
openmsx::ZlibInflate::getCString
std::string getCString()
Definition: ZlibInflate.cc:73
openmsx::CompressedFileAdapter
Definition: CompressedFileAdapter.hh:10
openmsx::ZlibInflate::inflate
size_t inflate(MemBuffer< uint8_t > &output, size_t sizeHint=65536)
Definition: ZlibInflate.cc:82
openmsx::EXTRA_FIELD
constexpr uint8_t EXTRA_FIELD
Definition: GZFileAdapter.cc:9
openmsx::ASCII_FLAG
constexpr uint8_t ASCII_FLAG
Definition: GZFileAdapter.cc:7
openmsx::GZFileAdapter::GZFileAdapter
GZFileAdapter(std::unique_ptr< FileBase > file)
Definition: GZFileAdapter.cc:15
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5
GZFileAdapter.hh