示例#1
0
        // Generates an expression that creates an NbtTag for given property of a directly-mappable types.
        // Directly-mappable types are: primitives, enums, byte[], int[], and string.
        public override Expression HandleDirectlyMappedType(string tagName, PropertyInfo property, NullPolicy selfPolicy)
        {
            // declare a local var, which will hold the property's value
            ParameterExpression varValue = Expression.Parameter(property.PropertyType);

            // Fallback path, in case value is null and NullPolicy is InsertDefaults
            Expression defaultVal = Expression.Constant(SerializationUtil.GetDefaultValue(property.PropertyType));
            // varRootTag.Add( new NbtTag(tagName, <defaultVal>) );
            Expression defaultValExpr =
                Expression.Call(varRootTag,
                                NbtCompoundAddMethod,
                                MakeNbtTagCtor(property.PropertyType,
                                               Expression.Constant(tagName, typeof(string)),
                                               defaultVal));

            // varRootTag.Add( new NbtTag(tagName, <varValue>) );
            Expression makeTagExpr =
                Expression.Call(varRootTag,
                                NbtCompoundAddMethod,
                                MakeNbtTagCtor(property.PropertyType,
                                               Expression.Constant(tagName, typeof(string)),
                                               varValue));

            // Getter for the property value
            Expression getPropertyExpr = Expression.MakeMemberAccess(argValue, property);

            // generate the appropriate enclosing expressions, depending on NullPolicy
            return NbtCompiler.MakeNullHandler(varValue, getPropertyExpr, selfPolicy,
                                               makeTagExpr, defaultValExpr, MakePropertyNullMessage(property));
        }
示例#2
0
 public override Expression HandleCompoundObject(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     return MakeNbtTagPropertyHandler(
         property, tagName, typeof(NbtCompound), selfPolicy,
         expr => callResolver.MakeCall(property.PropertyType,
                                       Expression.Constant(tagName, typeof(string)), expr));
 }
示例#3
0
        Expression MakeNbtTagHandler([NotNull] Type tagType, [NotNull] Type valueType, [NotNull] Expression tagNameExpr,
                                     [NotNull] Expression getPropertyExpr, NullPolicy selfPolicy,
                                     [NotNull] String nullMsg,
                                     [NotNull] Func <ParameterExpression, Expression> conversionFunc,
                                     [NotNull] Func <Expression, Expression> processTagExpr)
        {
            // declare a local var, which will hold the property's value
            ParameterExpression varValue = Expression.Parameter(valueType, "value");

            // Primary path, adds the root tag of the NbtFile
            Expression makeTagExpr = processTagExpr(conversionFunc(varValue));

            // Fallback path, in case value is null and NullPolicy is InsertDefaults
            ConstructorInfo tagCtor;

            if (tagType == typeof(NbtTag))
            {
                tagCtor = NbtCompoundCtor;
            }
            else
            {
                tagCtor = tagType.GetConstructor(new[] { typeof(string) });
            }
            Expression defaultVal     = Expression.New(tagCtor, tagNameExpr);
            Expression defaultValExpr = processTagExpr(defaultVal);

            // Generate the appropriate enclosing expressions, which choose path depending on NullPolicy
            return(NbtCompiler.MakeNullHandler(varValue, getPropertyExpr, selfPolicy,
                                               makeTagExpr, defaultValExpr, nullMsg));
        }
示例#4
0
 public SwarmBenchmark()
 {
     _policy = new NullPolicy <DumbAction>();
     _blocks = new List <Block <DumbAction> >
     {
         TestUtils.MineGenesis <DumbAction>(),
     };
     _blocks.Add(TestUtils.MineNext(_blocks[0]));
     _blocks.Add(TestUtils.MineNext(_blocks[1]));
     _blocks.Add(TestUtils.MineNext(_blocks[2]));
     _blocks.Add(TestUtils.MineNext(_blocks[3]));
 }
示例#5
0
        public override Expression HandleStringIDictionary(string tagName, PropertyInfo property, Type iDictImpl,
                                                           NullPolicy selfPolicy, NullPolicy elementPolicy)
        {
            Expression getIDictExpr       = Expression.MakeMemberAccess(argValue, property);
            string     nullElementMessage = MakeElementNullMessage(property);
            string     nullMessage        = MakePropertyNullMessage(property);

            return(MakeStringIDictionaryHandler(
                       Expression.Constant(tagName, typeof(string)), getIDictExpr, iDictImpl,
                       selfPolicy, elementPolicy, nullMessage, nullElementMessage,
                       expr => Expression.Call(varRootTag, NbtCompoundAddMethod, expr)));
        }
示例#6
0
 public SwarmBenchmark()
 {
     _policy = new NullPolicy <DumbAction>();
     _blocks = new List <Block <DumbAction> >
     {
         TestUtils.MineGenesis <DumbAction>(),
     };
     _appProtocolVersion = AppProtocolVersion.Sign(new PrivateKey(), 1);
     _blocks.Add(TestUtils.MineNext(_blocks[0]));
     _blocks.Add(TestUtils.MineNext(_blocks[1]));
     _blocks.Add(TestUtils.MineNext(_blocks[2]));
     _blocks.Add(TestUtils.MineNext(_blocks[3]));
 }
示例#7
0
        Expression MakeNbtTagPropertyHandler([NotNull] PropertyInfo property, [NotNull] string tagName,
                                             [NotNull] Type tagType, NullPolicy selfPolicy,
                                             [NotNull] Func <ParameterExpression, Expression> conversionFunc)
        {
            // Getter for the property value
            Expression getPropertyExpr = Expression.MakeMemberAccess(argValue, property);
            string     nullMsg         = MakePropertyNullMessage(property);
            Expression tagNameExpr     = Expression.Constant(tagName, typeof(string));

            // Generate the appropriate enclosing expressions, which choose path depending on NullPolicy
            return(MakeNbtTagHandler(tagType, property.PropertyType, tagNameExpr, getPropertyExpr, selfPolicy, nullMsg,
                                     conversionFunc,
                                     tagExpr => Expression.Call(varRootTag, NbtCompoundAddMethod, tagExpr)));
        }
示例#8
0
 public SwarmBenchmark()
 {
     _policy      = new NullPolicy <DumbAction>();
     _stagePolicy = new VolatileStagePolicy <DumbAction>();
     _miner       = TestUtils.ChainPrivateKey;
     _blocks      = new List <Block <DumbAction> >
     {
         TestUtils.MineGenesisBlock <DumbAction>(_policy.GetHashAlgorithm, _miner),
     };
     _appProtocolVersion = AppProtocolVersion.Sign(new PrivateKey(), 1);
     _blocks.Add(TestUtils.MineNextBlock(_blocks[0], _policy.GetHashAlgorithm, _miner));
     _blocks.Add(TestUtils.MineNextBlock(_blocks[1], _policy.GetHashAlgorithm, _miner));
     _blocks.Add(TestUtils.MineNextBlock(_blocks[2], _policy.GetHashAlgorithm, _miner));
     _blocks.Add(TestUtils.MineNextBlock(_blocks[3], _policy.GetHashAlgorithm, _miner));
 }
