private object ExportField(GFF.FieldDefinition def, long offset, ExportState state) { var input = this.Data; input.Seek(offset + def.Offset, SeekOrigin.Begin); if (def.IsReference == true && def.IsList == true) { var listOffset = input.ReadValueU32(LittleEndian); if (listOffset == 0xFFFFFFFF) { return null; } input.Seek(listOffset, SeekOrigin.Begin); var count = input.ReadValueU32(LittleEndian); long itemOffset = input.Position; var list = new List<object>(); for (uint i = 0; i < count; i++) { list.Add(this.ExportGeneric(state)); itemOffset += 8; input.Seek(itemOffset, SeekOrigin.Begin); } return list; } else if (def.IsList == true) { //var type = GFF.Builtin.ToNativeType(def.Type); var listOffset = input.ReadValueU32(LittleEndian); if (listOffset == 0xFFFFFFFF) { /*if (def.Type == GFF.FieldType.UInt8) { return new byte[0]; } else { throw new NotSupportedException(); }*/ return null; } input.Seek(listOffset, SeekOrigin.Begin); var count = input.ReadValueU32(LittleEndian); switch (def.Type) { case GFF.FieldType.String: { long itemOffset = input.Position; var list = new List<string>(); for (uint i = 0; i < count; i++) { var dataOffset = input.ReadValueU32(LittleEndian); if (dataOffset == 0xFFFFFFFF) { list.Add(null); } else { if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var length = input.ReadValueU32(LittleEndian); list.Add(input.ReadString(length * 2, true, LittleEndian == true ? Encoding.Unicode : Encoding.BigEndianUnicode)); } else { list.Add(this.StringTable[(int)dataOffset]); } } itemOffset += 4; input.Seek(itemOffset, SeekOrigin.Begin); } return list; } case GFF.FieldType.Structure: { long itemOffset = input.Position; var subdef = this.Structures[def.StructureId]; var list = new List<KeyValue>(); for (uint i = 0; i < count; i++) { list.Add(this.ExportStructure( subdef, itemOffset, state)); itemOffset += subdef.DataSize; } return list; } default: { if (def.Type == GFF.FieldType.UInt8) { var list = new byte[count]; input.Read(list, 0, list.Length); return list; } else { var type = GFF.Builtin.ToNativeType(def.Type); var list = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(type)); for (uint i = 0; i < count; i++) { list.Add(GFF.Builtin.Deserialize(input, def.Type, LittleEndian)); } return list; } } } } else { if (def.IsReference == true && def.Type == GFF.FieldType.Generic) { return this.ExportGeneric(state); } else if (def.IsReference == true) { var referenceOffset = input.ReadValueU32(LittleEndian); if (referenceOffset == 0xFFFFFFFF) { return null; } else if (state.References.ContainsKey(referenceOffset) == true) { return state.References[referenceOffset]; } input.Seek(referenceOffset, SeekOrigin.Begin); } switch (def.Type) { case GFF.FieldType.Generic: { throw new FormatException(); } case GFF.FieldType.String: { var dataOffset = input.ReadValueU32(LittleEndian); if (dataOffset == 0xFFFFFFFF) { return ""; } if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(LittleEndian); return input.ReadString(count * 2, true, LittleEndian == true ? Encoding.Unicode : Encoding.BigEndianUnicode); } else { return this.StringTable[(int)dataOffset]; } } case GFF.FieldType.TalkString: { var tlk = new GFF.Builtins.TalkString(); tlk.Id = input.ReadValueU32(LittleEndian); var dataOffset = input.ReadValueU32(LittleEndian); if (dataOffset == 0xFFFFFFFF) { tlk.String = null; } else if (dataOffset == 0) { tlk.String = ""; } else { if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(LittleEndian); tlk.String = input.ReadString(count * 2, true, LittleEndian == true ? Encoding.Unicode : Encoding.BigEndianUnicode); } else { tlk.String = this.StringTable[(int)dataOffset]; } } return tlk; } case GFF.FieldType.Structure: { var subdef = this.Structures[def.StructureId]; return this.ExportStructure(subdef, input.Position, state); } default: { return GFF.Builtin.Deserialize(input, def.Type, LittleEndian); } } } }
private object ExportTypeField(GFF.FieldDefinition def, Type type, long offset) { if (ValidateField(def, type) == false) { throw new FormatException("field validation failed"); } var endian = this.Endian; var input = this.Data; input.Seek(offset + def.Offset, SeekOrigin.Begin); if (def.IsReference == true) { throw new NotSupportedException(); } if (def.IsList == true) { var listOffset = input.ReadValueU32(endian); if (listOffset == 0xFFFFFFFF) { if (def.Type == GFF.FieldType.UInt8 && type == typeof(byte[])) { return(new byte[0]); } else { return(Activator.CreateInstance(type)); } } input.Seek(listOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); switch (def.Type) { case GFF.FieldType.String: { long itemOffset = input.Position; var list = new List <string>(); for (uint i = 0; i < count; i++) { var dataOffset = input.ReadValueU32(endian); if (dataOffset == 0xFFFFFFFF) { return(""); } if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var length = input.ReadValueU32(endian); list.Add(input.ReadString(length * 2, true, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode)); } else { input.Seek(dataOffset, SeekOrigin.Begin); list.Add(this.StringTable[(int)dataOffset]); } itemOffset += 4; input.Seek(itemOffset, SeekOrigin.Begin); } return(list); } case GFF.FieldType.Structure: { long itemOffset = input.Position; var subtype = type.GetGenericArguments()[0]; var subdef = this.Structures[def.StructureId]; var list = (IList)Activator.CreateInstance(type); for (uint i = 0; i < count; i++) { list.Add(this.ExportTypeStructure( subdef, subtype, itemOffset)); itemOffset += subdef.DataSize; } return(list); } default: { if (def.Type == GFF.FieldType.UInt8 && type == typeof(byte[])) { var list = new byte[count]; input.Read(list, 0, list.Length); return(list); } else { var list = (IList)Activator.CreateInstance(type); for (uint i = 0; i < count; i++) { list.Add(GFF.Builtin.Deserialize(input, def.Type, endian)); } return(list); } } } } else { switch (def.Type) { case GFF.FieldType.String: { var dataOffset = input.ReadValueU32(endian); if (dataOffset == 0xFFFFFFFF) { return(""); } if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); return(input.ReadString(count * 2, true, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode)); } else { return(this.StringTable[(int)dataOffset]); } } case GFF.FieldType.TalkString: { var tlk = new GFF.Builtins.TalkString(); tlk.Id = input.ReadValueU32(endian); var dataOffset = input.ReadValueU32(endian); if (dataOffset == 0xFFFFFFFF) { tlk.String = null; } else if (dataOffset == 0) { tlk.String = ""; } else { if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); tlk.String = input.ReadString(count * 2, true, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode); } else { tlk.String = this.StringTable[(int)dataOffset]; } } return(tlk); } case GFF.FieldType.Structure: { var subdef = this.Structures[def.StructureId]; return(this.ExportTypeStructure(subdef, type, input.Position)); } default: { return(GFF.Builtin.Deserialize(input, def.Type, endian)); } } } }
private object ExportField(GFF.FieldDefinition def, long offset, ExportState state) { var endian = this.Endian; var input = this.Data; input.Seek(offset + def.Offset, SeekOrigin.Begin); if (def.IsReference == true && def.IsList == true) { var listOffset = input.ReadValueU32(endian); if (listOffset == 0xFFFFFFFF) { return(null); } input.Seek(listOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); long itemOffset = input.Position; var list = new List <object>(); for (uint i = 0; i < count; i++) { list.Add(this.ExportGeneric(state)); itemOffset += 8; input.Seek(itemOffset, SeekOrigin.Begin); } return(list); } else if (def.IsList == true) { //var type = GFF.Builtin.ToNativeType(def.Type); var listOffset = input.ReadValueU32(endian); if (listOffset == 0xFFFFFFFF) { /*if (def.Type == GFF.FieldType.UInt8) * { * return new byte[0]; * } * else * { * throw new NotSupportedException(); * }*/ return(null); } input.Seek(listOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); switch (def.Type) { case GFF.FieldType.String: { long itemOffset = input.Position; var list = new List <string>(); for (uint i = 0; i < count; i++) { var dataOffset = input.ReadValueU32(endian); if (dataOffset == 0xFFFFFFFF) { list.Add(null); } else { if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var length = input.ReadValueU32(endian); list.Add(input.ReadString(length * 2, true, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode)); } else { list.Add(this.StringTable[(int)dataOffset]); } } itemOffset += 4; input.Seek(itemOffset, SeekOrigin.Begin); } return(list); } case GFF.FieldType.Structure: { long itemOffset = input.Position; var subdef = this.Structures[def.StructureId]; var list = new List <GenericKeyValue>(); for (uint i = 0; i < count; i++) { list.Add(this.ExportStructure( subdef, itemOffset, state)); itemOffset += subdef.DataSize; } return(list); } default: { if (def.Type == GFF.FieldType.UInt8) { var list = new byte[count]; input.Read(list, 0, list.Length); return(list); } else { var type = GFF.Builtin.ToNativeType(def.Type); var list = (IList)Activator.CreateInstance(typeof(List <>).MakeGenericType(type)); for (uint i = 0; i < count; i++) { list.Add(GFF.Builtin.Deserialize(input, def.Type, endian)); } return(list); } } } } else { if (def.IsReference == true && def.Type == GFF.FieldType.Generic) { return(this.ExportGeneric(state)); } else if (def.IsReference == true) { var referenceOffset = input.ReadValueU32(endian); if (referenceOffset == 0xFFFFFFFF) { return(null); } else if (state.References.ContainsKey(referenceOffset) == true) { return(state.References[referenceOffset]); } input.Seek(referenceOffset, SeekOrigin.Begin); } switch (def.Type) { case GFF.FieldType.Generic: { throw new FormatException(); } case GFF.FieldType.String: { var dataOffset = input.ReadValueU32(endian); if (dataOffset == 0xFFFFFFFF) { return(""); } if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); return(input.ReadString(count * 2, true, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode)); } else { return(this.StringTable[(int)dataOffset]); } } case GFF.FieldType.TalkString: { var tlk = new GFF.Builtins.TalkString(); tlk.Id = input.ReadValueU32(endian); var dataOffset = input.ReadValueU32(endian); if (dataOffset == 0xFFFFFFFF) { tlk.String = null; } else if (dataOffset == 0) { tlk.String = ""; } else { if (this.FileVersion < 1) { input.Seek(dataOffset, SeekOrigin.Begin); var count = input.ReadValueU32(endian); tlk.String = input.ReadString(count * 2, true, endian == Endian.Little ? Encoding.Unicode : Encoding.BigEndianUnicode); } else { tlk.String = this.StringTable[(int)dataOffset]; } } return(tlk); } case GFF.FieldType.Structure: { var subdef = this.Structures[def.StructureId]; return(this.ExportStructure(subdef, input.Position, state)); } default: { return(GFF.Builtin.Deserialize(input, def.Type, endian)); } } } }