public void Deserialize(byte[] buffer, ref int offset, ref RectOffset value) { value.left = SerializerBinary.ReadInt32Fixed(buffer, ref offset); value.right = SerializerBinary.ReadInt32Fixed(buffer, ref offset); value.top = SerializerBinary.ReadInt32Fixed(buffer, ref offset); value.bottom = SerializerBinary.ReadInt32Fixed(buffer, ref offset); }
public void Deserialize <T>(ref T value, byte[] buffer, ref int offset, int expectedReadLength = -1) { if (buffer == null) { throw new ArgumentNullException("Must provide a buffer to deserialize from!"); } EnterRecursive(RecursionMode.Deserialization); try { var formatter = (IFormatter <T>)GetGenericFormatter(typeof(T)); int offsetBeforeRead = offset; if (Config.EmbedChecksum) { var checksum = SerializerBinary.ReadInt32Fixed(buffer, ref offset); if (checksum != ProtocolChecksum.Checksum) { throw new InvalidOperationException($"Checksum does not match embedded checksum (Serializer={ProtocolChecksum.Checksum}, Data={checksum})"); } } formatter.Deserialize(buffer, ref offset, ref value); if (expectedReadLength != -1) { int bytesActuallyRead = offset - offsetBeforeRead; if (bytesActuallyRead != expectedReadLength) { throw new UnexpectedBytesConsumedException("The deserialization has completed, but not all of the given bytes were consumed. " + " Maybe you tried to deserialize something directly from a larger byte-array?", expectedReadLength, bytesActuallyRead, offsetBeforeRead, offset); } } // todo: instead of clearing and re-adding the known types, the type-cache should have a fallback cache inside it // todo: .. that gets used when the ID is out of range. So outside is the dynamic stuff (with an offset of where IDs will start), and inside are the // todo: .. known elements, and if we're given an ID that is too low, we defer to the inner cache. // Very important to clear out caches and stuff that is only valid for this call if (!Config.PersistTypeCache) { InstanceData.TypeCache.ClearDeserializationCache(); foreach (var t in Config.KnownTypes) { InstanceData.TypeCache.AddKnownType(t); } } if (!Config.PersistObjectCache) { InstanceData.ObjectCache.ClearDeserializationCache(); } } finally { LeaveRecursive(RecursionMode.Deserialization); } }
public void Deserialize(byte[] buffer, ref int offset, ref LayerMask value) { value.value = SerializerBinary.ReadInt32Fixed(buffer, ref offset); }
/// <summary> /// The most advanced deserialize method. /// <para>Again, you can put in an existing object to populate (or a variable that's currently null, in which case Ceras creates an object for you)</para> /// <para>In this version you can put in the offset as well, telling Ceras where to start reading from inside the buffer.</para> /// <para>After the method is done, the offset will be where Ceras has stopped reading.</para> /// <para>If you pass in a value >0 for <paramref name="expectedReadLength"/> then Ceras will check how many bytes it has read (only rarely useful)</para> /// </summary> public void Deserialize <T>(ref T value, byte[] buffer, ref int offset, int expectedReadLength = -1) { if (buffer == null) { throw new ArgumentNullException("Must provide a buffer to deserialize from!"); } EnterRecursive(RecursionMode.Deserialization); try { int offsetBeforeRead = offset; // // Actual deserialization { if (Config.Advanced.EmbedChecksum) { var checksum = SerializerBinary.ReadInt32Fixed(buffer, ref offset); if (checksum != ProtocolChecksum.Checksum) { throw new InvalidOperationException($"Checksum does not match embedded checksum (Serializer={ProtocolChecksum.Checksum}, Data={checksum})"); } } var formatter = (IFormatter <T>)GetReferenceFormatter(typeof(T)); formatter.Deserialize(buffer, ref offset, ref value); } if (expectedReadLength != -1) { int bytesActuallyRead = offset - offsetBeforeRead; if (bytesActuallyRead != expectedReadLength) { throw new UnexpectedBytesConsumedException("The deserialization has completed, but not all of the given bytes were consumed. " + " Maybe you tried to deserialize something directly from a larger byte-array?", expectedReadLength, bytesActuallyRead, offsetBeforeRead, offset); } } // todo: use a custom 'Bag' collection or so for deserialization caches, so we can quickly remove everything above a certain index // Clearing and re-adding the known types is really bad... // But how would we optimize it best? // Maybe having a sort of fallback-cache? I guess it would be faster than what we're doing now, // but then we'd have an additional if() check every time :/ // // The deserialization cache is a list, we'd check for out of range, and then check the secondary cache? // // Or maybe the most straight-forward approach would be to simply remember at what index the KnownTypes end and the dynamic types start, // and then we can just RemoveRange() everything above the known index... if (!Config.Advanced.PersistTypeCache) { InstanceData.TypeCache.ResetDeserializationCache(); } InstanceData.ObjectCache.ClearDeserializationCache(); } finally { LeaveRecursive(RecursionMode.Deserialization); } }