New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AURORA: GFF3Writer #300

Closed
wants to merge 3 commits into
base: master
from

Conversation

2 participants
@Nostritius
Contributor

Nostritius commented Jun 19, 2018

I thought long about my first attempt on a gff3 writer, but ultimately decided that it would be better to write an external class for exporting gff3, since the internal structure of the GFF3File class makes it very difficult to modify values. Also it is difficult to get the necessary information for exporting in an easy way. This class is only for generating a gff3 tree and export it. I have made many unit tests and also tested it against the original kotor executable by replacing a simple file by one created by the writer, and it behaved as i expected.

@Nostritius Nostritius force-pushed the Nostritius:aurora_gff3writer branch 3 times, most recently from c7adebe to 29f5a1e Jun 19, 2018

@DrMcCoy

This comment has been minimized.

@Nostritius Nostritius force-pushed the Nostritius:aurora_gff3writer branch from 29f5a1e to 3fb0982 Jun 25, 2018

@Nostritius

This comment has been minimized.

Contributor

Nostritius commented Jun 25, 2018

The memory leaks should now be fixed.

} else {
// If the values are complex (greater then 4 bytes) write the index to the field data.
stream.writeUint32LE(fieldDataIndex);
switch (field.type) {

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 25, 2018

Member

Isn't that a repeat of lines 61ff?

Move that into a method getFieldSize() or something like that.

// Write labels.
for (size_t i = 0; i < _labels.size(); ++i) {
Common::UString label = _labels[i];

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 25, 2018

Member

Is that copy there necessary?

namespace Aurora {
GFF3Writer::GFF3Writer(uint32 id, uint32 version) : _id(id), _version(version) {
_structs.push_back(GFF3WriterStructPtr(new GFF3WriterStruct(this)));

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 25, 2018

Member

Can you use boost::make_shared instead of new'ing the struct into the shared_ptr (here and everywhere else as well)?

I.e. boost::make_shared<GFF3WriterStruct>(this) should be equivalent to boost::shared_ptr<GFF3WriterStruct>(new GFF3WriterStruct(this)), and gets rid of the explicit new.

* Determine if this field has simple values (less equal 32 bit) which are written in the field
* or complex values, bigger than 32bit like strings written in the field data section.
*/
bool simple =

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 25, 2018

Member

That's a const.

break;
case GFF3Struct::kFieldTypeResRef:
stream.writeByte(MIN(static_cast<byte>(16), static_cast<byte>(field.stringValue.size())));
stream.write(field.stringValue.c_str(), field.stringValue.size());

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 25, 2018

Member

You still might write a longer string than 16 bytes here

field.type = GFF3Struct::kFieldTypeByte;
field.labelIndex = _parent->addLabel(label);
field.uint32Value = value;
_parent->_fields.push_back(field);

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 25, 2018

Member

Lots of code duplication here in these methods. Creating the field index and adding the field, i.e. everything except setting the actual value, can be abstracted into a method.

@Nostritius Nostritius force-pushed the Nostritius:aurora_gff3writer branch from 3fb0982 to 9d15b0f Jun 25, 2018

@Nostritius

This comment has been minimized.

Contributor

Nostritius commented Jun 25, 2018

The issues should now be fixed

/** Write the LocString to a write stream. */
void writeLocString(Common::WriteStream &stream, bool withNullTerminate = false);
void writeLocString(Common::WriteStream &stream, bool withNullTerminate = false) const ;

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 26, 2018

Member

There's now an extra space between the const and the ;

// Insert the struct to the field vector.
_parent->_fields.push_back(field);

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 26, 2018

Member

Trailing whitespace

void GFF3WriterStruct::addByte(const Common::UString &label, byte value) {
size_t index = _parent->createField(GFF3Struct::kFieldTypeByte, label);
_parent->_fields[index].uint32Value = value;
_fieldIndices.push_back(index);

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 26, 2018

Member

I'd go even further. GFF3Writer::Field &GFF3WriterStruct::createField(GFF3Struct::FieldType type, const Common::UString &label). Calls _parent->createField(), put the index into _fieldIndices and returns a direct reference to the field.

Then you only need to do

createField(GFF3Struct::kFieldTypeByte, label).uint32Value = value;

etc. in each method.

class GFF3Writer {
public:
//TODO: Add a constructor consuming a GFF3File object.

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 26, 2018

Member

// TODO:

/** Get the toplevel struct. */
GFF3WriterStructPtr getTopLevelStruct();
/** Write the gff3 to stream. */

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 26, 2018

Member

Please, capitalize GFF and GFF3.

stringValue = field.stringValue;
locStringValue = field.locStringValue;
if (field.voidData.get() != 0) {

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 26, 2018

Member

You should still do an unconditional field.voidData.reset() before that. Otherwise, "a = b", with a.voidData filled and b.voidData empty will not empty a.voidData.

}
// Write fields.
unsigned int fieldDataIndex = 0;

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 26, 2018

Member

Why the move to unsigned int instead of size_t here?

}
}
uint32 GFF3Writer::getFieldDataSize(const Aurora::GFF3Writer::Field &field) {

This comment has been minimized.

@DrMcCoy

DrMcCoy Jun 26, 2018

Member

That can even be a static function in this file's scope. It doesn't need to be a method of GFF3Writer.

@Nostritius Nostritius force-pushed the Nostritius:aurora_gff3writer branch from 9d15b0f to 061090d Jun 27, 2018

@Nostritius Nostritius force-pushed the Nostritius:aurora_gff3writer branch from 061090d to c947e90 Jun 27, 2018

@Nostritius

This comment has been minimized.

Contributor

Nostritius commented Jun 27, 2018

The issues should now be fixed

@DrMcCoy DrMcCoy added this to File format writers in TODO: Standalone Jul 9, 2018

@DrMcCoy

This comment has been minimized.

Member

DrMcCoy commented Jul 26, 2018

Merged as 4971a26...da35c58, thanks! :)

@DrMcCoy DrMcCoy closed this Jul 26, 2018

@Nostritius Nostritius deleted the Nostritius:aurora_gff3writer branch Dec 8, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment