dongshuo1856 2014-04-25 00:46
浏览 21
已采纳

无法使用goprotobuf解码邮件

I have the following proto file:

package dogs;

enum Breed {
    terrier = 0;
    shepherd = 1;
    hound = 2;
};

message Dog {
    required int64 nbLegs = 1;
    optional int64 nbTeeth = 2 [default=24];
    optional Breed breed = 3;
    optional string name = 4;
}

And the following Go program written using the goprotobuf package. The program

  1. reads a Varint from stdin in order to get the length of the encoded message,
  2. reads that number of bytes from stdin into a buffer, and
  3. attempts to unmarshal the buffer into a Dog.

--START CODE--

package main

import "bufio"
import "encoding/binary"
import "os"
import "log"
import "fmt"
import "dogs"
import "code.google.com/p/goprotobuf/proto"

func render(dog *dogs.Dog) string {
    return fmt.Sprintf("Dog: %v %v %v %v", dog.GetName(), dog.GetBreed(), dog.GetNbLegs(), dog.GetNbTeeth())
}

func main() {
    var dog = new(dogs.Dog)
    stdin := bufio.NewReader(os.Stdin)
    sz, _ := binary.ReadVarint(stdin)
    bytes := make([]byte, sz)
    os.Stdin.Read(bytes)
    buf := proto.NewBuffer(bytes)
    err := buf.Unmarshal(dog)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Fprintf(os.Stderr, "Receiving %s of length %d
", render(dog), sz)

}

--END CODE--

And the this encoded message (preceded by a Varint) (in hexdump form)

0000000: 1408 0418 0222 0446 6964 6f              .....".Fido

which i can successfully decode using c++ and libprotobuf as a Dog with

  • name: Fido
  • breed: hound
  • nbLegs: 4
  • nbTeeth: 24

Unmarshaling in the go program, however, always returns the error "illegal tag 0".

I suspect that I've misunderstood the decoding API but, so far, I can't see how.

  • 写回答

1条回答 默认 最新

  • drxv39706 2014-04-28 11:50
    关注

    Try just umarshalling the bytes instead of creating a buffer like this: You may also want to check to see if os.Stdin.Read(bytes) is actually reading sz.

    func main() {
        var dog = new(dogs.Dog)
        stdin := bufio.NewReader(os.Stdin)
        sz, _ := binary.ReadVarint(stdin)
        bytes := make([]byte, sz)
        stdin.Read(bytes)
        err := buf.Unmarshal(dog, bytes)
        if err != nil {
            log.Fatal(err)
        }
        fmt.Fprintf(os.Stderr, "Receiving %s of length %d
    ", render(dog), sz)
    
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何使用simulink建立一个永磁同步直线电机模型?
  • ¥30 天体光谱图的的绘制并得到星表
  • ¥15 PointNet++的onnx模型只能使用一次
  • ¥20 西南科技大学数字信号处理
  • ¥15 有两个非常“自以为是”烦人的问题急期待大家解决!
  • ¥30 STM32 INMP441无法读取数据
  • ¥15 R语言绘制密度图,一个密度曲线内fill不同颜色如何实现
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