mirror of
https://github.com/GerbilSoft/mst06.git
synced 2025-06-18 19:45:32 -04:00
Mst: Added overloads that take FILE* instead of a filename.
main.cpp: Use these overloads.
This commit is contained in:
parent
490bfe1413
commit
c2014f11e1
103
src/Mst.cpp
103
src/Mst.cpp
@ -25,8 +25,14 @@
|
||||
|
||||
// C includes. (C++ namespace)
|
||||
#include <cerrno>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define fseeko(stream, offset, whence) _fseeki64((stream), (offset), (whence))
|
||||
# define ftello(stream) _ftelli64(stream)
|
||||
#endif
|
||||
|
||||
// C++ includes.
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@ -61,6 +67,27 @@ int Mst::loadMST(const TCHAR *filename)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
FILE *f_mst = _tfopen(filename, _T("rb"));
|
||||
if (!f_mst) {
|
||||
// Error opening the file.
|
||||
return -errno;
|
||||
}
|
||||
int ret = loadMST(f_mst);
|
||||
fclose(f_mst);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an MST string table.
|
||||
* @param fp MST string table file.
|
||||
* @return 0 on success; negative POSIX error code on error.
|
||||
*/
|
||||
int Mst::loadMST(FILE *fp)
|
||||
{
|
||||
if (!fp) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int err;
|
||||
|
||||
// Clear the current string tables.
|
||||
@ -68,26 +95,18 @@ int Mst::loadMST(const TCHAR *filename)
|
||||
m_vStrTbl.clear();
|
||||
m_vStrLkup.clear();
|
||||
|
||||
FILE *f_mst = _tfopen(filename, _T("rb"));
|
||||
if (!f_mst) {
|
||||
// Error opening the file.
|
||||
return -errno;
|
||||
}
|
||||
|
||||
// Read the MST header.
|
||||
MST_Header mst;
|
||||
size_t size = fread(&mst, 1, sizeof(mst), f_mst);
|
||||
size_t size = fread(&mst, 1, sizeof(mst), fp);
|
||||
if (size != sizeof(mst)) {
|
||||
// Read error.
|
||||
// TODO: Store more comprehensive error information.
|
||||
fclose(f_mst);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
// Check the BINA magic number.
|
||||
if (mst.bina_magic != cpu_to_be32(BINA_MAGIC)) {
|
||||
// TODO: Store more comprehensive error information.
|
||||
fclose(f_mst);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -95,7 +114,6 @@ int Mst::loadMST(const TCHAR *filename)
|
||||
if (mst.version != '1' || (mst.endianness != 'B' && mst.endianness != 'L')) {
|
||||
// Unsupported version and/or invalid endianness.
|
||||
// TODO: Store more comprehensive error information.
|
||||
fclose(f_mst);
|
||||
return -EIO;
|
||||
}
|
||||
m_version = 1;
|
||||
@ -115,12 +133,10 @@ int Mst::loadMST(const TCHAR *filename)
|
||||
if (mst.file_size < sizeof(MST_Header) + sizeof(WTXT_Header) + sizeof(WTXT_MsgPointer)) {
|
||||
// Sanity check: File is too small.
|
||||
// TODO: Store more comprehensive error information.
|
||||
fclose(f_mst);
|
||||
return -EIO;
|
||||
} else if (mst.file_size > 16U*1024*1024) {
|
||||
// Sanity check: Must be 16 MB or less.
|
||||
// TODO: Store more comprehensive error information.
|
||||
fclose(f_mst);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -128,17 +144,17 @@ int Mst::loadMST(const TCHAR *filename)
|
||||
if ((uint64_t)sizeof(MST_Header) + (uint64_t)mst.doff_tbl_offset + (uint64_t)mst.doff_tbl_length > mst.file_size) {
|
||||
// Offset table error.
|
||||
// TODO: Store more comprehensive error information.
|
||||
fclose(f_mst);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
// Read the entire file.
|
||||
// NOTE: Using a relative seek in case the file pointer was set by
|
||||
// the caller to not be at the beginning of the file.
|
||||
unique_ptr<uint8_t[]> mst_data(new uint8_t[mst.file_size]);
|
||||
rewind(f_mst);
|
||||
fseeko(fp, -(off_t)(sizeof(mst)), SEEK_CUR);
|
||||
errno = 0;
|
||||
size = fread(mst_data.get(), 1, mst.file_size, f_mst);
|
||||
size = fread(mst_data.get(), 1, mst.file_size, fp);
|
||||
err = errno;
|
||||
fclose(f_mst);
|
||||
if (size != mst.file_size) {
|
||||
// Short read.
|
||||
// TODO: Store more comprehensive error information.
|
||||
@ -348,22 +364,37 @@ int Mst::loadXML(const TCHAR *filename, std::vector<std::string> *pVecErrs)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// Clear the current string tables.
|
||||
m_name.clear();
|
||||
m_vStrTbl.clear();
|
||||
m_vStrLkup.clear();
|
||||
|
||||
// Open the XML document.
|
||||
FILE *f_xml = _tfopen(filename, _T("r"));
|
||||
if (!f_xml) {
|
||||
// Error opening the XML document.
|
||||
return -errno;
|
||||
}
|
||||
int ret = loadXML(f_xml, pVecErrs);
|
||||
fclose(f_xml);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an XML string table.
|
||||
* @param fp [in] XML file.
|
||||
* @param pVecErrs [out,opt] Vector of user-readable error messages.
|
||||
* @return 0 on success; negative POSIX error code or positive TinyXML2 error code on error.
|
||||
*/
|
||||
int Mst::loadXML(FILE *fp, std::vector<std::string> *pVecErrs)
|
||||
{
|
||||
if (!fp) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// Clear the current string tables.
|
||||
m_name.clear();
|
||||
m_vStrTbl.clear();
|
||||
m_vStrLkup.clear();
|
||||
|
||||
// Parse the XML document.
|
||||
XMLDocument xml;
|
||||
int ret = xml.LoadFile(f_xml);
|
||||
fclose(f_xml);
|
||||
int ret = xml.LoadFile(fp);
|
||||
if (ret != 0) {
|
||||
// Error parsing the XML document.
|
||||
if (pVecErrs) {
|
||||
@ -515,6 +546,23 @@ int Mst::saveXML(const TCHAR *filename) const
|
||||
return -ENODATA; // TODO: Better error code?
|
||||
}
|
||||
|
||||
FILE *f_xml = _tfopen(filename, _T("w"));
|
||||
if (!f_xml) {
|
||||
// Error opening the XML file.
|
||||
return -errno;
|
||||
}
|
||||
int ret = saveXML(f_xml);
|
||||
fclose(f_xml);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the string table as XML.
|
||||
* @param fp XML file.
|
||||
* @return 0 on success; negative POSIX error code or positive TinyXML2 error code on error.
|
||||
*/
|
||||
int Mst::saveXML(FILE *fp) const
|
||||
{
|
||||
// Create an XML document.
|
||||
XMLDocument xml;
|
||||
XMLDeclaration *const xml_decl = xml.NewDeclaration();
|
||||
@ -536,15 +584,8 @@ int Mst::saveXML(const TCHAR *filename) const
|
||||
|
||||
// Save the XML document.
|
||||
// NOTE: Using our custom XMLPrinter for tabs instead of spaces.
|
||||
FILE *f_xml = _tfopen(filename, _T("w"));
|
||||
if (!f_xml) {
|
||||
// Error opening the XML file.
|
||||
return -errno;
|
||||
}
|
||||
|
||||
MstXMLPrinter stream(f_xml, false);
|
||||
MstXMLPrinter stream(fp, false);
|
||||
xml.Print(&stream);
|
||||
fclose(f_xml);
|
||||
return xml.ErrorID();
|
||||
}
|
||||
|
||||
|
26
src/Mst.hpp
26
src/Mst.hpp
@ -23,6 +23,10 @@
|
||||
|
||||
#include "tcharx.h"
|
||||
|
||||
// C includes. (C++ namespace)
|
||||
#include <cstdio>
|
||||
|
||||
// C++ includes.
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -46,6 +50,13 @@ class Mst
|
||||
*/
|
||||
int loadMST(const TCHAR *filename);
|
||||
|
||||
/**
|
||||
* Load an MST string table.
|
||||
* @param fp MST string table file.
|
||||
* @return 0 on success; negative POSIX error code on error.
|
||||
*/
|
||||
int loadMST(FILE *fp);
|
||||
|
||||
/**
|
||||
* Load an XML string table.
|
||||
* @param filename [in] XML filename.
|
||||
@ -54,6 +65,14 @@ class Mst
|
||||
*/
|
||||
int loadXML(const TCHAR *filename, std::vector<std::string> *pVecErrs = nullptr);
|
||||
|
||||
/**
|
||||
* Load an XML string table.
|
||||
* @param fp [in] XML file.
|
||||
* @param pVecErrs [out,opt] Vector of user-readable error messages.
|
||||
* @return 0 on success; negative POSIX error code or positive TinyXML2 error code on error.
|
||||
*/
|
||||
int loadXML(FILE *fp, std::vector<std::string> *pVecErrs = nullptr);
|
||||
|
||||
/**
|
||||
* Save the string table as XML.
|
||||
* @param filename XML filename.
|
||||
@ -61,6 +80,13 @@ class Mst
|
||||
*/
|
||||
int saveXML(const TCHAR *filename) const;
|
||||
|
||||
/**
|
||||
* Save the string table as XML.
|
||||
* @param fp XML file.
|
||||
* @return 0 on success; negative POSIX error code or positive TinyXML2 error code on error.
|
||||
*/
|
||||
int saveXML(FILE *fp) const;
|
||||
|
||||
public:
|
||||
// TODO: Save MST, Load XML
|
||||
// TODO: Iterator and mutator functions.
|
||||
|
10
src/main.cpp
10
src/main.cpp
@ -52,7 +52,6 @@ int _tmain(int argc, TCHAR *argv[])
|
||||
}
|
||||
|
||||
// Open the file and check if it's MST or XML.
|
||||
// TODO: loadMST() overload for FILE*.
|
||||
FILE *f_in = _tfopen(argv[1], _T("rb"));
|
||||
if (!f_in) {
|
||||
_ftprintf(stderr, _T("*** ERROR opening %s: %s\n"), argv[1], _tcserror(errno));
|
||||
@ -63,12 +62,12 @@ int _tmain(int argc, TCHAR *argv[])
|
||||
errno = 0;
|
||||
size_t size = fread(buf, 1, sizeof(buf), f_in);
|
||||
int err = errno;
|
||||
fclose(f_in);
|
||||
if (size != sizeof(buf)) {
|
||||
if (err == 0) err = EIO;
|
||||
_ftprintf(stderr, _T("*** ERROR reading file %s: %s\n"), argv[1], _tcserror(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
rewind(f_in);
|
||||
|
||||
Mst mst;
|
||||
int ret;
|
||||
@ -81,15 +80,18 @@ int _tmain(int argc, TCHAR *argv[])
|
||||
// Parse as XML and convert to MST.
|
||||
out_ext = _T(".mst");
|
||||
writeMST = true;
|
||||
ret = mst.loadXML(argv[1]);
|
||||
ret = mst.loadXML(f_in);
|
||||
fclose(f_in);
|
||||
} else if (!memcmp(&buf[0x18], "BINA", 4)) {
|
||||
// This is an MST file.
|
||||
// Parse as MST and convert to XML.
|
||||
out_ext = _T(".xml");
|
||||
writeXML = true;
|
||||
ret = mst.loadMST(argv[1]);
|
||||
ret = mst.loadMST(f_in);
|
||||
fclose(f_in);
|
||||
} else {
|
||||
// Unrecognized file format.
|
||||
fclose(f_in);
|
||||
_ftprintf(stderr, _T("*** ERROR: File %s is not recognized.\n"), argv[1]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user