/// <summary> /// Load an <see cref="AttributeDictionary"/> from the <see cref="Package"/> and the <see cref="BinaryReader"/>. /// </summary> /// <param name="package">The <see cref="Package"/> the dictionary is in.</param> /// <param name="reader">The <see cref="BinaryReader"/> that holds the dictionary's data.</param> /// <returns>The <see cref="AttributeDictionary"/> or <c>null</c> if there was no entries.</returns> public static AttributeDictionary Load(Package package, BinaryReader reader) { AttributeDictionary result = null; while (true) { var name = package.ReadNameIndex(reader).Value; if (name == "None") { break; } if (result == null) { result = new AttributeDictionary(); } object current; result.TryGetValue(name, out current); result[name] = Field.Load(package, reader, current); } return(result); }
static object LoadSingle(Package package, BinaryReader reader, FieldInfo info, bool inArray = false) { if (info.Size < 1) { throw new Exception(); } switch (info.Type) { case FieldTypeBase.Byte: if (!inArray && info.Size != 1) { throw new Exception(); } return(reader.ReadByte()); case FieldTypeBase.Float: if (!inArray && info.Size != 4) { throw new Exception(); } return(reader.ReadSingle()); case FieldTypeBase.Integer: if (!inArray && info.Size != 4) { throw new Exception(); } return(reader.ReadInt32()); case FieldTypeBase.Name: return(package.ReadNameIndex(reader).Value); case FieldTypeBase.Object: return(package.ReadReference(reader)); case FieldTypeBase.Str: var stringLength = reader.ReadByte(); if (stringLength != info.Size - 1) { throw new Exception("String length isn't the field size minus 1."); } return(reader.ReadStringz(stringLength, Encoding.ASCII)); case FieldTypeBase.Struct: string name; if (info.IsLiteralSizeForm) { name = package.Names[info.Size].Value; info.Size = UIndex.Read(reader); } else { name = package.ReadNameIndex(reader).Value; } var end = reader.BaseStream.Position + info.Size; object result; switch (name) { case "InitialAllianceInfo": result = InitialAllianceInfo.Read(reader, package); break; case "PointRegion": if (!inArray && info.Size < 6) { throw new Exception("PointRegion structure size must be at least 6 bytes."); } result = PointRegion.Read(reader, package); break; case "Rotator": result = Rotator.Read(reader); break; case "Scale": if (!inArray && info.Size != 17) { throw new Exception("Scale structure size is a constant 17 bytes."); } result = Scale.Read(reader); break; case "Vector": if (!inArray && info.Size != 12) { throw new Exception("Vector structure size is a constant 12 bytes."); } result = reader.ReadVector3f(); break; default: throw new Exception("Unhandled or unknown struct type " + name + "."); } if (!inArray && reader.BaseStream.Position != end) { throw new Exception("Structure wasn't fully devoured or was overconsumed."); } return(result); default: throw new Exception("Unknown or unhandled type " + info.Type + "."); } }