Example #1
0
 public override void WriteSignedVarint(long number)
 {
     Varint.ToBase128(number, _stream);
 }
Example #2
0
        private static void SerializeClass(IClass cls, ProtoStream protostream)
        {
            foreach (IField field in cls.Fields)
            {
                if (field.IsTransient)
                {
                    continue;
                }

                // Treat all lists as un-packed
                for (int i = 0; i < field.Count; i++)
                {
                    if (field is IEnumField enumField)
                    {
                        protostream.WriteFieldInfo(enumField.Number, WireType.VARINT);
                        Varint.ToBase128(enumField[i], protostream);
                    }
                    else if (field is IPrimitiveField primitiveField)
                    {
                        switch (primitiveField.Type)
                        {
                        case IPrimitiveField.Types.Bool:
                            protostream.WriteFieldInfo(primitiveField.Number, WireType.VARINT);
                            protostream.WriteVarint(((bool)primitiveField[i]) ? (ulong)1 : (ulong)0);
                            break;

                        case IPrimitiveField.Types.Int32:
                            protostream.WriteFieldInfo(primitiveField.Number, WireType.VARINT);
                            protostream.WriteSignedVarint((int)primitiveField[i]);
                            break;

                        case IPrimitiveField.Types.Int64:
                            protostream.WriteFieldInfo(primitiveField.Number, WireType.VARINT);
                            protostream.WriteSignedVarint((long)primitiveField[i]);
                            break;

                        case IPrimitiveField.Types.Uint32:
                            protostream.WriteFieldInfo(primitiveField.Number, WireType.VARINT);
                            protostream.WriteVarint((ulong)(uint)primitiveField[i]);
                            break;

                        case IPrimitiveField.Types.Uint64:
                            protostream.WriteFieldInfo(primitiveField.Number, WireType.VARINT);
                            protostream.WriteVarint((ulong)primitiveField[i]);
                            break;

                        case IPrimitiveField.Types.Double:
                            protostream.WriteFieldInfo(primitiveField.Number, WireType.FIXED_64);
                            byte[] doubleBytes = BitConverter.GetBytes((double)primitiveField[i]);
                            protostream.Write(doubleBytes, 0, 8);
                            break;

                        case IPrimitiveField.Types.Float:
                            protostream.WriteFieldInfo(primitiveField.Number, WireType.FIXED_32);
                            byte[] floatBytes = BitConverter.GetBytes((float)primitiveField[i]);
                            protostream.Write(floatBytes, 0, 4);
                            break;

                        case IPrimitiveField.Types.Bytes:
                            protostream.WriteFieldInfo(primitiveField.Number, WireType.LENGTH_DELIMITED);
                            byte[] bytes = (byte[])(primitiveField[i]);
                            protostream.WriteVarint((ulong)bytes.Length);
                            protostream.Write(bytes, 0, bytes.Length);
                            break;

                        case IPrimitiveField.Types.String:
                            protostream.WriteFieldInfo(primitiveField.Number, WireType.LENGTH_DELIMITED);
                            byte[] stringBytes = Encoding.UTF8.GetBytes((string)primitiveField[i]);
                            protostream.WriteVarint((ulong)stringBytes.Length);
                            protostream.Write(stringBytes, 0, stringBytes.Length);
                            break;

                        case IPrimitiveField.Types.External:
                            throw new NotSupportedException("External type must always be transient");
                        }
                    }
                    else if (field is IClassField classField)
                    {
                        using CountingProtoStream counting = new();
                        SerializeClass(classField[i], counting);
                        protostream.WriteFieldInfo(classField.Number, WireType.LENGTH_DELIMITED);
                        protostream.WriteVarint((ulong)counting.Length);
                        SerializeClass(classField[i], protostream);
                    }
                }
            }
        }