Exemple #1
0
        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);
        }