interfaces make it easy to get what you want,
as is often the case with Go...
note that the logging package uses an arbitrary
io.Writer to write the logged data. you can create
an io.Writer that stores its data in reverse order.
here's an example:
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())
}
It's a copy of data.
Instead of using data directly and having the same underlying array.
This appends the items in data to an empty slice with a different
underlying array.
copy() would also work, but would require more lines.
eg.
a := []byte(nil)
copy(a,data);
w.msgs = &msg{a, w.msgs}
- jessta
- jessta
--
=====================
http://jessta.id.au