Ejemplo n.º 1
0
        /// <summary>
        /// Writes a controller to a stream.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="controller"></param>
        public void Write(Stream stream, object controller)
        {
            if (controller == null)
            {
                throw new ArgumentNullException(nameof(controller));
            }

            // For fallback support, allow byte arrays/streams to be passed.
            // We simply write it as is.
            if (controller is byte[] byteBuffer)
            {
                stream.Write(byteBuffer, 0, byteBuffer.Length);
                return;
            }

            if (controller is Stream inputStream)
            {
                inputStream.CopyTo(stream);
                return;
            }

            using (var writer = new BinaryWriter(stream, FileEncoding.Default, true))
            {
                Type controllerType      = controller.GetType();
                IControllerSerializer cs = _controllerSerializerResolver.GetSerializer(controllerType);

                if (!controllerType.IsBehaviorController())
                {
                    ControllerAttribute controllerAttribute = controllerType.GetCustomAttribute <ControllerAttribute>() ?? new ControllerAttribute();
                    if (controllerAttribute.SubType.HasValue)
                    {
                        writer.Write(controllerAttribute.SubType.Value);
                    }

                    if (controllerType.IsAnimationController() || !controllerAttribute.SubType.HasValue)
                    {
                        // Skip writing the count field, the serializer will take care of it.
                    }
                    else
                    {
                        writer.Write((ushort)0);
                    }

                    cs.Serialize(stream, (Controller)controller);

                    return;
                }

                // Test if the type is from our controller assembly.
                if (!_controllerFactory.CanCreate(controllerType))
                {
                    throw new NotSupportedException("Invalid controller.");
                }

                // We don't know the size yet, so just write 0 for now.
                writer.Write(0);

                long startPos = stream.Position;

                cs.Serialize(stream, (Controller)controller);

                // After the controller is written, determine and write the size.
                long currentPos = stream.Position;
                stream.Position = startPos - 4;
                writer.Write((int)(currentPos - startPos));

                // Restore position to the end of the controller.
                stream.Position = currentPos;
            }
        }