00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020
00021 #include "U8SaveFile.h"
00022 #include "IDataSource.h"
00023
00024 DEFINE_RUNTIME_CLASSTYPE_CODE(U8SaveFile,NamedArchiveFile);
00025
00026
00027 U8SaveFile::U8SaveFile(IDataSource* ds_)
00028 {
00029 ds = ds_;
00030 count = 0;
00031 valid = isU8SaveFile(ds);
00032
00033 if (valid)
00034 valid = readMetadata();
00035 }
00036
00037 U8SaveFile::~U8SaveFile()
00038 {
00039 delete ds;
00040 }
00041
00042
00043 bool U8SaveFile::isU8SaveFile(IDataSource* ds)
00044 {
00045 ds->seek(0);
00046 char buf[24];
00047 ds->read(buf, 23);
00048 buf[23] = '\0';
00049
00050 return (std::strncmp(buf, "Ultima 8 SaveGame File.", 23) == 0);
00051 }
00052
00053 bool U8SaveFile::readMetadata()
00054 {
00055 ds->seek(0x18);
00056 count = ds->read2();
00057
00058 offsets.resize(count);
00059 sizes.resize(count);
00060
00061 for (unsigned int i = 0; i < count; ++i)
00062 {
00063 uint32 namelen = ds->read4();
00064 char* buf = new char[namelen];
00065 ds->read(buf, static_cast<sint32>(namelen));
00066 std::string filename = buf;
00067 indices[filename] = i;
00068 storeIndexedName(filename);
00069 delete[] buf;
00070 sizes[i] = ds->read4();
00071 offsets[i] = ds->getPos();
00072 ds->skip(sizes[i]);
00073 }
00074
00075 return true;
00076 }
00077
00078 bool U8SaveFile::findIndex(const std::string& name, uint32& index)
00079 {
00080 std::map<std::string, uint32>::iterator iter;
00081 iter = indices.find(name);
00082 if (iter == indices.end()) return false;
00083 index = iter->second;
00084 return true;
00085 }
00086
00087 bool U8SaveFile::exists(const std::string& name)
00088 {
00089 uint32 index;
00090 return findIndex(name, index);
00091 }
00092
00093 uint8* U8SaveFile::getObject(const std::string& name, uint32* sizep)
00094 {
00095 uint32 index;
00096 if (!findIndex(name, index)) return 0;
00097
00098 uint32 size = sizes[index];
00099 if (size == 0) return 0;
00100
00101 uint8 *object = new uint8[size];
00102 uint32 offset = offsets[index];
00103
00104 ds->seek(offset);
00105 ds->read(object, size);
00106
00107 if (sizep) *sizep = size;
00108
00109 return object;
00110 }
00111
00112
00113 uint32 U8SaveFile::getSize(const std::string& name)
00114 {
00115 uint32 index;
00116 if (!findIndex(name, index)) return 0;
00117
00118 return sizes[index];
00119 }