private GFFObject[] ReadList(long offset) { long pos = file.Position; file.Position = lioffset + offset; //read the size of the list byte[] buffer = new byte[DWORD_SIZE]; file.Read(buffer, 0, buffer.Length); uint count = BitConverter.ToUInt32(buffer, 0); //read the elements of the list (each being 1 uint index into the struct array) buffer = new byte[DWORD_SIZE * count]; file.Read(buffer, 0, buffer.Length); file.Position = pos; GFFObject[] structs = new GFFObject[count]; for (int i = 0, j = 0; i < count; i++, j += DWORD_SIZE) { GFFStructDef def = ReadStruct(BitConverter.ToUInt32(buffer, j)); structs[i] = new GFFObject(null, GFFObject.FieldType.Struct, def.structValue, def.structID); } return(structs); }
public GFFLoader(Stream file) { this.file = file; //read the file type and version byte[] buffer = new byte[DWORD_SIZE * 14]; file.Read(buffer, 0, DWORD_SIZE * 14); string filetype = Encoding.ASCII.GetString(buffer, 0, 4); string filever = Encoding.ASCII.GetString(buffer, 4, 4); //get the offset to and number of structs in the file structoffset = BitConverter.ToUInt32(buffer, 8); structcount = BitConverter.ToInt32(buffer, 12); //get the offset to and number of fields in the file fieldoffset = BitConverter.ToUInt32(buffer, 16); fieldcount = BitConverter.ToInt32(buffer, 20); //get the offset to and number of labels in the file labeloffset = BitConverter.ToUInt32(buffer, 24); labelcount = BitConverter.ToInt32(buffer, 28); //get the offset to and number of field data in the file fdoffset = BitConverter.ToUInt32(buffer, 32); fdcount = BitConverter.ToInt32(buffer, 36); //get the offset to and number of field indices in the file fioffset = BitConverter.ToUInt32(buffer, 40); ficount = BitConverter.ToInt32(buffer, 44); //get the offset to and number of list indices in the file lioffset = BitConverter.ToUInt32(buffer, 48); licount = BitConverter.ToInt32(buffer, 52); //read the top level struct, recursively reading the file GFFStructDef def = ReadStruct(0); TopStruct = new GFFObject(null, GFFObject.FieldType.Struct, def.structValue, def.structID); }
private GFFObject ReadField(uint index) { //fields are returned as a tuple (label, data) for ease of parsing long pos = file.Position; file.Position = fieldoffset + (index * DWORD_SIZE * 3); byte[] buffer = new byte[DWORD_SIZE * 3]; file.Read(buffer, 0, DWORD_SIZE * 3); string label = ReadLabel(BitConverter.ToUInt32(buffer, 4)); //label = label.Replace(" ", ""); file.Position = pos; GFFObject.FieldType type = (GFFObject.FieldType)BitConverter.ToUInt32(buffer, 0); switch (type) { case GFFObject.FieldType.Byte: return(new GFFObject(label, type, buffer[8])); case GFFObject.FieldType.Char: return(new GFFObject(label, type, (char)buffer[8])); case GFFObject.FieldType.Word: return(new GFFObject(label, type, BitConverter.ToUInt16(buffer, 8))); case GFFObject.FieldType.Short: return(new GFFObject(label, type, BitConverter.ToInt16(buffer, 8))); case GFFObject.FieldType.DWord: return(new GFFObject(label, type, BitConverter.ToUInt32(buffer, 8))); case GFFObject.FieldType.Int: return(new GFFObject(label, type, BitConverter.ToInt32(buffer, 8))); case GFFObject.FieldType.DWord64: return(new GFFObject(label, type, ReadUInt64(BitConverter.ToUInt32(buffer, 8)))); case GFFObject.FieldType.Int64: return(new GFFObject(label, type, ReadInt64(BitConverter.ToUInt32(buffer, 8)))); case GFFObject.FieldType.Float: return(new GFFObject(label, type, BitConverter.ToSingle(buffer, 8))); case GFFObject.FieldType.Double: return(new GFFObject(label, type, ReadDouble(BitConverter.ToUInt32(buffer, 8)))); case GFFObject.FieldType.CExoString: return(new GFFObject(label, type, ReadString(BitConverter.ToUInt32(buffer, 8)))); case GFFObject.FieldType.ResRef: return(new GFFObject(label, type, ReadResRef(BitConverter.ToUInt32(buffer, 8)))); case GFFObject.FieldType.CExoLocString: return(new GFFObject(label, type, ReadLocalizedString(BitConverter.ToUInt32(buffer, 8)))); case GFFObject.FieldType.Void: return(new GFFObject(label, type, ReadBytes(BitConverter.ToUInt32(buffer, 8)))); case GFFObject.FieldType.Struct: GFFStructDef def = ReadStruct(BitConverter.ToUInt32(buffer, 8)); return(new GFFObject(label, type, def.structValue, def.structID)); case GFFObject.FieldType.List: return(new GFFObject(label, type, ReadList(BitConverter.ToUInt32(buffer, 8)))); case GFFObject.FieldType.Quaternion: return(new GFFObject(label, type, ReadQuaternion(BitConverter.ToUInt32(buffer, 8)))); case GFFObject.FieldType.Vector3: return(new GFFObject(label, type, ReadVector3(BitConverter.ToUInt32(buffer, 8)))); default: Debug.LogWarningFormat("{0} has unknown GFF type ID: {1}", label, type); return(new GFFObject(label, type, null)); } }