示例#1
0
        internal bool TrySerializeAuxiliaryType(ProtoWriter writer, Type type, DataFormat format, int tag, object value, bool isInsideList)
        {
            if (type == null)
            {
                type = value.GetType();
            }
            ProtoTypeCode typecode = Helpers.GetTypeCode(type);
            int           modelKey;
            WireType      wireType = this.GetWireType(typecode, format, ref type, out modelKey);

            if (modelKey >= 0)
            {
                if (Helpers.IsEnum(type))
                {
                    this.Serialize(modelKey, value, writer);
                    return(true);
                }
                ProtoWriter.WriteFieldHeader(tag, wireType, writer);
                switch (wireType)
                {
                case WireType.None:
                    throw ProtoWriter.CreateException(writer);

                case WireType.String:
                case WireType.StartGroup:
                {
                    SubItemToken token = ProtoWriter.StartSubItem(value, writer);
                    this.Serialize(modelKey, value, writer);
                    ProtoWriter.EndSubItem(token, writer);
                    return(true);
                }
                }
                this.Serialize(modelKey, value, writer);
                return(true);
            }
            else
            {
                if (wireType != WireType.None)
                {
                    ProtoWriter.WriteFieldHeader(tag, wireType, writer);
                }
                ProtoTypeCode protoTypeCode = typecode;
                switch (protoTypeCode)
                {
                case ProtoTypeCode.Boolean:
                    ProtoWriter.WriteBoolean((bool)value, writer);
                    return(true);

                case ProtoTypeCode.Char:
                    ProtoWriter.WriteUInt16((ushort)((char)value), writer);
                    return(true);

                case ProtoTypeCode.SByte:
                    ProtoWriter.WriteSByte((sbyte)value, writer);
                    return(true);

                case ProtoTypeCode.Byte:
                    ProtoWriter.WriteByte((byte)value, writer);
                    return(true);

                case ProtoTypeCode.Int16:
                    ProtoWriter.WriteInt16((short)value, writer);
                    return(true);

                case ProtoTypeCode.UInt16:
                    ProtoWriter.WriteUInt16((ushort)value, writer);
                    return(true);

                case ProtoTypeCode.Int32:
                    ProtoWriter.WriteInt32((int)value, writer);
                    return(true);

                case ProtoTypeCode.UInt32:
                    ProtoWriter.WriteUInt32((uint)value, writer);
                    return(true);

                case ProtoTypeCode.Int64:
                    ProtoWriter.WriteInt64((long)value, writer);
                    return(true);

                case ProtoTypeCode.UInt64:
                    ProtoWriter.WriteUInt64((ulong)value, writer);
                    return(true);

                case ProtoTypeCode.Single:
                    ProtoWriter.WriteSingle((float)value, writer);
                    return(true);

                case ProtoTypeCode.Double:
                    ProtoWriter.WriteDouble((double)value, writer);
                    return(true);

                case ProtoTypeCode.Decimal:
                    BclHelpers.WriteDecimal((decimal)value, writer);
                    return(true);

                case ProtoTypeCode.DateTime:
                    BclHelpers.WriteDateTime((DateTime)value, writer);
                    return(true);

                case (ProtoTypeCode)17:
                    break;

                case ProtoTypeCode.String:
                    ProtoWriter.WriteString((string)value, writer);
                    return(true);

                default:
                    switch (protoTypeCode)
                    {
                    case ProtoTypeCode.TimeSpan:
                        BclHelpers.WriteTimeSpan((TimeSpan)value, writer);
                        return(true);

                    case ProtoTypeCode.ByteArray:
                        ProtoWriter.WriteBytes((byte[])value, writer);
                        return(true);

                    case ProtoTypeCode.Guid:
                        BclHelpers.WriteGuid((Guid)value, writer);
                        return(true);

                    case ProtoTypeCode.Uri:
                        ProtoWriter.WriteString(((Uri)value).AbsoluteUri, writer);
                        return(true);
                    }
                    break;
                }
                IEnumerable sequence = value as IEnumerable;
                if (sequence == null)
                {
                    return(false);
                }
                if (isInsideList)
                {
                    throw TypeModel.CreateNestedListsNotSupported();
                }
                foreach (object item in sequence)
                {
                    if (item == null)
                    {
                        throw new NullReferenceException();
                    }
                    if (!this.TrySerializeAuxiliaryType(writer, null, format, tag, item, true))
                    {
                        TypeModel.ThrowUnexpectedType(item.GetType());
                    }
                }
                return(true);
            }
        }
