protected override object DeserializeEnvelope(ReadOnlySpan <byte> data, Type envType) { var env = GetDefaultConstructor(envType)(); var nextIndex = 4; // skip header size field SetStringProperty(envType, env, nameof(SerializedEnvelope <object> .J), data, ref nextIndex); SetDateTimeProperty(envType, env, nameof(SerializedEnvelope <object> .At), data, ref nextIndex); SetIntProperty(envType, env, nameof(SerializedEnvelope <object> .R), data, ref nextIndex); SetIntProperty(envType, env, nameof(SerializedEnvelope <object> .T), data, ref nextIndex); SetStringProperty(envType, env, nameof(SerializedEnvelope <object> .G), data, ref nextIndex); var indexBeforePeriodicRunInfo = nextIndex; var periodicRunInfo = new PeriodicRunInfo(); SetIntProperty(typeof(PeriodicRunInfo), periodicRunInfo, nameof(PeriodicRunInfo.RepeatSeconds), data, ref nextIndex); SetDateTimeProperty(typeof(PeriodicRunInfo), periodicRunInfo, nameof(PeriodicRunInfo.NextRunTime), data, ref nextIndex); SetDateTimeProperty(typeof(PeriodicRunInfo), periodicRunInfo, nameof(PeriodicRunInfo.LastRunTimeUtc), data, ref nextIndex); SetDateTimeProperty(typeof(PeriodicRunInfo), periodicRunInfo, nameof(PeriodicRunInfo.EndAtUtc), data, ref nextIndex); SetStringProperty(typeof(PeriodicRunInfo), periodicRunInfo, nameof(PeriodicRunInfo.CronExp), data, ref nextIndex); SetStringProperty(typeof(PeriodicRunInfo), periodicRunInfo, nameof(PeriodicRunInfo.TzId), data, ref nextIndex); if (nextIndex > indexBeforePeriodicRunInfo + 18) // headers 2 + 2 + 2 + 2 + 5 + 5 { var pProp = GetPublicProperty(envType, nameof(SerializedEnvelope <object> .P)); pProp.SetValue(env, periodicRunInfo); } var headerSize = BitConverter.ToInt32(data.Slice(0, 4).ToArray(), 0); // sanity check if (headerSize < nextIndex) { throw new Exception("Invalid header size"); } // skip header part that we don't understand (future proofing) nextIndex = headerSize; var arg = DeserializeObject(envType.GenericTypeArguments[0], data, ref nextIndex); var argProp = GetPublicProperty(envType, nameof(SerializedEnvelope <object> .A)); argProp.SetValue(env, arg); return(env); }
private static int SerializeObject(Type type, object obj, ICollection <byte[]> objectProps) { var wrappedType = type.GetWrapperType(); object wrappedObj; if (type.ShouldWrap()) { wrappedObj = GetDefaultConstructor(wrappedType)(); GetPublicProperty(wrappedType, nameof(PrimitiveWrapper <object> .Value)).SetValue(wrappedObj, obj); } else { wrappedObj = obj; } if (wrappedObj == null) { return(0); // possible for VoidArgs } var properties = GetPublicProperties(wrappedType); var hasOrderedProperties = false; var size = 0; foreach (var property in properties) { if (property.Item1 == int.MaxValue) { break; // no more properties with PropertyOrder attribute } var propertyType = property.Item3; hasOrderedProperties = true; if (propertyType == typeof(string)) { size += Serialize((string)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(byte) || propertyType == typeof(byte?)) { size += Serialize((byte?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(short) || propertyType == typeof(short?)) { size += Serialize((short?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(int) || propertyType == typeof(int?)) { size += Serialize((int?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(long) || propertyType == typeof(long?)) { size += Serialize((long?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(ushort) || propertyType == typeof(ushort?)) { size += Serialize((ushort?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(uint) || propertyType == typeof(uint?)) { size += Serialize((uint?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(ulong) || propertyType == typeof(ulong?)) { size += Serialize((ulong?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(double) || propertyType == typeof(double?)) { size += Serialize((double?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(float) || propertyType == typeof(float?)) { size += Serialize((float?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(DateTime) || propertyType == typeof(DateTime?)) { size += Serialize((DateTime?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(DateTimeOffset) || propertyType == typeof(DateTimeOffset?)) { size += Serialize((DateTimeOffset?)property.GetValue(wrappedObj), objectProps); } else if (propertyType == typeof(decimal) || propertyType == typeof(decimal?)) { size += Serialize((decimal?)property.GetValue(wrappedObj), objectProps); } } if (!hasOrderedProperties) { throw new Exception( $"Cannot serialize object without PropertyOrder attributes ({wrappedType.FullName})"); } return(size); }