Beispiel #1
0
        /// <summary>
        /// Serializes a tag block.
        /// </summary>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStream">The stream to write completed blocks of tag data to.</param>
        /// <param name="block">The temporary block to write incomplete tag data to.</param>
        /// <param name="list">The list of values in the tag block.</param>
        /// <param name="listType">Type of the list.</param>
        private static void SerializeTagBlock(ISerializationContext context, MemoryStream tagStream, IDataBlock block, object list, Type listType)
        {
            var writer    = block.Writer;
            var listCount = 0;

            if (list != null)
            {
                // Use reflection to get the number of elements in the list
                var countProperty = listType.GetProperty("Count");
                listCount = (int)countProperty.GetValue(list);
            }
            if (listCount == 0)
            {
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                return;
            }

            // Serialize each value in the list to a data block
            var tagBlock       = context.CreateBlock();
            var enumerableList = (System.Collections.IEnumerable)list;
            var valueType      = listType.GenericTypeArguments[0];

            foreach (var val in enumerableList)
            {
                SerializeValue(context, tagStream, tagBlock, val, null, valueType);
            }

            // Finalize the block and write the tag block reference
            writer.Write(listCount);
            block.WritePointer(tagBlock.Finalize(tagStream), listType);
            writer.Write(0);
        }
Beispiel #2
0
        /// <summary>
        /// Serializes a tag structure into a context.
        /// </summary>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStructure">The tag structure.</param>
        public void Serialize(ISerializationContext context, object tagStructure, uint? offset = null)
        {
            // Serialize the structure to a data block
            var info = new TagStructureInfo(tagStructure.GetType(), _version);
            context.BeginSerialize(info);
            var tagStream = new MemoryStream();
            var structBlock = context.CreateBlock();
            SerializeStruct(context, tagStream, structBlock, info, tagStructure);

            // Finalize the block and write all of the tag data out
            var mainStructOffset = offset.HasValue ? offset.Value : structBlock.Finalize(tagStream);
            var data = tagStream.ToArray();
            context.EndSerialize(info, data, mainStructOffset);
        }
Beispiel #3
0
        /// <summary>
        /// Serializes a tag block.
        /// </summary>
        /// <param name="version"></param>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStream">The stream to write completed blocks of tag data to.</param>
        /// <param name="block">The temporary block to write incomplete tag data to.</param>
        /// <param name="list">The list of values in the tag block.</param>
        /// <param name="listType">Type of the list.</param>
        /// <param name="valueInfo">Information about the value. Can be <c>null</c>.</param>
        private void SerializeTagBlock(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, object list, Type listType, TagFieldAttribute valueInfo)
        {
            var writer = block.Writer;
            var count  = 0;

            if (list != null)
            {
                // Use reflection to get the number of elements in the list
                var countProperty = listType.GetProperty("Count");
                count = (int)countProperty.GetValue(list);
            }
            if (count == 0)
            {
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                return;
            }

            var elementType = listType.GenericTypeArguments[0];
            TagStructureAttribute structure;

            try
            {
                structure = TagStructure.GetTagStructureInfo(elementType, Version).Structure;
            }
            catch
            {
                structure = null;
            }

            // Serialize each value in the list to a data block
            var tagBlock       = context.CreateBlock();
            var enumerableList = (System.Collections.IEnumerable)list;

            foreach (var val in enumerableList)
            {
                SerializeValue(version, context, tagStream, tagBlock, val, null, elementType);
            }

            // Ensure the block is aligned correctly
            var align = Math.Max(DefaultBlockAlign, (valueInfo != null) ? valueInfo.Align : 0);

            StreamUtil.Align(tagStream, (int)align);

            // Finalize the block and write the tag block reference
            writer.Write(count);
            block.WritePointer(tagBlock.Finalize(tagStream), listType);
            writer.Write(0);
        }
Beispiel #4
0
        /// <summary>
        /// Serializes a tag structure into a context.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStructure">The tag structure.</param>
        public static void Serialize <T>(ISerializationContext context, T tagStructure)
        {
            // Serialize the structure to a data block
            context.BeginSerialize();
            var tagStream   = new MemoryStream();
            var structBlock = context.CreateBlock();

            SerializeStruct(context, tagStream, structBlock, tagStructure);

            // Finalize the block and write all of the tag data out
            var mainStructOffset = structBlock.Finalize(tagStream);
            var data             = tagStream.ToArray();

            context.EndSerialize(data, mainStructOffset);
        }
