Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
DrMcCoy committed Mar 3, 2016
1 parent 085d5ff commit 51e38bf
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 35 deletions.
57 changes: 28 additions & 29 deletions src/aurora/gff3file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,13 @@ void GFF3File::loadLists() {
listCount++;
}

_listOffsetToUID.resize(rawLists.size(), 0xFFFFFFFF);
std::vector<uint32> listOffsetToUID(rawLists.size(), 0xFFFFFFFF);

// Converting the raw list array into real, usable lists
for (size_t i = 0; i < rawLists.size(); ) {
const uint32 listUID = _nextListUID++;

_listOffsetToUID[i] = listUID;
listOffsetToUID[i] = listUID;

const uint32 n = rawLists[i++];
if ((i + n) > rawLists.size())
Expand All @@ -279,28 +279,14 @@ void GFF3File::loadLists() {

_lists.insert(std::make_pair(listUID, GFF3List(*this, listUID, list)));
}

// Structs reference lists by offset, not UID. Let's fix that
for (StructMap::iterator s = _structs.begin(); s != _structs.end(); ++s)
s->second->fixupListUIDs(listOffsetToUID);
}

// --- Helpers for GFF3Struct ---

uint32 GFF3File::getListUID(uint32 offset) const {
if ((offset % 4) != 0)
throw Common::Exception("GFF3: Invalid list offset");

offset /= 4;

if (offset >= _listOffsetToUID.size())
throw Common::Exception("GFF3: List offset out of range (%u >= %u)",
offset, (uint) _listOffsetToUID.size());

const uint32 listUID = _listOffsetToUID[offset];

if (listUID == 0xFFFFFFFF)
throw Common::Exception("GFF3: Empty list at %u", offset);

return listUID;
}

const GFF3Struct &GFF3File::getStruct(uint32 uid) const {
StructMap::const_iterator strct = _structs.find(uid);
if ((strct == _structs.end()) || !strct->second)
Expand Down Expand Up @@ -510,6 +496,25 @@ Common::UString GFF3Struct::readLabel(Common::SeekableReadStream &data, uint32 i
return Common::readStringFixed(data, Common::kEncodingASCII, 16);
}

void GFF3Struct::fixupListUIDs(const std::vector<uint32> &listOffsetToUID) {
for (FieldMap::iterator f = _fields.begin(); f != _fields.end(); ++f) {
if (f->second.type != kFieldTypeList)
continue;

if ((f->second.data % 4) != 0)
throw Common::Exception("GFF3: Invalid list offset");

const size_t offset = f->second.data / 4;
if (offset >= listOffsetToUID.size())
throw Common::Exception("GFF3: List offset out of range (%u >= %u)",
(uint) offset, (uint) listOffsetToUID.size());

f->second.data = listOffsetToUID[offset];
if (f->second.data == 0xFFFFFFFF)
throw Common::Exception("GFF3: Empty list at %u", (uint) offset);
}
}

Common::SeekableReadStream &GFF3Struct::getData(const Field &field) const {
assert(field.extended);

Expand Down Expand Up @@ -872,9 +877,7 @@ const GFF3List &GFF3Struct::getList(const Common::UString &field) const {
if (f->type != kFieldTypeList)
throw Common::Exception("GFF3: Field is not a list type");

const uint32 uid = f->ownData ? f->data : _parent->getListUID(f->data);

return _parent->getList(uid);
return _parent->getList(f->data);
}

// --- Field adding and deleting ---
Expand Down Expand Up @@ -990,9 +993,7 @@ void GFF3Struct::removeList(const Common::UString &field) {
if (f->second.type != kFieldTypeList)
throw Common::Exception("GFF3: Field is not a list type");

const uint32 uid = f->second.ownData ? f->second.data : _parent->getListUID(f->second.data);

GFF3List &list = _parent->getList(uid);
GFF3List &list = _parent->getList(f->second.data);

list.destroy();
_parent->destroyList(list);
Expand Down Expand Up @@ -1310,9 +1311,7 @@ void GFF3Struct::destroy() {

} else if (i->second.type == kFieldTypeList) {

const uint32 uid = i->second.ownData ? i->second.data : _parent->getListUID(i->second.data);

GFF3List &list = _parent->getList(uid);
GFF3List &list = _parent->getList(i->second.data);

list.destroy();

Expand Down
8 changes: 2 additions & 6 deletions src/aurora/gff3file.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@ class GFF3File : public AuroraFile {
StructMap _structs; ///< Our structs.
ListMap _lists; ///< Our lists.

/** To convert list offsets found in GFF3 to list UIDs. */
std::vector<uint32> _listOffsetToUID;

/** The unique ID to give the next struct. */
uint32 _nextStructUID;
/** The unique ID to give the next list. */
Expand All @@ -163,9 +160,6 @@ class GFF3File : public AuroraFile {
/** Return the GFF3 stream seeked to the start of the field data. */
Common::SeekableReadStream &getFieldData() const;

/** Return the list UID from a list offset found in a GFF3 field. */
uint32 getListUID(uint32 offset) const;

/** Return a struct within the GFF3. */
const GFF3Struct &getStruct(uint32 uid) const;
/** Return a list within the GFF3. */
Expand Down Expand Up @@ -373,6 +367,8 @@ class GFF3Struct {
std::vector<uint32> &indices, uint32 count) const;

Common::UString readLabel(Common::SeekableReadStream &data, uint32 index) const;

void fixupListUIDs(const std::vector<uint32> &listOffsetToUID);
// '---

// .--- Field and field data accessors
Expand Down

0 comments on commit 51e38bf

Please sign in to comment.