コード例 #1
0
        public static PropertyList Read(
            Stream input,
            DataFormats.PropertyList resource,
            Endian endian,
            PropertySetSchemaProvider schemaProvider)
        {
            var instance = new PropertyList();

            instance._Flags       = resource.Flags;
            instance._TypeId      = (byte)resource.TypeId;
            instance._TotalWeight = resource.TotalWeight;

            instance.Items.Clear();
            instance.Weights.Clear();

            if (resource.ItemCount > 0)
            {
                var handler = HandlerFactory.Get(resource.TypeId);
                if (handler.ByteSize != resource.ItemSize)
                {
                    throw new InvalidOperationException();
                }

                if (resource.DataOffset == 0)
                {
                    throw new InvalidOperationException();
                }

                input.Position = resource.DataOffset;
                using (var data = input.ReadToMemoryStream(resource.ItemCount * resource.ItemSize))
                {
                    for (uint i = 0, o = 0; i < resource.ItemCount; i++, o += resource.ItemSize)
                    {
                        data.Position = o;

                        object item;
                        if (handler.UsesPointer == false)
                        {
                            item = handler.Read(data, endian, schemaProvider);
                        }
                        else
                        {
                            var pointerOffset = data.ReadOffset(endian);
                            if (pointerOffset == 0)
                            {
                                throw new InvalidOperationException();
                            }

                            input.Position = resource.DataOffset + pointerOffset;
                            item           = handler.Read(input, endian, schemaProvider);
                        }
                        instance.Items.Add(item);
                    }
                }

                if (resource.WeightsOffset != 0)
                {
                    input.Position = resource.WeightsOffset;
                    for (uint i = 0; i < resource.ItemCount; i++)
                    {
                        var weight = input.ReadValueU32(endian);
                        instance.Weights.Add(weight);
                    }
                }
            }

            return(instance);
        }
コード例 #2
0
        public static void Write(
            Stream output,
            PropertyList instance,
            Endian endian,
            DataFormats.PropertyList resource,
            long ownerOffset,
            PropertySetSchemaProvider schemaProvider)
        {
            if (instance.TypeId == 29)
            {
                resource.Flags         = instance._Flags;
                resource.DataOffset    = 0;
                resource.TypeId        = instance._TypeId;
                resource.ItemSize      = 0;
                resource.WeightsOffset = 0;
                resource.ItemCount     = 0;
                resource.TotalWeight   = 0;
                return;
            }

            if (instance.Weights.Count > 0 &&
                instance.Weights.Count != instance.Items.Count)
            {
                throw new InvalidOperationException();
            }

            var handler = HandlerFactory.Get(instance._TypeId);

            resource.Flags       = instance._Flags;
            resource.TypeId      = instance._TypeId;
            resource.ItemSize    = (uint)handler.ByteSize;
            resource.ItemCount   = (uint)instance.Items.Count;
            resource.TotalWeight = instance._TotalWeight;

            var dataSize = resource.ItemSize * resource.ItemCount;

            resource.DataOffset    = output.Position;
            resource.WeightsOffset = resource.DataOffset + dataSize;

            long dataOffset;

            if (instance.Weights.Count > 0)
            {
                resource.WeightsOffset = resource.DataOffset + dataSize;
                dataOffset             = resource.WeightsOffset + (4 * resource.ItemCount);
            }
            else
            {
                dataOffset             = resource.WeightsOffset;
                resource.WeightsOffset = 0;
            }

            if (resource.ItemCount > 0)
            {
                output.Position = dataOffset;

                using (var data = new MemoryStream())
                {
                    foreach (var item in instance.Items)
                    {
                        if (handler.UsesPointer == false)
                        {
                            handler.Write(data, item, endian, ownerOffset, schemaProvider);
                            data.Position = data.Position.Align(handler.Alignment);
                            data.SetLength(data.Position);
                        }
                        else
                        {
                            var pointerOffset = output.Position - resource.DataOffset;
                            handler.Write(output, item, endian, ownerOffset, schemaProvider);
                            output.Position = output.Position.Align(handler.Alignment);

                            data.WriteOffset(pointerOffset, endian);
                            data.Position = data.Position.Align(8);
                            data.SetLength(data.Position);
                        }
                    }

                    data.Flush();

                    if (data.Length != dataSize)
                    {
                        throw new InvalidOperationException();
                    }

                    var endPosition = output.Position;

                    output.Position = resource.DataOffset;
                    data.Position   = 0;
                    output.WriteFromStream(data, data.Length);

                    if (instance.Weights.Count > 0)
                    {
                        output.Position = resource.WeightsOffset;
                        foreach (var weight in instance.Weights)
                        {
                            output.WriteValueU32(weight, endian);
                        }
                    }

                    output.Position = endPosition;
                }
            }
        }