Exemple #1
0
        static object ParseSingleVarint(IPrimitiveField.Types type, Stream stream, ulong max_len, out ulong length)
        {
            switch (type)
            {
            case IPrimitiveField.Types.Bool:
                return(Varint.FromBase128(stream, max_len, out length) != 0);

            case IPrimitiveField.Types.Int32:
                return((int)Varint.FromBase128Signed(stream, max_len, out length));

            case IPrimitiveField.Types.Int64:
                return((long)Varint.FromBase128Signed(stream, max_len, out length));

            case IPrimitiveField.Types.Uint32:
                return((uint)Varint.FromBase128(stream, max_len, out length));

            case IPrimitiveField.Types.Uint64:
                return((ulong)Varint.FromBase128(stream, max_len, out length));

            default:
                throw new InvalidOperationException("This function can only parse values from varints");
            }
        }
Exemple #2
0
        static void ParseClass(IClass cls, Stream stream, long allowed_length = -1)
        {
            // How do I want to deal with invalid stuff?
            if (allowed_length < 0)
            {
                allowed_length = stream.Length;
            }
            bool done = false;

            try {
                while (stream.Position != allowed_length && !done)
                {
                    Tuple <int, WireType> fieldInfo = ReadFieldInfo(stream);
                    WireType wireType = fieldInfo.Item2;
                    int      fieldNum = fieldInfo.Item1;

                    IField field = cls.Fields.Where((field) => { return(field.Number == fieldNum); }).SingleOrDefault();
                    if (field == null)
                    {
                        // Discard this field
                        DiscardWire(wireType, stream);
                        continue;
                    }

                    switch (field)
                    {
                    case IClassField classField:
                        DiscardIfNot(stream, WireType.LENGTH_DELIMITED, wireType, () => {
                            ulong length = Varint.FromBase128(stream);
                            AppendIfList(classField);
                            ParseClass(classField[classField.Count - 1], stream, stream.Position + (long)length);
                        });
                        break;

                    case IEnumField enumField:
                        Func <ulong, ulong> addOneEnum = (max_len) => {
                            AppendIfList(enumField);
                            enumField[enumField.Count - 1] = (int)Varint.FromBase128(stream, max_len, out ulong length);
                            return(length);
                        };
                        if (wireType == WireType.LENGTH_DELIMITED)
                        {
                            ulong length = Varint.FromBase128(stream);
                            for (ulong i = 0; i < length;)
                            {
                                i += addOneEnum(length - i);
                            }
                        }
                        else
                        {
                            DiscardIfNot(stream, WireType.VARINT, wireType, () => {
                                addOneEnum(10);
                            });
                        }
                        break;

                    case IPrimitiveField primitiveField:
                        IPrimitiveField.Types fieldType = primitiveField.Type;
                        switch (fieldType)
                        {
                        case IPrimitiveField.Types.Bool:
                        case IPrimitiveField.Types.Int32:
                        case IPrimitiveField.Types.Int64:
                        case IPrimitiveField.Types.Uint32:
                        case IPrimitiveField.Types.Uint64:
                            Func <ulong, ulong> addOnePrim = (max_len) => {
                                AppendIfList(primitiveField);
                                primitiveField[primitiveField.Count - 1] = ParseSingleVarint(fieldType, stream, max_len, out ulong length);
                                return(length);
                            };
                            if (wireType == WireType.LENGTH_DELIMITED)
                            {
                                ulong length = Varint.FromBase128(stream);
                                for (ulong i = 0; i < length;)
                                {
                                    i += addOnePrim(length - i);
                                }
                                ;
                            }
                            else
                            {
                                DiscardIfNot(stream, WireType.VARINT, wireType, () => {
                                    addOnePrim(10);
                                });
                            }
                            break;

                        case IPrimitiveField.Types.Double:
                            DiscardIfNot(stream, WireType.FIXED_64, wireType, () => {
                                AppendIfList(primitiveField);
                                primitiveField[primitiveField.Count - 1] = new BinaryReader(stream).ReadDouble();
                            });
                            break;

                        case IPrimitiveField.Types.Float:
                            DiscardIfNot(stream, WireType.FIXED_32, wireType, () => {
                                AppendIfList(primitiveField);
                                primitiveField[primitiveField.Count - 1] = new BinaryReader(stream).ReadSingle();
                            });
                            break;

                        case IPrimitiveField.Types.String:
                            DiscardIfNot(stream, WireType.LENGTH_DELIMITED, wireType, () => {
                                ulong length = Varint.FromBase128(stream);
                                StringWriter stringWriter = new();
                                for (ulong i = 0; i < length; i++)
                                {
                                    stringWriter.Write((char)stream.ReadByte());
                                }
                                AppendIfList(primitiveField);
                                primitiveField[primitiveField.Count - 1] = stringWriter.ToString();
                            });
                            break;
                        }
                        ;
                        break;
                    }
                }
            } catch (EndOfStreamException) {
            }
        }
Exemple #3
0
 static object ParseSingleVarint(IPrimitiveField.Types type, Stream stream, ulong max_len = 10) => ParseSingleVarint(type, stream, max_len, out _);