1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-04-01 04:20:20 +00:00

various ESMWriter fixes

This commit is contained in:
Marc Zinnschlag 2013-09-15 14:55:40 +02:00
parent 8326ac9b6f
commit bcd36bd378
3 changed files with 262 additions and 256 deletions

View File

@ -2,19 +2,18 @@
#include <cassert> #include <cassert>
#include <fstream> #include <fstream>
#include <iostream> #include <stdexcept>
bool count = true;
namespace ESM namespace ESM
{ {
ESMWriter::ESMWriter() : mRecordCount (0), mCounting (false) {}
int ESMWriter::getVersion() unsigned int ESMWriter::getVersion() const
{ {
return mHeader.mData.version; return mHeader.mData.version;
} }
void ESMWriter::setVersion(int ver) void ESMWriter::setVersion(unsigned int ver)
{ {
mHeader.mData.version = ver; mHeader.mData.version = ver;
} }
@ -55,8 +54,9 @@ void ESMWriter::save(const std::string& file)
void ESMWriter::save(std::ostream& file) void ESMWriter::save(std::ostream& file)
{ {
m_recordCount = 0; mRecordCount = 0;
m_stream = &file; mRecords.clear();
mStream = &file;
startRecord("TES3", 0); startRecord("TES3", 0);
@ -67,27 +67,25 @@ void ESMWriter::save(std::ostream& file)
void ESMWriter::close() void ESMWriter::close()
{ {
m_stream->flush(); if (!mRecords.empty())
throw std::runtime_error ("Unclosed record remaining");
if (!m_records.empty())
throw "Unclosed record remaining";
} }
void ESMWriter::startRecord(const std::string& name, uint32_t flags) void ESMWriter::startRecord(const std::string& name, uint32_t flags)
{ {
m_recordCount++; mRecordCount++;
writeName(name); writeName(name);
RecordData rec; RecordData rec;
rec.name = name; rec.name = name;
rec.position = m_stream->tellp(); rec.position = mStream->tellp();
rec.size = 0; rec.size = 0;
writeT<int>(0); // Size goes here writeT<int>(0); // Size goes here
writeT<int>(0); // Unused header? writeT<int>(0); // Unused header?
writeT(flags); writeT(flags);
m_records.push_back(rec); mRecords.push_back(rec);
assert(m_records.back().size == 0); assert(mRecords.back().size == 0);
} }
void ESMWriter::startSubRecord(const std::string& name) void ESMWriter::startSubRecord(const std::string& name)
@ -95,27 +93,27 @@ void ESMWriter::startSubRecord(const std::string& name)
writeName(name); writeName(name);
RecordData rec; RecordData rec;
rec.name = name; rec.name = name;
rec.position = m_stream->tellp(); rec.position = mStream->tellp();
rec.size = 0; rec.size = 0;
writeT<int>(0); // Size goes here writeT<int>(0); // Size goes here
m_records.push_back(rec); mRecords.push_back(rec);
assert(m_records.back().size == 0); assert(mRecords.back().size == 0);
} }
void ESMWriter::endRecord(const std::string& name) void ESMWriter::endRecord(const std::string& name)
{ {
RecordData rec = m_records.back(); RecordData rec = mRecords.back();
assert(rec.name == name); assert(rec.name == name);
m_records.pop_back(); mRecords.pop_back();
m_stream->seekp(rec.position); mStream->seekp(rec.position);
count = false; mCounting = false;
write((char*)&rec.size, sizeof(int)); write (reinterpret_cast<const char*> (&rec.size), sizeof(int));
count = true; mCounting = true;
m_stream->seekp(0, std::ios::end); mStream->seekp(0, std::ios::end);
} }
@ -148,7 +146,7 @@ void ESMWriter::writeHString(const std::string& data)
else else
{ {
// Convert to UTF8 and return // Convert to UTF8 and return
std::string ascii = m_encoder->getLegacyEnc(data); std::string ascii = mEncoder->getLegacyEnc(data);
write(ascii.c_str(), ascii.size()); write(ascii.c_str(), ascii.size());
} }
@ -169,18 +167,17 @@ void ESMWriter::writeName(const std::string& name)
void ESMWriter::write(const char* data, size_t size) void ESMWriter::write(const char* data, size_t size)
{ {
if (count && !m_records.empty()) if (mCounting && !mRecords.empty())
{ {
for (std::list<RecordData>::iterator it = m_records.begin(); it != m_records.end(); ++it) for (std::list<RecordData>::iterator it = mRecords.begin(); it != mRecords.end(); ++it)
it->size += size; it->size += size;
} }
m_stream->write(data, size); mStream->write(data, size);
} }
void ESMWriter::setEncoder(ToUTF8::Utf8Encoder* encoder) void ESMWriter::setEncoder(ToUTF8::Utf8Encoder* encoder)
{ {
m_encoder = encoder; mEncoder = encoder;
} }
} }

View File

@ -21,9 +21,12 @@ class ESMWriter
}; };
public: public:
int getVersion();
void setVersion(int ver); ESMWriter();
void setEncoder(ToUTF8::Utf8Encoder *encoding); // Write strings as UTF-8?
unsigned int getVersion() const;
void setVersion(unsigned int ver = 0x3fa66666);
void setEncoder(ToUTF8::Utf8Encoder *encoding);
void setAuthor(const std::string& author); void setAuthor(const std::string& author);
void setDescription(const std::string& desc); void setDescription(const std::string& desc);
void setRecordCount (int count); void setRecordCount (int count);
@ -32,8 +35,13 @@ public:
void addMaster(const std::string& name, uint64_t size); void addMaster(const std::string& name, uint64_t size);
void save(const std::string& file); void save(const std::string& file);
///< Start saving a file by writing the TES3 header.
void save(std::ostream& file); void save(std::ostream& file);
///< Start saving a file by writing the TES3 header.
void close(); void close();
///< \note Does not close the stream.
void writeHNString(const std::string& name, const std::string& data); void writeHNString(const std::string& name, const std::string& data);
void writeHNString(const std::string& name, const std::string& data, size_t size); void writeHNString(const std::string& name, const std::string& data, size_t size);
@ -91,14 +99,15 @@ public:
void write(const char* data, size_t size); void write(const char* data, size_t size);
private: private:
std::list<RecordData> m_records; std::list<RecordData> mRecords;
std::ostream* m_stream; std::ostream* mStream;
std::streampos m_headerPos; std::streampos mHeaderPos;
ToUTF8::Utf8Encoder* m_encoder; ToUTF8::Utf8Encoder* mEncoder;
int m_recordCount; int mRecordCount;
bool mCounting;
Header mHeader; Header mHeader;
}; };
} }
#endif #endif

View File

@ -24,7 +24,7 @@ namespace ESM
versions are 1.2 and 1.3. These correspond to: versions are 1.2 and 1.3. These correspond to:
1.2 = 0x3f99999a and 1.3 = 0x3fa66666 1.2 = 0x3f99999a and 1.3 = 0x3fa66666
*/ */
int version; unsigned int version;
int type; // 0=esp, 1=esm, 32=ess (unused) int type; // 0=esp, 1=esm, 32=ess (unused)
NAME32 author; // Author's name NAME32 author; // Author's name
NAME256 desc; // File description NAME256 desc; // File description