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())));
 }
Exemple #2
0
        public void Write(object value, ProtoWriter dest)
        {
            if (_allowNullWireType && value == null)
            {
                ProtoWriter.WriteFieldHeaderComplete(WireType.Null, dest);
                return;
            }

            bool write;
            int  dynamicTypeKey;

            var options = _options;

            if ((options & BclHelpers.NetObjectOptions.WriteAsLateReference) != 0 && !ProtoWriter.CheckIsOnHalfToRecursionDepthLimit(dest))
            {
                options &= ~BclHelpers.NetObjectOptions.WriteAsLateReference;
            }

            SubItemToken token = NetObjectHelpers.WriteNetObject_Start(value, dest, options, out dynamicTypeKey, out write);

            if (write)
            {
                // field header written!
                if ((options & BclHelpers.NetObjectOptions.DynamicType) != 0)
                {
                    if (dynamicTypeKey < 0)
                    {
                        ProtoTypeCode typeCode = HelpersInternal.GetTypeCode(value.GetType());
                        WireType      wireType = HelpersInternal.GetWireType(typeCode, _dataFormatForDynamicBuiltins);
                        if (wireType != WireType.None)
                        {
                            ProtoWriter.WriteFieldHeaderComplete(wireType, dest);
                            if (!ProtoWriter.TryWriteBuiltinTypeValue(value, typeCode, true, dest))
                            {
                                throw new ProtoException("Dynamic type is not a contract-type: " + value.GetType().Name);
                            }
                        }
                        else
                        {
                            throw new ProtoException("Dynamic type is not a contract-type: " + value.GetType().Name);
                        }
                    }
                    else
                    {
                        ProtoWriter.WriteRecursionSafeObject(value, dynamicTypeKey, dest);
                    }
                }
                else
                {
                    if ((options & BclHelpers.NetObjectOptions.WriteAsLateReference) != 0)
                    {
                        _lateReferenceTail.Write(value, dest);
                    }
                    else if (_tail != null)
                    {
                        _tail.Write(value, dest);
                    }
                    else
                    {
                        Debug.Assert(_baseKey >= 0);

                        if (_baseKeySerializer != null)
                        {
                            _baseKeySerializer.Write(value, dest);
                        }
                        else
                        {
                            ProtoWriter.WriteRecursionSafeObject(value, _baseKey, dest);
                        }
                    }
                }
            }
            ProtoWriter.EndSubItem(token, dest);
        }
Exemple #3
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('}');
            }
        }