public void Import(GenericKeyValue root) { this.Data = new MemoryStream(); this.FileVersion = 0; long newOffset = this.Structures[0].DataSize; this.ImportStructure(this.Structures[0], root, 0, ref newOffset, new ImportState()); }
private void ImportStructure(GFF.StructureDefinition def, GenericKeyValue data, long offset, ref long newOffset, ImportState state) { foreach (var fieldDef in def.Fields) { if (fieldDef.Id == 16208) { } GenericKeyValue value; if (data.Values.ContainsKey(fieldDef.Id) == false) { //throw new InvalidOperationException(); value = new GenericKeyValue(fieldDef.Type, null); } else { value = data[fieldDef.Id]; } this.ImportField(fieldDef, value, offset, ref newOffset, state); } }
private GenericKeyValue ExportStructure(GFF.StructureDefinition def, long offset, ExportState state) { var kv = new GenericKeyValue(GFF.FieldType.Structure, null); kv.StructureId = def.Id; foreach (var fieldDef in def.Fields) { var value = this.ExportField(fieldDef, offset, state); if (value is GenericKeyValue) { kv[fieldDef.Id] = (GenericKeyValue)value; } else { kv[fieldDef.Id] = new GenericKeyValue(fieldDef.Type, value); } } return(kv); }
private void ImportField(GFF.FieldDefinition def, GenericKeyValue data, long offset, ref long newOffset, ImportState state) { var endian = this.Endian; var output = this.Data; output.Seek(offset + def.Offset, SeekOrigin.Begin); if (def.IsList == true) { if (def.IsReference == true && (data.Value != null || def.Type != GFF.FieldType.Generic)) { throw new NotSupportedException(); } var list = (IList)data.Value; if (list == null) { output.WriteValueU32(0xFFFFFFFF, endian); } else { output.WriteValueU32((uint)newOffset, endian); output.Seek(newOffset, SeekOrigin.Begin); output.WriteValueS32(list.Count, endian); newOffset += 4; uint itemSize; if (def.Type == GFF.FieldType.Structure) { var subdef = this.Structures[def.StructureId]; itemSize = subdef.DataSize; } else { itemSize = GFF.Builtin.SizeOf(def.Type); } newOffset += list.Count * itemSize; switch (def.Type) { case GFF.FieldType.String: { throw new NotImplementedException(); } case GFF.FieldType.Structure: { var subdef = this.Structures[def.StructureId]; long itemOffset = output.Position; foreach (var item in list) { this.ImportStructure( subdef, (GenericKeyValue)item, itemOffset, ref newOffset, state); itemOffset += itemSize; } break; } default: { if (def.Type == GFF.FieldType.UInt8 && list.GetType() == typeof(byte[])) { var bytes = (byte[])list; output.Write(bytes, 0, bytes.Length); } else { long itemOffset = output.Position; foreach (var item in list) { GFF.Builtin.Serialize(output, def.Type, item, endian); itemOffset += itemSize; } } break; } } } } else { if (def.IsReference == true && def.Type != GFF.FieldType.Structure) { throw new NotSupportedException(); } switch (def.Type) { case GFF.FieldType.String: { var s = data.As <string>(); if (s == null || s.Length == 0) { output.WriteValueU32(0xFFFFFFFF, endian); } else { var length = s.Length + 1; output.WriteValueU32((uint)newOffset, endian); output.Seek(newOffset, SeekOrigin.Begin); output.WriteValueS32(length, endian); output.WriteString(s, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode); output.WriteValueU16(0, endian); newOffset += 4 + (2 * length); } break; } case GFF.FieldType.TalkString: { var s = data.As <GFF.Builtins.TalkString>(); output.WriteValueU32(s.Id, endian); if (s.String == null) { output.WriteValueU32(0xFFFFFFFF, endian); } else if (s.String.Length == 0) { output.WriteValueU32(0, endian); } else { var length = s.String.Length + 1; output.WriteValueU32((uint)newOffset, endian); output.Seek(newOffset, SeekOrigin.Begin); output.WriteValueS32(length, endian); output.WriteString(s.String, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode); output.WriteValueU16(0, endian); newOffset += 4 + (2 * length); } break; } case GFF.FieldType.Structure: { if (def.IsReference == true) { if (data == null || data.Values == null) { output.WriteValueU32(0xFFFFFFFF, endian); } else { output.WriteValueU32((uint)newOffset, endian); output.Seek(newOffset, SeekOrigin.Begin); var subdef = this.Structures[def.StructureId]; newOffset += subdef.DataSize; this.ImportStructure( subdef, data, output.Position, ref newOffset, state); } } else { var subdef = this.Structures[def.StructureId]; this.ImportStructure( subdef, data, output.Position, ref newOffset, state); } break; } default: { GFF.Builtin.Serialize(output, def.Type, data.Value, endian); break; } } } }