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;
};
IffFile::IffFile(char const* base, size_t length)
IffFile::IffFile(uint8_t const* base, size_t length)
: base_(base), length_(length)
{
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)
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));
}
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))
{
}
@@ -105,20 +105,23 @@ IffFile::Object::operator std::string() const
}
if (state == State::NULLS)
return std::string(base_);
return std::string(reinterpret_cast<char const*>(base_));
else if (state == State::STARTASCII)
return std::string(base_, length_);
return std::string(reinterpret_cast<char const*>(base_), length_);
else
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)
{
if (length < 4)
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;
while (pos+8 < length) {

View File

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

View File

@@ -7,7 +7,7 @@
#include "decompress.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_.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;
memcpy(&numHuffVals, data, 1);
@@ -196,7 +196,7 @@ std::vector<char> parseHuff_(char const* data, size_t len)
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) {
return decompressLZ(data+1, len-1);

View File

@@ -8,7 +8,7 @@
class MveDecoder {
public:
MveDecoder(char const* base, size_t length);
MveDecoder(uint8_t const* base, size_t length);
size_t numBranches() const {
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 table3EntrySize = 8;
TreFile::TreFile(char const* base, size_t length)
TreFile::TreFile(uint8_t const* base, size_t length)
: base_(base), length_(length)
{
if (length_ < 6*4)
@@ -66,7 +66,7 @@ TreFile::TreFile(char const* base, size_t length)
// Read table 3
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 length = readU32LE(entryBase+4)&0x0fffffffu;
@@ -119,7 +119,11 @@ TreFile::TreFile(char const* base, size_t length)
if (pos+nameLen+5 > header.table3Ofs)
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);
@@ -146,7 +150,7 @@ TreFile::TreFile(char const* base, size_t length)
// Read Table 1
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);
uint32_t table3Ptr = readU32LE(entryBase+4);

View File

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

View File

@@ -2,7 +2,7 @@
#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;

View File

@@ -9,6 +9,6 @@
/* LZ77-like format consisting of codes specifing copies from the input stream
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

16
util.cc
View File

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

14
util.hh
View File

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