Skip to content

修复 #148 #149

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 2, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 29 additions & 3 deletions utils/binary/reader.go
Original file line number Diff line number Diff line change
@@ -81,9 +81,15 @@ func (r *Reader) ReadAll() []byte {

func (r *Reader) ReadU8() (v uint8) {
if r.reader != nil {
_, _ = r.reader.Read(unsafe.Slice(&v, 1))
_, err := r.reader.Read(unsafe.Slice(&v, 1))
if err != nil {
return 0
}
return
}
if r.pos >= len(r.buffer) {
return 0
}
v = r.buffer[r.pos]
r.pos++
return
@@ -93,8 +99,16 @@ func readint[T ~uint16 | ~uint32 | ~uint64](r *Reader) (v T) {
sz := unsafe.Sizeof(v)
buf := make([]byte, 8)
if r.reader != nil {
_, _ = r.reader.Read(buf[8-sz:])
n, err := r.reader.Read(buf[8-sz:])
if err != nil || n < int(sz) {
// 读取失败或读取的数据不足,返回零值
return 0
}
} else {
// 确保缓冲区有足够的数据
if r.pos+int(sz) > len(r.buffer) {
return 0
}
copy(buf[8-sz:], r.buffer[r.pos:r.pos+int(sz)])
r.pos += int(sz)
}
@@ -129,6 +143,10 @@ func (r *Reader) ReadBytesNoCopy(length int) (v []byte) {
if r.reader != nil {
return r.ReadBytes(length)
}
// 确保缓冲区有足够的数据
if r.pos+length > len(r.buffer) {
return make([]byte, 0)
}
v = r.buffer[r.pos : r.pos+length]
r.pos += length
return
@@ -138,8 +156,16 @@ func (r *Reader) ReadBytes(length int) (v []byte) {
// 返回一个全新的数组罢
v = make([]byte, length)
if r.reader != nil {
_, _ = r.reader.Read(v)
n, err := io.ReadFull(r.reader, v)
if err != nil || n < length {
// 读取失败或读取的数据不足,返回空数组
return make([]byte, 0)
}
} else {
// 确保缓冲区有足够的数据
if r.pos+length > len(r.buffer) {
return make([]byte, 0)
}
copy(v, r.buffer[r.pos:r.pos+length])
r.pos += length
}
168 changes: 168 additions & 0 deletions utils/binary/reader_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package binary

import (
"io"
"testing"
)

// TestReaderEmptyBuffer 测试空缓冲区的情况
func TestReaderEmptyBuffer(t *testing.T) {
// 测试空缓冲区
r := NewReader([]byte{})

// 测试ReadU8
if v := r.ReadU8(); v != 0 {
t.Errorf("ReadU8 with empty buffer should return 0, got %d", v)
}

// 测试ReadU16
if v := r.ReadU16(); v != 0 {
t.Errorf("ReadU16 with empty buffer should return 0, got %d", v)
}

// 测试ReadU32
if v := r.ReadU32(); v != 0 {
t.Errorf("ReadU32 with empty buffer should return 0, got %d", v)
}

// 测试ReadU64
if v := r.ReadU64(); v != 0 {
t.Errorf("ReadU64 with empty buffer should return 0, got %d", v)
}

// 测试ReadBytes
if bytes := r.ReadBytes(10); len(bytes) != 0 {
t.Errorf("ReadBytes with empty buffer should return empty slice, got %v", bytes)
}

// 测试ReadBytesNoCopy
if bytes := r.ReadBytesNoCopy(10); len(bytes) != 0 {
t.Errorf("ReadBytesNoCopy with empty buffer should return empty slice, got %v", bytes)
}
}

// TestReaderIncompleteData 测试不完整数据的情况
func TestReaderIncompleteData(t *testing.T) {
// 测试不完整数据 - 只有1个字节
r := NewReader([]byte{0x01})

// 测试ReadU16 (需要2字节)
if v := r.ReadU16(); v != 0 {
t.Errorf("ReadU16 with incomplete data should return 0, got %d", v)
}

// 重置Reader
r = NewReader([]byte{0x01, 0x02})

// 测试ReadU32 (需要4字节)
if v := r.ReadU32(); v != 0 {
t.Errorf("ReadU32 with incomplete data should return 0, got %d", v)
}

// 测试ReadBytes超出可用长度
r = NewReader([]byte{0x01, 0x02, 0x03})
if bytes := r.ReadBytes(10); len(bytes) != 0 {
t.Errorf("ReadBytes with insufficient data should return empty slice, got %v", bytes)
}
}

// TestReaderWithIOReader 测试使用io.Reader的情况
func TestReaderWithIOReader(t *testing.T) {
// 创建一个会返回错误的Reader
errReader := &errorReader{}
r := ParseReader(errReader)

// 测试ReadU8
if v := r.ReadU8(); v != 0 {
t.Errorf("ReadU8 with error reader should return 0, got %d", v)
}

// 测试ReadU16
if v := r.ReadU16(); v != 0 {
t.Errorf("ReadU16 with error reader should return 0, got %d", v)
}

// 测试ReadU32
if v := r.ReadU32(); v != 0 {
t.Errorf("ReadU32 with error reader should return 0, got %d", v)
}

// 测试ReadBytes
if bytes := r.ReadBytes(10); len(bytes) != 0 {
t.Errorf("ReadBytes with error reader should return empty slice, got %v", bytes)
}

// 测试ReadAll
if data := r.ReadAll(); data != nil {
t.Errorf("ReadAll with error reader should return nil, got %v", data)
}
}

// TestReaderNormalData 测试正常数据的情况
func TestReaderNormalData(t *testing.T) {
// 准备测试数据
data := []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
r := NewReader(data)

// 测试ReadU8
if v := r.ReadU8(); v != 0x01 {
t.Errorf("ReadU8 should return 0x01, got 0x%02x", v)
}

// 测试ReadU16
if v := r.ReadU16(); v != 0x0203 {
t.Errorf("ReadU16 should return 0x0203, got 0x%04x", v)
}

// 测试ReadU32
if v := r.ReadU32(); v != 0x04050607 {
t.Errorf("ReadU32 should return 0x04050607, got 0x%08x", v)
}

// 测试ReadByte
if b, err := r.ReadByte(); err != nil || b != 0x08 {
t.Errorf("ReadByte should return 0x08, got 0x%02x, err: %v", b, err)
}

// 测试读取完所有数据后的ReadByte
if _, err := r.ReadByte(); err != io.EOF {
t.Errorf("ReadByte after end should return EOF, got %v", err)
}
}

// TestReaderShortRead 测试短读的情况
func TestReaderShortRead(t *testing.T) {
// 创建一个会返回短读的Reader
shortReader := &shortReader{data: []byte{0x01, 0x02, 0x03, 0x04}}
r := ParseReader(shortReader)

// 测试ReadBytes
if bytes := r.ReadBytes(10); len(bytes) != 0 {
t.Errorf("ReadBytes with short reader should return empty slice, got %v", bytes)
}
}

// 辅助测试结构

// errorReader 总是返回错误的Reader
type errorReader struct{}

func (r *errorReader) Read(p []byte) (n int, err error) {
return 0, io.ErrUnexpectedEOF
}

// shortReader 总是返回短读的Reader
type shortReader struct {
data []byte
pos int
}

func (r *shortReader) Read(p []byte) (n int, err error) {
if r.pos >= len(r.data) {
return 0, io.EOF
}
// 只读取一个字节,模拟短读
p[0] = r.data[r.pos]
r.pos++
return 1, nil
}