/// <summary> /// Serializes an object into a PackedBitWriter stream. /// </summary> /// <param name="writer">The stream to serialize to.</param> /// <param name="value">The object to serialize.</param> /// <exception cref="ArgumentNullException"><paramref name="writer" /> is null.</exception> /// <exception cref="ArgumentNullException"><paramref name="value" /> is null.</exception> public void Serialize(PackedBitWriter writer, object value) { if (object.ReferenceEquals(writer, null)) { throw new ArgumentNullException(nameof(writer)); } if (object.ReferenceEquals(value, null)) { throw new ArgumentNullException(nameof(value)); } if (ImplementsInterface) { ((IPackedBitSerializable)value).Serialize(writer); } else { var properties = GetProperties(SerializeType); if (HasOrder) { properties = properties.OrderBy(p => (p.GetCustomAttribute <PackedBitOrderAttribute>() ?? new PackedBitOrderAttribute(0)).LowBit); WriteImperativeBits(writer, value, properties, (prop) => { PackedBitOrderAttribute bitOrderAttr = prop.GetCustomAttribute <PackedBitOrderAttribute>(); return(new BitPair() { Count = bitOrderAttr.BitCount, Signed = bitOrderAttr.Signed, }); }); } else if (HasRange) { properties = properties.OrderBy(p => (p.GetCustomAttribute <PackedBitRangeAttribute>() ?? new PackedBitRangeAttribute(0)).LowBit); WriteImperativeBits(writer, value, properties, (prop) => { PackedBitRangeAttribute bitRangeAttr = prop.GetCustomAttribute <PackedBitRangeAttribute>(); return(new BitPair() { Count = bitRangeAttr.HasHighBit ? bitRangeAttr.HighBit - (bitRangeAttr.LowBit - 1) : 1, Signed = bitRangeAttr.Signed, }); }); } else if (HasSize) { WriteImperativeBits(writer, value, properties, (prop) => { PackedBitSizeAttribute bitSizeAttr = prop.GetCustomAttribute <PackedBitSizeAttribute>(); return(new BitPair() { Count = bitSizeAttr.BitCount, Signed = bitSizeAttr.Signed, }); }); } else { throw CodePath.Unreachable; } } }
/// <summary> /// Deserializes a PackedBitReader stream to an object. /// </summary> /// <param name="reader">The stream to deserialize.</param> /// <returns>An object populated by the stream.</returns> /// <exception cref="ArgumentNullException"><paramref name="reader" /> is null.</exception> public object Deserialize(PackedBitReader reader) { if (object.ReferenceEquals(reader, null)) { throw new ArgumentNullException(nameof(reader)); } object ret = Activator.CreateInstance(SerializeType); if (ImplementsInterface) { ((IPackedBitSerializable)ret).Deserialize(reader); } else { var properties = GetProperties(SerializeType); if (HasOrder) { properties = properties.OrderBy(p => p.GetCustomAttribute <PackedBitOrderAttribute>().LowBit); ReadImperativeBits(reader, ret, properties, (prop) => { PackedBitOrderAttribute bitOrderAttr = prop.GetCustomAttribute <PackedBitOrderAttribute>(); return(new BitPair() { Count = bitOrderAttr.BitCount, Signed = bitOrderAttr.Signed, }); }); } else if (HasRange) { properties = properties.OrderBy(p => p.GetCustomAttribute <PackedBitRangeAttribute>().LowBit); ReadImperativeBits(reader, ret, properties, (prop) => { PackedBitRangeAttribute bitRangeAttr = prop.GetCustomAttribute <PackedBitRangeAttribute>(); return(new BitPair() { Count = bitRangeAttr.HasHighBit ? bitRangeAttr.HighBit - (bitRangeAttr.LowBit - 1) : 1, Signed = bitRangeAttr.Signed, }); }); } else if (HasSize) { ReadImperativeBits(reader, ret, properties, (prop) => { PackedBitSizeAttribute bitSizeAttr = prop.GetCustomAttribute <PackedBitSizeAttribute>(); return(new BitPair() { Count = bitSizeAttr.BitCount, Signed = bitSizeAttr.Signed, }); }); } else { throw CodePath.Unreachable; } } return(ret); }