示例#9
0
        internal static Expression MakeNullHandler([NotNull] ParameterExpression varValue,
                                                   [NotNull] Expression getPropertyExpr,
                                                   NullPolicy policy, [NotNull] Expression nonNullExpr,
                                                   [NotNull] Expression defaultValExpr,
                                                   [NotNull] string exceptionMessage)
        {
            // locate the getter for this property
            Expression ifExpr;

            switch (policy)
            {
            case NullPolicy.Error:
                ifExpr = Expression.IfThenElse(
                    // if (value==null) throw new NullReferenceException(exceptionMessage)
                    Expression.ReferenceEqual(varValue, Expression.Constant(null)),
                    Expression.Throw(
                        Expression.New(NullReferenceExceptionCtor, Expression.Constant(exceptionMessage))),
                    // else <nonNullExpr>
                    nonNullExpr);
                break;

            case NullPolicy.Ignore:
                ifExpr = Expression.IfThen(
                    // if (value!=null) <nonNullExpr>
                    Expression.Not(Expression.ReferenceEqual(varValue, Expression.Constant(null))),
                    nonNullExpr);
                break;

            case NullPolicy.InsertDefault:
                ifExpr = Expression.IfThenElse(
                    // if (value==null) <defaultValExpr>
                    Expression.ReferenceEqual(varValue, Expression.Constant(null)),
                    defaultValExpr,
                    // else <nonNullExpr>
                    nonNullExpr);
                break;

            default:
                throw new ArgumentOutOfRangeException("Unrecognized value for NullPolicy: " + policy);
            }

            return(Expression.Block(
                       // var varValue = value.ThisProperty;
                       new[] { varValue },
                       Expression.Assign(varValue, getPropertyExpr),
                       // (check if value is null, and do something)
                       ifExpr));
        }
示例#10
0
        public override Expression HandleIList(string tagName, PropertyInfo property, Type iListImpl,
                                               NullPolicy selfPolicy, NullPolicy elementPolicy)
        {
            // Getter for the property value
            Expression getPropertyExpr = Expression.MakeMemberAccess(argValue, property);

            // Find the element type (the 'T' in IList<T>)
            Type elementType = iListImpl.GetGenericArguments()[0];

            Expression tagNameExpr    = Expression.Constant(tagName, typeof(string));
            string     selfNullMsg    = MakePropertyNullMessage(property);
            string     elementNullMsg = MakeElementNullMessage(property);

            return(MakeIListHandler(getPropertyExpr, elementType, tagNameExpr,
                                    selfPolicy, elementPolicy, selfNullMsg, elementNullMsg,
                                    expr => Expression.Call(varRootTag, NbtCompoundAddMethod, expr)));
        }
示例#11
0
        public async Task Copy()
        {
            using (StoreFixture fx = FxConstructor())
                using (StoreFixture fx2 = FxConstructor())
                {
                    IStore s1 = fx.Store, s2 = fx2.Store;
                    var    policy = new NullPolicy <DumbAction>();
                    var    blocks = new BlockChain <DumbAction>(
                        policy,
                        new VolatileStagePolicy <DumbAction>(),
                        s1,
                        fx.StateStore,
                        MineGenesis <DumbAction>(policy.GetHashAlgorithm, GenesisMiner.PublicKey)
                        .Evaluate(GenesisMiner, policy.BlockAction, fx.StateStore)
                        );

                    // FIXME: Need to add more complex blocks/transactions.
                    var key = new PrivateKey();
                    await blocks.MineBlock(key);

                    await blocks.MineBlock(key);

                    await blocks.MineBlock(key);

                    s1.Copy(to: Fx.Store);
                    Fx.Store.Copy(to: s2);

                    Assert.Equal(s1.ListChainIds().ToHashSet(), s2.ListChainIds().ToHashSet());
                    Assert.Equal(s1.GetCanonicalChainId(), s2.GetCanonicalChainId());
                    foreach (Guid chainId in s1.ListChainIds())
                    {
                        Assert.Equal(s1.IterateIndexes(chainId), s2.IterateIndexes(chainId));
                        foreach (BlockHash blockHash in s1.IterateIndexes(chainId))
                        {
                            Assert.Equal(
                                s1.GetBlock <DumbAction>(fx.GetHashAlgorithm, blockHash),
                                s2.GetBlock <DumbAction>(fx2.GetHashAlgorithm, blockHash)
                                );
                        }
                    }

                    // ArgumentException is thrown if the destination store is not empty.
                    Assert.Throws <ArgumentException>(() => Fx.Store.Copy(fx2.Store));
                }
        }
示例#12
0
        NbtTag HandleDirectlyMappedType([CanBeNull] string tagName, [CanBeNull] object value, [NotNull] PropertyInfo pinfo,
                                        NullPolicy nullPolicy, [NotNull] Type propType)
        {
            if (propType == null)
            {
                throw new ArgumentNullException("propType");
            }
            if (value == null)
            {
                switch (nullPolicy)
                {
                case NullPolicy.InsertDefault:
                    value = SerializationUtil.GetDefaultValue(propType);
                    break;

                case NullPolicy.Ignore:
                    return(null);

                default:     // Default and Error
                    throw MakeNullException(pinfo);
                }
            }
            if (propType == typeof(string))
            {
                return(new NbtString(tagName, (string)value));
            }
            else if (propType == typeof(byte[]))
            {
                return(new NbtByteArray(tagName, (byte[])value));
            }
            else if (propType == typeof(int[]))
            {
                return(new NbtIntArray(tagName, (int[])value));
            }
            else
            {
                throw new ArgumentException("Invalid property valueType given to DynamicConverter.HandleDirectlyMappedType: expected string, byte[], or int[]");
            }
        }
示例#13
0
        NbtTag HandleIListInner <T>([CanBeNull] string tagName, PropertyInfo pinfo, List <T> value)
        {
            Type elementType = typeof(T);

            if (value == null)
            {
                NullPolicy np = GetNullPolicy(pinfo);
                switch (np)
                {
                case NullPolicy.Ignore:
                    return(null);

                case NullPolicy.InsertDefault:
                    return(MakeEmptyList(tagName, elementType));

                default:
                    throw MakeNullException(pinfo);
                }
            }

            // Get list length
            int count = value.Count;

            if (count == 0)
            {
                return(MakeEmptyList(tagName, elementType));
            }

            NullPolicy elementNullPolicy = GetElementNullPolicy(pinfo);
            NbtList    newList           = new NbtList(tagName);

            foreach (T element in value)
            {
                newList.Add(HandleElement(null, element, elementNullPolicy));
            }
            return(newList);
        }
示例#14
0
        NbtTag HandleArray([CanBeNull] string tagName, [CanBeNull] Array value, [NotNull] PropertyInfo pinfo)
        {
            if (pinfo == null)
            {
                throw new ArgumentNullException("pinfo");
            }

            if (value == null)
            {
                NullPolicy np = GetNullPolicy(pinfo);
                switch (np)
                {
                case NullPolicy.Ignore:
                    return(null);

                case NullPolicy.InsertDefault:
                    return(MakeEmptyList(tagName, pinfo.PropertyType.GetElementType()));

                default:
                    throw MakeNullException(pinfo);
                }
            }

            if (value.Length == 0)
            {
                return(MakeEmptyList(tagName, pinfo.PropertyType.GetElementType()));
            }

            NullPolicy elementNullPolicy = GetElementNullPolicy(pinfo);
            NbtList    newList           = new NbtList(tagName);

            for (int i = 0; i < value.Length; i++)
            {
                newList.Add(HandleElement(null, value.GetValue(i), elementNullPolicy));
            }
            return(newList);
        }
示例#15
0
        NbtTag HandleNbtConvertible <T>([CanBeNull] string tagName, [CanBeNull] T value, [NotNull] PropertyInfo pinfo,
                                        Func <string, T, NbtTag> conversionFunc, Func <string, NbtTag> defaultValueFunc)
        {
            if (pinfo == null)
            {
                throw new ArgumentNullException("pinfo");
            }
            if (value == null)
            {
                NullPolicy np = GetNullPolicy(pinfo);
                switch (np)
                {
                case NullPolicy.InsertDefault:
                    return(defaultValueFunc(tagName));

                case NullPolicy.Ignore:
                    return(null);

                default:     // Default and Error
                    throw MakeNullException(pinfo);
                }
            }
            return(conversionFunc(tagName, value));
        }
