diff --git a/api/next/45628.txt b/api/next/45628.txt new file mode 100644 index 0000000000..5065ae4a60 --- /dev/null +++ b/api/next/45628.txt @@ -0,0 +1 @@ +pkg encoding/xml, method (*Decoder) InputPos() (int, int) #45628 diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go index ef51252dcb..a7a02f5b57 100644 --- a/src/encoding/xml/xml.go +++ b/src/encoding/xml/xml.go @@ -216,6 +216,7 @@ type Decoder struct { ns map[string]string err error line int + linestart int64 offset int64 unmarshalDepth int } @@ -919,6 +920,7 @@ func (d *Decoder) getc() (b byte, ok bool) { } if b == '\n' { d.line++ + d.linestart = d.offset + 1 } d.offset++ return b, true @@ -931,6 +933,13 @@ func (d *Decoder) InputOffset() int64 { return d.offset } +// InputPos retuns the line of the current decoder position and the 1 based +// input position of the line. The position gives the location of the end of the +// most recently returned token. +func (d *Decoder) InputPos() (line, column int) { + return d.line, int(d.offset-d.linestart) + 1 +} + // Return saved offset. // If we did ungetc (nextByte >= 0), have to back up one. func (d *Decoder) savedOffset() int { diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go index ab1dbf849b..8f0d97b6a6 100644 --- a/src/encoding/xml/xml_test.go +++ b/src/encoding/xml/xml_test.go @@ -502,6 +502,45 @@ func TestSyntax(t *testing.T) { } } +func TestInputLinePos(t *testing.T) { + testInput := ` + + +` + linePos := [][]int{ + {1, 7}, + {2, 1}, + {3, 4}, + {3, 6}, + {6, 7}, + {7, 1}, + {8, 4}, + {10, 4}, + {10, 10}, + {11, 1}, + {11, 8}, + } + dec := NewDecoder(strings.NewReader(testInput)) + for _, want := range linePos { + if _, err := dec.Token(); err != nil { + t.Errorf("Unexpected error: %v", err) + continue + } + + gotLine, gotCol := dec.InputPos() + if gotLine != want[0] || gotCol != want[1] { + t.Errorf("dec.InputPos() = %d,%d, want %d,%d", gotLine, gotCol, want[0], want[1]) + } + } +} + type allScalars struct { True1 bool True2 bool