为了账号安全,请及时绑定邮箱和手机立即绑定

如何在没有模式的情况下从原始语音消息中提取字段

如何在没有模式的情况下从原始语音消息中提取字段

Go
红糖糍粑 2022-08-24 16:45:54
根据这个问题,protoreflect包提供了用于访问protobuf消息的“未知字段”的API,但是如果没有任何现有的架构,我看不到任何使用它的方法。基本上,我想执行“弱解码”,类似于JSON unmarshaller在输出类型时执行的操作。map[string]interface{}文档中的示例如下所示:err := UnmarshalOptions{DiscardUnknown: true}.Unmarshal(b, m)其中 是输入字节切片,是输出消息,需要以某种方式进行初始化,如您在此处所示。我在想dynamicpb可以用于这个目的,但是如果没有现有的MessageDescriptor,它看起来是不可能的,这就是我陷入困境的地方......bm
查看完整描述

1 回答

?
慕妹3146593

TA贡献1820条经验 获得超9个赞

我能够使用低级protowire封装实现这一目标。下面是一个完整的示例,其中我提取了两个类型的字段(在原始架构中恰好分配了字段编号 4 和 5):uint64

import "google.golang.org/protobuf/encoding/protowire"


func getData(src []byte) (creationTime, expiryTime uint64, err error) {

    remaining := src

    for len(remaining) > 0 {

        fieldNum, wireType, n := protowire.ConsumeTag(remaining)

        if n < 0 {

            return 0, 0, fmt.Errorf("failed to consume tag: %w", protowire.ParseError(n))

        }

        remaining = remaining[n:]


        switch fieldNum {

        case 4: // Expiry time

            if wireType != protowire.VarintType {

                return 0, 0, fmt.Errorf("unexpected type for expiry time field: %d", wireType)

            }

            expiryTime, n = protowire.ConsumeVarint(remaining)

        case 5: // Creation time

            if wireType != protowire.VarintType {

                return 0, 0, fmt.Errorf("unexpected type for creation time field: %d", wireType)

            }

            creationTime, n = protowire.ConsumeVarint(remaining)

        default:

            n = protowire.ConsumeFieldValue(fieldNum, wireType, remaining)

        }

        if n < 0 {

            return 0, 0, fmt.Errorf("failed to consume value for field %d: %w", fieldNum, protowire.ParseError(n))

        }

        remaining = remaining[n:]

    }


    return

}




查看完整回答
反对 回复 2022-08-24
  • 1 回答
  • 0 关注
  • 61 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信