示例#16
0
 public abstract Expression HandleStringIDictionary([NotNull] string tagName, [NotNull] PropertyInfo property,
                                                    [NotNull] Type iDictImpl,
                                                    NullPolicy selfPolicy, NullPolicy elementPolicy);
示例#17
0
 public abstract Expression HandleNbtFile([NotNull] string tagName, [NotNull] PropertyInfo property,
                                          NullPolicy selfPolicy);
示例#18
0
        public NbtTag Serialize(object value, string tagName, bool skipInterfaceCheck = false,
                                NullPolicy thisNullPolicy = NullPolicy.Error,
                                NullPolicy elementNullPolicy = NullPolicy.Error)
        {
            if (value == null) {
                return new NbtCompound(tagName);
            }

            Type realType = value.GetType();
            if (realType.IsPrimitive) {
                return SerializePrimitiveType(tagName, value);
            }

            var valueAsString = value as string;
            if (valueAsString != null) {
                return new NbtString(tagName, valueAsString);
            }

            // Serialize arrays
            var valueAsArray = value as Array;
            if (valueAsArray != null) {
                var valueAsByteArray = value as byte[];
                if (valueAsByteArray != null) {
                    return new NbtByteArray(tagName, valueAsByteArray);
                }

                var valueAsIntArray = value as int[];
                if (valueAsIntArray != null) {
                    return new NbtIntArray(tagName, valueAsIntArray);
                }

                Type elementType = realType.GetElementType();
                return SerializeList(tagName, valueAsArray, elementType, elementNullPolicy);
            }

            if (!skipInterfaceCheck && value is INbtSerializable) {
                return ((INbtSerializable)value).Serialize(tagName);
            }

            // Serialize ILists
            if (realType.IsGenericType && realType.GetGenericTypeDefinition() == typeof(List<>)) {
                Type listType = realType.GetGenericArguments()[0];
                return SerializeList(tagName, (IList)value, listType, elementNullPolicy);
            }

            // Skip serializing NbtTags and NbtFiles
            var valueAsTag = value as NbtTag;
            if (valueAsTag != null) {
                return valueAsTag;
            }
            var file = value as NbtFile;
            if (file != null) {
                return file.RootTag;
            }

            // Fallback for compound tags
            var compound = new NbtCompound(tagName);
            if (!propertyInfoRead) ReadPropertyInfo();

            foreach (PropertyInfo property in properties) {
                if (!property.CanRead) continue;
                Type propType = property.PropertyType;
                object propValue = property.GetValue(value, null);

                // Handle null property values
                if (propValue == null) {
                    NullPolicy selfNullPolicy = GetElementPolicy(property);
                    switch (selfNullPolicy) {
                        case NullPolicy.Ignore:
                            continue;
                        case NullPolicy.Error:
                            throw new NullReferenceException("Null values not allowed for property " + property.Name);
                        case NullPolicy.InsertDefault:
                            propValue = SerializationUtil.GetDefaultValue(propType);
                            break;
                    }
                }

                string propTagName = propertyTagNames[property];
                NbtTag tag;
                if (propType.IsPrimitive) {
                    tag = SerializePrimitiveType(propTagName, propValue);
                } else if (propType.IsArray || propType == typeof(string)) {
                    tag = Serialize(propValue, propTagName);
                } else {
                    var innerSerializer = new NbtSerializer(property.PropertyType);
                    tag = innerSerializer.Serialize(propValue, propTagName);
                }
                compound.Add(tag);
            }

            return compound;
        }
示例#19
0
 public override Expression HandleDirectlyMappedType(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     throw new NotImplementedException();
 }
示例#20
0
        Expression MakeElementHandler([NotNull] Type elementType, [NotNull] Expression tagNameExpr,
                                      [NotNull] Expression tagValueExpr,
                                      NullPolicy elementPolicy, [NotNull] string nullElementMsg,
                                      [NotNull] Func <Expression, Expression> addTagExprFunc)
        {
            if (tagValueExpr.Type != elementType)
            {
                // In case value getter's return type is different from value return type (e.g. Array.GetValue(int))
                tagValueExpr = Expression.Convert(tagValueExpr, elementType);
            }

            if (elementType.IsPrimitive || elementType.IsEnum)
            {
                //=== Serializing primitives and enums ===
                // tag.Add( new NbtTag(kvp.Key, kvp.Value) );
                return(addTagExprFunc(MakeNbtTagCtor(elementType, tagNameExpr, tagValueExpr)));
            }
            else if (SerializationUtil.IsDirectlyMappedType(elementType))
            {
                //=== Serializing directly-mapped reference types (byte[], int[], string) ===
                // declare a local var, which will hold the property's value
                ParameterExpression varElementValue = Expression.Parameter(elementType, "elementValue");

                // Primary path, in case element value is not null:
                // iDictTag.Add(new NbtTag(kvp.Key, <getValueExpr>));
                Expression addElementExpr =
                    addTagExprFunc(MakeNbtTagCtor(elementType, tagNameExpr, tagValueExpr));

                // Fallback path, in case element value is null and elementPolicy is InsertDefaults:
                // Add a default-value tag to the list: listTag.Add(new NbtTag(null, <default>))
                Expression defaultValExpr     = Expression.Constant(SerializationUtil.GetDefaultValue(elementType));
                Expression defaultElementExpr =
                    addTagExprFunc(MakeNbtTagCtor(elementType, tagNameExpr, defaultValExpr));

                // generate the appropriate enclosing expressions, depending on NullPolicy
                return(NbtCompiler.MakeNullHandler(varElementValue, tagValueExpr, elementPolicy,
                                                   addElementExpr, defaultElementExpr, nullElementMsg));
            }
            else
            {
                //=== Serializing everything else ===
                // Check if this is an IList-of-ILists
                Type iListImpl = SerializationUtil.GetGenericInterfaceImpl(elementType, typeof(IList <>));
                Type iDictImpl = SerializationUtil.GetStringIDictionaryImpl(elementType);

                // check if this type can handle its own serialization
                if (typeof(INbtSerializable).IsAssignableFrom(elementType))
                {
                    // element is INbtSerializable
                    MethodInfo serializeMethod = elementType.GetMethod("Serialize", new[] { typeof(string) });
                    Expression newTagExpr      = Expression.Call(tagValueExpr, serializeMethod, tagNameExpr);
                    return(addTagExprFunc(newTagExpr));
                }
                else if (typeof(NbtTag).IsAssignableFrom(elementType))
                {
                    // element is NbtTag
                    return(MakeNbtTagHandler(
                               elementType, elementType, tagNameExpr, tagValueExpr, elementPolicy, nullElementMsg,
                               expr => expr, addTagExprFunc));
                }
                else if (typeof(NbtFile).IsAssignableFrom(elementType))
                {
                    // element is NbtFile
                    return(MakeNbtTagHandler(
                               typeof(NbtCompound), typeof(NbtFile), tagNameExpr, tagValueExpr, elementPolicy, nullElementMsg,
                               expr => Expression.MakeMemberAccess(expr, NbtFileRootTagProperty), addTagExprFunc));
                }
                else if (iListImpl != null)
                {
                    // element is IList<?>
                    Type subElementType = iListImpl.GetGenericArguments()[0];
                    return(MakeIListHandler(tagValueExpr, subElementType, tagNameExpr, elementPolicy,
                                            elementPolicy, nullElementMsg, nullElementMsg, addTagExprFunc));
                }
                else if (iDictImpl != null)
                {
                    // element is IDictionary<string,?>
                    return(MakeStringIDictionaryHandler(tagNameExpr, tagValueExpr, iDictImpl, elementPolicy,
                                                        elementPolicy, nullElementMsg, nullElementMsg, addTagExprFunc));
                }
                else
                {
                    // Get NbtSerialize<T> method for elementType
                    Expression makeElementTagExpr = callResolver.MakeCall(elementType, tagNameExpr, tagValueExpr);

                    // declare a local var, which will hold the element's value
                    ParameterExpression varElementValue = Expression.Parameter(elementType, "elementValue");

                    // Primary path, adds the newly-made Compound tag to our list
                    Expression addSerializedCompoundExpr = addTagExprFunc(makeElementTagExpr);

                    // Fallback path, in case element's value is null and NullPolicy is InsertDefaults
                    Expression addEmptyCompoundExpr =
                        addTagExprFunc(Expression.New(NbtCompoundCtor, tagNameExpr));

                    // Generate the appropriate enclosing expressions, which choose path depending on NullPolicy
                    return(NbtCompiler.MakeNullHandler(varElementValue, tagValueExpr, elementPolicy,
                                                       addSerializedCompoundExpr, addEmptyCompoundExpr, nullElementMsg));
                }
            }
        }
