/// <summary> /// Creates an instance of <see cref="SdbSchemaData"/> using embedded streams for constraint data and simple types. /// </summary> /// <remarks> /// Constraint data are contained in a binary file that is defined as: /// /// <![CDATA[ /// [SdbDataHead][SdbClassIdToSchemaTypeIndex][SdbSchemaType][SdbParticleConstraint][SdbParticleChildrenIndex][SdbAttributeConstraint] /// ]]> /// /// Since the size of the arrays are different for different <paramref name="fileFormat"/>, these are all marshalled separately, with the information /// of offsets contained in <see cref="SdbDataHead"/>. These items are deserialized in this method, while <see cref="SerializeSdbData(Stream)"/> provides /// the infrastructure to serialize them back to a binary file in the correct order /// </remarks> /// <param name="fileFormat">The version to load</param> private SdbSchemaData(FileFormatVersions fileFormat) { if (!fileFormat.Any()) { throw new ArgumentOutOfRangeException(nameof(fileFormat)); } _fileFormat = fileFormat; using (var schema = GetStream(fileFormat, Constraints)) { var dataHead = SdbData.Deserialize <SdbDataHead>(schema); dataHead.Validate(); var length = (int)schema.Length; if (dataHead.End != length) { throw new InvalidDataException(); } ClassIdMap = SdbData.Deserialize <SdbClassIdToSchemaTypeIndex>(schema, dataHead.ClassIds); SchemaTypes = SdbData.Deserialize <SdbSchemaType>(schema, dataHead.SchemaType); Particles = SdbData.Deserialize <SdbParticleConstraint>(schema, dataHead.Particles); ParticleIndexes = SdbData.Deserialize <SdbParticleChildrenIndex>(schema, dataHead.ParticleChildren); Attributes = SdbData.Deserialize <SdbAttributeConstraint>(schema, dataHead.Attributes); } }
private static T[] Deserialize <T>(byte[] data) where T : struct { using (var ms = new MemoryStream(data)) { return(SdbData.Deserialize <T>(ms, SdbSpan.Create <T>(0))); } }
/// <summary> /// Load the fields data from byte data. /// </summary> /// <param name="value">The byte data array.</param> /// <param name="startIndex">The offset the data begins at.</param> public override void LoadFromBytes(byte[] value, int startIndex) { Signature = new byte[SignatureSize]; Array.Copy(value, startIndex, Signature, 0, SignatureSize); startIndex += SignatureSize; for (int i = 0; i < SignatureSize; i++) { if (Signature[i] != SignatureConst[i]) { // TODO: change to resource string throw new InvalidDataException("Invalide schema constraint data."); } } // !!!!Caution: keep the order of the following code lines!!!! DataVersion = SdbData.LoadInt(value, ref startIndex); DataByteCount = SdbData.LoadInt(value, ref startIndex); if (DataVersion != LatestDataVersion) { // TODO: change to resource string throw new InvalidDataException("Invalide schema constraint data."); } StartClassId = SdbData.LoadInt(value, ref startIndex); ClassIdsCount = SdbData.LoadInt(value, ref startIndex); ClassIdsDataOffset = SdbData.LoadInt(value, ref startIndex); SchemaTypeCount = SdbData.LoadInt(value, ref startIndex); SchemaTypeDataOffset = SdbData.LoadInt(value, ref startIndex); ParticleCount = SdbData.LoadInt(value, ref startIndex); ParticleDataOffset = SdbData.LoadInt(value, ref startIndex); ParticleChildrenIndexCount = SdbData.LoadInt(value, ref startIndex); ParticleChildrenIndexDataOffset = SdbData.LoadInt(value, ref startIndex); AttributeCount = SdbData.LoadInt(value, ref startIndex); AttributeDataOffset = SdbData.LoadInt(value, ref startIndex); SimpleTypeCount = SdbData.LoadInt(value, ref startIndex); SimpleTypeDataOffset = SdbData.LoadInt(value, ref startIndex); }
private byte[] VerifyBytes <T>(T instance, byte[] expected) where T : struct { var structLayout = typeof(T).GetTypeInfo().StructLayoutAttribute; Assert.NotNull(structLayout); Assert.Equal(LayoutKind.Sequential, structLayout.Value); Assert.Equal(1, structLayout.Pack); var serialized = SdbData.Serialize(new[] { instance }); var str = string.Join(", ", serialized.Select(t => "0x" + t.ToString("X2"))); _output.WriteLine($"{{{str}}}"); Assert.Equal(expected.Length, Marshal.SizeOf <T>()); Assert.Equal(expected.Length, serialized.Length); Assert.Equal(expected, serialized); return(serialized); }
public void SerializeSdbData(Stream stream) { var head = new SdbDataHead( _fileFormat, ClassIdMap, SchemaTypes, Particles, ParticleIndexes, Attributes); head.Validate(); void ValidatePosition(int position) { if (position != stream.Position) { throw new InvalidDataException(); } } ValidatePosition(0); SdbData.Serialize(head, stream); ValidatePosition(head.ClassIds.Offset); SdbData.Serialize(ClassIdMap, stream); ValidatePosition(head.SchemaType.Offset); SdbData.Serialize(SchemaTypes, stream); ValidatePosition(head.Particles.Offset); SdbData.Serialize(Particles, stream); ValidatePosition(head.ParticleChildren.Offset); SdbData.Serialize(ParticleIndexes, stream); ValidatePosition(head.Attributes.Offset); SdbData.Serialize(Attributes, stream); }