mirror of
https://github.com/isledecomp/SIEdit.git
synced 2024-11-27 09:35:45 -05:00
lib: implement write functions for RIFF classes
This commit is contained in:
parent
6f8d3d500c
commit
4d05dc8ac8
5 changed files with 97 additions and 9 deletions
|
@ -8,9 +8,10 @@
|
|||
|
||||
namespace si {
|
||||
|
||||
Chunk::Chunk()
|
||||
Chunk::Chunk(uint32_t id) :
|
||||
id_(id),
|
||||
offset_(0)
|
||||
{
|
||||
id_ = 0;
|
||||
}
|
||||
|
||||
Chunk::~Chunk()
|
||||
|
@ -89,6 +90,40 @@ bool Chunk::Read(std::ifstream &f, uint32_t &version, uint32_t &alignment)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Chunk::Write(std::ofstream &f, const uint32_t &version) const
|
||||
{
|
||||
// Write 4-byte ID
|
||||
f.write((const char *) &id_, sizeof(id_));
|
||||
|
||||
// Write placeholder for size and store position so we can come back later
|
||||
uint32_t chunk_size = 0;
|
||||
std::ios::pos_type size_pos = f.tellp();
|
||||
f.write((const char *) &chunk_size, sizeof(chunk_size));
|
||||
|
||||
if (RIFF *writer = GetReaderFromType(type())) {
|
||||
writer->Write(f, data_, version);
|
||||
delete writer;
|
||||
}
|
||||
|
||||
for (Children::const_iterator it=GetChildren().begin(); it!=GetChildren().end(); it++) {
|
||||
static_cast<Chunk*>(*it)->Write(f, version);
|
||||
}
|
||||
|
||||
// Backtrack and write chunk size
|
||||
chunk_size = uint32_t(f.tellp()) - (uint32_t(size_pos) + sizeof(uint32_t));
|
||||
f.seekp(size_pos);
|
||||
f.write((const char *) &chunk_size, sizeof(chunk_size));
|
||||
f.seekp(0, std::ios::end);
|
||||
|
||||
// Byte align to 2
|
||||
if (chunk_size%2 == 1) {
|
||||
const char nothing = 0;
|
||||
f.write(¬hing, 1);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
RIFF *Chunk::GetReaderFromType(Type type)
|
||||
{
|
||||
switch (type) {
|
||||
|
@ -108,6 +143,8 @@ RIFF *Chunk::GetReaderFromType(Type type)
|
|||
return new pad_();
|
||||
case TYPE_MxOb:
|
||||
return new MxOb();
|
||||
case TYPE_MxDa:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -122,6 +159,23 @@ void Chunk::Clear()
|
|||
DeleteChildren();
|
||||
}
|
||||
|
||||
bool Chunk::Write(const std::string &f)
|
||||
{
|
||||
return Write(f.c_str());
|
||||
}
|
||||
|
||||
bool Chunk::Write(const char *f)
|
||||
{
|
||||
std::ofstream file(f, std::ios::out | std::ios::binary);
|
||||
if (!file.is_open() || !file.good()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t version = 0;
|
||||
|
||||
return Write(file, version);
|
||||
}
|
||||
|
||||
const char *Chunk::GetTypeDescription(Type type)
|
||||
{
|
||||
switch (type) {
|
||||
|
@ -141,6 +195,8 @@ const char *Chunk::GetTypeDescription(Type type)
|
|||
return "Padding";
|
||||
case TYPE_MxOb:
|
||||
return "Streamable Object";
|
||||
case TYPE_MxDa:
|
||||
return "Data";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
|
|
|
@ -24,16 +24,20 @@ public:
|
|||
TYPE_MxCh = 0x6843784d,
|
||||
TYPE_MxOf = 0x664f784d,
|
||||
TYPE_MxOb = 0x624f784d,
|
||||
TYPE_MxDa = 0x6144784d,
|
||||
TYPE_pad_ = 0x20646170
|
||||
};
|
||||
|
||||
LIBWEAVER_EXPORT Chunk();
|
||||
LIBWEAVER_EXPORT Chunk(uint32_t id = 0);
|
||||
virtual LIBWEAVER_EXPORT ~Chunk();
|
||||
|
||||
LIBWEAVER_EXPORT bool Read(const std::string &f);
|
||||
LIBWEAVER_EXPORT bool Read(const char *f);
|
||||
LIBWEAVER_EXPORT void Clear();
|
||||
|
||||
LIBWEAVER_EXPORT bool Write(const std::string &f);
|
||||
LIBWEAVER_EXPORT bool Write(const char *f);
|
||||
|
||||
LIBWEAVER_EXPORT Type type() const { return static_cast<Type>(id_); }
|
||||
LIBWEAVER_EXPORT const uint32_t &id() const { return id_; }
|
||||
LIBWEAVER_EXPORT const uint32_t &offset() const { return offset_; }
|
||||
|
@ -52,6 +56,7 @@ public:
|
|||
|
||||
private:
|
||||
bool Read(std::ifstream &f, uint32_t &version, uint32_t &alignment);
|
||||
bool Write(std::ofstream &f, const uint32_t &version) const;
|
||||
|
||||
static RIFF *GetReaderFromType(Type type);
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@ void WriteString(std::ofstream &os, const std::string &d)
|
|||
const char *s = &d[0];
|
||||
while ((*s) != 0) {
|
||||
os.write(s, 1);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -186,15 +187,19 @@ void MxOf::Write(std::ofstream &os, const DataMap &data, uint32_t version)
|
|||
|
||||
void pad_::Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size)
|
||||
{
|
||||
data["Size"] = size;
|
||||
is.seekg(size, std::ios::cur);
|
||||
}
|
||||
|
||||
void pad_::WritePadding(std::ofstream &os, size_t size)
|
||||
void pad_::Write(std::ofstream &os, const DataMap &data, uint32_t version)
|
||||
{
|
||||
bytearray b;
|
||||
b.resize(size);
|
||||
b.fill(0xCD);
|
||||
WriteBytes(os, b);
|
||||
uint32_t sz = data.at("Size").toU32();
|
||||
if (sz > 0) {
|
||||
bytearray b;
|
||||
b.resize(sz);
|
||||
b.fill(0xCD);
|
||||
WriteBytes(os, b);
|
||||
}
|
||||
}
|
||||
|
||||
const char *MxOb::GetTypeName(Type type)
|
||||
|
|
|
@ -18,6 +18,10 @@ namespace si {
|
|||
class RIFF
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
OMNI = 0x494e4d4f
|
||||
};
|
||||
|
||||
virtual ~RIFF(){}
|
||||
|
||||
virtual void Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size);
|
||||
|
@ -81,6 +85,13 @@ public:
|
|||
class MxCh : public RIFF
|
||||
{
|
||||
public:
|
||||
enum Flag {
|
||||
FLAG_SPLIT = 0x16,
|
||||
FLAG_END = 0x2
|
||||
};
|
||||
|
||||
static const uint32_t HEADER_SIZE = 14;
|
||||
|
||||
virtual void Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size);
|
||||
virtual void Write(std::ofstream &os, const DataMap &data, uint32_t version);
|
||||
};
|
||||
|
@ -110,7 +121,7 @@ class pad_ : public RIFF
|
|||
{
|
||||
public:
|
||||
virtual void Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size);
|
||||
void WritePadding(std::ofstream &os, size_t size);
|
||||
virtual void Write(std::ofstream &os, const DataMap &data, uint32_t version);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -146,6 +157,10 @@ class MxOb : public RIFF
|
|||
public:
|
||||
enum Type
|
||||
{
|
||||
/// Not an MxOb type, this is our identifier for an object that is in the TOC but doesn't
|
||||
/// actually exist
|
||||
Null = -1,
|
||||
|
||||
/// Video
|
||||
Video = 0x03,
|
||||
|
||||
|
@ -202,6 +217,9 @@ public:
|
|||
|
||||
/// Bitmap image
|
||||
STL = 0x4C545320,
|
||||
|
||||
/// FLIC animation
|
||||
FLC = 0x434c4620,
|
||||
};
|
||||
|
||||
// FIXME: sitypes.h probably won't be part of the public API, so this should
|
||||
|
|
|
@ -26,6 +26,10 @@ class bytearray : public std::vector<char>
|
|||
{
|
||||
public:
|
||||
bytearray(){}
|
||||
bytearray(size_t size)
|
||||
{
|
||||
resize(size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T *cast() { return reinterpret_cast<T*>(data()); }
|
||||
|
|
Loading…
Reference in a new issue