示例#21
0
        Expression MakeIListHandler([NotNull] Expression getIListExpr, [NotNull] Type elementType,
                                    [NotNull] Expression tagNameExpr,
                                    NullPolicy selfPolicy, NullPolicy elementPolicy, [NotNull] string selfNullMsg,
                                    [NotNull] string elementNullMsg,
                                    [NotNull] Func<Expression, Expression> processTagExpr)
        {
            Type listType = getIListExpr.Type;

            // Declare locals
            ParameterExpression varIList = Expression.Parameter(listType, "iList");
            ParameterExpression varListTag = Expression.Parameter(typeof(NbtList), "listTag");
            ParameterExpression varLength = Expression.Parameter(typeof(int), "length");
            ParameterExpression varIndex = Expression.Parameter(typeof(int), "i");

            // Find getters for this IList
            MethodInfo countGetterImpl, itemGetterImpl;
            if (listType.IsArray) {
                // Although Array claims to implement IList<>, there is no way to retrieve
                // the interface implementation: it's handled in an unusual way by the runtime.
                // So we have to resort to getting Length/GetValue instead of Count/Item
                countGetterImpl = listType.GetProperty("Length").GetGetMethod();
                itemGetterImpl = listType.GetMethod("GetValue", new[] { typeof(int) });
            } else {
                // For non-array IList<> types, grab this.Count getter (which maps to get_Count())
                countGetterImpl = SerializationUtil.GetGenericInterfaceMethodImpl(
                    listType, typeof(ICollection<>), "get_Count", new Type[0]);
                // ...and the getter for indexer this[int], which maps to get_Item(int)
                itemGetterImpl = SerializationUtil.GetGenericInterfaceMethodImpl(
                    listType, typeof(IList<>), "get_Item", new[] { typeof(int) });
            }

            // Create handler for a single element
            Expression getElementExpr = Expression.Call(varIList, itemGetterImpl, varIndex);
            Expression getCountExpr = Expression.Call(varIList, countGetterImpl);
            Expression handleOneElementExpr = MakeElementHandler(
                elementType, NbtCompiler.NullStringExpr, getElementExpr, elementPolicy, elementNullMsg,
                tag => Expression.Call(varListTag, NbtListAddMethod, tag));

            // Arrange tag construction in a loop
            LabelTarget loopBreak = Expression.Label(typeof(void));
            Expression mainLoop =
                // while (true)
                Expression.Loop(
                    Expression.Block(
                        // if (i >= length) break;
                        Expression.IfThen(
                            Expression.GreaterThanOrEqual(varIndex, varLength),
                            Expression.Break(loopBreak)),

                        // <process and add one element to the list>
                        handleOneElementExpr,

                        // ++i;
                        Expression.PreIncrementAssign(varIndex)),
                    loopBreak);

            // new NbtList(tagName, NbtTagType.*)
            Expression makeListTagExpr =
                Expression.New(NbtListCtor, tagNameExpr, Expression.Constant(GetNbtTagType(elementType)));

            // Fallback path, in case value our IList null and NullPolicy is InsertDefaults:
            // Add an empty list to root.
            Expression defaultValExpr = processTagExpr(makeListTagExpr);

            // Primary path, in case our IList is not null:
            // Package the list-building loop into a neat block, with locals
            Expression makeTagExpr = Expression.Block(
                new[] { varListTag, varIndex, varLength },

                // NbtList listTag = new NbtList(tagName, NbtTagType.*);
                Expression.Assign(varListTag, makeListTagExpr),

                // int length = iList.Count;
                Expression.Assign(varLength, getCountExpr),

                // int i=0;
                Expression.Assign(varIndex, Expression.Constant(0)),

                // (fill the list tag)
                mainLoop,

                // rootTag.Add( listTag );
                processTagExpr(varListTag));

            // Generate the appropriate enclosing expressions, which choose path depending on NullPolicy
            return NbtCompiler.MakeNullHandler(varIList, getIListExpr, selfPolicy,
                                               makeTagExpr, defaultValExpr, selfNullMsg);
        }
示例#22
0
        Expression MakeElementHandler([NotNull] Type elementType, [NotNull] Expression tagNameExpr,
                                      [NotNull] Expression tagValueExpr,
                                      NullPolicy elementPolicy, [NotNull] string nullElementMsg,
                                      [NotNull] Func<Expression, Expression> addTagExprFunc)
        {
            if (tagValueExpr.Type != elementType) {
                tagValueExpr = Expression.Convert(tagValueExpr, elementType);
            }

            if (elementType.IsPrimitive || elementType.IsEnum) {
                //=== Serializing primitives and enums ===
                // tag.Add( new NbtTag(kvp.Key, kvp.Value) );
                return addTagExprFunc(MakeNbtTagCtor(elementType, tagNameExpr, tagValueExpr));

            } else if (SerializationUtil.IsDirectlyMappedType(elementType)) {
                //=== Serializing directly-mapped reference types (byte[], int[], string) ===
                // declare a local var, which will hold the property's value
                ParameterExpression varElementValue = Expression.Parameter(elementType, "elementValue");

                // Primary path, in case element value is not null:
                // iDictTag.Add(new NbtTag(kvp.Key, <getValueExpr>));
                Expression addElementExpr =
                    addTagExprFunc(MakeNbtTagCtor(elementType, tagNameExpr, tagValueExpr));

                // Fallback path, in case element value is null and elementPolicy is InsertDefaults:
                // Add a default-value tag to the list: listTag.Add(new NbtTag(null, <default>))
                Expression defaultValExpr = Expression.Constant(SerializationUtil.GetDefaultValue(elementType));
                Expression defaultElementExpr =
                    addTagExprFunc(MakeNbtTagCtor(elementType, tagNameExpr, defaultValExpr));

                // generate the appropriate enclosing expressions, depending on NullPolicy
                return NbtCompiler.MakeNullHandler(varElementValue, tagValueExpr, elementPolicy,
                                                   addElementExpr, defaultElementExpr, nullElementMsg);
            } else {
                //=== Serializing everything else ===
                // Check if this is an IList-of-ILists
                Type iListImpl = SerializationUtil.GetGenericInterfaceImpl(elementType, typeof(IList<>));
                Type iDictImpl = SerializationUtil.GetStringIDictionaryImpl(elementType);

                // check if this type can handle its own serialization
                if (typeof(INbtSerializable).IsAssignableFrom(elementType)) {
                    // element is INbtSerializable
                    MethodInfo serializeMethod = elementType.GetMethod("Serialize", new[] { typeof(string) });
                    Expression newTagExpr = Expression.Call(tagValueExpr, serializeMethod, tagNameExpr);
                    return addTagExprFunc(newTagExpr);

                } else if (typeof(NbtTag).IsAssignableFrom(elementType)) {
                    // element is NbtTag
                    return MakeNbtTagHandler(
                        elementType, elementType, tagNameExpr, tagValueExpr, elementPolicy, nullElementMsg,
                        expr => expr, addTagExprFunc);

                } else if (typeof(NbtFile).IsAssignableFrom(elementType)) {
                    // element is NbtFile
                    PropertyInfo rootTagProp = typeof(NbtFile).GetProperty("RootTag");
                    return MakeNbtTagHandler(
                        typeof(NbtCompound), typeof(NbtFile), tagNameExpr, tagValueExpr, elementPolicy, nullElementMsg,
                        expr => Expression.MakeMemberAccess(expr, rootTagProp), addTagExprFunc);

                } else if (iListImpl != null) {
                    // element is IList<?>
                    Type subElementType = iListImpl.GetGenericArguments()[0];
                    return MakeIListHandler(tagValueExpr, subElementType, tagNameExpr, elementPolicy,
                                            elementPolicy, nullElementMsg, nullElementMsg, addTagExprFunc);

                } else if (iDictImpl != null) {
                    // element is IDictionary<string,?>
                    return MakeStringIDictionaryHandler(tagNameExpr, tagValueExpr, iDictImpl, elementPolicy,
                                                        elementPolicy, nullElementMsg, nullElementMsg, addTagExprFunc);

                } else {
                    // Get NbtSerialize<T> method for elementType
                    Expression makeElementTagExpr = callResolver.MakeCall(elementType, tagNameExpr, tagValueExpr);

                    // declare a local var, which will hold the element's value
                    ParameterExpression varElementValue = Expression.Parameter(elementType, "elementValue");

                    // Primary path, adds the newly-made Compound tag to our list
                    Expression addSerializedCompoundExpr = addTagExprFunc(makeElementTagExpr);

                    // Fallback path, in case element's value is null and NullPolicy is InsertDefaults
                    Expression addEmptyCompoundExpr =
                        addTagExprFunc(Expression.New(NbtCompoundCtor, tagNameExpr));

                    // Generate the appropriate enclosing expressions, which choose path depending on NullPolicy
                    return NbtCompiler.MakeNullHandler(varElementValue, tagValueExpr, elementPolicy,
                                                       addSerializedCompoundExpr, addEmptyCompoundExpr, nullElementMsg);
                }
            }
        }
