这个`binary.read`如何知道何时停止?

huangapple go评论72阅读模式
英文:

How does this binary.read know when to stop?

问题

请注意,这是伪代码,我正在进行总结。我正在从函数内部阅读一些源代码:

maxKeyLen := 100 * 1024 * 1024
maxValueLen := 100 * 1024 * 1024
var klen, vlen uint32
binary.Read(p.buffer, binary.BigEndian, &klen)

if klen > maxKeyLen {
    return nil, nil, fmt.Errorf("key exceeds max len %d, got %d bytes", maxKeyLen, klen)
}

在什么时候 binary.Read 停止?因为紧接着这个操作之后还有另一个读取操作:

key := make([]byte, klen)
_, err := p.buffer.Read(key)
if err != nil {
    return nil, nil, err
}

binary.Read(p.buffer, binary.BigEndian, &vlen)
if vlen > maxValueLen {
    return nil, nil, fmt.Errorf("value exceeds max len %d, got %d bytes", maxValueLen, vlen)
}

其中 p.buffer 是通过以下方式定义的:

buff := new(bytes.Buffer)
io.Copy(buff, r)
p.buffer = buff

而 r 是传入的一些数据。

起初我以为答案是在读取 4 个字节后停止。但事实并非如此,因为 maxKeyLen 检查的是是否大于该值。那么 binary.Read 如何知道何时停止,因为后面还有更多的数据,接下来的 binary.Read 是用于读取 vlen 的,它是如何找到正确的位置的?

英文:

Please note this is pseudo code and I am summarising.I am reading some source code from inside a function:

maxKeyLen  := 100 * 1024 * 1024
maxValueLen  := 100 * 1024 * 1024
var klen, vlen uint32
binary.Read(p.buffer, binary.BigEndian, &klen)

 if klen > maxKeyLen {
	return nil, nil, fmt.Errorf("key exceeds max len %d, got %d bytes", maxKeyLen, klen)
}

At what point does the binary.Read stop? Because straight after this there is another read:

key := make([]byte, klen)
_, err := p.buffer.Read(key)
if err != nil {
	return nil, nil, err
}

binary.Read(p.buffer, binary.BigEndian, &vlen)
if vlen > maxValueLen {
	return nil, nil, fmt.Errorf("value exceeds max len %d, got %d bytes", maxValueLen, vlen)
}

Where p.buffer is defined via:

buff := new(bytes.Buffer)
io.Copy(buff, r)
p.buffer = buff

And r is some data that has been passed in.

At first I thought the answer was at 4 bytes it stops. But that's not true because the maxkeylen checks for greater than that. So how does the binary.read know when to stop as there is more data ahead, because the next binary read on for the vlen then finds stuff?

答案1

得分: 3

当询问Go的超级英雄时,始终参考他们实际的源代码:

https://golang.org/src/encoding/binary/binary.go?s=4201:4264#L132

142	func Read(r io.Reader, order ByteOrder, data interface{}) error {
143		// Fast path for basic types and slices.
144		if n := intDataSize(data); n != 0 {

第144行展示了读取已知类型的初始大小的示例,并在后续的作用域中进行迭代或复制。

在你上面的代码示例中,它将是klen的4个字节长度,klen是一个uint32类型。也就是说,它将从p.buffer中读取4个字节到klen中。

文档中给出了一些提示:

https://golang.org/pkg/encoding/binary/#Read

func Read(r io.Reader, order ByteOrder, data interface{}) error

> Read从r中读取结构化的二进制数据到data中。data必须是一个指向固定大小值的指针或固定大小值的切片。从r中读取的字节使用指定的字节顺序进行解码,并写入到data的连续字段中。

英文:

When questioning the superheros of Go, always refer to their actual source code in question:

https://golang.org/src/encoding/binary/binary.go?s=4201:4264#L132

142	func Read(r io.Reader, order ByteOrder, data interface{}) error {
143		// Fast path for basic types and slices.
144		if n := intDataSize(data); n != 0 {

Line 144 shows an example of reading the initial size of know types, and iterating or copying as needed later in that scope.

In your code example above, it will be the 4 byte length of klen which is an uint32. That is, it will read 4 bytes from p.buffer into klen.

It gives a hint in the documentation:

https://golang.org/pkg/encoding/binary/#Read

func Read(r io.Reader, order ByteOrder, data interface{}) error

> Read reads structured binary data from r into data. Data must be a pointer to a fixed-size value or a slice of fixed-size values. Bytes read from r are decoded using the specified byte order and written to successive fields of the data.

huangapple
  • 本文由 发表于 2016年4月13日 20:51:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/36598964.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定