Skip to content

Instantly share code, notes, and snippets.

@border
Created April 1, 2011 02:45
Show Gist options
  • Save border/897651 to your computer and use it in GitHub Desktop.
Save border/897651 to your computer and use it in GitHub Desktop.
Logging in Reverse, Nice use of the reader interface in logging From: https://rogpeppe.wordpress.com/2011/03/31/logging-in-reverse/
package main
import (
"io"
"os"
"log"
)
type msg struct {
data []byte
next *msg
}
// ReverseBuffer is an implementation of io.Writer that stores data such
// that it can later be read with the data from all writes reversed.
type ReverseBuffer struct {
msgs *msg
}
type reverseReader struct {
data []byte
msgs *msg
}
func (w *ReverseBuffer) Write(data []byte) (int, os.Error) {
if len(data) == 0 {
return 0, nil
}
w.msgs = &msg{append([]byte(nil), data...), w.msgs}
return len(data), nil
}
// Reader returns a new io.Reader that can be used to read all the data
// written to w. The data from more recent writes is returned first.
func (w *ReverseBuffer) Reader() io.Reader {
return &reverseReader{nil, w.msgs}
}
func (r *reverseReader) Read(data []byte) (int, os.Error) {
if len(r.data) == 0 {
if r.msgs == nil {
return 0, os.EOF
}
r.data = r.msgs.data
r.msgs = r.msgs.next
}
n := copy(data, r.data)
r.data = r.data[n:]
return n, nil
}
func main() {
w := new(ReverseBuffer)
out := log.New(w, "", log.Ldate|log.Ltime)
out.Printf("one")
out.Printf("two")
out.Printf("three")
io.Copy(os.Stdout, w.Reader())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment