object IHandler.Read(Stream input, Endian endian, PropertySetSchemaProvider schemaProvider) { var resource = new DataFormats.PropertySet(); resource.Deserialize(input, endian); return(PropertySet.Read(input, resource, endian, schemaProvider)); }
public void Write( Stream data, Endian endian, DataFormats.PropertySet resource, long ownerOffset, PropertySetSchemaProvider schemaProvider) { Write(data, this, endian, resource, ownerOffset, schemaProvider); }
public void Write(Stream output, object value, Endian endian, long ownerOffset, PropertySetSchemaProvider schemaProvider) { var startPosition = output.Position; var resource = new DataFormats.PropertySet(); output.Position += resource.Size; ((PropertySet)value).Write(output, endian, resource, startPosition, schemaProvider); var endPosition = output.Position; output.Position = startPosition; resource.OwnerOffset = ownerOffset; resource.Serialize(output, endian); output.Position = endPosition; }
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; } } }