Exemplo n.º 1
0
        public void Serialize(ref byte[] buffer, ref int offset, T value)
        {
            if (EqualityComparer <T> .Default.Equals(value, default))
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, Null, Bias);
                return;
            }

            if (value is Type type)
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, InlineType, Bias);
                _typeFormatter.Serialize(ref buffer, ref offset, type);
                return;
            }

            if (value is IExternalRootObject externalObj)
            {
                if (!object.ReferenceEquals(_serializer.InstanceData.CurrentRoot, value))
                {
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, ExternalObject, Bias);

                    var refId = externalObj.GetReferenceId();
                    SerializerBinary.WriteInt32(ref buffer, ref offset, refId);

                    _serializer.Config.OnExternalObject?.Invoke(externalObj);

                    return;
                }
            }

            if (_serializer.InstanceData.ObjectCache.TryGetExistingObjectId(value, out int id))
            {
                // Existing value
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, id, Bias);
            }
            else
            {
                // Important: Insert the ID for this value into our dictionary BEFORE calling SerializeFirstTime, as that might recursively call us again (maybe with the same value!)
                _serializer.InstanceData.ObjectCache.RegisterObject(value);

                var specificType = value.GetType();
                if (typeof(T) == specificType)
                {
                    // New value (same type)
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewValueSameType, Bias);
                }
                else
                {
                    // New value (type included)
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewValue, Bias);
                    _typeFormatter.Serialize(ref buffer, ref offset, specificType);
                }

                // Write the object normally
                GetSpecificSerializerDispatcher(specificType)(ref buffer, ref offset, value);
            }
        }
Exemplo n.º 2
0
		public void Serialize(ref byte[] buffer, ref int offset, TItem[] ar)
		{
			if (ar == null)
			{
				SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, -1, 1);
				return;
			}

			SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, ar.Length, 1);

			var f = _itemFormatter; // Cache into local to prevent ram fetches
			for (int i = 0; i < ar.Length; i++)
				f.Serialize(ref buffer, ref offset, ar[i]);
		}
        public void Serialize(ref byte[] buffer, ref int offset, ImmutableArray <TItem> value)
        {
            if (value.IsDefault)
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, -1, 1);
                return;
            }
            SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, value.Length, 1);
            var itemFormatter = _itemFormatter;             // Cache into local to prevent ram fetches

            for (int i = 0; i < value.Length; i++)
            {
                itemFormatter.Serialize(ref buffer, ref offset, value[i]);
            }
        }
Exemplo n.º 4
0
        public void Serialize(ref byte[] buffer, ref int offset, TItem[] ar)
        {
            if (ar == null)
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, -1, 1);
                return;
            }

            SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, ar.Length, 1);

            for (int i = 0; i < ar.Length; i++)
            {
                _itemFormatter.Serialize(ref buffer, ref offset, ar[i]);
            }
        }
Exemplo n.º 5
0
        public void Serialize(ref byte[] buffer, ref int offset, byte[] ar)
        {
            if (ar == null)
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, -1, 1);
                return;
            }

            var len = ar.Length;

            // Ensure we have enough space for the worst-case VarInt plus the byte array itself
            SerializerBinary.EnsureCapacity(ref buffer, offset, 5 + len);

            // Write the length, no need to check the capacity (we did that here)
            SerializerBinary.WriteUInt32BiasNoCheck(ref buffer, ref offset, len, 1);

            // Blit the array
            System.Array.Copy(ar, 0, buffer, offset, len);
            offset += len;
        }
Exemplo n.º 6
0
        public void Serialize(ref byte[] buffer, ref int offset, Type type)
        {
            // Null
            if (type == null)
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, Null, Bias);
                return;
            }

            var typeCache = _serializer.InstanceData.TypeCache;

            // Existing
            if (typeCache.TryGetExistingObjectId(type, out int id))
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, id, Bias);
                return;
            }


            // Mode: New


            // Is it a composite type that we have to split into its parts? (aka any generic)
            bool isClosed = !type.ContainsGenericParameters;

            if (isClosed && type.IsGenericType)
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewGeneric, Bias);

                // Split and write

                // Base
                var baseType = type.GetGenericTypeDefinition();
                Serialize(ref buffer, ref offset, baseType);

                // Args
                var genericArgs = type.GetGenericArguments();

                SerializerBinary.WriteByte(ref buffer, ref offset, (byte)(genericArgs.Length));                 // We need count. Ex: Action<T1> and Action<T1, T2> share the name
                for (int i = 0; i < genericArgs.Length; i++)
                {
                    Serialize(ref buffer, ref offset, genericArgs[i]);
                }

                // Register composite type
                typeCache.RegisterObject(type);
            }
            else
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewSingle, Bias);

                // Open generic, something that can be serialized alone
                var typeName = _typeBinder.GetBaseName(type);

                // Name
                SerializerBinary.WriteString(ref buffer, ref offset, typeName);

                // Register single type
                typeCache.RegisterObject(type);
            }

            // todo: do we put this only in the if or else part? or is it ok here? it should be ok, since we want to embed the schema of every type
            if (_serializer.Config.VersionTolerance == VersionTolerance.AutomaticEmbedded)
            {
                if (!CerasSerializer.FrameworkAssemblies.Contains(type.Assembly))
                {
                    _serializer.WriteSchemaForType(ref buffer, ref offset, type);
                }
            }
        }