示例#23
0
        public override Expression HandleStringIDictionary(string tagName, PropertyInfo property, Type iDictImpl,
                                                           NullPolicy selfPolicy, NullPolicy elementPolicy)
        {
            Expression getIDictExpr = Expression.MakeMemberAccess(argValue, property);
            string nullElementMessage = MakeElementNullMessage(property);
            string nullMessage = MakePropertyNullMessage(property);

            return MakeStringIDictionaryHandler(
                Expression.Constant(tagName, typeof(string)), getIDictExpr, iDictImpl,
                selfPolicy, elementPolicy, nullMessage, nullElementMessage,
                expr => Expression.Call(varRootTag, NbtCompoundAddMethod, expr));
        }
示例#24
0
 public override Expression HandleNbtTag(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     // Add tag directly to the list
     return MakeNbtTagPropertyHandler(property, tagName, property.PropertyType, selfPolicy, expr => expr);
 }
示例#25
0
 public override Expression HandleNbtFile(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     // Add NbtFile's root tag directly to the list
     PropertyInfo rootTagProp = typeof(NbtFile).GetProperty("RootTag");
     return MakeNbtTagPropertyHandler(property, tagName, typeof(NbtCompound), selfPolicy,
                              expr => Expression.MakeMemberAccess(expr, rootTagProp));
 }
示例#26
0
        public override Expression HandleINbtSerializable(string tagName, PropertyInfo property, NullPolicy selfPolicy)
        {
            MethodInfo serializeMethod = property.PropertyType.GetMethod("Serialize", new[] { typeof(string) });
            ParameterExpression varValue = Expression.Parameter(property.PropertyType, "value");
            string nullMsg = MakePropertyNullMessage(property);

            // rootTag.Add( value.Serialize() )
            Expression serializeExpr = Expression.Call(
                varRootTag, NbtCompoundAddMethod,
                Expression.Call(varValue, serializeMethod, Expression.Constant(tagName)));

            // Fallback path, in case value is null and NullPolicy is InsertDefaults
            Expression defaultExpr = Expression.New(NbtCompoundCtor, Expression.Constant(tagName));

            // Getter for the property value
            Expression propValue = Expression.MakeMemberAccess(argValue, property);

            return NbtCompiler.MakeNullHandler(varValue, propValue, selfPolicy, serializeExpr, defaultExpr, nullMsg);
        }
示例#27
0
        public override Expression HandleIList(string tagName, PropertyInfo property, Type iListImpl,
                                               NullPolicy selfPolicy, NullPolicy elementPolicy)
        {
            // Getter for the property value
            Expression getPropertyExpr = Expression.MakeMemberAccess(argValue, property);

            Type elementType = iListImpl.GetGenericArguments()[0];
            Expression tagNameExpr = Expression.Constant(tagName, typeof(string));
            string selfNullMsg = MakePropertyNullMessage(property);
            string elementNullMsg = MakeElementNullMessage(property);
            return MakeIListHandler(getPropertyExpr, elementType, tagNameExpr,
                                    selfPolicy, elementPolicy, selfNullMsg, elementNullMsg,
                                    expr => Expression.Call(varRootTag, NbtCompoundAddMethod, expr));
        }
示例#28
0
        public override Expression HandleINbtSerializable(string tagName, PropertyInfo property, NullPolicy selfPolicy)
        {
            MethodInfo          serializeMethod = property.PropertyType.GetMethod("Serialize", new[] { typeof(string) });
            ParameterExpression varValue        = Expression.Parameter(property.PropertyType, "value");
            string nullMsg = MakePropertyNullMessage(property);

            // rootTag.Add( value.Serialize() )
            Expression serializeExpr = Expression.Call(
                varRootTag, NbtCompoundAddMethod,
                Expression.Call(varValue, serializeMethod, Expression.Constant(tagName)));

            // Fallback path, in case value is null and NullPolicy is InsertDefaults
            Expression defaultExpr = Expression.New(NbtCompoundCtor, Expression.Constant(tagName));

            // Getter for the property value
            Expression propValue = Expression.MakeMemberAccess(argValue, property);

            return(NbtCompiler.MakeNullHandler(varValue, propValue, selfPolicy, serializeExpr, defaultExpr, nullMsg));
        }
示例#29
0
 public override Expression HandleStringIDictionary(string tagName, PropertyInfo property, Type iDictImpl, NullPolicy selfPolicy, NullPolicy elementPolicy)
 {
     throw new NotImplementedException();
 }
示例#30
0
        Expression MakeNbtTagHandler([NotNull] Type tagType, [NotNull] Type valueType, [NotNull] Expression tagNameExpr,
                                     [NotNull] Expression getPropertyExpr, NullPolicy selfPolicy,
                                     [NotNull] String nullMsg,
                                     [NotNull] Func<ParameterExpression, Expression> conversionFunc,
                                     [NotNull] Func<Expression, Expression> processTagExpr)
        {
            // declare a local var, which will hold the property's value
            ParameterExpression varValue = Expression.Parameter(valueType, "value");

            // Primary path, adds the root tag of the NbtFile
            Expression makeTagExpr = processTagExpr(conversionFunc(varValue));

            // Fallback path, in case value is null and NullPolicy is InsertDefaults
            ConstructorInfo tagCtor;
            if (tagType == typeof(NbtTag)) {
                tagCtor = NbtCompoundCtor;
            } else {
                tagCtor = tagType.GetConstructor(new[] { typeof(string) });
            }
            Expression defaultVal = Expression.New(tagCtor, tagNameExpr);
            Expression defaultValExpr = processTagExpr(defaultVal);

            // Generate the appropriate enclosing expressions, which choose path depending on NullPolicy
            return NbtCompiler.MakeNullHandler(varValue, getPropertyExpr, selfPolicy,
                                               makeTagExpr, defaultValExpr, nullMsg);
        }
