Treat data files as uint8_t, not char
This commit is contained in:
17
IffFile.cc
17
IffFile.cc
@@ -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) {
|
||||||
|
|||||||
16
IffFile.hh
16
IffFile.hh
@@ -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_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
12
TreFile.cc
12
TreFile.cc
@@ -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);
|
||||||
|
|||||||
12
TreFile.hh
12
TreFile.hh
@@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
16
util.cc
@@ -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
14
util.hh
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user