protected SerializationInfo(Type objType, IFormatterConverter converter) { Type = objType; Converter = converter; // create an instance of the object to get missing values from the field initializers. object instance = STDFFormatterServices.GetUninitializedObject(Type); FieldInfo[] fields = STDFFormatterServices.GetSerializeableFields(Type); Info = new SerializationInfoEntry[fields.Length]; for (int i = 0; i < fields.Length; i++) { var field = fields[i]; object value = field.GetValue(instance); string itemCountField = (field.GetCustomAttribute <STDFAttribute>() ?? field.GetCustomAttribute <STDFOptionalAttribute>())?.ItemCountProperty; var entry = new SerializationInfoEntry() { Index = i, Name = field.Name, Type = field.FieldType, IsOptional = field.GetCustomAttribute <STDFOptionalAttribute>() != null, IsSet = false, ItemCountIndex = Array.FindIndex(fields, x => x.Name == itemCountField), Value = value, MissingValue = value }; Info[i] = entry; } }
/// <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); }