protobuf解码未知的消息结构



场景

对于一个地图平铺项目(想想谷歌地球(,我有一个.mbtile文件,我对它一无所知,除了它有很多关于地球上城市的数据。我已经研究了几天,发现了以下内容:

  • 文件是一个sqlite数据库
  • 数据库有一个满是Blob的表tiles
  • Blob是带有gzip签名的二进制文件
  • 解压缩后,结果是一个协议缓冲区

我没怎么和protobuf合作过,所以我正在上速成班。我取了解压缩的二进制文件,用protoc --decode_raw收到了以下

$ echo 1a900178010a06706c6163657328802012121208000001010202030318012204095cd6341213120800040105020603071801220509e206b2361a047a6d696e1a046e616d651a0a706f70756c6174696f6e1a0773756274696c652202280322070a053f73616b61220528b0aab105220328c006220919333333333333fb3f22070a05546f6b796f220528e0be8111220328e306 | xxd -r -p | protoc --decode_raw
3 {
15: 1
1: "places"
5: 4096
2 {
2: "0000010102020303"
3: 1
4: "t\3264"
}
2 {
2: "0004010502060307"
3: 1
4: "t342062626"
}
3: "zmin"
3: "name"
3: "population"
3: "subtile"
4 {
5: 3
}
4 {
1: "?saka"
}
4 {
5: 11294000
}
4 {
5: 832
}
4 {
3: 0x3ffb333333333333
}
4 {
1: "Tokyo"
}
4 {
5: 35676000
}
4 {
5: 867
}
}

问题

如果我理解正确的话,这个告诉我一些关于消息结构的信息。如何为该输出创建[ProtoContract]?以下是我当前(未操作(的尝试

[ProtoContract]
struct Place
{
[ProtoMember(1)]
public string name { get; set; }
[ProtoMember(2)]
public double population { get; set; }
[ProtoMember(3)]
public uint subtile { get; set; }
[ProtoMember(4)]
public double zmin { get; set; }
[ProtoMember(5)]
public int[] location { get; set; }
}

正在工作的c#protobuf将thx合同授予@MarcGravell

#region Designer generated code
#pragma warning disable CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
namespace MapBox
{
[global::ProtoBuf.ProtoContract()]
public partial class Tile : global::ProtoBuf.IExtensible
{
private global::ProtoBuf.IExtension __pbn__extensionData;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
=> global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
[global::ProtoBuf.ProtoMember(3, Name = @"layers")]
public global::System.Collections.Generic.List<Layer> Layers { get; } = new global::System.Collections.Generic.List<Layer>();
[global::ProtoBuf.ProtoContract()]
public partial class Value : global::ProtoBuf.IExtensible
{
private global::ProtoBuf.IExtension __pbn__extensionData;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
=> global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
[global::ProtoBuf.ProtoMember(1, Name = @"string_value")]
[global::System.ComponentModel.DefaultValue("")]
public string StringValue
{
get => __pbn__StringValue ?? "";
set => __pbn__StringValue = value;
}
public bool ShouldSerializeStringValue() => __pbn__StringValue != null;
public void ResetStringValue() => __pbn__StringValue = null;
private string __pbn__StringValue;
[global::ProtoBuf.ProtoMember(2, Name = @"float_value")]
public float FloatValue
{
get => __pbn__FloatValue.GetValueOrDefault();
set => __pbn__FloatValue = value;
}
public bool ShouldSerializeFloatValue() => __pbn__FloatValue != null;
public void ResetFloatValue() => __pbn__FloatValue = null;
private float? __pbn__FloatValue;
[global::ProtoBuf.ProtoMember(3, Name = @"double_value")]
public double DoubleValue
{
get => __pbn__DoubleValue.GetValueOrDefault();
set => __pbn__DoubleValue = value;
}
public bool ShouldSerializeDoubleValue() => __pbn__DoubleValue != null;
public void ResetDoubleValue() => __pbn__DoubleValue = null;
private double? __pbn__DoubleValue;
[global::ProtoBuf.ProtoMember(4, Name = @"int_value")]
public long IntValue
{
get => __pbn__IntValue.GetValueOrDefault();
set => __pbn__IntValue = value;
}
public bool ShouldSerializeIntValue() => __pbn__IntValue != null;
public void ResetIntValue() => __pbn__IntValue = null;
private long? __pbn__IntValue;
[global::ProtoBuf.ProtoMember(5, Name = @"uint_value")]
public ulong UintValue
{
get => __pbn__UintValue.GetValueOrDefault();
set => __pbn__UintValue = value;
}
public bool ShouldSerializeUintValue() => __pbn__UintValue != null;
public void ResetUintValue() => __pbn__UintValue = null;
private ulong? __pbn__UintValue;
[global::ProtoBuf.ProtoMember(6, Name = @"sint_value", DataFormat = global::ProtoBuf.DataFormat.ZigZag)]
public long SintValue
{
get => __pbn__SintValue.GetValueOrDefault();
set => __pbn__SintValue = value;
}
public bool ShouldSerializeSintValue() => __pbn__SintValue != null;
public void ResetSintValue() => __pbn__SintValue = null;
private long? __pbn__SintValue;
[global::ProtoBuf.ProtoMember(7, Name = @"bool_value")]
public bool BoolValue
{
get => __pbn__BoolValue.GetValueOrDefault();
set => __pbn__BoolValue = value;
}
public bool ShouldSerializeBoolValue() => __pbn__BoolValue != null;
public void ResetBoolValue() => __pbn__BoolValue = null;
private bool? __pbn__BoolValue;
}
[global::ProtoBuf.ProtoContract()]
public partial class Feature : global::ProtoBuf.IExtensible
{
private global::ProtoBuf.IExtension __pbn__extensionData;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
=> global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
[global::ProtoBuf.ProtoMember(1, Name = @"id")]
[global::System.ComponentModel.DefaultValue(typeof(ulong), "0")]
public ulong Id
{
get => __pbn__Id ?? 0;
set => __pbn__Id = value;
}
public bool ShouldSerializeId() => __pbn__Id != null;
public void ResetId() => __pbn__Id = null;
private ulong? __pbn__Id;
[global::ProtoBuf.ProtoMember(2, Name = @"tags", IsPacked = true)]
public uint[] Tags { get; set; }
[global::ProtoBuf.ProtoMember(3, Name = @"type")]
[global::System.ComponentModel.DefaultValue(Tile.GeomType.Unknown)]
public Tile.GeomType Type
{
get => __pbn__Type ?? Tile.GeomType.Unknown;
set => __pbn__Type = value;
}
public bool ShouldSerializeType() => __pbn__Type != null;
public void ResetType() => __pbn__Type = null;
private Tile.GeomType? __pbn__Type;
[global::ProtoBuf.ProtoMember(4, Name = @"geometry", IsPacked = true)]
public uint[] Geometries { get; set; }
}
[global::ProtoBuf.ProtoContract()]
public partial class Layer : global::ProtoBuf.IExtensible
{
private global::ProtoBuf.IExtension __pbn__extensionData;
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing)
=> global::ProtoBuf.Extensible.GetExtensionObject(ref __pbn__extensionData, createIfMissing);
[global::ProtoBuf.ProtoMember(15, Name = @"version", IsRequired = true)]
public uint Version { get; set; }
[global::ProtoBuf.ProtoMember(1, Name = @"name", IsRequired = true)]
public string Name { get; set; }
[global::ProtoBuf.ProtoMember(2, Name = @"features")]
public global::System.Collections.Generic.List<Tile.Feature> Features { get; } = new global::System.Collections.Generic.List<Tile.Feature>();
[global::ProtoBuf.ProtoMember(3, Name = @"keys")]
public global::System.Collections.Generic.List<string> Keys { get; } = new global::System.Collections.Generic.List<string>();
[global::ProtoBuf.ProtoMember(4, Name = @"values")]
public global::System.Collections.Generic.List<Tile.Value> Values { get; } = new global::System.Collections.Generic.List<Tile.Value>();
[global::ProtoBuf.ProtoMember(5, Name = @"extent")]
[global::System.ComponentModel.DefaultValue(4096)]
public uint Extent
{
get => __pbn__Extent ?? 4096;
set => __pbn__Extent = value;
}
public bool ShouldSerializeExtent() => __pbn__Extent != null;
public void ResetExtent() => __pbn__Extent = null;
private uint? __pbn__Extent;
}
[global::ProtoBuf.ProtoContract()]
public enum GeomType
{
[global::ProtoBuf.ProtoEnum(Name = @"UNKNOWN")]
Unknown = 0,
[global::ProtoBuf.ProtoEnum(Name = @"POINT")]
Point = 1,
[global::ProtoBuf.ProtoEnum(Name = @"LINESTRING")]
Linestring = 2,
[global::ProtoBuf.ProtoEnum(Name = @"POLYGON")]
Polygon = 3,
}
}
}
#pragma warning restore CS0612, CS0618, CS1591, CS3021, IDE0079, IDE1006, RCS1036, RCS1057, RCS1085, RCS1192
#endregion

最新更新