@@ -135,6 +135,23 @@ func CopyToken(t Token) Token {
135
135
return t
136
136
}
137
137
138
+ // A TokenReader is anything that can decode a stream of XML tokens, including a
139
+ // Decoder.
140
+ //
141
+ // When Token encounters an error or end-of-file condition after successfully
142
+ // reading a token, it returns the token. It may return the (non-nil) error from
143
+ // the same call or return the error (and a nil token) from a subsequent call.
144
+ // An instance of this general case is that a TokenReader returning a non-nil
145
+ // token at the end of the token stream may return either io.EOF or a nil error.
146
+ // The next Read should return nil, io.EOF.
147
+ //
148
+ // Implementations of Token are discouraged from returning a nil token with a
149
+ // nil error. Callers should treat a return of nil, nil as indicating that
150
+ // nothing happened; in particular it does not indicate EOF.
151
+ type TokenReader interface {
152
+ Token () (Token , error )
153
+ }
154
+
138
155
// A Decoder represents an XML parser reading a particular input stream.
139
156
// The parser assumes that its input is encoded in UTF-8.
140
157
type Decoder struct {
@@ -190,6 +207,7 @@ type Decoder struct {
190
207
DefaultSpace string
191
208
192
209
r io.ByteReader
210
+ t TokenReader
193
211
buf bytes.Buffer
194
212
saved * bytes.Buffer
195
213
stk * stack
@@ -219,6 +237,22 @@ func NewDecoder(r io.Reader) *Decoder {
219
237
return d
220
238
}
221
239
240
+ // NewTokenDecoder creates a new XML parser using an underlying token stream.
241
+ func NewTokenDecoder (t TokenReader ) * Decoder {
242
+ // Is it already a Decoder?
243
+ if d , ok := t .(* Decoder ); ok {
244
+ return d
245
+ }
246
+ d := & Decoder {
247
+ ns : make (map [string ]string ),
248
+ t : t ,
249
+ nextByte : - 1 ,
250
+ line : 1 ,
251
+ Strict : true ,
252
+ }
253
+ return d
254
+ }
255
+
222
256
// Token returns the next XML token in the input stream.
223
257
// At the end of the input stream, Token returns nil, io.EOF.
224
258
//
@@ -243,6 +277,9 @@ func NewDecoder(r io.Reader) *Decoder {
243
277
// If Token encounters an unrecognized name space prefix,
244
278
// it uses the prefix as the Space rather than report an error.
245
279
func (d * Decoder ) Token () (Token , error ) {
280
+ if d .t != nil {
281
+ return d .t .Token ()
282
+ }
246
283
var t Token
247
284
var err error
248
285
if d .stk != nil && d .stk .kind == stkEOF {
0 commit comments