示例#31
0
 public abstract Expression HandleStringIDictionary([NotNull] string tagName, [NotNull] PropertyInfo property,
                                                    [NotNull] Type iDictImpl,
                                                    NullPolicy selfPolicy, NullPolicy elementPolicy);
示例#32
0
        Expression MakeNbtTagPropertyHandler([NotNull] PropertyInfo property, [NotNull] string tagName,
                                             Type tagType, NullPolicy selfPolicy,
                                             [NotNull] Func<ParameterExpression, Expression> conversionFunc)
        {
            // Getter for the property value
            Expression getPropertyExpr = Expression.MakeMemberAccess(argValue, property);
            string nullMsg = MakePropertyNullMessage(property);
            Expression tagNameExpr = Expression.Constant(tagName, typeof(string));

            // Generate the appropriate enclosing expressions, which choose path depending on NullPolicy
            return MakeNbtTagHandler(tagType, property.PropertyType, tagNameExpr, getPropertyExpr, selfPolicy, nullMsg,
                conversionFunc, tagExpr => Expression.Call(varRootTag, NbtCompoundAddMethod, tagExpr));
        }
示例#33
0
        Expression MakeStringIDictionaryHandler([NotNull] Expression tagNameExpr, [NotNull] Expression getIDictExpr,
                                                [NotNull] Type iDictImpl,
                                                NullPolicy selfPolicy, NullPolicy elementPolicy,
                                                [NotNull] string selfNullMsg, [NotNull] string elementNullMsg,
                                                [NotNull] Func<Expression, Expression> processTagExpr)
        {
            Type elementType = iDictImpl.GetGenericArguments()[1];

            // find type of KeyValuePair<string,?> that the enumerator will return
            Type kvpType = typeof(KeyValuePair<,>).MakeGenericType(iDictImpl.GetGenericArguments());
            PropertyInfo keyProp = kvpType.GetProperty("Key");
            PropertyInfo valueProp = kvpType.GetProperty("Value");

            // locate IDictionary.GetEnumerator()
            Type enumerableType = typeof(IEnumerable<>).MakeGenericType(kvpType);
            Type enumeratorType = typeof(IEnumerator<>).MakeGenericType(kvpType);
            MethodInfo getEnumeratorImpl =
                SerializationUtil.GetGenericInterfaceMethodImpl(
                    iDictImpl, enumerableType, "GetEnumerator", Type.EmptyTypes);

            // locate IEnumerator.MoveNext()
            MethodInfo moveNextMethod = typeof(IEnumerator).GetMethod("MoveNext");
            MethodInfo disposeMethod = typeof(IDisposable).GetMethod("Dispose");
            PropertyInfo currentProp = enumeratorType.GetProperty("Current");

            ParameterExpression varIDict = Expression.Parameter(iDictImpl, "iDict");
            ParameterExpression varCompTag = Expression.Parameter(typeof(NbtCompound), "compTag");
            ParameterExpression varEnumerator = Expression.Parameter(enumeratorType, "enumerator");
            ParameterExpression varKvp = Expression.Parameter(kvpType, "element");

            // generate handlers for individual elements
            Expression getNameExpr = Expression.MakeMemberAccess(varKvp, keyProp);
            Expression getValueExpr = Expression.MakeMemberAccess(varKvp, valueProp);
            Expression handleOneElementExpr = MakeElementHandler(
                elementType, getNameExpr, getValueExpr, elementPolicy, elementNullMsg,
                tag => Expression.Call(varCompTag, NbtCompoundAddMethod, tag));

            // Make glue code to hold everything together
            LabelTarget loopBreak = Expression.Label(typeof(void));

            Expression loopBody = Expression.Block(
                new[] { varKvp },
                Expression.Assign(varKvp, Expression.MakeMemberAccess(varEnumerator, currentProp)),
                handleOneElementExpr);

            Expression makeIDictTagExpr =
                Expression.Block(
                    new[] { varCompTag, varEnumerator },

                    // varCompTag = new NbtCompound(tagName)
                    Expression.Assign(varCompTag, Expression.New(NbtCompoundCtor, tagNameExpr)),
                    // varEnumerator = iDict.GetEnumerator()
                    Expression.Assign(varEnumerator, Expression.Call(varIDict, getEnumeratorImpl)),

                    // try {
                    Expression.MakeTry(
                        typeof(void),
                        // while (enumerator.MoveNext()) <loopBody>;
                        Expression.Loop(
                            Expression.IfThenElse(Expression.Call(varEnumerator, moveNextMethod),
                                                  loopBody,
                                                  Expression.Break(loopBreak)),
                            loopBreak),

                        // } finally { enumerator.Dispose(); }
                        Expression.Call(varEnumerator, disposeMethod),
                        null, null),

                    processTagExpr(varCompTag));

            // default value (in case selfPolicy is InsertDefault): new NbtCompound(tagName)
            Expression defaultValExpr = Expression.New(NbtCompoundCtor, tagNameExpr);

            return NbtCompiler.MakeNullHandler(varIDict, getIDictExpr, selfPolicy,
                                               makeIDictTagExpr, defaultValExpr, selfNullMsg);
        }
示例#34
0
 public abstract Expression HandleINbtSerializable([NotNull] string tagName, [NotNull] PropertyInfo property, NullPolicy selfPolicy);
示例#35
0
 NbtTag HandleElement(string tagName, object value, NullPolicy nullPolicy)
 {
     throw new NotImplementedException();
 }
示例#36
0
 public abstract Expression HandleIList([NotNull] string tagName, [NotNull] PropertyInfo property,
                                        [NotNull] Type iListImpl,
                                        NullPolicy selfPolicy, NullPolicy elementPolicy);
示例#37
0
        NbtTag SerializeList(string tagName, IList valueAsArray, Type elementType, NullPolicy elementNullPolicy)
        {
            NbtTagType listType;
            if (elementType == typeof(byte) || elementType == typeof(sbyte) || elementType == typeof(bool)) {
                listType = NbtTagType.Byte;
            } else if (elementType == typeof(byte[])) {
                listType = NbtTagType.ByteArray;
            } else if (elementType == typeof(double)) {
                listType = NbtTagType.Double;
            } else if (elementType == typeof(float)) {
                listType = NbtTagType.Float;
            } else if (elementType == typeof(int) || elementType == typeof(uint)) {
                listType = NbtTagType.Int;
            } else if (elementType == typeof(int[])) {
                listType = NbtTagType.IntArray;
            } else if (elementType == typeof(long) || elementType == typeof(ulong)) {
                listType = NbtTagType.Long;
            } else if (elementType == typeof(short) || elementType == typeof(ushort)) {
                listType = NbtTagType.Short;
            } else if (elementType == typeof(string)) {
                listType = NbtTagType.String;
            } else {
                listType = NbtTagType.Compound;
            }

            var list = new NbtList(tagName, listType);

            if (elementType.IsPrimitive) {
                // speedy serialization for basic types
                for (int i = 0; i < valueAsArray.Count; i++) {
                    list.Add(SerializePrimitiveType(null, valueAsArray[i]));
                }
            } else if (SerializationUtil.IsDirectlyMappedType(elementType)) {
                // speedy serialization for directly-mapped types
                for (int i = 0; i < valueAsArray.Count; i++) {
                    var value = valueAsArray[i];
                    if (value == null) {
                        switch (elementNullPolicy) {
                            case NullPolicy.Error:
                                throw new NullReferenceException("Null elements not allowed for tag " + tagName);
                            case NullPolicy.InsertDefault:
                                list.Add(Serialize(SerializationUtil.GetDefaultValue(elementType), true));
                                break;
                            case NullPolicy.Ignore:
                                continue;
                        }
                    } else {
                        list.Add(Serialize(valueAsArray[i], true));
                    }
                }
            } else {
                // serialize complex types
                var innerSerializer = new NbtSerializer(elementType);
                for (int i = 0; i < valueAsArray.Count; i++) {
                    var value = valueAsArray[i];
                    if (value == null) {
                        switch (elementNullPolicy) {
                            case NullPolicy.Error:
                                throw new NullReferenceException("Null elements not allowed for tag " + tagName);
                            case NullPolicy.Ignore:
                                continue;
                            case NullPolicy.InsertDefault:
                                // TODO
                                break;
                        }
                    } else {
                        list.Add(innerSerializer.Serialize(valueAsArray[i], null));
                    }
                }
            }
            return list;
        }