Exemplo n.º 7
0
        public void Serialize(ref byte[] buffer, ref int offset, T value)
        {
            if (ReferenceEquals(value, null))
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, Null, Bias);
                return;
            }

            var specificType = value.GetType();
            var entry        = GetOrCreateEntry(specificType);

            if (entry.IsType)             // This is very rare, so we cache the check itself, and do the cast below
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, InlineType, Bias);
                _typeFormatter.Serialize(ref buffer, ref offset, (Type)(object)value);
                return;
            }

            if (entry.IsExternalRootObject)
            {
                var externalObj = (IExternalRootObject)value;

                if (!ReferenceEquals(_ceras.InstanceData.CurrentRoot, value))
                {
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, ExternalObject, Bias);

                    var refId = externalObj.GetReferenceId();
                    SerializerBinary.WriteInt32(ref buffer, ref offset, refId);

                    _ceras.Config.OnExternalObject?.Invoke(externalObj);

                    return;
                }
            }

            if (_allowReferences)
            {
                if (_ceras.InstanceData.ObjectCache.TryGetExistingObjectId(value, out int id))
                {
                    // Existing value
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, id, Bias);
                }
                else
                {
                    // Register new object
                    _ceras.InstanceData.ObjectCache.RegisterObject(value);

                    // Embedd type (if needed)
                    if (ReferenceEquals(typeof(T), specificType))
                    {
                        // New value (same type)
                        SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewValueSameType, Bias);
                    }
                    else
                    {
                        // New value (type included)
                        SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewValue, Bias);
                        _typeFormatter.Serialize(ref buffer, ref offset, specificType);
                    }

                    // Write object
                    entry.CurrentSerializeDispatcher(ref buffer, ref offset, value);
                }
            }
            else
            {
                // Embedd type (if needed)
                if (ReferenceEquals(typeof(T), specificType))
                {
                    // New value (same type)
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewValueSameType, Bias);
                }
                else
                {
                    // New value (type included)
                    SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewValue, Bias);
                    _typeFormatter.Serialize(ref buffer, ref offset, specificType);
                }

                // Write object
                entry.CurrentSerializeDispatcher(ref buffer, ref offset, value);
            }
        }
Exemplo n.º 8
0
        public void Serialize(ref byte[] buffer, ref int offset, Type type)
        {
            // Null
            if (type == null)
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, Null, Bias);
                return;
            }

            var typeCache = _serializer.InstanceData.TypeCache;

            // Existing
            if (typeCache.TryGetExistingObjectId(type, out int id))
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, id, Bias);
                return;
            }


            // Mode: New


            // Is it a composite type that we have to split into its parts? (aka any generic)
            bool isClosed = !type.ContainsGenericParameters;

            if (isClosed && type.IsGenericType)
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewComposite, Bias);

                // Split and write

                // Base
                var baseType = type.GetGenericTypeDefinition();
                Serialize(ref buffer, ref offset, baseType);


                // Args
                var genericArgs = type.GetGenericArguments();

                SerializerBinary.WriteByte(ref buffer, ref offset, (byte)(genericArgs.Length));                 // We need count. Ex: Action<T1> and Action<T1, T2> share the name.
                for (int i = 0; i < genericArgs.Length; i++)
                {
                    Serialize(ref buffer, ref offset, genericArgs[i]);
                }


                // Register composite type
                typeCache.RegisterObject(type);
            }
            else
            {
                SerializerBinary.WriteUInt32Bias(ref buffer, ref offset, NewSingle, Bias);

                // Open generic, something that can be serialized alone

                var typeName = _typeBinder.GetBaseName(type);

                // Name
                SerializerBinary.WriteString(ref buffer, ref offset, typeName);


                // Register single type
                typeCache.RegisterObject(type);
            }
        }