public bool CanPack(Type type, BinaryDataFormat?contentBinaryFormatHint)
 {
     return(type != _model.MapType(typeof(string)) &&
            !CanTypeBeNull(type) &&
            !RuntimeTypeModel.CheckTypeIsCollection(_model, type) &&
            ListDecorator.CanPack(HelpersInternal.GetWireType(HelpersInternal.GetTypeCode(type), contentBinaryFormatHint.GetValueOrDefault())));
 }
Beispiel #2
0
        private IEnumerable <IRenderable> GenerateHtmlElements(int min, int max)
        {
            yield return(new BeginList(_ulClass));

            // Previous
            yield return(new ListDecorator(
                             new LinkDecorator(
                                 new ContentItem(_resource.Previous), _currentPage > 1
                        ? _urlBuilder(_currentPage - 1)
                        : "#")));

            // 1
            if (min >= 2)
            {
                yield return(new ListDecorator(
                                 new LinkDecorator(
                                     new ContentItem("1"), _urlBuilder(1))));
            }

            // ...
            var dots = new ListDecorator(
                new SpanDecorator(
                    new ContentItem(_resource.Separator)), _liDisabledClass);

            if (min >= 3)
            {
                yield return(dots);
            }

            // 4 5 [6] 7 9
            foreach (var x in Enumerable.Range(min, max - min + 1).ToList())
            {
                yield return
                    (new ListDecorator(
                         new LinkDecorator(
                             new ContentItem(x.ToString(CultureInfo.InvariantCulture)), _urlBuilder(x)), x == _currentPage ? _currentPageClass : string.Empty));
            }

            // ...
            if (max + 1 < _total)
            {
                yield return(dots);
            }

            // 999
            if (max < _total)
            {
                yield return(new ListDecorator(
                                 new LinkDecorator(
                                     new ContentItem(_total.ToString(CultureInfo.InvariantCulture)), _urlBuilder(_total))));
            }

            // Next
            yield return(new ListDecorator(
                             new LinkDecorator(
                                 new ContentItem(_resource.Next), _currentPage < _total ? _urlBuilder(_currentPage + 1) : "#")));

            yield return(new EndList());
        }
        public void Insert()
        {
            var decorator = new ListDecorator<int>() { 1, 2, 3 };

            decorator.Insert(1, 5);

            Assert.Equal(5, decorator[1]);
        }
        public void Insert()
        {
            var decorator = new ListDecorator<int>() { 1, 2, 3 };

            decorator.Insert(1, 5);

            Assert.Equal(5, decorator[1]);
        }
        public void Clear()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            decorator.Clear();

            Assert.True(decorator.Empty());
        }
        public void Clear()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            decorator.Clear();

            Assert.True(decorator.Empty());
        }
        public void RemoveAt()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            decorator.RemoveAt(1);

            Assert.Equal(2, decorator.Count);
        }
        public void Remove()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            decorator.Remove(1);

            Assert.Equal(2, decorator.Count);
        }
        public void CopyTo()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            int[] array = new int[3];

            decorator.CopyTo(array, 0);

            Assert.True(decorator.SequenceEqual(array));
        }
        public void CopyTo()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            int[] array = new int[3];

            decorator.CopyTo(array, 0);

            Assert.True(decorator.SequenceEqual(array));
        }
Beispiel #11
0
        private IProtoSerializer BuildSerializer()
        {
            WireType         wireType;
            IProtoSerializer ser = GetCoreSerializer(itemType ?? memberType, out wireType);

            // apply tags
            ser = new TagDecorator(fieldNumber, wireType, isStrict, ser);
            // apply lists if appropriate
            if (itemType != null)
            {
                Helpers.DebugAssert(itemType == ser.ExpectedType, "Wrong type in the tail");
                if (memberType.IsArray)
                {
                    ser = new ArrayDecorator(ser, isPacked ? fieldNumber : 0, isPacked ? wireType : WireType.None);
                }
                else
                {
                    ser = new ListDecorator(memberType, defaultType, ser, isPacked ? fieldNumber : 0, isPacked ? wireType : WireType.None);
                }
            }
            else if (defaultValue != null && !isRequired)
            {
                ser = new DefaultValueDecorator(defaultValue, ser);
            }
            if (memberType == typeof(Uri))
            {
                ser = new UriDecorator(ser);
            }
            switch (member.MemberType)
            {
            case MemberTypes.Property:
                ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break;

            case MemberTypes.Field:
                ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break;

            default:
                throw new InvalidOperationException();
            }
            if (getSpecified != null || setSpecified != null)
            {
                ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
            }
            return(ser);
        }
        public void IsReadOnly()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            Assert.False(decorator.IsReadOnly);
        }
