1
0
mirror of https://github.com/golang/go synced 2024-11-19 03:34:41 -07:00

tabwriter: use append

R=rsc
CC=golang-dev
https://golang.org/cl/2798041
This commit is contained in:
Robert Griesemer 2010-10-28 21:23:04 -07:00
parent 5762cd3755
commit 75855a8f5e

View File

@ -12,7 +12,6 @@ package tabwriter
import ( import (
"bytes" "bytes"
"container/vector"
"io" "io"
"os" "os"
"utf8" "utf8"
@ -88,19 +87,16 @@ type Writer struct {
flags uint flags uint
// current state // current state
buf bytes.Buffer // collected text excluding tabs or line breaks buf bytes.Buffer // collected text excluding tabs or line breaks
pos int // buffer position up to which cell.width of incomplete cell has been computed pos int // buffer position up to which cell.width of incomplete cell has been computed
cell cell // current incomplete cell; cell.width is up to buf[pos] excluding ignored sections cell cell // current incomplete cell; cell.width is up to buf[pos] excluding ignored sections
endChar byte // terminating char of escaped sequence (Escape for escapes, '>', ';' for HTML tags/entities, or 0) endChar byte // terminating char of escaped sequence (Escape for escapes, '>', ';' for HTML tags/entities, or 0)
lines vector.Vector // list of lines; each line is a list of cells lines [][]cell // list of lines; each line is a list of cells
widths vector.IntVector // list of column widths in runes - re-used during formatting widths []int // list of column widths in runes - re-used during formatting
} }
func (b *Writer) addLine() { b.lines.Push(new(vector.Vector)) } func (b *Writer) addLine() { b.lines = append(b.lines, []cell{}) }
func (b *Writer) line(i int) *vector.Vector { return b.lines.At(i).(*vector.Vector) }
// Reset the current state. // Reset the current state.
@ -109,8 +105,8 @@ func (b *Writer) reset() {
b.pos = 0 b.pos = 0
b.cell = cell{} b.cell = cell{}
b.endChar = 0 b.endChar = 0
b.lines.Resize(0, 0) b.lines = b.lines[0:0]
b.widths.Resize(0, 0) b.widths = b.widths[0:0]
b.addLine() b.addLine()
} }
@ -124,9 +120,9 @@ func (b *Writer) reset() {
// - cell.width is text width in runes of that cell from the start of the cell to // - cell.width is text width in runes of that cell from the start of the cell to
// position pos; html tags and entities are excluded from this width if html // position pos; html tags and entities are excluded from this width if html
// filtering is enabled // filtering is enabled
// - the sizes and widths of processed text are kept in the lines vector // - the sizes and widths of processed text are kept in the lines list
// which contains a vector of cells for each line // which contains a list of cells for each line
// - the widths vector is a temporary vector with current widths used during // - the widths list is a temporary list with current widths used during
// formatting; it is kept in Writer because it's re-used // formatting; it is kept in Writer because it's re-used
// //
// |<---------- size ---------->| // |<---------- size ---------->|
@ -213,11 +209,9 @@ func (b *Writer) Init(output io.Writer, minwidth, tabwidth, padding int, padchar
// debugging support (keep code around) // debugging support (keep code around)
func (b *Writer) dump() { func (b *Writer) dump() {
pos := 0 pos := 0
for i := 0; i < b.lines.Len(); i++ { for i, line := range b.lines {
line := b.line(i)
print("(", i, ") ") print("(", i, ") ")
for j := 0; j < line.Len(); j++ { for _, c := range line {
c := line.At(j).(cell)
print("[", string(b.buf.Bytes()[pos:pos+c.size]), "]") print("[", string(b.buf.Bytes()[pos:pos+c.size]), "]")
pos += c.size pos += c.size
} }
@ -286,14 +280,12 @@ var vbar = []byte{'|'}
func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int) { func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int) {
pos = pos0 pos = pos0
for i := line0; i < line1; i++ { for i := line0; i < line1; i++ {
line := b.line(i) line := b.lines[i]
// if TabIndent is set, use tabs to pad leading empty cells // if TabIndent is set, use tabs to pad leading empty cells
useTabs := b.flags&TabIndent != 0 useTabs := b.flags&TabIndent != 0
for j := 0; j < line.Len(); j++ { for j, c := range line {
c := line.At(j).(cell)
if j > 0 && b.flags&Debug != 0 { if j > 0 && b.flags&Debug != 0 {
// indicate column break // indicate column break
b.write0(vbar) b.write0(vbar)
@ -301,8 +293,8 @@ func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int) {
if c.size == 0 { if c.size == 0 {
// empty cell // empty cell
if j < b.widths.Len() { if j < len(b.widths) {
b.writePadding(c.width, b.widths.At(j), useTabs) b.writePadding(c.width, b.widths[j], useTabs)
} }
} else { } else {
// non-empty cell // non-empty cell
@ -310,12 +302,12 @@ func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int) {
if b.flags&AlignRight == 0 { // align left if b.flags&AlignRight == 0 { // align left
b.write0(b.buf.Bytes()[pos : pos+c.size]) b.write0(b.buf.Bytes()[pos : pos+c.size])
pos += c.size pos += c.size
if j < b.widths.Len() { if j < len(b.widths) {
b.writePadding(c.width, b.widths.At(j), false) b.writePadding(c.width, b.widths[j], false)
} }
} else { // align right } else { // align right
if j < b.widths.Len() { if j < len(b.widths) {
b.writePadding(c.width, b.widths.At(j), false) b.writePadding(c.width, b.widths[j], false)
} }
b.write0(b.buf.Bytes()[pos : pos+c.size]) b.write0(b.buf.Bytes()[pos : pos+c.size])
pos += c.size pos += c.size
@ -323,7 +315,7 @@ func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int) {
} }
} }
if i+1 == b.lines.Len() { if i+1 == len(b.lines) {
// last buffered line - we don't have a newline, so just write // last buffered line - we don't have a newline, so just write
// any outstanding buffered data // any outstanding buffered data
b.write0(b.buf.Bytes()[pos : pos+b.cell.size]) b.write0(b.buf.Bytes()[pos : pos+b.cell.size])
@ -344,11 +336,11 @@ func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int) {
// //
func (b *Writer) format(pos0 int, line0, line1 int) (pos int) { func (b *Writer) format(pos0 int, line0, line1 int) (pos int) {
pos = pos0 pos = pos0
column := b.widths.Len() column := len(b.widths)
for this := line0; this < line1; this++ { for this := line0; this < line1; this++ {
line := b.line(this) line := b.lines[this]
if column < line.Len()-1 { if column < len(line)-1 {
// cell exists in this column => this line // cell exists in this column => this line
// has more cells than the previous line // has more cells than the previous line
// (the last cell per line is ignored because cells are // (the last cell per line is ignored because cells are
@ -364,10 +356,10 @@ func (b *Writer) format(pos0 int, line0, line1 int) (pos int) {
width := b.minwidth // minimal column width width := b.minwidth // minimal column width
discardable := true // true if all cells in this column are empty and "soft" discardable := true // true if all cells in this column are empty and "soft"
for ; this < line1; this++ { for ; this < line1; this++ {
line = b.line(this) line = b.lines[this]
if column < line.Len()-1 { if column < len(line)-1 {
// cell exists in this column // cell exists in this column
c := line.At(column).(cell) c := line[column]
// update width // update width
if w := c.width + b.padding; w > width { if w := c.width + b.padding; w > width {
width = w width = w
@ -389,9 +381,9 @@ func (b *Writer) format(pos0 int, line0, line1 int) (pos int) {
// format and print all columns to the right of this column // format and print all columns to the right of this column
// (we know the widths of this column and all columns to the left) // (we know the widths of this column and all columns to the left)
b.widths.Push(width) b.widths = append(b.widths, width) // push width
pos = b.format(pos, line0, this) pos = b.format(pos, line0, this)
b.widths.Pop() b.widths = b.widths[0 : len(b.widths)-1] // pop width
line0 = this line0 = this
} }
} }
@ -464,10 +456,10 @@ func (b *Writer) endEscape() {
// //
func (b *Writer) terminateCell(htab bool) int { func (b *Writer) terminateCell(htab bool) int {
b.cell.htab = htab b.cell.htab = htab
line := b.line(b.lines.Len() - 1) line := &b.lines[len(b.lines)-1]
line.Push(b.cell) *line = append(*line, b.cell)
b.cell = cell{} b.cell = cell{}
return line.Len() return len(*line)
} }
@ -497,7 +489,7 @@ func (b *Writer) Flush() (err os.Error) {
} }
// format contents of buffer // format contents of buffer
b.format(0, 0, b.lines.Len()) b.format(0, 0, len(b.lines))
return return
} }