Created
April 1, 2011 02:45
-
-
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/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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