Beispiel #13
0
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;

            try
            {
                model.TakeLock(ref opaqueToken);// check nobody is still adding this type
                WireType         wireType;
                Type             finalType = itemType == null ? memberType : itemType;
                IProtoSerializer ser       = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList);
                if (ser == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
                }
                // apply tags
                if (itemType != null && SupportNull)
                {
                    if (IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser);
                    ser = new NullDecorator(ser);
                    ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser);
                }
                else
                {
                    ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser);
                }
                // apply lists if appropriate
                if (itemType != null)
                {
#if NO_GENERICS
                    Type underlyingItemType = itemType;
#else
                    Type underlyingItemType = SupportNull ? itemType : Nullable.GetUnderlyingType(itemType) ?? itemType;
#endif
                    Helpers.DebugAssert(underlyingItemType == ser.ExpectedType, "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType);
                    if (memberType.IsArray)
                    {
                        ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull);
                    }
                    else
                    {
                        ser = new ListDecorator(memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member == null || PropertyDecorator.CanWrite(member), OverwriteList, SupportNull);
                    }
                }
                else if (defaultValue != null && !IsRequired)
                {
                    ser = new DefaultValueDecorator(defaultValue, ser);
                }
                if (memberType == typeof(Uri))
                {
                    ser = new UriDecorator(ser);
                }
                if (member != null)
                {
                    switch (member.MemberType)
                    {
                    case MemberTypes.Property:
                        ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break;

                    case MemberTypes.Field:
                        ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break;

                    default:
                        throw new InvalidOperationException();
                    }
                    if (getSpecified != null || setSpecified != null)
                    {
                        ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
                    }
                }
                return(ser);
            }
            finally
            {
                model.ReleaseLock(opaqueToken);
            }
        }
        public void Contains()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            Assert.True(decorator.Contains(2));
        }
Beispiel #15
0
        // Token: 0x0600040A RID: 1034 RVA: 0x00015168 File Offset: 0x00013368
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;
            IProtoSerializer result;

            try
            {
                this.model.TakeLock(ref opaqueToken);
                Type             type = (this.itemType == null) ? this.memberType : this.itemType;
                WireType         wireType;
                IProtoSerializer protoSerializer = ValueMember.TryGetCoreSerializer(this.model, this.dataFormat, type, out wireType, this.asReference, this.dynamicType, this.OverwriteList, true);
                if (protoSerializer == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + type.FullName);
                }
                if (this.itemType != null && this.SupportNull)
                {
                    if (this.IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    protoSerializer = new TagDecorator(1, wireType, this.IsStrict, protoSerializer);
                    protoSerializer = new NullDecorator(this.model, protoSerializer);
                    protoSerializer = new TagDecorator(this.fieldNumber, WireType.StartGroup, false, protoSerializer);
                }
                else
                {
                    protoSerializer = new TagDecorator(this.fieldNumber, wireType, this.IsStrict, protoSerializer);
                }
                if (this.itemType != null)
                {
                    if (!this.SupportNull)
                    {
                        if (Helpers.GetUnderlyingType(this.itemType) == null)
                        {
                            Type type2 = this.itemType;
                        }
                    }
                    else
                    {
                        Type type3 = this.itemType;
                    }
                    if (this.memberType.IsArray)
                    {
                        protoSerializer = new ArrayDecorator(this.model, protoSerializer, this.fieldNumber, this.IsPacked, wireType, this.memberType, this.OverwriteList, this.SupportNull);
                    }
                    else
                    {
                        protoSerializer = ListDecorator.Create(this.model, this.memberType, this.defaultType, protoSerializer, this.fieldNumber, this.IsPacked, wireType, this.member != null && PropertyDecorator.CanWrite(this.model, this.member), this.OverwriteList, this.SupportNull);
                    }
                }
                else if (this.defaultValue != null && !this.IsRequired && this.getSpecified == null)
                {
                    protoSerializer = new DefaultValueDecorator(this.model, this.defaultValue, protoSerializer);
                }
                if (this.memberType == this.model.MapType(typeof(Uri)))
                {
                    protoSerializer = new UriDecorator(this.model, protoSerializer);
                }
                if (this.member != null)
                {
                    if (this.member is PropertyInfo)
                    {
                        protoSerializer = new PropertyDecorator(this.model, this.parentType, (PropertyInfo)this.member, protoSerializer);
                    }
                    else
                    {
                        if (!(this.member is FieldInfo))
                        {
                            throw new InvalidOperationException();
                        }
                        protoSerializer = new FieldDecorator(this.parentType, (FieldInfo)this.member, protoSerializer);
                    }
                    if (this.getSpecified != null || this.setSpecified != null)
                    {
                        protoSerializer = new MemberSpecifiedDecorator(this.getSpecified, this.setSpecified, protoSerializer);
                    }
                }
                result = protoSerializer;
            }
            finally
            {
                this.model.ReleaseLock(opaqueToken);
            }
            return(result);
        }
        public void Contains()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            Assert.True(decorator.Contains(2));
        }
