Skip to content

Latest commit

 

History

History
69 lines (48 loc) · 1.98 KB

README.md

File metadata and controls

69 lines (48 loc) · 1.98 KB

writerat-pipe

Implementation of Go's io.Pipe whose writer implements io.WriterAt, with some caveats.

It can be thought of as a normal pipe, except with a buffered writer that implements io.WriterAt.

Read the documentation for more information.

Installation

go get github.com/termermc/writerat-pipe

Usage

package main

import "github.com/termermc/writerat-pipe"

func main() {
	reader, writer := writerat_pipe.WriterAtPipe()
	
	go func() {
		// Write at an offset so that the reader cannot read anything yet.
		// Currently, bytes 1-13 have been written, but since 0 bytes have been consumed, the reader cannot read anything.
		_, err := writer.WriteAt([]byte("Hello, world!"), 1)
		if err != nil {
			panic(err)
		}
		
		// Write at offset 0, which will make a line of contiguous bytes from 0-13 readable.
		// The reader will now be able to read everything.
		_, err = writer.WriteAt([]byte("!"), 0)
		if err != nil {
			panic(err)
		}
	}()
	
	readBuf := make([]byte, 1024)
	n, err := reader.Read(readBuf)
	if err != nil {
		panic(err)
	}
	
	println(string(readBuf[:n])) // "!Hello, world!"
	
	_ = writer.Close()
}

For more examples, see the writerat-pipe_test.go file.

Caveats

The following caveats apply to this implementation:

  1. Writes cannot be at offsets less than the number of bytes that have already been consumed by the reader.
  2. There is no limit on the buffer size.

Caveat #1

The reader only implements io.Reader, not io.ReaderAt, so bytes are read sequentially once, not randomly at any time. This means that any bytes that are written at an offset less than the number of consumed bytes will be unreadable; effectively a memory leak. To prevent this, io.ErrOffsetLessThanConsumed will be returned when a write at such an offset is attempted.

Caveat #2

I just did not implement a buffer limit. Feel free to send in a PR with appropriate tests if you need this feature.