diff options
Diffstat (limited to 'src/encoding/xml/xml.go')
| -rw-r--r-- | src/encoding/xml/xml.go | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go index 1aba31ce60..be90b62c9a 100644 --- a/src/encoding/xml/xml.go +++ b/src/encoding/xml/xml.go @@ -135,6 +135,23 @@ func CopyToken(t Token) Token { return t } +// A TokenReader is anything that can decode a stream of XML tokens, including a +// Decoder. +// +// When Token encounters an error or end-of-file condition after successfully +// reading a token, it returns the token. It may return the (non-nil) error from +// the same call or return the error (and a nil token) from a subsequent call. +// An instance of this general case is that a TokenReader returning a non-nil +// token at the end of the token stream may return either io.EOF or a nil error. +// The next Read should return nil, io.EOF. +// +// Implementations of Token are discouraged from returning a nil token with a +// nil error. Callers should treat a return of nil, nil as indicating that +// nothing happened; in particular it does not indicate EOF. +type TokenReader interface { + Token() (Token, error) +} + // A Decoder represents an XML parser reading a particular input stream. // The parser assumes that its input is encoded in UTF-8. type Decoder struct { @@ -190,6 +207,7 @@ type Decoder struct { DefaultSpace string r io.ByteReader + t TokenReader buf bytes.Buffer saved *bytes.Buffer stk *stack @@ -219,6 +237,22 @@ func NewDecoder(r io.Reader) *Decoder { return d } +// NewTokenDecoder creates a new XML parser using an underlying token stream. +func NewTokenDecoder(t TokenReader) *Decoder { + // Is it already a Decoder? + if d, ok := t.(*Decoder); ok { + return d + } + d := &Decoder{ + ns: make(map[string]string), + t: t, + nextByte: -1, + line: 1, + Strict: true, + } + return d +} + // Token returns the next XML token in the input stream. // At the end of the input stream, Token returns nil, io.EOF. // @@ -243,6 +277,9 @@ func NewDecoder(r io.Reader) *Decoder { // If Token encounters an unrecognized name space prefix, // it uses the prefix as the Space rather than report an error. func (d *Decoder) Token() (Token, error) { + if d.t != nil { + return d.t.Token() + } var t Token var err error if d.stk != nil && d.stk.kind == stkEOF { |