示例#2
0
        internal bool TryDeserializeAuxiliaryType(ProtoReader reader, DataFormat format, int tag, Type type, ref object value, bool skipOtherFields, bool asListItem, bool autoCreate, bool insideList)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            ProtoTypeCode typecode = Helpers.GetTypeCode(type);
            int           modelKey;
            WireType      wiretype = this.GetWireType(typecode, format, ref type, out modelKey);
            bool          found    = false;

            if (wiretype == WireType.None)
            {
                Type itemType = TypeModel.GetListItemType(this, type);
                if (itemType == null && type.IsArray && type.GetArrayRank() == 1 && type != typeof(byte[]))
                {
                    itemType = type.GetElementType();
                }
                if (itemType != null)
                {
                    if (insideList)
                    {
                        throw TypeModel.CreateNestedListsNotSupported();
                    }
                    found = this.TryDeserializeList(this, reader, format, tag, type, itemType, ref value);
                    if (!found && autoCreate)
                    {
                        value = TypeModel.CreateListInstance(type, itemType);
                    }
                    return(found);
                }
                else
                {
                    TypeModel.ThrowUnexpectedType(type);
                }
            }
            while (!found || !asListItem)
            {
                int fieldNumber = reader.ReadFieldHeader();
                if (fieldNumber <= 0)
                {
                    break;
                }
                if (fieldNumber != tag)
                {
                    if (!skipOtherFields)
                    {
                        throw ProtoReader.AddErrorData(new InvalidOperationException("Expected field " + tag.ToString() + ", but found " + fieldNumber.ToString()), reader);
                    }
                    reader.SkipField();
                }
                else
                {
                    found = true;
                    reader.Hint(wiretype);
                    if (modelKey >= 0)
                    {
                        switch (wiretype)
                        {
                        case WireType.String:
                        case WireType.StartGroup:
                        {
                            SubItemToken token = ProtoReader.StartSubItem(reader);
                            value = this.Deserialize(modelKey, value, reader);
                            ProtoReader.EndSubItem(token, reader);
                            break;
                        }

                        default:
                            value = this.Deserialize(modelKey, value, reader);
                            break;
                        }
                    }
                    else
                    {
                        ProtoTypeCode protoTypeCode = typecode;
                        switch (protoTypeCode)
                        {
                        case ProtoTypeCode.Boolean:
                            value = reader.ReadBoolean();
                            break;

                        case ProtoTypeCode.Char:
                            value = (char)reader.ReadUInt16();
                            break;

                        case ProtoTypeCode.SByte:
                            value = reader.ReadSByte();
                            break;

                        case ProtoTypeCode.Byte:
                            value = reader.ReadByte();
                            break;

                        case ProtoTypeCode.Int16:
                            value = reader.ReadInt16();
                            break;

                        case ProtoTypeCode.UInt16:
                            value = reader.ReadUInt16();
                            break;

                        case ProtoTypeCode.Int32:
                            value = reader.ReadInt32();
                            break;

                        case ProtoTypeCode.UInt32:
                            value = reader.ReadUInt32();
                            break;

                        case ProtoTypeCode.Int64:
                            value = reader.ReadInt64();
                            break;

                        case ProtoTypeCode.UInt64:
                            value = reader.ReadUInt64();
                            break;

                        case ProtoTypeCode.Single:
                            value = reader.ReadSingle();
                            break;

                        case ProtoTypeCode.Double:
                            value = reader.ReadDouble();
                            break;

                        case ProtoTypeCode.Decimal:
                            value = BclHelpers.ReadDecimal(reader);
                            break;

                        case ProtoTypeCode.DateTime:
                            value = BclHelpers.ReadDateTime(reader);
                            break;

                        case (ProtoTypeCode)17:
                            break;

                        case ProtoTypeCode.String:
                            value = reader.ReadString();
                            break;

                        default:
                            switch (protoTypeCode)
                            {
                            case ProtoTypeCode.TimeSpan:
                                value = BclHelpers.ReadTimeSpan(reader);
                                break;

                            case ProtoTypeCode.ByteArray:
                                value = ProtoReader.AppendBytes((byte[])value, reader);
                                break;

                            case ProtoTypeCode.Guid:
                                value = BclHelpers.ReadGuid(reader);
                                break;

                            case ProtoTypeCode.Uri:
                                value = new Uri(reader.ReadString());
                                break;
                            }
                            break;
                        }
                    }
                }
            }
            if (!found && !asListItem && autoCreate && type != typeof(string))
            {
                value = Activator.CreateInstance(type);
            }
            return(found);
        }
示例#3
0
 internal void ResolveListTypes(Type type, ref Type itemType, ref Type defaultType)
 {
     if (type == null)
     {
         return;
     }
     if (Helpers.GetTypeCode(type) != ProtoTypeCode.Unknown)
     {
         return;
     }
     if (this[type].IgnoreListHandling)
     {
         return;
     }
     if (type.IsArray)
     {
         if (type.GetArrayRank() != 1)
         {
             throw new NotSupportedException("Multi-dimension arrays are supported");
         }
         itemType = type.GetElementType();
         if (itemType == base.MapType(typeof(byte)))
         {
             Type type2;
             itemType    = (type2 = null);
             defaultType = type2;
         }
         else
         {
             defaultType = type;
         }
     }
     if (itemType == null)
     {
         itemType = TypeModel.GetListItemType(this, type);
     }
     if (itemType != null)
     {
         Type nestedItemType    = null;
         Type nestedDefaultType = null;
         this.ResolveListTypes(itemType, ref nestedItemType, ref nestedDefaultType);
         if (nestedItemType != null)
         {
             throw TypeModel.CreateNestedListsNotSupported();
         }
     }
     if (itemType != null && defaultType == null)
     {
         if (type.IsClass && !type.IsAbstract && Helpers.GetConstructor(type, Helpers.EmptyTypes, true) != null)
         {
             defaultType = type;
         }
         if (defaultType == null && type.IsInterface)
         {
             Type[] genArgs;
             if (type.IsGenericType && type.GetGenericTypeDefinition() == base.MapType(typeof(IDictionary <,>)) && itemType == base.MapType(typeof(KeyValuePair <,>)).MakeGenericType(genArgs = type.GetGenericArguments()))
             {
                 defaultType = base.MapType(typeof(Dictionary <,>)).MakeGenericType(genArgs);
             }
             else
             {
                 defaultType = base.MapType(typeof(List <>)).MakeGenericType(new Type[]
                 {
                     itemType
                 });
             }
         }
         if (defaultType != null && !Helpers.IsAssignableFrom(type, defaultType))
         {
             defaultType = null;
         }
     }
 }