示例#38
0
 public override Expression HandleINbtSerializable(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     throw new NotImplementedException();
 }
示例#39
0
 public abstract Expression HandleDirectlyMappedType([NotNull] string tagName, [NotNull] PropertyInfo property,
                                                     NullPolicy selfPolicy);
示例#40
0
 public override Expression HandleNbtTag(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     // Add tag directly to the list
     return(MakeNbtTagPropertyHandler(property, tagName, property.PropertyType, selfPolicy, expr => expr));
 }
示例#41
0
 public abstract Expression HandleIList([NotNull] string tagName, [NotNull] PropertyInfo property,
                                        [NotNull] Type iListImpl,
                                        NullPolicy selfPolicy, NullPolicy elementPolicy);
示例#42
0
 public NullPolicyAttribute(NullPolicy selfPolicy, NullPolicy elementPolicy)
 {
     SelfPolicy = selfPolicy;
     ElementPolicy = elementPolicy;
 }
示例#43
0
 public abstract Expression HandleCompoundObject([NotNull] string tagName, [NotNull] PropertyInfo property,
                                                 NullPolicy selfPolicy);
示例#44
0
        Expression MakeIListHandler([NotNull] Expression getIListExpr, [NotNull] Type elementType,
                                    [NotNull] Expression tagNameExpr,
                                    NullPolicy selfPolicy, NullPolicy elementPolicy, [NotNull] string selfNullMsg,
                                    [NotNull] string elementNullMsg,
                                    [NotNull] Func <Expression, Expression> processTagExpr)
        {
            Type listType = getIListExpr.Type;

            // Declare locals
            ParameterExpression varIList   = Expression.Parameter(listType, "iList");
            ParameterExpression varListTag = Expression.Parameter(typeof(NbtList), "listTag");
            ParameterExpression varLength  = Expression.Parameter(typeof(int), "length");
            ParameterExpression varIndex   = Expression.Parameter(typeof(int), "i");

            // Find getters for this IList
            MethodInfo countGetterImpl, itemGetterImpl;

            if (listType.IsArray)
            {
                // Although Array claims to implement IList<>, there is no way to retrieve
                // the interface implementation: it's handled in an unusual way by the runtime.
                // So we have to resort to getting Length/GetValue instead of Count/Item
                countGetterImpl = listType.GetProperty("Length").GetGetMethod();
                itemGetterImpl  = listType.GetMethod("GetValue", new[] { typeof(int) });
            }
            else
            {
                // For non-array IList<> types, grab this.Count getter (which maps to get_Count())
                countGetterImpl = SerializationUtil.GetGenericInterfaceMethodImpl(
                    listType, typeof(ICollection <>), "get_Count", Type.EmptyTypes);
                // ...and the getter for indexer this[int], which maps to get_Item(int)
                itemGetterImpl = SerializationUtil.GetGenericInterfaceMethodImpl(
                    listType, typeof(IList <>), "get_Item", new[] { typeof(int) });
            }

            // Create handler for a single element
            Expression getElementExpr       = Expression.Call(varIList, itemGetterImpl, varIndex);
            Expression getCountExpr         = Expression.Call(varIList, countGetterImpl);
            Expression handleOneElementExpr = MakeElementHandler(
                elementType, NbtCompiler.NullStringExpr, getElementExpr, elementPolicy, elementNullMsg,
                tag => Expression.Call(varListTag, NbtListAddMethod, tag));

            // Arrange tag construction in a loop
            LabelTarget loopBreak = Expression.Label(typeof(void));
            Expression  mainLoop  =
                // while (true)
                Expression.Loop(
                    Expression.Block(
                        // if (i >= length) break;
                        Expression.IfThen(
                            Expression.GreaterThanOrEqual(varIndex, varLength),
                            Expression.Break(loopBreak)),

                        // <process and add one element to the list>
                        handleOneElementExpr,

                        // ++i;
                        Expression.PreIncrementAssign(varIndex)),
                    loopBreak);

            // new NbtList(tagName, NbtTagType.*)
            ConstructorInfo listTagCtor =
                typeof(NbtList).GetConstructor(new[] { typeof(string), typeof(NbtTagType) });
            Expression makeListTagExpr =
                Expression.New(listTagCtor, tagNameExpr, Expression.Constant(GetNbtTagType(elementType)));

            // Fallback path, in case value our IList null and NullPolicy is InsertDefaults:
            // Add an empty list to root.
            Expression defaultValExpr = processTagExpr(makeListTagExpr);

            // Primary path, in case our IList is not null:
            // Package the list-building loop into a neat block, with locals
            Expression makeTagExpr = Expression.Block(
                new[] { varListTag, varIndex, varLength },

                // NbtList listTag = new NbtList(tagName, NbtTagType.*);
                Expression.Assign(varListTag, makeListTagExpr),

                // int length = iList.Count;
                Expression.Assign(varLength, getCountExpr),

                // int i=0;
                Expression.Assign(varIndex, Expression.Constant(0)),

                // (fill the list tag)
                mainLoop,

                // rootTag.Add( listTag );
                processTagExpr(varListTag));

            // Generate the appropriate enclosing expressions, which choose path depending on NullPolicy
            return(NbtCompiler.MakeNullHandler(varIList, getIListExpr, selfPolicy,
                                               makeTagExpr, defaultValExpr, selfNullMsg));
        }
示例#45
0
 public abstract Expression HandleDirectlyMappedType([NotNull] string tagName, [NotNull] PropertyInfo property,
                                                     NullPolicy selfPolicy);
示例#46
0
 public override Expression HandleNbtTag(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     throw new NotImplementedException();
 }
示例#47
0
 public override Expression HandleNbtFile(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     // Add NbtFile's root tag directly to the list
     return(MakeNbtTagPropertyHandler(
                property, tagName, typeof(NbtCompound), selfPolicy,
                expr => Expression.MakeMemberAccess(expr, NbtFileRootTagProperty)));
 }
示例#48
0
 public NullPolicyAttribute(NullPolicy selfPolicy)
 {
     SelfPolicy = selfPolicy;
     ElementPolicy = NullPolicy.Default;
 }
示例#49
0
 public override Expression HandleCompoundObject(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     return(MakeNbtTagPropertyHandler(
                property, tagName, typeof(NbtCompound), selfPolicy,
                expr => callResolver.MakeCall(property.PropertyType,
                                              Expression.Constant(tagName, typeof(string)), expr)));
 }
示例#50
0
 public abstract Expression HandleCompoundObject([NotNull] string tagName, [NotNull] PropertyInfo property,
                                                 NullPolicy selfPolicy);
