/// <summary> /// Reads data from an STDF data stream and deserializes it into the corresponding STDF record type. /// </summary> /// <param name="stream">Stream object to read the record data from.</param> /// <returns></returns> public override object Deserialize(Stream stream) { SerializeStream = stream; EndOfStream = SerializeStream.Position >= SerializeStream.Length; if (EndOfStream) { return(null); } ReadHeader(out ushort recordLength, out ushort recordTypeCode); if (SerializeStream.Position + recordLength > SerializeStream.Length) { throw new EndOfStreamException("Unexpected end of record during serialization."); } Type recordType = STDFFormatterServices.ConvertTypeCode(recordTypeCode); ISurrogate serializerSurrogate = TypeSurrogateSelector.GetSurrogate(recordType); if (serializerSurrogate == null) { // no surrogate to deserialize this type. Skip to next record and return SerializeStream.Seek(recordLength, SeekOrigin.Current); //Console.WriteLine("Skipping record type " + recordType.Name); return(null); } ISTDFRecord record = (ISTDFRecord)STDFFormatterServices.GetUninitializedObject(recordType); record.RecordLength = recordLength; SerializationInfo info = SerializationInfo.Create(recordType, Converter); long startPosition = SerializeStream.Position; foreach (SerializationInfoEntry field in info) { EndOfRecord = (SerializeStream.Position - startPosition) >= recordLength; if (EndOfRecord) { // If end of record reached yet we still have more fields to serialize, then we can skip the rest of the record. break; } if (field.ItemCountIndex >= 0) { // Field has an item count property, so we are deserializing an array. // Get the number of items to deserialize from the value that was deserialized earlier. int itemCount = info.GetValue <int>((int)field.ItemCountIndex); if (itemCount > 0) { info.SetValue(field.Index, ReadArray(field.Type.GetElementType(), itemCount)); } } else { info.SetValue(field.Index, Read(field.Type)); } } EndOfStream = SerializeStream.Position >= SerializeStream.Length; // Set the fields on the record serializerSurrogate.SetObjectData(record, info); return(record); }
/// <summary> /// Serializes and STDF record object to the output stream. /// </summary> /// <param name="stream">Stream object to serialized the STDF data to.</param> /// <param name="obj">STDF record object to serialize.</param> public override void Serialize(Stream stream, object obj) { Buffer.SetLength(0); SerializeStream = Buffer; EndOfStream = false; EndOfRecord = false; ushort recordLength = 0; if (obj is ISTDFRecord record) { ISurrogate typeSurrogate = TypeSurrogateSelector.GetSurrogate(record.GetType()); if (typeSurrogate == null) { return; } //WriteHeader(0, record.RecordType); // long recordStartPosition = SerializeStream.Position; Type recordType = record.GetType(); SerializationInfo info = SerializationInfo.Create(recordType, Converter); typeSurrogate.GetObjectData(record, info); foreach (SerializationInfoEntry field in info) { if (field.ItemCountIndex >= 0) { // field has an item count property, so we are serializing an array. Get the number of items // to serialize from the item count field serialized earlier (we always serialize according // to the item count field rather than the array size for the array field. Normally these are // equal but it is not mandatory that they be equal). int itemCount = field.ItemCountIndex != null?info.GetValue <int>((int)field.ItemCountIndex) : 0; if (itemCount > 0) { WriteArray(field.Value, field.Type.GetElementType(), 0, itemCount); } } else { WriteMember(field.Value, field.Type); } // For optional fields, save the position after the last field written // that does not have a missing value. Per spec, we can truncate any contiguous missing // value fields from the end of the record. if (!field.IsMissingValue) { recordLength = (ushort)(SerializeStream.Position); } } //recordLength = (ushort)(lastValidPosition - recordStartPosition); if (recordLength != record.RecordLength) { throw new Exception("Mismatched record length."); } record.RecordLength = recordLength; //SerializeStream.Seek(-(SerializeStream.Position - recordStartPosition + 4), SeekOrigin.Current); SerializeStream.Flush(); SerializeStream = stream; WriteHeader(record.RecordLength, record.RecordType); // SerializeStream.Seek(record.RecordLength, SeekOrigin.Current); // SerializeStream.SetLength(SerializeStream.Position); Buffer.SetLength(recordLength); Buffer.WriteTo(stream); EndOfRecord = true; } }