Пример #1
0
        private static object WriteObject(MappingWriteArgs args, object item, int baseOffset = 0)
        {
            var properties = item.GetType()
                             .GetProperties()
                             .Select(x => GetPropertySettings(item.GetType(), x))
                             .Where(x => x.DataInfo != null)
                             .ToList();

            foreach (var property in properties)
            {
                if (property.DataInfo.Offset.HasValue)
                {
                    var newPosition = baseOffset + property.DataInfo.Offset.Value;
                    if (args.Writer.BaseStream.Position != newPosition)
                    {
                        FlushBitField(args);
                    }

                    args.Writer.BaseStream.Position = newPosition;
                }

                var value = property.MemberInfo.GetValue(item, BindingFlags.Default, null, null, null);
                args.Count = property.GetLengthFunc?.Invoke(item) ?? property.DataInfo.Count;
                WriteProperty(args, value, property.MemberInfo.PropertyType, property);
            }

            FlushBitField(args);
            return(item);
        }
Пример #2
0
        private static void FlushBitField(MappingWriteArgs args)
        {
            if (args.BitIndex <= 0)
            {
                return;
            }

            args.Writer.Write(args.BitData);
            args.BitIndex = 0;
            args.BitData  = 0;
        }
Пример #3
0
        private static void WriteObject(MappingWriteArgs args, object value, Type listType, MyProperty property)
        {
            var writer      = args.Writer;
            var oldPosition = (int)writer.BaseStream.Position;

            WriteProperty(args, value, listType, property);

            var newPosition = writer.BaseStream.Position;
            var stride      = property.DataInfo.Stride;

            if (stride > 0)
            {
                var missingBytes = stride - (int)(newPosition - oldPosition);
                if (missingBytes < 0)
                {
                    throw new InvalidOperationException($"The stride is smaller than {listType.Name} definition.");
                }
                else if (missingBytes > 0)
                {
                    writer.BaseStream.Position += missingBytes;
                }
            }
        }
Пример #4
0
        private static void WriteProperty(MappingWriteArgs args, object value, Type type, MyProperty property)
        {
            if (type != typeof(bool))
            {
                FlushBitField(args);
            }

            if (mappings.TryGetValue(type, out var mapping))
            {
                args.Item          = value;
                args.DataAttribute = property.DataInfo;
                mapping.Writer(args);
            }
            else if (type.IsEnum)
            {
                var underlyingType = Enum.GetUnderlyingType(type);
                if (!mappings.TryGetValue(underlyingType, out mapping))
                {
                    throw new InvalidDataException($"The enum {type.Name} has an unsupported size.");
                }

                args.DataAttribute = property.DataInfo;
                args.Item          = value;
                mapping.Writer(args);
            }
            else if (type.CanEnumerate())
            {
                Type itemType;
                if (type.IsArray)
                {
                    itemType = type?
                               .GetMethod("Get")?
                               .ReturnType;
                }
                else
                {
                    itemType = type.GetGenericArguments().FirstOrDefault();
                }

                if (itemType == null)
                {
                    throw new InvalidDataException($"The list {property.MemberInfo.Name} does not have any specified type.");
                }

                var missing = args.Count;
                foreach (var item in value as IEnumerable)
                {
                    if (missing-- < 1)
                    {
                        break;
                    }

                    WriteObject(args, item, itemType, property);
                }

                while (missing-- > 0)
                {
                    var item = Activator.CreateInstance(itemType);
                    WriteObject(args, item, itemType, property);
                }
            }
            else
            {
                WriteObject(args.Writer, value, (int)args.Writer.BaseStream.Position);
            }
        }