public void Write( Stream data, Endian endian, DataFormats.PropertySet resource, long ownerOffset, PropertySetSchemaProvider schemaProvider) { Write(data, this, endian, resource, ownerOffset, schemaProvider); }
void IHandler.Write( Stream output, object value, Endian endian, long ownerOffset, PropertySetSchemaProvider schemaProvider) { this.Write(output, (T)value, endian, ownerOffset); }
public static PropertySet Read( Stream input, DataFormats.PropertySet resource, Endian endian, PropertySetSchemaProvider schemaProvider) { var instance = new PropertySet(); instance._Name = resource.Name; instance._ReferenceCount = resource.ReferenceCount; instance._SchemaName = resource.SchemaName; instance._Flags = resource.Flags; var parentHandles = new ResourceHandle[resource.ParentCount]; if (resource.ParentCount > 0) { input.Position = resource.ParentsOffset; for (uint i = 0; i < resource.ParentCount; i++) { parentHandles[i] = ResourceHandle.Read(input, endian); } } instance._Parents.Clear(); instance._Parents.AddRange(parentHandles); PropertySetSchema schema; if (resource.SchemaName == Symbol.Invalid || resource.SchemaName == resource.Name) { if ((resource.Flags & PropertyCollectionFlags.InheritSchema) != 0) { throw new InvalidOperationException(); } var properties = new PropertySchema[resource.PropertyCount]; if (resource.PropertyCount > 0) { input.Position = resource.PropertiesOffset; for (uint i = 0; i < resource.PropertyCount; i++) { properties[i] = PropertySchema.Read(input, endian); } } schema = new PropertySetSchema(properties, resource.DataSize); if (resource.Name != Symbol.Invalid && resource.SchemaName == resource.Name) { schemaProvider.Add(resource.Name.Id, schema); } instance._DefinedSchema = schema; } else { if (resource.PropertyCount != 0) { throw new NotSupportedException(); } schema = schemaProvider.Get(resource.SchemaName.Id); } instance._Properties.Clear(); instance._DefaultProperties.Clear(); if (schema.Count > 0) { if (resource.DataOffset == 0) { throw new InvalidOperationException(); } input.Position = resource.DefaultBitsOffset; var defaultBits = new uint[(schema.Count + 31) >> 5]; for (int i = 0; i < defaultBits.Length; i++) { defaultBits[i] = input.ReadValueU32(endian); } input.Position = resource.DataOffset; using (var data = input.ReadToMemoryStream(schema.DataSize)) { for (int i = 0; i < schema.Count; i++) { var property = schema[i]; var isDefault = (defaultBits[i >> 5] & (1u << (i % 32))) != 0; var handler = HandlerFactory.Get(property.Type); data.Position = property.Offset; object value; if (handler.UsesPointer == false) { value = handler.Read(data, endian, schemaProvider); } else { var pointerOffset = data.ReadOffset(endian); if (pointerOffset == 0) { throw new InvalidOperationException(); } input.Position = resource.DataOffset + pointerOffset; value = handler.Read(input, endian, schemaProvider); } instance._Properties.Add(property.Id, value); if (isDefault == true) { instance._DefaultProperties.Add(property.Id); } } } } return(instance); }
public static void Write( Stream output, PropertySet instance, Endian endian, DataFormats.PropertySet resource, long ownerOffset, PropertySetSchemaProvider schemaProvider) { resource.Flags = instance._Flags; resource.Name = instance._Name; resource.ReferenceCount = instance._ReferenceCount; resource.ParentCount = (ushort)instance._Parents.Count; resource.ParentMask = 0xFFFFFFFFu; resource.SchemaName = instance._SchemaName; resource.PropertyMask = 0xFFFFFFFFu; if (resource.ParentCount == 0) { resource.ParentsOffset = 0; } else { resource.ParentsOffset = output.Position; foreach (var parentHandle in instance._Parents) { parentHandle.Write(output, endian); } } bool writeSchema; PropertySetSchema schema; if (resource.SchemaName == Symbol.Invalid || resource.SchemaName == resource.Name) { if ((resource.Flags & PropertyCollectionFlags.InheritSchema) != 0) { throw new InvalidOperationException(); } /* * var properties = new List<PropertySchema>(); * uint runningOffset = 0; * foreach (var kv in instance.Properties) * { * var propertyValue = kv.Value; * if (propertyValue == null) * { * throw new InvalidOperationException(); * } * var handler = HandlerFactory.Get(propertyValue.GetType()); * * runningOffset = runningOffset.Align((uint)handler.Alignment); * * var propertyId = kv.Key; * var propertyType = handler.Id; * var propertyOffset = runningOffset; * * properties.Add(new PropertySchema(propertyId, propertyType, propertyOffset)); * * if (handler.UsesPointer == false) * { * runningOffset += (uint)handler.ByteSize; * } * else * { * runningOffset += 8; * } * } * * if (runningOffset > ushort.MaxValue) * { * throw new InvalidOperationException(); * } */ schema = instance._DefinedSchema; writeSchema = true; if (resource.Name != Symbol.Invalid && resource.SchemaName == resource.Name) { schemaProvider.Add(resource.Name.Id, schema); } resource.PropertyCount = (ushort)instance._Properties.Count; resource.DataSize = schema.DataSize; } else { if (resource.PropertyCount != 0) { throw new NotSupportedException(); } schema = schemaProvider.Get(resource.SchemaName.Id); writeSchema = false; resource.PropertyCount = 0; resource.DataSize = 0; } if (schema.Count == 0) { resource.PropertiesOffset = 0; resource.DefaultBitsOffset = 0; resource.DataOffset = 0; } else { if (writeSchema == true) { resource.PropertiesOffset = output.Position; resource.DefaultBitsOffset = resource.PropertiesOffset + (8 * schema.Count); } else { resource.PropertiesOffset = 0; resource.DefaultBitsOffset = output.Position; } resource.DataOffset = resource.DefaultBitsOffset + (((schema.Count + 31) >> 5) * 4); var defaultBits = new uint[(schema.Count + 31) >> 5]; output.Position = (resource.DataOffset + schema.DataSize).Align(16); using (var data = new MemoryStream(schema.DataSize)) { for (int i = 0; i < schema.Count; i++) { var property = schema[i]; if (instance.Properties.ContainsKey(property.Id) == false) { throw new InvalidOperationException(); } var value = instance.Properties[property.Id]; var handler = HandlerFactory.Get(property.Type); if (instance.DefaultProperties.Contains(property.Id) == true) { defaultBits[i >> 5] |= 1u << (i % 32); } data.Position = property.Offset; if (handler.UsesPointer == false) { handler.Write(data, value, endian, ownerOffset, schemaProvider); } else { output.Position = output.Position.Align(handler.Alignment); var pointerOffset = output.Position - resource.DataOffset; handler.Write(output, value, endian, ownerOffset, schemaProvider); data.WriteOffset(pointerOffset, endian); } } data.Flush(); if (data.Length != schema.DataSize) { throw new InvalidOperationException(); } var endPosition = output.Position; if (writeSchema == true) { output.Position = resource.PropertiesOffset; for (int i = 0; i < schema.Count; i++) { var property = schema[i]; property.Write(output, endian); } } output.Position = resource.DefaultBitsOffset; foreach (var defaultBit in defaultBits) { output.WriteValueU32(defaultBit, endian); } output.Position = resource.DataOffset; data.Position = 0; output.WriteFromStream(data, schema.DataSize); output.Position = endPosition; } } }
object IHandler.Read(Stream input, Endian endian, PropertySetSchemaProvider schemaProvider) { return(this.Read(input, endian)); }
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); }
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; } } }