private static FieldSetting <T> CreateValue(int fieldNum, WireType wireType, Action <T, BasicSerializer, byte[]> writeAction, Action <T, BasicDeserializer> readActionWithoutTag, Func <T, bool> hasValueFunc)
 {
     CheckFieldNum(fieldNum);
     return(new FieldSetting <T>(fieldNum, WireFormat.MakeTag(fieldNum, wireType), writeAction, readActionWithoutTag, hasValueFunc));
 }
        public void SkipField(WireType wireType)
        {
            switch (wireType)
            {
            case WireType.Varint:
                int tmp;
                int cnt = 0;
                while ((tmp = ReadByteFromStream()) >= 128)
                {
                    cnt++;

                    if (cnt == 10)
                    {
                        throw InvalidProtocolBufferException.MalformedVarint();
                    }
                }

                break;

            case WireType.Fixed64:
                ReadFromStream(buffForSeek, 0, 8);

                break;

            case WireType.LengthDelimited:
                var len = ReadLength();
                if (len <= buffForSeek.Length)
                {
                    ReadFromStream(buffForSeek, 0, len);
                }
                else
                {
                    ReadFromStream(new byte[len], 0, len);
                }

                break;

            case WireType.StartGroup:
                recursionDepth++;
                uint     tag;
                WireType wt;
                do
                {
                    tag = ReadTag();
                    if (tag == 0)
                    {
                        throw InvalidProtocolBufferException.TruncatedMessage();
                    }

                    wt = WireFormat.GetTagWireType(tag);
                    SkipField(wt);
                } while (wt != WireType.EndGroup);
                recursionDepth--;

                break;

            case WireType.EndGroup:
                break;

            case WireType.Fixed32:
                ReadFromStream(buffForSeek, 0, 4);
                break;

            default:
                throw InvalidProtocolBufferException.UnknownWireType();
                break;
            }
        }
Beispiel #3
0
        private void Initialize()
        {
            // create write action
            if (useHasValue)
            {
                if (getterFieldNumsForSerialization != null)
                {
                    writeAction = (value, serializer) =>
                    {
                        var settings = getterFieldNumsForSerialization(value).Select(x => fieldSettings[x]).OrderBy(x => x.FieldNum).ToArray();
                        foreach (var s in settings)
                        {
                            if (s.HasValueFunc == null || s.HasValueFunc(value))
                            {
                                s.WriteAction(value, serializer, s.RawTag);
                            }
                        }
                    };
                }
                else
                {
                    writeAction = (value, serializer) =>
                    {
                        foreach (var s in fieldSettings.Values)
                        {
                            if (s.HasValueFunc == null || s.HasValueFunc(value))
                            {
                                s.WriteAction(value, serializer, s.RawTag);
                            }
                        }
                    };
                }
            }
            else
            {
                if (getterFieldNumsForSerialization != null)
                {
                    writeAction = (value, serializer) =>
                    {
                        var settings = getterFieldNumsForSerialization(value).Select(x => fieldSettings[x]).OrderBy(x => x.FieldNum).ToArray();
                        foreach (var s in settings)
                        {
                            s.WriteAction(value, serializer, s.RawTag);
                        }
                    };
                }
                else
                {
                    writeAction = (value, serializer) =>
                    {
                        foreach (var s in fieldSettings.Values)
                        {
                            s.WriteAction(value, serializer, s.RawTag);
                        }
                    };
                }
            }

            // create read actions
            if (actionOnMessageRead != null)
            {
                readAction = deserializer =>
                {
                    T           value         = new T();
                    List <int>  readFieldNums = new List <int>();
                    List <uint> unknownTags   = new List <uint>();
                    uint        tag;
                    while ((tag = deserializer.ReadTag()) > 0)
                    {
                        var fnum = WireFormat.GetTagFieldNumber(tag);

                        Action <T, BasicDeserializer> ra;
                        if (readActionsByTag.TryGetValue(tag, out ra))
                        {
                            ra(value, deserializer);
                            readFieldNums.Add(fnum);
                        }
                        else
                        {
                            deserializer.SkipField(WireFormat.GetTagWireType(tag));
                            unknownTags.Add(tag);
                        }
                    }

                    actionOnMessageRead(value, new MessageReadData(readFieldNums, unknownTags));

                    return(value);
                };

                lenLimitedReadAction = (deserializer, lenght) =>
                {
                    T           value         = new T();
                    List <int>  readFieldNums = new List <int>();
                    List <uint> unknownTags   = new List <uint>();
                    uint        tag;

                    long limitPos = deserializer.stream.Position + lenght;

                    while (deserializer.stream.Position < limitPos)
                    {
                        tag = deserializer.ReadTag();
                        var fnum = WireFormat.GetTagFieldNumber(tag);

                        Action <T, BasicDeserializer> ra;
                        if (readActionsByTag.TryGetValue(tag, out ra))
                        {
                            ra(value, deserializer);
                            readFieldNums.Add(fnum);
                        }
                        else
                        {
                            deserializer.SkipField(WireFormat.GetTagWireType(tag));
                            unknownTags.Add(tag);
                        }
                    }

                    if (deserializer.stream.Position > limitPos)
                    {
                        throw InvalidProtocolBufferException.AllowableMessageLengthWasExceeded();
                    }

                    actionOnMessageRead(value, new MessageReadData(readFieldNums, unknownTags));

                    return(value);
                };
            }
            else
            {
                readAction = deserializer =>
                {
                    T    value = new T();
                    uint tag;
                    while ((tag = deserializer.ReadTag()) > 0)
                    {
                        Action <T, BasicDeserializer> ra;
                        if (readActionsByTag.TryGetValue(tag, out ra))
                        {
                            ra(value, deserializer);
                        }
                        else
                        {
                            deserializer.SkipField(WireFormat.GetTagWireType(tag));
                        }
                    }

                    return(value);
                };

                lenLimitedReadAction = (deserializer, lenght) =>
                {
                    T    value = new T();
                    uint tag;
                    long limitPos = deserializer.stream.Position + lenght;
                    while (deserializer.stream.Position < limitPos)
                    {
                        tag = deserializer.ReadTag();

                        Action <T, BasicDeserializer> ra;
                        if (readActionsByTag.TryGetValue(tag, out ra))
                        {
                            ra(value, deserializer);
                        }
                        else
                        {
                            deserializer.SkipField(WireFormat.GetTagWireType(tag));
                        }
                    }

                    if (deserializer.stream.Position > limitPos)
                    {
                        throw InvalidProtocolBufferException.AllowableMessageLengthWasExceeded();
                    }

                    return(value);
                };
            }

            initialized = true;
        }