Beispiel #17
0
        private IProtoSerializer BuildSerializer()
        {
            IProtoSerializer serializer2;
            int opaqueToken = 0;

            try
            {
                WireType type;
                this.model.TakeLock(ref opaqueToken);
                Type             type2 = (this.itemType == null) ? this.memberType : this.itemType;
                IProtoSerializer tail  = TryGetCoreSerializer(this.model, this.dataFormat, type2, out type, this.asReference, this.dynamicType, this.OverwriteList, true);
                if (tail == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + type2.FullName);
                }
                if ((this.itemType != null) && this.SupportNull)
                {
                    if (this.IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    tail = new TagDecorator(1, type, this.IsStrict, tail);
                    tail = new NullDecorator(this.model, tail);
                    tail = new TagDecorator(this.fieldNumber, WireType.StartGroup, false, tail);
                }
                else
                {
                    tail = new TagDecorator(this.fieldNumber, type, this.IsStrict, tail);
                }
                if (this.itemType != null)
                {
                    if (!this.SupportNull)
                    {
                        Helpers.GetUnderlyingType(this.itemType);
                    }
                    if (this.memberType.IsArray)
                    {
                        tail = new ArrayDecorator(this.model, tail, this.fieldNumber, this.IsPacked, type, this.memberType, this.OverwriteList, this.SupportNull);
                    }
                    else
                    {
                        tail = new ListDecorator(this.model, this.memberType, this.defaultType, tail, this.fieldNumber, this.IsPacked, type, (this.member != null) && PropertyDecorator.CanWrite(this.model, this.member), this.OverwriteList, this.SupportNull);
                    }
                }
                else if (((this.defaultValue != null) && !this.IsRequired) && (this.getSpecified == null))
                {
                    tail = new DefaultValueDecorator(this.model, this.defaultValue, tail);
                }
                if (this.memberType == this.model.MapType(typeof(Uri)))
                {
                    tail = new UriDecorator(this.model, tail);
                }
                if (this.member != null)
                {
                    PropertyInfo member = this.member as PropertyInfo;
                    if (member != null)
                    {
                        tail = new PropertyDecorator(this.model, this.parentType, (PropertyInfo)this.member, tail);
                    }
                    else
                    {
                        FieldInfo info2 = this.member as FieldInfo;
                        if (info2 == null)
                        {
                            throw new InvalidOperationException();
                        }
                        tail = new FieldDecorator(this.parentType, (FieldInfo)this.member, tail);
                    }
                    if ((this.getSpecified != null) || (this.setSpecified != null))
                    {
                        tail = new MemberSpecifiedDecorator(this.getSpecified, this.setSpecified, tail);
                    }
                }
                serializer2 = tail;
            }
            finally
            {
                this.model.ReleaseLock(opaqueToken);
            }
            return(serializer2);
        }
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;

            try
            {
                model.TakeLock(ref opaqueToken);// check nobody is still adding this type
                WireType         wireType;
                Type             finalType = itemType == null ? memberType : itemType;
                IProtoSerializer ser       = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType, OverwriteList, true);
                if (ser == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
                }

                // apply tags
                if (itemType != null && SupportNull)
                {
                    if (IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser);
                    ser = new NullDecorator(model, ser);
                    ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser);
                }
                else
                {
                    ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser);
                }
                // apply lists if appropriate
                if (itemType != null)
                {
#if NO_GENERICS
                    Type underlyingItemType = itemType;
#else
                    Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType;
#endif
                    Helpers.DebugAssert(underlyingItemType == ser.ExpectedType ||
                                        (ser.ExpectedType == model.MapType(typeof(object)) && !Helpers.IsValueType(underlyingItemType))
                                        , "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType);
                    if (memberType.IsArray)
                    {
                        ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull);
                    }
                    else
                    {
                        ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull);
                    }
                }
                else if (defaultValue != null && !IsRequired && getSpecified == null)
                {   // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue,
                    // as does "IsRequired"
                    ser = new DefaultValueDecorator(model, defaultValue, ser);
                }
                if (memberType == model.MapType(typeof(Uri)))
                {
                    ser = new UriDecorator(model, ser);
                }
#if PORTABLE
                else if (memberType.FullName == typeof(Uri).FullName)
                {
                    // In PCLs, the Uri type may not match (WinRT uses Internal/Uri, .Net uses System/Uri)
                    ser = new ReflectedUriDecorator(memberType, model, ser);
                }
