github.com/bluenviron/mediacommon@v1.9.3/pkg/formats/fmp4/seekablebuffer/seekablebuffer.go (about)

     1  // Package seekablebuffer contains a bytes.Buffer with an additional Seek() method.
     2  package seekablebuffer
     3  
     4  import (
     5  	"bytes"
     6  	"fmt"
     7  	"io"
     8  )
     9  
    10  // Buffer is a bytes.Buffer with an additional Seek() method.
    11  type Buffer struct {
    12  	bytes.Buffer
    13  	pos int64
    14  }
    15  
    16  // Write implements io.Writer.
    17  func (b *Buffer) Write(p []byte) (int, error) {
    18  	n := 0
    19  
    20  	if b.pos < int64(b.Len()) {
    21  		n = copy(b.Bytes()[b.pos:], p)
    22  		p = p[n:]
    23  	}
    24  
    25  	if len(p) > 0 {
    26  		// Buffer.Write can't return an error.
    27  		nn, _ := b.Buffer.Write(p) //nolint:errcheck
    28  		n += nn
    29  	}
    30  
    31  	b.pos += int64(n)
    32  	return n, nil
    33  }
    34  
    35  // Read implements io.Reader.
    36  func (b *Buffer) Read(_ []byte) (int, error) {
    37  	return 0, fmt.Errorf("unimplemented")
    38  }
    39  
    40  // Seek implements io.Seeker.
    41  func (b *Buffer) Seek(offset int64, whence int) (int64, error) {
    42  	pos2 := int64(0)
    43  
    44  	switch whence {
    45  	case io.SeekStart:
    46  		pos2 = offset
    47  
    48  	case io.SeekCurrent:
    49  		pos2 = b.pos + offset
    50  
    51  	case io.SeekEnd:
    52  		pos2 = int64(b.Len()) + offset
    53  	}
    54  
    55  	if pos2 < 0 {
    56  		return 0, fmt.Errorf("negative position")
    57  	}
    58  
    59  	b.pos = pos2
    60  
    61  	diff := b.pos - int64(b.Len())
    62  	if diff > 0 {
    63  		// Buffer.Write can't return an error.
    64  		b.Buffer.Write(make([]byte, diff)) //nolint:errcheck
    65  	}
    66  
    67  	return pos2, nil
    68  }
    69  
    70  // Reset resets the buffer state.
    71  func (b *Buffer) Reset() {
    72  	b.Buffer.Reset()
    73  	b.pos = 0
    74  }