Beispiel #5
0
        /// <summary>
        /// Serializes a tag structure into a context.
        /// </summary>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStructure">The tag structure.</param>
        /// <param name="offset">An optional offset to begin serializing at.</param>
        public void Serialize(ISerializationContext context, object tagStructure, uint?offset = null)
        {
            // Serialize the structure to a data block
            var info = TagStructure.GetTagStructureInfo(tagStructure.GetType(), Version);

            context.BeginSerialize(info);
            var tagStream   = new MemoryStream();
            var structBlock = context.CreateBlock();

            SerializeStruct(context, tagStream, structBlock, info, tagStructure);

            // Finalize the block and write all of the tag data out
            var mainStructOffset = offset ?? structBlock.Finalize(tagStream);
            var data             = tagStream.ToArray();

            context.EndSerialize(info, data, mainStructOffset);
        }
Beispiel #6
0
        private void SerializeIndirectValue(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, object val, Type valueType)
        {
            var writer = block.Writer;

            if (val == null)
            {
                writer.Write(0);
                return;
            }

            // Serialize the value to a temporary block
            var valueBlock = context.CreateBlock();

            SerializeValue(version, context, tagStream, valueBlock, val, null, valueType);

            // Finalize the block and write the pointer
            block.WritePointer(valueBlock.Finalize(tagStream), valueType);
        }
Beispiel #7
0
        /// <summary>
        /// Serializes a tag block.
        /// </summary>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStream">The stream to write completed blocks of tag data to.</param>
        /// <param name="block">The temporary block to write incomplete tag data to.</param>
        /// <param name="list">The list of values in the tag block.</param>
        /// <param name="listType">Type of the list.</param>
        /// <param name="valueInfo">Information about the value. Can be <c>null</c>.</param>
        private void SerializeTagBlock(ISerializationContext context, MemoryStream tagStream, IDataBlock block, object list, Type listType, TagFieldAttribute valueInfo)
        {
            var writer = block.Writer;
            var listCount = 0;
            if (list != null)
            {
                // Use reflection to get the number of elements in the list
                var countProperty = listType.GetProperty("Count");
                listCount = (int)countProperty.GetValue(list);
            }
            if (listCount == 0)
            {
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                return;
            }

            // Serialize each value in the list to a data block
            var tagBlock = context.CreateBlock();
            var enumerableList = (System.Collections.IEnumerable)list;
            var valueType = listType.GenericTypeArguments[0];
            foreach (var val in enumerableList)
                SerializeValue(context, tagStream, tagBlock, val, null, valueType);

            // Ensure the block is aligned correctly
            var align = Math.Max(DefaultBlockAlign, (valueInfo != null) ? valueInfo.DataAlign : 0);
            StreamUtil.Align(tagStream, (int)align);

            // Finalize the block and write the tag block reference
            writer.Write(listCount);
            block.WritePointer(tagBlock.Finalize(tagStream), listType);
            writer.Write(0);
        }
Beispiel #8
0
        private void SerializeIndirectValue(ISerializationContext context, MemoryStream tagStream, IDataBlock block, object val, Type valueType)
        {
            var writer = block.Writer;
            if (val == null)
            {
                writer.Write(0);
                return;
            }

            // Serialize the value to a temporary block
            var valueBlock = context.CreateBlock();
            SerializeValue(context, tagStream, valueBlock, val, null, valueType);

            // Finalize the block and write the pointer
            block.WritePointer(valueBlock.Finalize(tagStream), valueType);
        }
