예제 #1
0
 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);
 }
예제 #2
0
        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);
            }
        }
예제 #3
0
 public void Deserialize(byte[] buffer, ref int offset, ref LayerMask value)
 {
     value.value = SerializerBinary.ReadInt32Fixed(buffer, ref offset);
 }
예제 #4
0
        /// <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);
            }
        }