#endif
                if (member != null)
                {
                    PropertyInfo prop = member as PropertyInfo;
                    if (prop != null)
                    {
                        ser = new PropertyDecorator(model, parentType, (PropertyInfo)member, ser);
                    }
                    else
                    {
                        FieldInfo fld = member as FieldInfo;
                        if (fld != null)
                        {
                            ser = new FieldDecorator(parentType, (FieldInfo)member, ser);
                        }
                        else
                        {
                            throw new InvalidOperationException();
                        }
                    }
                    if (getSpecified != null || setSpecified != null)
                    {
                        ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
                    }
                }
                return(ser);
            }
            finally
            {
                model.ReleaseLock(opaqueToken);
            }
        }
        public void IndexOf()
        {
            var decorator = new ListDecorator<int>() { 1, 2, 3 };

            Assert.Equal(2, decorator.IndexOf(3));
        }
        public void IndexOf()
        {
            var decorator = new ListDecorator<int>() { 1, 2, 3 };

            Assert.Equal(2, decorator.IndexOf(3));
        }
        IProtoSerializerWithWireType BuildValueFinalSerializer(ValueSerializationSettings settings, bool isMemberOrNested, out WireType wireType, int levelNumber)
        {
            object defaultValue;
            var    l = CompleteLevel(settings, levelNumber, out defaultValue).Basic;

            // to ensure that model can be copied and used again
            for (int i = 1; i <= 3; i++)
            {
                var l2 = CompleteLevel(settings, levelNumber, out defaultValue);
                Debug.Assert(l.Equals(l2.Basic));
            }

            Debug.Assert(l.ContentBinaryFormatHint != null, "l.ContentBinaryFormatHint != null");
            Debug.Assert(l.WriteAsDynamicType != null, "l.WriteAsDynamicType != null");
            Debug.Assert(l.Collection.Append != null, "l.Collection.Append != null");

            // postpone all checks for types when adding member till BuildSerializer, resolve everything only on buildserializer! till that have only local not inherited settings.
            // do not allow EnumPassthru and other settings to affect anything until buildling serializer
            wireType = 0;
            Type itemType = l.Collection.ItemType ?? l.EffectiveType;

            bool itemTypeCanBeNull = CanTypeBeNull(itemType);

            bool isPacked = CanBePackedCollection(l);

            IProtoSerializerWithWireType ser = null;

            if (l.Collection.IsCollection)
            {
                Type     nestedItemType    = null;
                Type     nestedDefaultType = null;
                int      idx  = _model.FindOrAddAuto(itemType, false, true, false);
                MetaType type = idx < 0 ? null : _model[itemType];
                if (!type?.GetFinalSettingsCopy().IgnoreListHandling ?? true)
                {
                    MetaType.ResolveListTypes(_model, itemType, ref nestedItemType, ref nestedDefaultType);
                }

                bool itemIsNestedCollection = nestedItemType != null;

                // primitive types except System.Object may be handled as nested through recursion
                bool tryHandleAsRegistered = !isMemberOrNested || itemType == _model.MapType(typeof(object));

                if (tryHandleAsRegistered)
                {
                    var nestedLevel = settings.GetSettingsCopy(levelNumber + 1);
                    nestedLevel = PrepareNestedLevelForBuild(nestedLevel, itemType);
                    settings.SetSettings(nestedLevel, levelNumber + 1);
                    // should use its level settings and merge from type, ...
                    ser = BuildValueFinalSerializer(settings, true, out wireType, levelNumber + 1);

                    //object dummy = null;

                    //ser = TryGetCoreSerializer(l.ContentBinaryFormatHint.Value, nestedLevel.Basic.EffectiveType, out wireType, ref nestedLevel.Basic.Format, nestedLevel.Basic.WriteAsDynamicType.GetValueOrDefault(), l.Collection.Append.Value, isPacked, true, ref dummy);
                    //if (ser != null)
                    //    ThrowIfHasMoreLevels(settings, levelNumber + 1, l, ", no more nested type detected");
                }
                else if (!itemIsNestedCollection)
                {
                    var nestedLevel = settings.GetSettingsCopy(levelNumber + 1);
                    nestedLevel = PrepareNestedLevelForBuild(nestedLevel, itemType);
                    nestedLevel.Basic.Collection.ItemType = null; // IgnoreListHandling or not a collection
                    settings.SetSettings(nestedLevel, levelNumber + 1);

                    ser = BuildValueFinalSerializer(settings, true, out wireType, levelNumber + 1);
                }

                if (ser == null && itemIsNestedCollection)
                {
                    // if we already tried to lookup registered type no need to do it again

                    MetaType metaType;
                    if (_model.FindOrAddAuto(itemType, false, true, false, out metaType) >= 0)
                    {
                        nestedDefaultType = metaType.GetFinalSettingsCopy().ConstructType ?? nestedDefaultType ?? metaType.Type;
                    }

                    var nestedLevel = settings.GetSettingsCopy(levelNumber + 1);

                    if (nestedLevel.Basic.Collection.ConcreteType == null)
                    {
                        nestedLevel.Basic.Collection.ConcreteType = nestedDefaultType;
                    }

                    if (nestedLevel.IsNotAssignable)
                    {
                        throw new ProtoException("Nested collection item should be assignable");
                    }

                    nestedLevel.Basic.Collection.Append = false;
                    // TODO throw if set to true: throw new ProtoException("AppendCollection is not supported for nested types: " + objectType.Name);

                    if (nestedLevel.Basic.Collection.ItemType == null)
                    {
                        nestedLevel.Basic.Collection.ItemType = nestedItemType;
                    }
                    else if (!Helpers.IsAssignableFrom(nestedItemType, nestedLevel.Basic.Collection.ItemType))
                    {
                        throw new ProtoException(
                                  "Nested collection item type " + nestedLevel.Basic.Collection.ItemType + " is not assignable to " + nestedItemType + " for declared collection type " +
                                  l.EffectiveType);
                    }

                    nestedLevel = PrepareNestedLevelForBuild(nestedLevel, itemType);

                    settings.SetSettings(nestedLevel, levelNumber + 1);

                    WireType wt;
                    ser = BuildValueFinalSerializer(
                        settings,
                        true,
                        out wt,
                        levelNumber + 1);

                    isPacked = false;
                }
            }
            else
            {
                // handled outside and not wrapped with collection
                if (!isMemberOrNested)
                {
                    l.Format = ValueFormat.Compact;
                }

                isPacked = false; // it's not even a collection
                ser      = TryGetCoreSerializer(l.ContentBinaryFormatHint.Value, itemType, out wireType, ref l.Format, l.WriteAsDynamicType.Value, l.Collection.Append.Value, isPacked, true, ref defaultValue);
                if (ser != null)
                {
                    ThrowIfHasMoreLevels(settings, levelNumber, l, ", no more nested type detected");
                }
            }

            if (ser == null)
            {
                throw new InvalidOperationException("No serializer defined for type: " + itemType.FullName);
            }

            if (itemTypeCanBeNull &&
                (
                    (Helpers.GetNullableUnderlyingType(itemType) != null && Helpers.GetNullableUnderlyingType(ser.ExpectedType) == null)
                    // TODO get rid of ugly casting, maybe use builder pattern
                    || (!Helpers.IsValueType(itemType) && !(ser is NetObjectValueDecorator))
                ))
            {
                // nested level may be not collection and already wrapped with nonull, may later add check whether handled as registered vs as nested
                if (!(ser is NoNullDecorator))
                {
                    // if not wrapped with net obj - wrap with write-null check
                    ser = new NoNullDecorator(_model, ser, l.Collection.ItemType != null); // throw only for collection elements, otherwise don't write
                }
            }

            if (itemType != ser.ExpectedType && (!l.WriteAsDynamicType.Value || !Helpers.IsAssignableFrom(ser.ExpectedType, itemType)))
            {
                throw new ProtoException(string.Format("Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, itemType));
            }

            // apply lists if appropriate
            if (l.Collection.IsCollection)
            {
                bool protoCompatibility = l.Collection.Format == CollectionFormat.Protobuf || l.Collection.Format == CollectionFormat.ProtobufNotPacked;

                WireType packedReadWt;
                if (!protoCompatibility)
                {
                    packedReadWt = WireType.None;
                    Debug.Assert(!isPacked); // should be determinated before passing to TryGetCoreSerializer
                    isPacked = false;
                }
                else
                {
                    packedReadWt = CanPack(l.Collection.ItemType, l.ContentBinaryFormatHint)
                                       ? l.Collection.PackedWireTypeForRead.GetValueOrDefault(wireType)
                                       : WireType.None;
                }

                if (l.EffectiveType.IsArray)
                {
                    if (l.EffectiveType.GetArrayRank() == 1)
                    {
                        ser = new ArrayDecorator(
                            _model,
                            ser,
                            isPacked,
                            packedReadWt,
                            l.EffectiveType,
                            !l.Collection.Append.Value,
                            l.Collection.ArrayLengthReadLimit.Value,
                            protoCompatibility);
                    }
                    else
                    {
                        if (protoCompatibility)
                        {
                            throw new NotSupportedException("Multi-dimensional arrays are supported only in Enhanced collection format");
                        }

                        ser = new MultiDimensionalArrayDecorator(
                            _model,
                            ser,
                            l.EffectiveType,
                            !l.Collection.Append.Value,
                            l.Collection.ArrayLengthReadLimit.Value);
                    }
                }
                else
                {
                    ser = ListDecorator.Create(
                        _model,
                        l.EffectiveType,
                        l.Collection.ConcreteType,
                        ser,
                        isPacked,
                        packedReadWt,
                        !l.Collection.Append.Value,
                        protoCompatibility,
                        true);
                }

                if (isMemberOrNested)
                {
                    if (MetaType.IsNetObjectValueDecoratorNecessary(_model, l.Format))
                    {
                        ser = new NetObjectValueDecorator(
                            ser,
                            Helpers.GetNullableUnderlyingType(l.EffectiveType) != null,
                            l.Format == ValueFormat.Reference || l.Format == ValueFormat.LateReference,
                            l.Format == ValueFormat.LateReference && CanTypeBeAsLateReferenceOnBuildStage(_model.GetKey(l.EffectiveType, false, true), _model),
                            !_model.ProtoCompatibility.SuppressNullWireType,
                            _model);
                    }
                    else if (!Helpers.IsValueType(l.EffectiveType) || Helpers.GetNullableUnderlyingType(l.EffectiveType) != null)
                    {
                        ser = new NoNullDecorator(_model, ser, false);
                    }
                }


                if (l.EffectiveType != ser.ExpectedType && (!l.WriteAsDynamicType.Value || !Helpers.IsAssignableFrom(ser.ExpectedType, itemType)))
                {
                    throw new ProtoException(string.Format("Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, itemType));
                }
            }

            if (levelNumber == 0 && defaultValue != null)
            {
                ser = new DefaultValueDecorator(_model, defaultValue, ser);
            }

            return(ser);
        }
Beispiel #22
0
        private IProtoSerializer BuildSerializer()
        {
            bool lockTaken = false;

            try
            {
                model.TakeLock(ref lockTaken);// check nobody is still adding this type
                WireType         wireType;
                Type             finalType = itemType == null ? memberType : itemType;
                IProtoSerializer ser       = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, asReference, dynamicType);
                if (ser == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
                }
                // apply tags
                ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser);
                // apply lists if appropriate
                if (itemType != null)
                {
                    Helpers.DebugAssert(itemType == ser.ExpectedType, "Wrong type in the tail");
                    if (memberType.IsArray)
                    {
                        ser = new ArrayDecorator(ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList);
                    }
                    else
                    {
                        ser = new ListDecorator(memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member == null || PropertyDecorator.CanWrite(member), OverwriteList);
                    }
                }
                else if (defaultValue != null && !IsRequired)
                {
                    ser = new DefaultValueDecorator(defaultValue, ser);
                }
                if (memberType == typeof(Uri))
                {
                    ser = new UriDecorator(ser);
                }
                if (member != null)
                {
                    switch (member.MemberType)
                    {
                    case MemberTypes.Property:
                        ser = new PropertyDecorator(parentType, (PropertyInfo)member, ser); break;

                    case MemberTypes.Field:
                        ser = new FieldDecorator(parentType, (FieldInfo)member, ser); break;

                    default:
                        throw new InvalidOperationException();
                    }
                    if (getSpecified != null || setSpecified != null)
                    {
                        ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
                    }
                }
                return(ser);
            }
            finally
            {
                model.ReleaseLock(lockTaken);
            }
        }
Beispiel #23
0
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;

            try
            {
                model.TakeLock(ref opaqueToken);// check nobody is still adding this type
                var member = backingMember ?? originalMember;
                IProtoSerializer ser;
                if (IsMap)
                {
                    ResolveMapTypes(out var dictionaryType, out var keyType, out var valueType);

                    if (dictionaryType == null)
                    {
                        throw new InvalidOperationException("Unable to resolve map type for type: " + memberType.FullName);
                    }
                    var concreteType = defaultType;
                    if (concreteType == null && Helpers.IsClass(memberType))
                    {
                        concreteType = memberType;
                    }
                    var keySer = TryGetCoreSerializer(model, MapKeyFormat, keyType, out var keyWireType, false, false, false, false);
                    if (!AsReference)
                    {
                        AsReference = MetaType.GetAsReferenceDefault(model, valueType);
                    }
                    var valueSer = TryGetCoreSerializer(model, MapValueFormat, valueType, out var valueWireType, AsReference, DynamicType, false, true);
#if PROFILE259
                    IEnumerable <ConstructorInfo> ctors = typeof(MapDecorator <, ,>).MakeGenericType(new Type[] { dictionaryType, keyType, valueType }).GetTypeInfo().DeclaredConstructors;
                    if (ctors.Count() != 1)
                    {
                        throw new InvalidOperationException("Unable to resolve MapDecorator constructor");
                    }
                    ser = (IProtoSerializer)ctors.First().Invoke(new object[] { model, concreteType, keySer, valueSer, fieldNumber,
                                                                                DataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String, keyWireType, valueWireType, OverwriteList });
#else
                    var ctors = typeof(MapDecorator <, ,>).MakeGenericType(new Type[] { dictionaryType, keyType, valueType }).GetConstructors(
                        BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
                    if (ctors.Length != 1)
                    {
                        throw new InvalidOperationException("Unable to resolve MapDecorator constructor");
                    }
                    ser = (IProtoSerializer)ctors[0].Invoke(new object[] { model, concreteType, keySer, valueSer, fieldNumber,
                                                                           DataFormat == DataFormat.Group ? WireType.StartGroup : WireType.String, keyWireType, valueWireType, OverwriteList });
#endif
                }
                else
                {
                    WireType wireType;
                    Type     finalType = itemType == null ? memberType : itemType;
                    ser = TryGetCoreSerializer(model, dataFormat, finalType, out wireType, AsReference, DynamicType, OverwriteList, true);
                    if (ser == null)
                    {
                        throw new InvalidOperationException("No serializer defined for type: " + finalType.FullName);
                    }

                    // apply tags
                    if (itemType != null && SupportNull)
                    {
                        if (IsPacked)
                        {
                            throw new NotSupportedException("Packed encodings cannot support null values");
                        }
                        ser = new TagDecorator(NullDecorator.Tag, wireType, IsStrict, ser);
                        ser = new NullDecorator(model, ser);
                        ser = new TagDecorator(fieldNumber, WireType.StartGroup, false, ser);
                    }
                    else
                    {
                        ser = new TagDecorator(fieldNumber, wireType, IsStrict, ser);
                    }
                    // apply lists if appropriate
                    if (itemType != null)
                    {
                        Type underlyingItemType = SupportNull ? itemType : Helpers.GetUnderlyingType(itemType) ?? itemType;

                        Helpers.DebugAssert(underlyingItemType == ser.ExpectedType ||
                                            (ser.ExpectedType == model.MapType(typeof(object)) && !Helpers.IsValueType(underlyingItemType))
                                            , "Wrong type in the tail; expected {0}, received {1}", ser.ExpectedType, underlyingItemType);
                        if (memberType.IsArray)
                        {
                            ser = new ArrayDecorator(model, ser, fieldNumber, IsPacked, wireType, memberType, OverwriteList, SupportNull);
                        }
                        else
                        {
                            ser = ListDecorator.Create(model, memberType, defaultType, ser, fieldNumber, IsPacked, wireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull);
                        }
                    }
                    else if (defaultValue != null && !IsRequired && getSpecified == null)
                    {   // note: "ShouldSerialize*" / "*Specified" / etc ^^^^ take precedence over defaultValue,
                        // as does "IsRequired"
                        ser = new DefaultValueDecorator(model, defaultValue, ser);
                    }
                    if (memberType == model.MapType(typeof(Uri)))
                    {
                        ser = new UriDecorator(model, ser);
                    }
#if PORTABLE
                    else if (memberType.FullName == typeof(Uri).FullName)
                    {
                        // In PCLs, the Uri type may not match (WinRT uses Internal/Uri, .Net uses System/Uri)
                        ser = new ReflectedUriDecorator(memberType, model, ser);
                    }
#endif
                }
                if (member != null)
                {
                    if (member is PropertyInfo prop)
                    {
                        ser = new PropertyDecorator(model, parentType, prop, ser);
                    }
                    else if (member is FieldInfo fld)
                    {
                        ser = new FieldDecorator(parentType, fld, ser);
                    }
                    else
                    {
                        throw new InvalidOperationException();
                    }

                    if (getSpecified != null || setSpecified != null)
                    {
                        ser = new MemberSpecifiedDecorator(getSpecified, setSpecified, ser);
                    }
                }
                return(ser);
            }
            finally
            {
                model.ReleaseLock(opaqueToken);
            }
        }
        public void IsReadOnly()
        {
            var decorator = new ListDecorator<int> { 1, 2, 3 };

            Assert.False(decorator.IsReadOnly);
        }
Beispiel #25
0
        private IProtoSerializer BuildSerializer()
        {
            int opaqueToken = 0;

            try
            {
                model.TakeLock(ref opaqueToken);
                Type             type            = (itemType == null) ? memberType : itemType;
                IProtoSerializer protoSerializer = TryGetCoreSerializer(model, dataFormat, type, out WireType defaultWireType, asReference, dynamicType, OverwriteList, allowComplexTypes: true);
                if (protoSerializer == null)
                {
                    throw new InvalidOperationException("No serializer defined for type: " + type.FullName);
                }
                if (itemType != null && SupportNull)
                {
                    if (IsPacked)
                    {
                        throw new NotSupportedException("Packed encodings cannot support null values");
                    }
                    protoSerializer = new TagDecorator(1, defaultWireType, IsStrict, protoSerializer);
                    protoSerializer = new NullDecorator(model, protoSerializer);
                    protoSerializer = new TagDecorator(fieldNumber, WireType.StartGroup, strict: false, protoSerializer);
                }
                else
                {
                    protoSerializer = new TagDecorator(fieldNumber, defaultWireType, IsStrict, protoSerializer);
                }
                if (itemType != null)
                {
                    if (!SupportNull)
                    {
                        if (Helpers.GetUnderlyingType(itemType) == null)
                        {
                            _ = itemType;
                        }
                    }
                    else
                    {
                        _ = itemType;
                    }
                    protoSerializer = ((!memberType.IsArray) ? ((ProtoDecoratorBase)ListDecorator.Create(model, memberType, defaultType, protoSerializer, fieldNumber, IsPacked, defaultWireType, member != null && PropertyDecorator.CanWrite(model, member), OverwriteList, SupportNull)) : ((ProtoDecoratorBase) new ArrayDecorator(model, protoSerializer, fieldNumber, IsPacked, defaultWireType, memberType, OverwriteList, SupportNull)));
                }
                else if (defaultValue != null && !IsRequired && getSpecified == null)
                {
                    protoSerializer = new DefaultValueDecorator(model, defaultValue, protoSerializer);
                }
                if (memberType == model.MapType(typeof(Uri)))
                {
                    protoSerializer = new UriDecorator(model, protoSerializer);
                }
                if (member != null)
                {
                    if (member is PropertyInfo)
                    {
                        protoSerializer = new PropertyDecorator(model, parentType, (PropertyInfo)member, protoSerializer);
                    }
                    else
                    {
                        if (!(member is FieldInfo))
                        {
                            throw new InvalidOperationException();
                        }
                        protoSerializer = new FieldDecorator(parentType, (FieldInfo)member, protoSerializer);
                    }
                    if (getSpecified != null || setSpecified != null)
                    {
                        protoSerializer = new MemberSpecifiedDecorator(getSpecified, setSpecified, protoSerializer);
                    }
                }
                return(protoSerializer);
            }
            finally
            {
                model.ReleaseLock(opaqueToken);
            }
        }
Beispiel #26
0
        internal void WriteSchema(System.Text.StringBuilder builder, int indent, ref bool requiresBclImport)
        {
            Serializer.GetHashCode();
            if (_surrogate != null)
            {
                return;                     // nothing to write
            }
            ValueMember[] fieldsArr = new ValueMember[_fields.Count];
            _fields.CopyTo(fieldsArr, 0);
            Array.Sort(fieldsArr, ValueMember.Comparer.Default);

            if (IsList)
            {
                string itemTypeName = _model.GetSchemaTypeName(TypeModel.GetListItemType(_model, Type), BinaryDataFormat.Default, false, false, ref requiresBclImport);
                NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {");
                NewLine(builder, indent + 1).Append("repeated ").Append(itemTypeName).Append(" items = 1;");
                NewLine(builder, indent).Append('}');
            }
            else if (_settingsValueFinal.IsAutoTuple)
            { // key-value-pair etc
                MemberInfo[] mapping;
                if (ResolveTupleConstructor(Type, out mapping) != null)
                {
                    NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {");
                    for (int i = 0; i < mapping.Length; i++)
                    {
                        Type effectiveType;
                        if (mapping[i] is PropertyInfo)
                        {
                            effectiveType = ((PropertyInfo)mapping[i]).PropertyType;
                        }
                        else if (mapping[i] is FieldInfo)
                        {
                            effectiveType = ((FieldInfo)mapping[i]).FieldType;
                        }
                        else
                        {
                            throw new NotSupportedException("Unknown member type: " + mapping[i].GetType().Name);
                        }
                        NewLine(builder, indent + 1)
                        .Append("optional ")
                        .Append(_model.GetSchemaTypeName(effectiveType, BinaryDataFormat.Default, false, false, ref requiresBclImport).Replace('.', '_'))
                        .Append(' ').Append(mapping[i].Name).Append(" = ").Append(i + 1).Append(';');
                    }
                    NewLine(builder, indent).Append('}');
                }
            }
            else if (Helpers.IsEnum(Type))
            {
                NewLine(builder, indent).Append("enum ").Append(GetSchemaTypeName()).Append(" {");
                if (_settingsValueFinal.EnumPassthru.GetValueOrDefault())
                {
                    if (Type
#if WINRT
                        .GetTypeInfo()
#endif
                        .IsDefined(_model.MapType(typeof(FlagsAttribute)), false))
                    {
                        NewLine(builder, indent + 1).Append("// this is a composite/flags enumeration");
                    }
                    else
                    {
                        NewLine(builder, indent + 1).Append("// this enumeration will be passed as a raw value");
                    }
                    foreach (FieldInfo field in
#if WINRT
                             Type.GetRuntimeFields()
#else
                             Type.GetFields()
#endif
                             )
                    {
                        if (field.IsStatic && field.IsLiteral)
                        {
                            object enumVal;
#if WINRT || PORTABLE || CF || FX11
                            enumVal = field.GetValue(null);
#else
                            enumVal = field.GetRawConstantValue();
#endif
                            NewLine(builder, indent + 1).Append(field.Name).Append(" = ").Append(enumVal).Append(";");
                        }
                    }
                }
                else
                {
                    foreach (ValueMember member in fieldsArr)
                    {
                        NewLine(builder, indent + 1).Append(member.Name).Append(" = ").Append(member.FieldNumber).Append(';');
                    }
                }
                NewLine(builder, indent).Append('}');
            }
            else
            {
                NewLine(builder, indent).Append("message ").Append(GetSchemaTypeName()).Append(" {");
                foreach (ValueMember member in fieldsArr)
                {
                    member.Serializer.GetHashCode();
                    MemberLevelSettingsValue s = member.GetFinalSettingsCopy(0);
                    string ordinality          = s.Collection.IsCollection ? "repeated" : member.IsRequired ? "required" : "optional";
                    NewLine(builder, indent + 1).Append(ordinality).Append(' ');
                    if (s.ContentBinaryFormatHint.GetValueOrDefault() == BinaryDataFormat.Group)
                    {
                        builder.Append("group ");
                    }
                    string schemaTypeName = member.GetSchemaTypeName(true, ref requiresBclImport);
                    builder.Append(schemaTypeName).Append(" ")
                    .Append(member.Name).Append(" = ").Append(member.FieldNumber);

                    object defaultValue = member.GetFinalDefaultValue();
                    if (defaultValue != null && member.IsRequired == false)
                    {
                        if (defaultValue is string)
                        {
                            builder.Append(" [default = \"").Append(defaultValue).Append("\"]");
                        }
                        else if (defaultValue is bool)
                        { // need to be lower case (issue 304)
                            builder.Append((bool)defaultValue ? " [default = true]" : " [default = false]");
                        }
                        else
                        {
                            builder.Append(" [default = ").Append(defaultValue).Append(']');
                        }
                    }
                    if (s.Collection.IsCollection && s.Collection.Format == CollectionFormat.Protobuf &&
                        ListDecorator.CanPack(HelpersInternal.GetWireType(Helpers.GetTypeCode(member.MemberType), s.ContentBinaryFormatHint.GetValueOrDefault())))
                    {
                        builder.Append(" [packed=true]");
                    }
                    builder.Append(';');
                    if (schemaTypeName == "bcl.NetObjectProxy" && (s.Format == ValueFormat.Reference || s.Format == ValueFormat.LateReference) &&
                        !s.WriteAsDynamicType.GetValueOrDefault())    // we know what it is; tell the user
                    {
                        builder.Append(" // reference-tracked ").Append(member.GetSchemaTypeName(false, ref requiresBclImport));
                    }
                }
                if (_subTypes != null && _subTypes.Count != 0)
                {
                    NewLine(builder, indent + 1).Append("// the following represent sub-types; at most 1 should have a value");
                    SubType[] subTypeArr = new SubType[_subTypes.Count];
                    _subTypes.CopyTo(subTypeArr, 0);
                    Array.Sort(subTypeArr, SubType.Comparer.Default);
                    foreach (SubType subType in subTypeArr)
                    {
                        string subTypeName = subType.DerivedType.GetSchemaTypeName();
                        NewLine(builder, indent + 1).Append("optional ").Append(subTypeName)
                        .Append(" ").Append(subTypeName).Append(" = ").Append(subType.FieldNumber).Append(';');
                    }
                }
                NewLine(builder, indent).Append('}');
            }
        }