Beispiel #9
0
        /// <summary>
        /// Serializes a tag structure into a context.
        /// </summary>
        /// <param name="context">The serialization context to use.</param>
        /// <param name="tagStructure">The tag structure.</param>
        /// <param name="offset">An optional offset to begin serializing at.</param>
        public override void Serialize(ISerializationContext context, object tagStructure, uint?offset = null)
        {
            if (context.GetType() != typeof(ResourceDefinitionSerializationContext))
            {
                throw new Exception($"Invalid context type given resource deserialization");
            }

            var resourceContext = context as ResourceDefinitionSerializationContext;

            // Serialize the structure to a data block
            var info = TagStructure.GetTagStructureInfo(tagStructure.GetType(), Version);

            context.BeginSerialize(info);
            var tagStream   = new MemoryStream();
            var structBlock = (ResourceDefinitionSerializationContext.ResourceDefinitionDataBlock)context.CreateBlock();

            structBlock.BlockType     = resourceContext.InitialAddressType;
            structBlock.Writer.Format = Format;
            SerializeStruct(context, tagStream, structBlock, info, tagStructure);

            // Finalize the block and write all of the tag data out
            var mainStructOffset = offset ?? structBlock.Finalize(tagStream);

            var data = tagStream.ToArray();

            context.EndSerialize(info, data, mainStructOffset);
            var mainOffset = resourceContext.MainStructOffset.Offset;

            // move over the remaining fixups to the context
            foreach (var fixup in structBlock.FixupLocations)
            {
                fixup.BlockOffset += (uint)mainOffset;
                resourceContext.FixupLocations.Add(fixup);
            }

            foreach (var location in structBlock.InteropLocations)
            {
                location.Address = new CacheAddress(location.Address.Type, (int)(location.Address.Offset + mainOffset));
                resourceContext.InteropLocations.Add(location);
            }
        }
Beispiel #10
0
        public override void SerializeD3DStructure(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, object val, Type valueType)
        {
            if (context.GetType() != typeof(ResourceDefinitionSerializationContext))
            {
                throw new Exception($"Invalid context type given resource deserialization");
            }

            if (block.GetType() != typeof(ResourceDefinitionSerializationContext.ResourceDefinitionDataBlock))
            {
                throw new Exception($"Invalid block type given resource deserialization");
            }

            var resourceBlock   = block as ResourceDefinitionSerializationContext.ResourceDefinitionDataBlock;
            var resourceContext = context as ResourceDefinitionSerializationContext;

            var writer = block.Writer;

            if (val == null)
            {
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                return;
            }

            var addressType = (CacheAddressType)valueType.GetField("AddressType").GetValue(val);
            var nextStream  = (MemoryStream)resourceContext.GetWriter(addressType).BaseStream;
            var genericType = valueType.GenericTypeArguments[0];
            var def         = valueType.GetField("Definition").GetValue(val);
            // Serialize the value to a temporary block
            var resourceBlock2 = (ResourceDefinitionSerializationContext.ResourceDefinitionDataBlock)context.CreateBlock();

            resourceBlock2.BlockType = addressType;
            SerializeValue(version, context, tagStream, resourceBlock2, def, null, genericType);

            // Finalize the block and write the pointer

            var offset = (int)resourceBlock2.Finalize(nextStream);


            // find where in the stream the d3dstructure pointer will be written
            var blockOffset = (int)writer.BaseStream.Position;
            var address     = new CacheAddress(addressType, blockOffset);


            int structureTypeIndex;

            if (genericType == typeof(BitmapDefinition))
            {
                structureTypeIndex = 2;
            }
            else if (genericType == typeof(BitmapInterleavedDefinition))
            {
                structureTypeIndex = 3;
            }
            else if (genericType == typeof(VertexBufferDefinition))
            {
                structureTypeIndex = 0;
            }
            else if (genericType == typeof(IndexBufferDefinition))
            {
                structureTypeIndex = 1;
            }
            else
            {
                throw new Exception();
            }

            var interopLocation = new ResourceInteropLocation
            {
                ResourceStructureTypeIndex = structureTypeIndex,
                Address = address
            };

            var fixupLocation = new ResourceFixupLocation
            {
                Address     = new CacheAddress(addressType, offset),
                BlockOffset = (uint)blockOffset
            };

            foreach (var fixup in resourceBlock2.FixupLocations)
            {
                fixup.BlockOffset += (uint)offset;
                resourceContext.FixupLocations.Add(fixup);
            }

            resourceBlock.FixupLocations.Add(fixupLocation);
            resourceBlock.InteropLocations.Add(interopLocation);

            writer.Write(address.Value);
            writer.Write(0);
            writer.Write(0);
        }