예제 #1
0
        /// <summary>
        /// Collect properties information of the given object.
        /// </summary>
        private static IEnumerable <ValueToFormat> CollectPropertiesForWriting(object obj)
        {
            var type = obj.GetType();

            return(from prop in type.GetProperties()
                   let val = prop.GetValue(obj, Array.Empty <object>())
                             let isArray = prop.PropertyType.IsArray
                                           select new ValueToFormat
            {
                Value = val,
                IsArray = isArray,
                Format = val == null
                                ? PiffDataFormats.Skip
                                : prop.GetCustomAttribute <PiffDataFormatAttribute>()?.Format
                         ?? (isArray
                                   ? PiffDataUtility.GetDefaultFormat(prop.PropertyType.GetElementType())
                                   : PiffDataUtility.GetDefaultFormat(prop.PropertyType))
            });
        }
예제 #2
0
        /// <summary>
        /// Read a box if it is of expected type. Back off if it's not.
        /// </summary>
        /// <param name="expectedType">Expected box type</typeparam>
        /// <param name="bytes"></param>
        /// <returns>Box object or null</returns>
        internal static object ReadBox(Stream bytes, Type expectedType)
        {
            var length = GetInt32(bytes);

            if (length < 8)
            {
                throw new ArgumentException($"Improper box length {length}.");
            }

            var id = GetFixedString(bytes, 4);

            if (!sBoxes.TryGetValue(id, out var type))
            {
                throw new ArgumentException($"Inrecognized box type '{id}'.");
            }

            if (type != expectedType)
            {
                // Not expected type, back off
                bytes.Seek(-8, SeekOrigin.Current);
                return(null);
            }

            var obj = Activator.CreateInstance(type);

            var props =
                from prop in type.GetProperties()
                let isArray = prop.PropertyType.IsArray
                              select new ValueToRead
            {
                Property = prop,
                IsArray  = isArray,
                Format   = prop.GetCustomAttribute <PiffDataFormatAttribute>()?.Format
                           ?? (isArray
                                ? PiffDataUtility.GetDefaultFormat(prop.PropertyType.GetElementType())
                                : PiffDataUtility.GetDefaultFormat(prop.PropertyType))
            };

            ReadBoxValues(bytes, obj, props.ToArray());

            return(obj);
        }