示例#51
0
        Expression MakeStringIDictionaryHandler([NotNull] Expression tagNameExpr, [NotNull] Expression getIDictExpr,
                                                [NotNull] Type iDictImpl,
                                                NullPolicy selfPolicy, NullPolicy elementPolicy,
                                                [NotNull] string selfNullMsg, [NotNull] string elementNullMsg,
                                                [NotNull] Func <Expression, Expression> processTagExpr)
        {
            Type elementType = iDictImpl.GetGenericArguments()[1];

            // find type of KeyValuePair<string,?> that the enumerator will return
            Type         kvpType   = typeof(KeyValuePair <,>).MakeGenericType(iDictImpl.GetGenericArguments());
            PropertyInfo keyProp   = kvpType.GetProperty("Key");
            PropertyInfo valueProp = kvpType.GetProperty("Value");

            // locate IDictionary.GetEnumerator()
            Type       enumerableType    = typeof(IEnumerable <>).MakeGenericType(kvpType);
            Type       enumeratorType    = typeof(IEnumerator <>).MakeGenericType(kvpType);
            MethodInfo getEnumeratorImpl =
                SerializationUtil.GetGenericInterfaceMethodImpl(
                    iDictImpl, enumerableType, "GetEnumerator", Type.EmptyTypes);

            // locate IEnumerator.MoveNext()
            MethodInfo   moveNextMethod = typeof(IEnumerator).GetMethod("MoveNext");
            MethodInfo   disposeMethod  = typeof(IDisposable).GetMethod("Dispose");
            PropertyInfo currentProp    = enumeratorType.GetProperty("Current");

            ParameterExpression varIDict      = Expression.Parameter(iDictImpl, "iDict");
            ParameterExpression varCompTag    = Expression.Parameter(typeof(NbtCompound), "compTag");
            ParameterExpression varEnumerator = Expression.Parameter(enumeratorType, "enumerator");
            ParameterExpression varKvp        = Expression.Parameter(kvpType, "element");

            // generate handlers for individual elements
            Expression getNameExpr          = Expression.MakeMemberAccess(varKvp, keyProp);
            Expression getValueExpr         = Expression.MakeMemberAccess(varKvp, valueProp);
            Expression handleOneElementExpr = MakeElementHandler(
                elementType, getNameExpr, getValueExpr, elementPolicy, elementNullMsg,
                tag => Expression.Call(varCompTag, NbtCompoundAddMethod, tag));

            // Make glue code to hold everything together
            LabelTarget loopBreak = Expression.Label(typeof(void));

            Expression loopBody = Expression.Block(
                new[] { varKvp },
                Expression.Assign(varKvp, Expression.MakeMemberAccess(varEnumerator, currentProp)),
                handleOneElementExpr);

            Expression makeIDictTagExpr =
                Expression.Block(
                    new[] { varCompTag, varEnumerator },

                    // varCompTag = new NbtCompound(tagName)
                    Expression.Assign(varCompTag, Expression.New(NbtCompoundCtor, tagNameExpr)),
                    // varEnumerator = iDict.GetEnumerator()
                    Expression.Assign(varEnumerator, Expression.Call(varIDict, getEnumeratorImpl)),

                    // try {
                    Expression.MakeTry(
                        typeof(void),
                        // while (enumerator.MoveNext()) <loopBody>;
                        Expression.Loop(
                            Expression.IfThenElse(Expression.Call(varEnumerator, moveNextMethod),
                                                  loopBody,
                                                  Expression.Break(loopBreak)),
                            loopBreak),

                        // } finally { enumerator.Dispose(); }
                        Expression.Call(varEnumerator, disposeMethod),
                        null, null),

                    processTagExpr(varCompTag));

            // default value (in case selfPolicy is InsertDefault): new NbtCompound(tagName)
            Expression defaultValExpr = Expression.New(NbtCompoundCtor, tagNameExpr);

            return(NbtCompiler.MakeNullHandler(varIDict, getIDictExpr, selfPolicy,
                                               makeIDictTagExpr, defaultValExpr, selfNullMsg));
        }
示例#52
0
        internal static Expression MakeNullHandler([NotNull] ParameterExpression varValue,
                                                   [NotNull] Expression getPropertyExpr,
                                                   NullPolicy policy, [NotNull] Expression nonNullExpr,
                                                   [NotNull] Expression defaultValExpr,
                                                   [NotNull] string exceptionMessage) {
            // locate the getter for this property
            Expression ifExpr;

            switch (policy) {
                case NullPolicy.Error:
                    ifExpr = Expression.IfThenElse(
                        // if (value==null) throw new NullReferenceException(exceptionMessage)
                        Expression.ReferenceEqual(varValue, Expression.Constant(null)),
                        Expression.Throw(
                            Expression.New(NullReferenceExceptionCtor, Expression.Constant(exceptionMessage))),
                        // else <nonNullExpr>
                        nonNullExpr);
                    break;
                case NullPolicy.Ignore:
                    ifExpr = Expression.IfThen(
                        // if (value!=null) <nonNullExpr>
                        Expression.Not(Expression.ReferenceEqual(varValue, Expression.Constant(null))),
                        nonNullExpr);
                    break;
                case NullPolicy.InsertDefault:
                    ifExpr = Expression.IfThenElse(
                        // if (value==null) <defaultValExpr>
                        Expression.ReferenceEqual(varValue, Expression.Constant(null)),
                        defaultValExpr,
                        // else <nonNullExpr>
                        nonNullExpr);
                    break;
                default:
                    throw new ArgumentOutOfRangeException("Unrecognized value for NullPolicy: " + policy);
            }

            return Expression.Block(
                // var varValue = value.ThisProperty;
                new[] { varValue },
                Expression.Assign(varValue, getPropertyExpr),
                // (check if value is null, and do something)
                ifExpr);
        }
示例#53
0
 public override Expression HandleCompoundObject(string tagName, PropertyInfo property, NullPolicy selfPolicy)
 {
     throw new NotImplementedException();
 }
示例#54
0
 public abstract Expression HandleNbtTag([NotNull] string tagName, [NotNull] PropertyInfo property,
                                         NullPolicy selfPolicy);
示例#55
0
        // Generates an expression that creates an NbtTag for given property of a directly-mappable types.
        // Directly-mappable types are: primitives, enums, byte[], int[], and string.
        // HandlePrimitiveOrEnum is actually more efficient (and preferred by NbtCompiler) for primitives and enums,
        // because it skips boxing and NullPolicy checks. This one is pretty much only used for byte[]/int[]/string.
        public override Expression HandleDirectlyMappedType(string tagName, PropertyInfo property, NullPolicy selfPolicy)
        {
            // declare a local var, which will hold the property's value
            ParameterExpression varValue = Expression.Parameter(property.PropertyType);

            // Fallback path, in case value is null and NullPolicy is InsertDefaults
            Expression defaultVal = Expression.Constant(SerializationUtil.GetDefaultValue(property.PropertyType));
            // varRootTag.Add( new NbtTag(tagName, <defaultVal>) );
            Expression defaultValExpr =
                Expression.Call(varRootTag,
                                NbtCompoundAddMethod,
                                MakeNbtTagCtor(property.PropertyType,
                                               Expression.Constant(tagName, typeof(string)),
                                               defaultVal));

            // varRootTag.Add( new NbtTag(tagName, <varValue>) );
            Expression makeTagExpr =
                Expression.Call(varRootTag,
                                NbtCompoundAddMethod,
                                MakeNbtTagCtor(property.PropertyType,
                                               Expression.Constant(tagName, typeof(string)),
                                               varValue));

            // Getter for the property value
            Expression getPropertyExpr = Expression.MakeMemberAccess(argValue, property);

            // generate the appropriate enclosing expressions, depending on NullPolicy
            return(NbtCompiler.MakeNullHandler(varValue, getPropertyExpr, selfPolicy,
                                               makeTagExpr, defaultValExpr, MakePropertyNullMessage(property)));
        }
示例#56
0
 public override Expression HandleStringIDictionary(string tagName, PropertyInfo property, Type iDictImpl, NullPolicy selfPolicy, NullPolicy elementPolicy)
 {
     throw new NotImplementedException();
 }