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:
parent
5762cd3755
commit
75855a8f5e
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user