// ----------------------------------------------------------------------------
-// Tabwriter is a filter implementing the IO.Write interface. It assumes
+// Writer is a filter implementing the io.Write interface. It assumes
// that the incoming bytes represent ASCII encoded text consisting of
// lines of tab-separated "cells". Cells in adjacent lines constitute
-// a column. Tabwriter rewrites the incoming text such that all cells
-// in a column have the same width; thus it effectively aligns cells.
-// It does this by adding padding where necessary.
+// a column. Writer rewrites the incoming text such that all cells in
+// a column have the same width; thus it effectively aligns cells. It
+// does this by adding padding where necessary.
//
// Formatting can be controlled via parameters:
//
// pendant cell and tab width.
-export type TabWriter struct {
+export type Writer struct {
// TODO should not export any of the fields
// configuration
writer io.Write;
}
-func (b *TabWriter) AddLine() {
+func (b *Writer) AddLine() {
b.lines.Push(array.NewIntArray(0));
}
-func (b *TabWriter) Init(writer io.Write, tabwidth, padding int, usetabs bool) *TabWriter {
+func (b *Writer) Init(writer io.Write, tabwidth, padding int, usetabs bool) *Writer {
b.writer = writer;
b.tabwidth = tabwidth;
b.padding = padding;
}
-func (b *TabWriter) Line(i int) *array.IntArray {
+func (b *Writer) Line(i int) *array.IntArray {
return b.lines.At(i).(*array.IntArray);
}
-func (b *TabWriter) LastLine() *array.IntArray {
+func (b *Writer) LastLine() *array.IntArray {
return b.lines.At(b.lines.Len() - 1).(*array.IntArray);
}
// debugging support
-func (b *TabWriter) Dump() {
+func (b *Writer) Dump() {
pos := 0;
for i := 0; i < b.lines.Len(); i++ {
line := b.Line(i);
}
-func (b *TabWriter) Write0(buf *[]byte) *os.Error {
+func (b *Writer) Write0(buf *[]byte) *os.Error {
n, err := b.writer.Write(buf);
if n != len(buf) && err == nil {
err = os.EIO;
var Newline = &[]byte{'\n'}
-func (b *TabWriter) WritePadding(textw, cellw int) (err *os.Error) {
+func (b *Writer) WritePadding(textw, cellw int) (err *os.Error) {
if b.usetabs {
// make cell width a multiple of tabwidth
cellw = ((cellw + b.tabwidth - 1) / b.tabwidth) * b.tabwidth;
}
-func (b *TabWriter) WriteLines(pos0 int, line0, line1 int) (pos int, err *os.Error) {
+func (b *Writer) WriteLines(pos0 int, line0, line1 int) (pos int, err *os.Error) {
pos = pos0;
for i := line0; i < line1; i++ {
line := b.Line(i);
}
-func (b *TabWriter) Format(pos0 int, line0, line1 int) (pos int, err *os.Error) {
+func (b *Writer) Format(pos0 int, line0, line1 int) (pos int, err *os.Error) {
pos = pos0;
column := b.widths.Len();
last := line0;
}
-func (b *TabWriter) Append(buf *[]byte) {
+func (b *Writer) Append(buf *[]byte) {
b.buf.Append(buf);
b.width += len(buf);
}
-/* export */ func (b *TabWriter) Flush() *os.Error {
+/* export */ func (b *Writer) Flush() *os.Error {
dummy, err := b.Format(0, 0, b.lines.Len());
// reset (even in the presence of errors)
b.buf.Clear();
}
-/* export */ func (b *TabWriter) Write(buf *[]byte) (written int, err *os.Error) {
+/* export */ func (b *Writer) Write(buf *[]byte) (written int, err *os.Error) {
i0, n := 0, len(buf);
// split text into cells
// The last line has only one cell which does not have an
// impact on the formatting of the following lines (the
// last cell per line is ignored by Format), thus we can
- // flush the TabWriter contents.
+ // flush the Writer contents.
err = b.Flush();
if err != nil {
return i0, err;
}
-export func New(writer io.Write, tabwidth, padding int, usetabs bool) *TabWriter {
- return new(TabWriter).Init(writer, tabwidth, padding, usetabs)
+export func New(writer io.Write, tabwidth, padding int, usetabs bool) *Writer {
+ return new(Writer).Init(writer, tabwidth, padding, usetabs)
}
--- /dev/null
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tabwriter
+
+import (
+ "os";
+ "io";
+ "tabwriter";
+ "testing";
+)
+
+
+type Buffer struct {
+ a *[]byte;
+}
+
+
+func (b *Buffer) Init(n int) {
+ b.a = new([]byte, n)[0 : 0];
+}
+
+
+func (b *Buffer) Write(buf *[]byte) (written int, err *os.Error) {
+ n := len(b.a);
+ m := len(buf);
+ if n + m <= cap(b.a) {
+ b.a = b.a[0 : n + m];
+ for i := 0; i < m; i++ {
+ b.a[n+i] = buf[i];
+ }
+ } else {
+ panicln("buffer too small", n, m, cap(b.a));
+ }
+ return len(buf), nil;
+}
+
+
+func (b *Buffer) String() string {
+ return string(b.a);
+}
+
+
+func Check(t *testing.T, tabwidth, padding int, usetabs bool, src, expected string) {
+ var b Buffer;
+ b.Init(1000);
+
+ var w tabwriter.Writer;
+ w.Init(&b, tabwidth, padding, usetabs);
+
+ io.WriteString(&w, src);
+
+ res := b.String();
+ if res != expected {
+ t.Errorf("src:\n%s\nfound:\n%s\nexpected:\n%s\n", src, res, expected)
+ }
+}
+
+
+export func Test1(t *testing.T) {
+ Check(
+ t, 8, 1, false,
+ "\n",
+ "\n"
+ );
+
+ Check(
+ t, 8, 1, false,
+ "Hello, world!\n",
+ "Hello, world!\n"
+ );
+
+ Check(
+ t, 8, 1, false,
+ "a\tb\tc\naa\tbbb\tcccc\naaa\tbbbb\n\n",
+ "a b c\n"
+ "aa bbb cccc\n"
+ "aaa bbbb\n\n"
+ );
+}