diff --git a/ring_buffer.go b/ring_buffer.go index 61259ce..dc1f620 100644 --- a/ring_buffer.go +++ b/ring_buffer.go @@ -1,6 +1,7 @@ package ringbuffer import ( + "encoding/binary" "errors" "fmt" "unsafe" @@ -174,6 +175,58 @@ func (r *RingBuffer) PeekAll() (first []byte, end []byte) { return } +func (r *RingBuffer) PeekUint8() uint8 { + if r.Length() < 1 { + return 0 + } + + f, e := r.Peek(1) + if len(e) > 0 { + return e[0] + } else { + return f[0] + } +} + +func (r *RingBuffer) PeekUint16() uint16 { + if r.Length() < 2 { + return 0 + } + + f, e := r.Peek(2) + if len(e) > 0 { + return binary.BigEndian.Uint16(copyByte(f, e)) + } else { + return binary.BigEndian.Uint16(f) + } +} + +func (r *RingBuffer) PeekUint32() uint32 { + if r.Length() < 4 { + return 0 + } + + f, e := r.Peek(4) + if len(e) > 0 { + return binary.BigEndian.Uint32(copyByte(f, e)) + } else { + return binary.BigEndian.Uint32(f) + } +} + +func (r *RingBuffer) PeekUint64() uint64 { + if r.Length() < 8 { + return 0 + } + + f, e := r.Peek(8) + if len(e) > 0 { + return binary.BigEndian.Uint64(copyByte(f, e)) + } else { + return binary.BigEndian.Uint64(f) + } +} + func (r *RingBuffer) Read(p []byte) (n int, err error) { if len(p) == 0 { return 0, nil @@ -374,3 +427,10 @@ func (r *RingBuffer) free() int { return r.size - r.w + r.r } + +func copyByte(f, e []byte) []byte { + buf := make([]byte, len(f)+len(e)) + _ = copy(buf, f) + _ = copy(buf, e) + return buf +} diff --git a/ring_buffer_test.go b/ring_buffer_test.go index e5de6f5..1a2a94a 100644 --- a/ring_buffer_test.go +++ b/ring_buffer_test.go @@ -2,6 +2,7 @@ package ringbuffer import ( "bytes" + "encoding/binary" "io" "strings" "testing" @@ -582,3 +583,48 @@ func TestRingBuffer_VirtualXXX(t *testing.T) { } } + +func TestRingBuffer_PeekUintXX(t *testing.T) { + rb := New(1024) + _ = rb.WriteByte(0x01) + + toWrite := make([]byte, 2) + binary.BigEndian.PutUint16(toWrite, 100) + _, _ = rb.Write(toWrite) + + toWrite = make([]byte, 4) + binary.BigEndian.PutUint32(toWrite, 200) + _, _ = rb.Write(toWrite) + + toWrite = make([]byte, 8) + binary.BigEndian.PutUint64(toWrite, 300) + _, _ = rb.Write(toWrite) + + if rb.Length() != 15 { + t.Fatal() + } + + v := rb.PeekUint8() + if v != 0x01 { + t.Fatal() + } + rb.Retrieve(1) + + v1 := rb.PeekUint16() + if v1 != 100 { + t.Fatal() + } + rb.Retrieve(2) + + v2 := rb.PeekUint32() + if v2 != 200 { + t.Fatal() + } + rb.Retrieve(4) + + v3 := rb.PeekUint64() + if v3 != 300 { + t.Fatal(v3) + } + rb.Retrieve(8) +}