public object ReadEnumerator(Type enumType) { if (!enumType.IsEnum) { throw new ArgumentException(); } if (enumType.IsDefined(typeof(FlagsAttribute), false)) { var flags = new HashSet <CName>(); while (true) { var flag = ReadCName(); if (CName.IsNullOrEmpty(flag)) { break; } flags.Add(flag); } return(EnumExtensions.ConvertToEnum(enumType, flags)); } else { var name = ReadCName(); return(Enum.Parse(enumType, name)); } }
public void ParseObject(object instance, REDBinaryReader red) { // Each object is prefixed with a zero byte header. var b = red.ReadByte(); if (b != 0) { throw new FormatException($"Invalid object null header: {b}"); } // Keep looping until the 2 byte null termintator is reached. while (true) { var name = red.ReadCName(); if (CName.IsNullOrEmpty(name)) { // 2 byte null terminator instead of the next name id indicates the end of the object. break; } var type = red.ReadCName(); var start = red.BaseStream.Position; var size = red.ReadUInt32(); // Size value includes the size of the uint size value itself (+ 4). if (size < sizeof(uint)) { throw new FormatException($"Invalid object size: {size}"); } // Check to see if the current class contains a property with the name and type read. var field = REDReflection.GetREDField(instance.GetType(), name, type); if (field == null) { throw new FormatException($"Property '{name}' : '{type}', not found in class {instance.GetType().Name}, Aborting!"); } var value = ReadObject(field.FieldType, red); var diff = start.CompareTo(red.BaseStream.Position); if (diff != 0) { throw new FormatException($"Property '{name}' : '{type}', read unknown size of bytes, aborting!"); } field.SetValue(instance, value); } }