private static CommandPropertySpec BuildPropertySpecForType(Type t) { int length = GetLengthFromAttribute(t); var props = new List <PropertySpec>(); var rawProps = t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(prop => prop.GetCustomAttribute <NoSerializeAttribute>() == null); foreach (PropertyInfo prop in rawProps) { SerializeAttribute attr = prop.GetCustomAttribute <SerializeAttribute>(); if (attr == null) // This means the property shouldnt be serialized { continue; } SerializableAttributeBase serAttr = prop.GetCustomAttribute <SerializableAttributeBase>(); if (serAttr == null) { throw new SerializationException(t.Name, "Missing serialization definition on property {0}", prop.Name); } MethodInfo tmpSetter = prop.CanWrite ? prop.GetSetMethod(true) : null; MethodInfo tmpGetter = prop.GetGetMethod(true); Delegate setter = tmpSetter != null?Delegate.CreateDelegate(Expression.GetActionType(t, prop.PropertyType), tmpSetter) : null; Delegate getter = tmpGetter != null?Delegate.CreateDelegate(Expression.GetFuncType(t, prop.PropertyType), tmpGetter) : null; bool isCommandId = prop.GetCustomAttribute <CommandIdAttribute>() != null; props.Add(new PropertySpec(setter, getter, serAttr, attr, prop, isCommandId)); } return(_propertySpecCache[t] = new CommandPropertySpec(length, props)); }
public virtual void Deserialize(ParsedByteArray cmd) { CommandPropertySpec info = GetPropertySpecForType(GetType()); int attrLength = info.Length; if (attrLength != -1 && attrLength != cmd.BodyLength) { throw new SerializationException(GetType().Name, "Auto deserialize length mismatch"); } foreach (PropertySpec prop in info.Properties) { prop.Setter?.DynamicInvoke(this, prop.SerAttr.Deserialize(cmd.ReverseBytes, cmd.Body, prop.Attr.StartByte, prop.PropInfo)); } if (GetLength() != cmd.BodyLength) { throw new Exception("Auto deserialize final length mismatch"); } }
public virtual void Serialize(ByteArrayBuilder cmd) { CommandPropertySpec info = GetPropertySpecForType(GetType()); int length = GetLength(); if (length < 0) { throw new SerializationException(GetType().Name, "Cannot auto serialize without a defined length"); } var res = new byte[length]; foreach (PropertySpec prop in info.Properties) { if (prop.Getter != null) { prop.SerAttr.Serialize(cmd.ReverseBytes, res, prop.Attr.StartByte, prop.Getter.DynamicInvoke(this)); } } cmd.AddByte(res); }