Exemplo n.º 1
0
    protected virtual CodeNode ReadField(string fieldName)
    {
        var field     = GetType().GetField(fieldName);
        var fieldType = field.FieldType;

        if (fieldType.IsArray)
        {
            var elementType = fieldType.GetElementType();
            if (elementType.IsValueType)
            {
                int len;
                if (field.TryGetAttribute(out ExpectedAttribute e))
                {
                    if (e.Value is string s)
                    {
                        len = s.Length;
                    }
                    else
                    {
                        len = ((Array)e.Value).Length;
                    }
                }
                else
                {
                    len = GetCount(fieldName);
                }

                var san = typeof(StructArrayNode <>).MakeGenericType(elementType);
                var o   = (CodeNode)Activator.CreateInstance(san, len);
                o.Bytes = Bytes;
                o.Read();

                var value = san.GetField("arr").GetValue(o);
                field.SetValue(this, value);
                o.NodeValue = value.GetString();
                return(o);
            }

            throw new InvalidOperationException($"{GetType().FullName}. {field.Name} is an array {elementType}[]");
        }
        if (fieldType.IsClass)
        {
            var o = (CodeNode)(field.GetValue(this) ?? (CodeNode)Activator.CreateInstance(fieldType));
            o.Bytes = Bytes;
            o.Read();
            field.SetValue(this, o);
            return(o);
        }
        Type sn;

        if (fieldType.IsEnum)
        {
            sn = typeof(EnumNode <>).MakeGenericType(fieldType);;
        }
        else if (fieldType.IsValueType)
        {
            sn = typeof(StructNode <>).MakeGenericType(fieldType);
        }
        else
        {
            throw new InvalidOperationException(fieldType.Name);
        }
        {
            CodeNode o = (CodeNode)Activator.CreateInstance(sn);
            o.Bytes = Bytes;
            o.Read();
            var value = sn.GetField("t").GetValue(o);
            field.SetValue(this, value);
            o.NodeValue = value.GetString();
            return(o);
        }
    }