Treat data files as uint8_t, not char

This commit is contained in:
2015-04-30 16:33:45 +02:00
parent 7fb5f66091
commit 82ee2586d3
10 changed files with 53 additions and 46 deletions

View File

@@ -9,7 +9,7 @@ struct ChunkHeader {
uint32_t length; uint32_t length;
}; };
IffFile::IffFile(char const* base, size_t length) IffFile::IffFile(uint8_t const* base, size_t length)
: base_(base), length_(length) : base_(base), length_(length)
{ {
size_t pos = 0; size_t pos = 0;
@@ -50,7 +50,7 @@ void IffFile::printStructure(unsigned level) const
} }
std::unique_ptr<IffFile::Object> IffFile::parseObject(char const* base, size_t length) std::unique_ptr<IffFile::Object> IffFile::parseObject(uint8_t const* base, size_t length)
{ {
if (length < 8) if (length < 8)
throw FormatException{"length < header size"}; throw FormatException{"length < header size"};
@@ -72,7 +72,7 @@ std::unique_ptr<IffFile::Object> IffFile::parseObject(char const* base, size_t l
return std::make_unique<Object>(std::string(header.typeID, 4), base+8, static_cast<size_t>(header.length)); return std::make_unique<Object>(std::string(header.typeID, 4), base+8, static_cast<size_t>(header.length));
} }
IffFile::Object::Object(std::string type, char const* base, size_t length) IffFile::Object::Object(std::string type, uint8_t const* base, size_t length)
: base_(base), length_(length), type_(std::move(type)) : base_(base), length_(length), type_(std::move(type))
{ {
} }
@@ -105,20 +105,23 @@ IffFile::Object::operator std::string() const
} }
if (state == State::NULLS) if (state == State::NULLS)
return std::string(base_); return std::string(reinterpret_cast<char const*>(base_));
else if (state == State::STARTASCII) else if (state == State::STARTASCII)
return std::string(base_, length_); return std::string(reinterpret_cast<char const*>(base_), length_);
else else
throw FormatException{"BLOB not string"}; throw FormatException{"BLOB not string"};
} }
IffFile::Form::Form(std::string type, char const* base, size_t length) IffFile::Form::Form(std::string type, uint8_t const* base, size_t length)
: Object(std::move(type), base, length) : Object(std::move(type), base, length)
{ {
if (length < 4) if (length < 4)
throw FormatException{"length < subtype id length"}; throw FormatException{"length < subtype id length"};
subtype_ = std::string(base, 4); for (unsigned i = 0;i < 4;++i)
if (!isprint(base[i]))
throw FormatException{"Subtype not printable"};
subtype_ = std::string(reinterpret_cast<char const*>(base), 4);
size_t pos = 4; size_t pos = 4;
while (pos+8 < length) { while (pos+8 < length) {

View File

@@ -9,7 +9,7 @@
class IffFile { class IffFile {
public: public:
IffFile(char const* base, size_t length); IffFile(uint8_t const* base, size_t length);
~IffFile(); ~IffFile();
@@ -111,7 +111,7 @@ public:
class Object { class Object {
public: public:
Object(std::string type, char const* base, size_t length); Object(std::string type, uint8_t const* base, size_t length);
Object(Object const& copy) = delete; Object(Object const& copy) = delete;
virtual ~Object() { virtual ~Object() {
@@ -129,25 +129,25 @@ public:
return length_; return length_;
} }
char const* begin() const { uint8_t const* begin() const {
return base_; return base_;
} }
char const* end() const { uint8_t const* end() const {
return base_+length_; return base_+length_;
} }
operator std::string() const; operator std::string() const;
protected: protected:
char const* base_; uint8_t const* base_;
const size_t length_; const size_t length_;
std::string const type_; std::string const type_;
}; };
class Form final : public Object { class Form final : public Object {
public: public:
Form(std::string type, char const* base, size_t length); Form(std::string type, uint8_t const* base, size_t length);
~Form() {} ~Form() {}
@@ -186,9 +186,9 @@ public:
void printStructure(unsigned level = 0) const; void printStructure(unsigned level = 0) const;
private: private:
static std::unique_ptr<Object> parseObject(char const* base, size_t length); static std::unique_ptr<Object> parseObject(uint8_t const* base, size_t length);
char const* base_; uint8_t const* base_;
const size_t length_; const size_t length_;
std::vector<std::unique_ptr<Object> > roots_; std::vector<std::unique_ptr<Object> > roots_;
}; };

View File

@@ -7,7 +7,7 @@
#include "decompress.hh" #include "decompress.hh"
#include "MveDecoder.hh" #include "MveDecoder.hh"
MveDecoder::MveDecoder(char const* base, size_t length) MveDecoder::MveDecoder(uint8_t const* base, size_t length)
: iff_(base, length), width_(320), height_(165) : iff_(base, length), width_(320), height_(165)
{ {
//iff_.printStructure(); //iff_.printStructure();
@@ -130,7 +130,7 @@ MveDecoder::MveDecoder(char const* base, size_t length)
} }
} }
std::vector<char> parseHuff_(char const* data, size_t len) std::vector<char> parseHuff_(uint8_t const* data, size_t len)
{ {
uint8_t numHuffVals; uint8_t numHuffVals;
memcpy(&numHuffVals, data, 1); memcpy(&numHuffVals, data, 1);
@@ -196,7 +196,7 @@ std::vector<char> parseHuff_(char const* data, size_t len)
return commands; return commands;
} }
std::vector<uint8_t> parsePixels_(char const* data, size_t len) std::vector<uint8_t> parsePixels_(uint8_t const* data, size_t len)
{ {
if (*data == 0x02) { if (*data == 0x02) {
return decompressLZ(data+1, len-1); return decompressLZ(data+1, len-1);

View File

@@ -8,7 +8,7 @@
class MveDecoder { class MveDecoder {
public: public:
MveDecoder(char const* base, size_t length); MveDecoder(uint8_t const* base, size_t length);
size_t numBranches() const { size_t numBranches() const {
return branches_.size(); return branches_.size();

View File

@@ -20,7 +20,7 @@ static const size_t headerSize = 24;
static const size_t table1EntrySize = 8; static const size_t table1EntrySize = 8;
static const size_t table3EntrySize = 8; static const size_t table3EntrySize = 8;
TreFile::TreFile(char const* base, size_t length) TreFile::TreFile(uint8_t const* base, size_t length)
: base_(base), length_(length) : base_(base), length_(length)
{ {
if (length_ < 6*4) if (length_ < 6*4)
@@ -66,7 +66,7 @@ TreFile::TreFile(char const* base, size_t length)
// Read table 3 // Read table 3
for (size_t i = 0;i < numTable3Entries;++i) { for (size_t i = 0;i < numTable3Entries;++i) {
char const* const entryBase = base_+header.table3Ofs+i*table3EntrySize; uint8_t const* const entryBase = base_+header.table3Ofs+i*table3EntrySize;
const uint32_t dataPtr = readU32LE(entryBase); const uint32_t dataPtr = readU32LE(entryBase);
const uint32_t length = readU32LE(entryBase+4)&0x0fffffffu; const uint32_t length = readU32LE(entryBase+4)&0x0fffffffu;
@@ -119,7 +119,11 @@ TreFile::TreFile(char const* base, size_t length)
if (pos+nameLen+5 > header.table3Ofs) if (pos+nameLen+5 > header.table3Ofs)
throw FormatException{"Table 2 entry exceeds table " + std::to_string(nameLen)}; throw FormatException{"Table 2 entry exceeds table " + std::to_string(nameLen)};
std::string nameStr(base+pos+1, nameLen); for (unsigned i = 0;i < nameLen;++i)
if (!isprint(base[pos+1+i]))
throw FormatException{"Filename not printable"};
std::string nameStr(reinterpret_cast<char const*>(base)+pos+1, nameLen);
const uint32_t table3Ptr = readU32LE(base+pos+nameLen+1); const uint32_t table3Ptr = readU32LE(base+pos+nameLen+1);
@@ -146,7 +150,7 @@ TreFile::TreFile(char const* base, size_t length)
// Read Table 1 // Read Table 1
for (size_t i = 0;i < numTable1Entries;++i) { for (size_t i = 0;i < numTable1Entries;++i) {
char const* const entryBase = base+header.table1Ofs+i*table1EntrySize; uint8_t const* const entryBase = base+header.table1Ofs+i*table1EntrySize;
const uint32_t crc = readU32LE(entryBase); const uint32_t crc = readU32LE(entryBase);
uint32_t table3Ptr = readU32LE(entryBase+4); uint32_t table3Ptr = readU32LE(entryBase+4);

View File

@@ -10,7 +10,7 @@
class TreFile { class TreFile {
public: public:
TreFile(char const* base, size_t length); TreFile(uint8_t const* base, size_t length);
~TreFile(); ~TreFile();
@@ -47,9 +47,9 @@ public:
return *this; return *this;
} }
char const* data() const { uint8_t const* data() const {
if (data_) if (data_)
return (char const*)(data_->data()); return data_->data();
else else
return base_; return base_;
} }
@@ -66,10 +66,10 @@ public:
// Object either owns data (when decompressed) ... // Object either owns data (when decompressed) ...
std::experimental::optional<std::vector<uint8_t> > data_; std::experimental::optional<std::vector<uint8_t> > data_;
// .. or points to area in underlying data (when not compressed) // .. or points to area in underlying data (when not compressed)
char const* base_; uint8_t const* base_;
size_t length_; size_t length_;
Object(char const* base, size_t length) Object(uint8_t const* base, size_t length)
: data_(), base_(base), length_(length) { : data_(), base_(base), length_(length) {
} }
@@ -112,7 +112,7 @@ private:
// base, size, comp. size, flags // base, size, comp. size, flags
std::vector<std::tuple<uint32_t, uint32_t, uint32_t, uint8_t> > table3_; std::vector<std::tuple<uint32_t, uint32_t, uint32_t, uint8_t> > table3_;
char const* base_; uint8_t const* base_;
size_t length_; size_t length_;
}; };

View File

@@ -2,7 +2,7 @@
#include "decompress.hh" #include "decompress.hh"
std::vector<uint8_t> decompressLZ(char const* data, size_t len) std::vector<uint8_t> decompressLZ(uint8_t const* data, size_t len)
{ {
std::vector<uint8_t> ret; std::vector<uint8_t> ret;

View File

@@ -9,6 +9,6 @@
/* LZ77-like format consisting of codes specifing copies from the input stream /* LZ77-like format consisting of codes specifing copies from the input stream
and/or replication of previously output data */ and/or replication of previously output data */
std::vector<uint8_t> decompressLZ(char const* data, size_t len); std::vector<uint8_t> decompressLZ(uint8_t const* data, size_t len);
#endif #endif

16
util.cc
View File

@@ -74,11 +74,11 @@ size_t MmapFile::size() const
return size_; return size_;
} }
char const* MmapFile::data() const uint8_t const* MmapFile::data() const
{ {
if (!*this) if (!*this)
throw std::logic_error("data() called on invalid MmapFile"); throw std::logic_error("data() called on invalid MmapFile");
return static_cast<char const*>(base_); return static_cast<uint8_t const*>(base_);
} }
MmapFile::operator bool() const MmapFile::operator bool() const
@@ -87,7 +87,7 @@ MmapFile::operator bool() const
} }
uint16_t readU16BE(char const* data) uint16_t readU16BE(uint8_t const* data)
{ {
if(!data) if(!data)
throw std::logic_error("readU16BE() called with nullptr"); throw std::logic_error("readU16BE() called with nullptr");
@@ -96,7 +96,7 @@ uint16_t readU16BE(char const* data)
static_cast<uint8_t>(*(data+1)); static_cast<uint8_t>(*(data+1));
} }
uint32_t readU24BE(char const* data) uint32_t readU24BE(uint8_t const* data)
{ {
if(!data) if(!data)
throw std::logic_error("readU24BE() called with nullptr"); throw std::logic_error("readU24BE() called with nullptr");
@@ -106,7 +106,7 @@ uint32_t readU24BE(char const* data)
static_cast<uint8_t>(*(data+2)); static_cast<uint8_t>(*(data+2));
} }
uint32_t readU32BE(char const* data) uint32_t readU32BE(uint8_t const* data)
{ {
if(!data) if(!data)
throw std::logic_error("readU32BE() called with nullptr"); throw std::logic_error("readU32BE() called with nullptr");
@@ -117,7 +117,7 @@ uint32_t readU32BE(char const* data)
static_cast<uint8_t>(*(data+3)); static_cast<uint8_t>(*(data+3));
} }
uint16_t readU16LE(char const* data) uint16_t readU16LE(uint8_t const* data)
{ {
if(!data) if(!data)
throw std::logic_error("readU16LE() called with nullptr"); throw std::logic_error("readU16LE() called with nullptr");
@@ -126,7 +126,7 @@ uint16_t readU16LE(char const* data)
static_cast<uint8_t>(*data); static_cast<uint8_t>(*data);
} }
uint32_t readU24LE(char const* data) uint32_t readU24LE(uint8_t const* data)
{ {
if(!data) if(!data)
throw std::logic_error("readU24LE() called with nullptr"); throw std::logic_error("readU24LE() called with nullptr");
@@ -136,7 +136,7 @@ uint32_t readU24LE(char const* data)
static_cast<uint8_t>(*data); static_cast<uint8_t>(*data);
} }
uint32_t readU32LE(char const* data) uint32_t readU32LE(uint8_t const* data)
{ {
if(!data) if(!data)
throw std::logic_error("readU32LE() called with nullptr"); throw std::logic_error("readU32LE() called with nullptr");

14
util.hh
View File

@@ -19,7 +19,7 @@ public:
std::string const& name() const; std::string const& name() const;
size_t size() const; size_t size() const;
char const* data() const; uint8_t const* data() const;
operator bool() const; operator bool() const;
private: private:
@@ -30,14 +30,14 @@ private:
}; };
// Helper functions to read big endian numbers // Helper functions to read big endian numbers
uint16_t readU16BE(char const* data); uint16_t readU16BE(uint8_t const* data);
uint32_t readU24BE(char const* data); uint32_t readU24BE(uint8_t const* data);
uint32_t readU32BE(char const* data); uint32_t readU32BE(uint8_t const* data);
// Helper functions to read little endian numbers // Helper functions to read little endian numbers
uint16_t readU16LE(char const* data); uint16_t readU16LE(uint8_t const* data);
uint32_t readU24LE(char const* data); uint32_t readU24LE(uint8_t const* data);
uint32_t readU32LE(char const* data); uint32_t readU32LE(uint8_t const* data);
// Sign-extend b starting at msb // Sign-extend b starting at msb
int sextend(unsigned b, unsigned msb); int sextend(unsigned b, unsigned msb);