Ejemplo n.º 1
0
 public ResourceDefinitionSerializationContext(EndianReader dataReader, EndianWriter dataWriter, EndianReader secondaryDataReader, EndianWriter secondaryDataWriter, EndianReader definitionReader, EndianWriter definitionWriter, CacheAddressType initialAddressType)
 {
     DataReader          = dataReader;
     DataWriter          = dataWriter;
     DefinitionReader    = definitionReader;
     DefinitionWriter    = definitionWriter;
     SecondaryDataReader = secondaryDataReader;
     SecondaryDataWriter = secondaryDataWriter;
     InitialAddressType  = initialAddressType;
 }
Ejemplo n.º 2
0
        public EndianWriter GetWriter(CacheAddressType type)
        {
            switch (type)
            {
            case CacheAddressType.Data:
                return(DataWriter);

            case CacheAddressType.Definition:
                return(DefinitionWriter);

            case CacheAddressType.SecondaryData:
                return(SecondaryDataWriter);

            default:
                return(null);
            }
        }
Ejemplo n.º 3
0
 public TagBlock(CacheAddressType addressType, List <T> elements)
 {
     AddressType = addressType;
     Elements    = elements;
 }
Ejemplo n.º 4
0
 public TagBlock(CacheAddressType addressType)
 {
     AddressType = addressType;
     Elements    = new List <T>();
 }
Ejemplo n.º 5
0
 public ResourceDefinitionSerializationContext(EndianWriter dataWriter, EndianWriter secondaryDataWriter, EndianWriter definitionWriter, CacheAddressType initialAddressType) :
     this(null, dataWriter, null, secondaryDataWriter, null, definitionWriter, initialAddressType)
 {
 }
Ejemplo n.º 6
0
 public ResourceDefinitionSerializationContext(EndianReader dataReader, EndianReader definitionReader, CacheAddressType initialAddressType) :
     this(dataReader, null, null, null, definitionReader, null, initialAddressType)
 {
 }
Ejemplo n.º 7
0
 public CacheAddress(CacheAddressType type, int offset) : this((((uint)type) << TypeShift) | ((uint)offset & OffsetMask))
 {
 }
Ejemplo n.º 8
0
 public DataSerializationContext(EndianWriter writer, CacheAddressType addressType = CacheAddressType.Memory) :
     this(null, writer, addressType)
 {
 }
Ejemplo n.º 9
0
 public DataSerializationContext(EndianReader reader, CacheAddressType addressType = CacheAddressType.Memory) :
     this(reader, null, addressType)
 {
 }
Ejemplo n.º 10
0
 public DataSerializationContext(EndianReader reader, EndianWriter writer, CacheAddressType addressType = CacheAddressType.Memory)
 {
     Reader      = reader;
     Writer      = writer;
     AddressType = addressType;
 }
Ejemplo n.º 11
0
        public override void SerializeTagData(ISerializationContext context, MemoryStream tagStream, IDataBlock block, TagData tagData, TagFieldAttribute valueInfo)
        {
            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 (tagData == null || tagData.Data == null || tagData.Data.Length == 0)
            {
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                writer.Write(0);
                return;
            }

            CacheAddressType addressType = tagData.AddressType;

            int  dataOffset  = 0;                                      // offset in the data stream to the start of the data
            uint blockOffset = (uint)writer.BaseStream.Position + 0xC; // offset to the address pointing to the above relative to the current block.
            uint size        = 0;

            // stream where the byte[] in the data should be written to:
            var dataStream = (MemoryStream)resourceContext.GetWriter(addressType).BaseStream;

            var data = tagData.Data;

            if (data != null && data.Length > 0)
            {
                // Ensure the block is aligned correctly
                var align = Math.Max(DefaultResourceAlign, (valueInfo != null) ? valueInfo.Align : 0);
                StreamUtil.Align(dataStream, (int)align);

                // Write its data
                dataOffset = (int)dataStream.Position;
                size       = (uint)data.Length;
                dataStream.Write(data, 0, data.Length);
                StreamUtil.Align(dataStream, DefaultResourceAlign);
            }

            var dataAddress = new CacheAddress(addressType, dataOffset);

            var dataFixup = new ResourceFixupLocation
            {
                BlockOffset = blockOffset,
                Address     = dataAddress
            };

            resourceBlock.FixupLocations.Add(dataFixup);

            // this fixup will need to be adjusted when we move the block

            // Write the reference data
            writer.Write(size);
            writer.Write(0);
            writer.Write(0);
            writer.Write(dataAddress.Value);
            writer.Write(0);
        }
Ejemplo n.º 12
0
        public override void SerializeTagBlock(CacheVersion version, ISerializationContext context, MemoryStream tagStream, IDataBlock block, object list, Type listType, TagFieldAttribute valueInfo)
        {
            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;
            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];

            CacheAddressType addressType = (CacheAddressType)listType.GetField("AddressType").GetValue(list);

            // Serialize each value in the list to a data block
            var resourceBlock2 = (ResourceDefinitionSerializationContext.ResourceDefinitionDataBlock)resourceContext.CreateBlock();

            resourceBlock2.BlockType = addressType;
            var addressTypeStream = (MemoryStream)resourceContext.GetWriter(addressType).BaseStream;

            var enumerableList = (System.Collections.IEnumerable)list;

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

            // Ensure the block is aligned correctly
            var align = 0x10;

            StreamUtil.Align(resourceBlock2.Stream, align);

            // Finalize the block and write the tag block reference using a cache address
            var offset = resourceBlock2.Finalize(addressTypeStream);    // offset of the data in the tagblock on the actual stream
            //var blockOffset = addressTypeStream.Position;               // no need to fix that particular fixup later
            var address = new CacheAddress(addressType, (int)offset);

            var resourceFixup = new ResourceFixupLocation
            {
                Address     = address,
                BlockOffset = (uint)writer.BaseStream.Position + 0x4
            };

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

            foreach (var location in resourceBlock2.InteropLocations)
            {
                location.Address = new CacheAddress(location.Address.Type, (int)(location.Address.Offset + offset));
                resourceContext.InteropLocations.Add(location);
            }

            resourceBlock.FixupLocations.Add(resourceFixup);

            writer.Write(count);
            writer.Write(address.Value);    // write address as 0, we use the fixups
            writer.Write(0);
        }