Blame vendor/github.com/vmware/govmomi/vim25/xml/xml.go

Packit 63bb0d
// Copyright 2009 The Go Authors. All rights reserved.
Packit 63bb0d
// Use of this source code is governed by a BSD-style
Packit 63bb0d
// license that can be found in the LICENSE file.
Packit 63bb0d
Packit 63bb0d
// Package xml implements a simple XML 1.0 parser that
Packit 63bb0d
// understands XML name spaces.
Packit 63bb0d
package xml
Packit 63bb0d
Packit 63bb0d
// References:
Packit 63bb0d
//    Annotated XML spec: https://www.xml.com/axml/testaxml.htm
Packit 63bb0d
//    XML name spaces: https://www.w3.org/TR/REC-xml-names/
Packit 63bb0d
Packit 63bb0d
// TODO(rsc):
Packit 63bb0d
//	Test error handling.
Packit 63bb0d
Packit 63bb0d
import (
Packit 63bb0d
	"bufio"
Packit 63bb0d
	"bytes"
Packit 63bb0d
	"errors"
Packit 63bb0d
	"fmt"
Packit 63bb0d
	"io"
Packit 63bb0d
	"reflect"
Packit 63bb0d
	"strconv"
Packit 63bb0d
	"strings"
Packit 63bb0d
	"unicode"
Packit 63bb0d
	"unicode/utf8"
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
// A SyntaxError represents a syntax error in the XML input stream.
Packit 63bb0d
type SyntaxError struct {
Packit 63bb0d
	Msg  string
Packit 63bb0d
	Line int
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (e *SyntaxError) Error() string {
Packit 63bb0d
	return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// A Name represents an XML name (Local) annotated
Packit 63bb0d
// with a name space identifier (Space).
Packit 63bb0d
// In tokens returned by Decoder.Token, the Space identifier
Packit 63bb0d
// is given as a canonical URL, not the short prefix used
Packit 63bb0d
// in the document being parsed.
Packit 63bb0d
type Name struct {
Packit 63bb0d
	Space, Local string
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// An Attr represents an attribute in an XML element (Name=Value).
Packit 63bb0d
type Attr struct {
Packit 63bb0d
	Name  Name
Packit 63bb0d
	Value string
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// A Token is an interface holding one of the token types:
Packit 63bb0d
// StartElement, EndElement, CharData, Comment, ProcInst, or Directive.
Packit 63bb0d
type Token interface{}
Packit 63bb0d
Packit 63bb0d
// A StartElement represents an XML start element.
Packit 63bb0d
type StartElement struct {
Packit 63bb0d
	Name Name
Packit 63bb0d
	Attr []Attr
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Copy creates a new copy of StartElement.
Packit 63bb0d
func (e StartElement) Copy() StartElement {
Packit 63bb0d
	attrs := make([]Attr, len(e.Attr))
Packit 63bb0d
	copy(attrs, e.Attr)
Packit 63bb0d
	e.Attr = attrs
Packit 63bb0d
	return e
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// End returns the corresponding XML end element.
Packit 63bb0d
func (e StartElement) End() EndElement {
Packit 63bb0d
	return EndElement{e.Name}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// An EndElement represents an XML end element.
Packit 63bb0d
type EndElement struct {
Packit 63bb0d
	Name Name
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// A CharData represents XML character data (raw text),
Packit 63bb0d
// in which XML escape sequences have been replaced by
Packit 63bb0d
// the characters they represent.
Packit 63bb0d
type CharData []byte
Packit 63bb0d
Packit 63bb0d
func makeCopy(b []byte) []byte {
Packit 63bb0d
	b1 := make([]byte, len(b))
Packit 63bb0d
	copy(b1, b)
Packit 63bb0d
	return b1
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Copy creates a new copy of CharData.
Packit 63bb0d
func (c CharData) Copy() CharData { return CharData(makeCopy(c)) }
Packit 63bb0d
Packit 63bb0d
// A Comment represents an XML comment of the form .
Packit 63bb0d
// The bytes do not include the  comment markers.
Packit 63bb0d
type Comment []byte
Packit 63bb0d
Packit 63bb0d
// Copy creates a new copy of Comment.
Packit 63bb0d
func (c Comment) Copy() Comment { return Comment(makeCopy(c)) }
Packit 63bb0d
Packit 63bb0d
// A ProcInst represents an XML processing instruction of the form 
Packit 63bb0d
type ProcInst struct {
Packit 63bb0d
	Target string
Packit 63bb0d
	Inst   []byte
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Copy creates a new copy of ProcInst.
Packit 63bb0d
func (p ProcInst) Copy() ProcInst {
Packit 63bb0d
	p.Inst = makeCopy(p.Inst)
Packit 63bb0d
	return p
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// A Directive represents an XML directive of the form .
Packit 63bb0d
// The bytes do not include the  markers.
Packit 63bb0d
type Directive []byte
Packit 63bb0d
Packit 63bb0d
// Copy creates a new copy of Directive.
Packit 63bb0d
func (d Directive) Copy() Directive { return Directive(makeCopy(d)) }
Packit 63bb0d
Packit 63bb0d
// CopyToken returns a copy of a Token.
Packit 63bb0d
func CopyToken(t Token) Token {
Packit 63bb0d
	switch v := t.(type) {
Packit 63bb0d
	case CharData:
Packit 63bb0d
		return v.Copy()
Packit 63bb0d
	case Comment:
Packit 63bb0d
		return v.Copy()
Packit 63bb0d
	case Directive:
Packit 63bb0d
		return v.Copy()
Packit 63bb0d
	case ProcInst:
Packit 63bb0d
		return v.Copy()
Packit 63bb0d
	case StartElement:
Packit 63bb0d
		return v.Copy()
Packit 63bb0d
	}
Packit 63bb0d
	return t
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// A TokenReader is anything that can decode a stream of XML tokens, including a
Packit 63bb0d
// Decoder.
Packit 63bb0d
//
Packit 63bb0d
// When Token encounters an error or end-of-file condition after successfully
Packit 63bb0d
// reading a token, it returns the token. It may return the (non-nil) error from
Packit 63bb0d
// the same call or return the error (and a nil token) from a subsequent call.
Packit 63bb0d
// An instance of this general case is that a TokenReader returning a non-nil
Packit 63bb0d
// token at the end of the token stream may return either io.EOF or a nil error.
Packit 63bb0d
// The next Read should return nil, io.EOF.
Packit 63bb0d
//
Packit 63bb0d
// Implementations of Token are discouraged from returning a nil token with a
Packit 63bb0d
// nil error. Callers should treat a return of nil, nil as indicating that
Packit 63bb0d
// nothing happened; in particular it does not indicate EOF.
Packit 63bb0d
type TokenReader interface {
Packit 63bb0d
	Token() (Token, error)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// A Decoder represents an XML parser reading a particular input stream.
Packit 63bb0d
// The parser assumes that its input is encoded in UTF-8.
Packit 63bb0d
type Decoder struct {
Packit 63bb0d
	// Strict defaults to true, enforcing the requirements
Packit 63bb0d
	// of the XML specification.
Packit 63bb0d
	// If set to false, the parser allows input containing common
Packit 63bb0d
	// mistakes:
Packit 63bb0d
	//	* If an element is missing an end tag, the parser invents
Packit 63bb0d
	//	  end tags as necessary to keep the return values from Token
Packit 63bb0d
	//	  properly balanced.
Packit 63bb0d
	//	* In attribute values and character data, unknown or malformed
Packit 63bb0d
	//	  character entities (sequences beginning with &) are left alone.
Packit 63bb0d
	//
Packit 63bb0d
	// Setting:
Packit 63bb0d
	//
Packit 63bb0d
	//	d.Strict = false
Packit 63bb0d
	//	d.AutoClose = xml.HTMLAutoClose
Packit 63bb0d
	//	d.Entity = xml.HTMLEntity
Packit 63bb0d
	//
Packit 63bb0d
	// creates a parser that can handle typical HTML.
Packit 63bb0d
	//
Packit 63bb0d
	// Strict mode does not enforce the requirements of the XML name spaces TR.
Packit 63bb0d
	// In particular it does not reject name space tags using undefined prefixes.
Packit 63bb0d
	// Such tags are recorded with the unknown prefix as the name space URL.
Packit 63bb0d
	Strict bool
Packit 63bb0d
Packit 63bb0d
	// When Strict == false, AutoClose indicates a set of elements to
Packit 63bb0d
	// consider closed immediately after they are opened, regardless
Packit 63bb0d
	// of whether an end element is present.
Packit 63bb0d
	AutoClose []string
Packit 63bb0d
Packit 63bb0d
	// Entity can be used to map non-standard entity names to string replacements.
Packit 63bb0d
	// The parser behaves as if these standard mappings are present in the map,
Packit 63bb0d
	// regardless of the actual map content:
Packit 63bb0d
	//
Packit 63bb0d
	//	"lt": "<",
Packit 63bb0d
	//	"gt": ">",
Packit 63bb0d
	//	"amp": "&",
Packit 63bb0d
	//	"apos": "'",
Packit 63bb0d
	//	"quot": `"`,
Packit 63bb0d
	Entity map[string]string
Packit 63bb0d
Packit 63bb0d
	// CharsetReader, if non-nil, defines a function to generate
Packit 63bb0d
	// charset-conversion readers, converting from the provided
Packit 63bb0d
	// non-UTF-8 charset into UTF-8. If CharsetReader is nil or
Packit 63bb0d
	// returns an error, parsing stops with an error. One of the
Packit 63bb0d
	// CharsetReader's result values must be non-nil.
Packit 63bb0d
	CharsetReader func(charset string, input io.Reader) (io.Reader, error)
Packit 63bb0d
Packit 63bb0d
	// DefaultSpace sets the default name space used for unadorned tags,
Packit 63bb0d
	// as if the entire XML stream were wrapped in an element containing
Packit 63bb0d
	// the attribute xmlns="DefaultSpace".
Packit 63bb0d
	DefaultSpace string
Packit 63bb0d
Packit 63bb0d
	// TypeFunc is used to map type names to actual types.
Packit 63bb0d
	TypeFunc func(string) (reflect.Type, bool)
Packit 63bb0d
Packit 63bb0d
	r              io.ByteReader
Packit 63bb0d
	t              TokenReader
Packit 63bb0d
	buf            bytes.Buffer
Packit 63bb0d
	saved          *bytes.Buffer
Packit 63bb0d
	stk            *stack
Packit 63bb0d
	free           *stack
Packit 63bb0d
	needClose      bool
Packit 63bb0d
	toClose        Name
Packit 63bb0d
	nextToken      Token
Packit 63bb0d
	nextByte       int
Packit 63bb0d
	ns             map[string]string
Packit 63bb0d
	err            error
Packit 63bb0d
	line           int
Packit 63bb0d
	offset         int64
Packit 63bb0d
	unmarshalDepth int
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// NewDecoder creates a new XML parser reading from r.
Packit 63bb0d
// If r does not implement io.ByteReader, NewDecoder will
Packit 63bb0d
// do its own buffering.
Packit 63bb0d
func NewDecoder(r io.Reader) *Decoder {
Packit 63bb0d
	d := &Decoder{
Packit 63bb0d
		ns:       make(map[string]string),
Packit 63bb0d
		nextByte: -1,
Packit 63bb0d
		line:     1,
Packit 63bb0d
		Strict:   true,
Packit 63bb0d
	}
Packit 63bb0d
	d.switchToReader(r)
Packit 63bb0d
	return d
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// NewTokenDecoder creates a new XML parser using an underlying token stream.
Packit 63bb0d
func NewTokenDecoder(t TokenReader) *Decoder {
Packit 63bb0d
	// Is it already a Decoder?
Packit 63bb0d
	if d, ok := t.(*Decoder); ok {
Packit 63bb0d
		return d
Packit 63bb0d
	}
Packit 63bb0d
	d := &Decoder{
Packit 63bb0d
		ns:       make(map[string]string),
Packit 63bb0d
		t:        t,
Packit 63bb0d
		nextByte: -1,
Packit 63bb0d
		line:     1,
Packit 63bb0d
		Strict:   true,
Packit 63bb0d
	}
Packit 63bb0d
	return d
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Token returns the next XML token in the input stream.
Packit 63bb0d
// At the end of the input stream, Token returns nil, io.EOF.
Packit 63bb0d
//
Packit 63bb0d
// Slices of bytes in the returned token data refer to the
Packit 63bb0d
// parser's internal buffer and remain valid only until the next
Packit 63bb0d
// call to Token. To acquire a copy of the bytes, call CopyToken
Packit 63bb0d
// or the token's Copy method.
Packit 63bb0d
//
Packit 63bb0d
// Token expands self-closing elements such as 
Packit 63bb0d
// into separate start and end elements returned by successive calls.
Packit 63bb0d
//
Packit 63bb0d
// Token guarantees that the StartElement and EndElement
Packit 63bb0d
// tokens it returns are properly nested and matched:
Packit 63bb0d
// if Token encounters an unexpected end element
Packit 63bb0d
// or EOF before all expected end elements,
Packit 63bb0d
// it will return an error.
Packit 63bb0d
//
Packit 63bb0d
// Token implements XML name spaces as described by
Packit 63bb0d
// https://www.w3.org/TR/REC-xml-names/.  Each of the
Packit 63bb0d
// Name structures contained in the Token has the Space
Packit 63bb0d
// set to the URL identifying its name space when known.
Packit 63bb0d
// If Token encounters an unrecognized name space prefix,
Packit 63bb0d
// it uses the prefix as the Space rather than report an error.
Packit 63bb0d
func (d *Decoder) Token() (Token, error) {
Packit 63bb0d
	var t Token
Packit 63bb0d
	var err error
Packit 63bb0d
	if d.stk != nil && d.stk.kind == stkEOF {
Packit 63bb0d
		return nil, io.EOF
Packit 63bb0d
	}
Packit 63bb0d
	if d.nextToken != nil {
Packit 63bb0d
		t = d.nextToken
Packit 63bb0d
		d.nextToken = nil
Packit 63bb0d
	} else if t, err = d.rawToken(); err != nil {
Packit 63bb0d
		if err == io.EOF && d.stk != nil && d.stk.kind != stkEOF {
Packit 63bb0d
			err = d.syntaxError("unexpected EOF")
Packit 63bb0d
		}
Packit 63bb0d
		return t, err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if !d.Strict {
Packit 63bb0d
		if t1, ok := d.autoClose(t); ok {
Packit 63bb0d
			d.nextToken = t
Packit 63bb0d
			t = t1
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	switch t1 := t.(type) {
Packit 63bb0d
	case StartElement:
Packit 63bb0d
		// In XML name spaces, the translations listed in the
Packit 63bb0d
		// attributes apply to the element name and
Packit 63bb0d
		// to the other attribute names, so process
Packit 63bb0d
		// the translations first.
Packit 63bb0d
		for _, a := range t1.Attr {
Packit 63bb0d
			if a.Name.Space == xmlnsPrefix {
Packit 63bb0d
				v, ok := d.ns[a.Name.Local]
Packit 63bb0d
				d.pushNs(a.Name.Local, v, ok)
Packit 63bb0d
				d.ns[a.Name.Local] = a.Value
Packit 63bb0d
			}
Packit 63bb0d
			if a.Name.Space == "" && a.Name.Local == xmlnsPrefix {
Packit 63bb0d
				// Default space for untagged names
Packit 63bb0d
				v, ok := d.ns[""]
Packit 63bb0d
				d.pushNs("", v, ok)
Packit 63bb0d
				d.ns[""] = a.Value
Packit 63bb0d
			}
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		d.translate(&t1.Name, true)
Packit 63bb0d
		for i := range t1.Attr {
Packit 63bb0d
			d.translate(&t1.Attr[i].Name, false)
Packit 63bb0d
		}
Packit 63bb0d
		d.pushElement(t1.Name)
Packit 63bb0d
		t = t1
Packit 63bb0d
Packit 63bb0d
	case EndElement:
Packit 63bb0d
		d.translate(&t1.Name, true)
Packit 63bb0d
		if !d.popElement(&t1) {
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		t = t1
Packit 63bb0d
	}
Packit 63bb0d
	return t, err
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
const (
Packit 63bb0d
	xmlURL      = "http://www.w3.org/XML/1998/namespace"
Packit 63bb0d
	xmlnsPrefix = "xmlns"
Packit 63bb0d
	xmlPrefix   = "xml"
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
// Apply name space translation to name n.
Packit 63bb0d
// The default name space (for Space=="")
Packit 63bb0d
// applies only to element names, not to attribute names.
Packit 63bb0d
func (d *Decoder) translate(n *Name, isElementName bool) {
Packit 63bb0d
	switch {
Packit 63bb0d
	case n.Space == xmlnsPrefix:
Packit 63bb0d
		return
Packit 63bb0d
	case n.Space == "" && !isElementName:
Packit 63bb0d
		return
Packit 63bb0d
	case n.Space == xmlPrefix:
Packit 63bb0d
		n.Space = xmlURL
Packit 63bb0d
	case n.Space == "" && n.Local == xmlnsPrefix:
Packit 63bb0d
		return
Packit 63bb0d
	}
Packit 63bb0d
	if v, ok := d.ns[n.Space]; ok {
Packit 63bb0d
		n.Space = v
Packit 63bb0d
	} else if n.Space == "" {
Packit 63bb0d
		n.Space = d.DefaultSpace
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (d *Decoder) switchToReader(r io.Reader) {
Packit 63bb0d
	// Get efficient byte at a time reader.
Packit 63bb0d
	// Assume that if reader has its own
Packit 63bb0d
	// ReadByte, it's efficient enough.
Packit 63bb0d
	// Otherwise, use bufio.
Packit 63bb0d
	if rb, ok := r.(io.ByteReader); ok {
Packit 63bb0d
		d.r = rb
Packit 63bb0d
	} else {
Packit 63bb0d
		d.r = bufio.NewReader(r)
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Parsing state - stack holds old name space translations
Packit 63bb0d
// and the current set of open elements. The translations to pop when
Packit 63bb0d
// ending a given tag are *below* it on the stack, which is
Packit 63bb0d
// more work but forced on us by XML.
Packit 63bb0d
type stack struct {
Packit 63bb0d
	next *stack
Packit 63bb0d
	kind int
Packit 63bb0d
	name Name
Packit 63bb0d
	ok   bool
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
const (
Packit 63bb0d
	stkStart = iota
Packit 63bb0d
	stkNs
Packit 63bb0d
	stkEOF
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
func (d *Decoder) push(kind int) *stack {
Packit 63bb0d
	s := d.free
Packit 63bb0d
	if s != nil {
Packit 63bb0d
		d.free = s.next
Packit 63bb0d
	} else {
Packit 63bb0d
		s = new(stack)
Packit 63bb0d
	}
Packit 63bb0d
	s.next = d.stk
Packit 63bb0d
	s.kind = kind
Packit 63bb0d
	d.stk = s
Packit 63bb0d
	return s
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (d *Decoder) pop() *stack {
Packit 63bb0d
	s := d.stk
Packit 63bb0d
	if s != nil {
Packit 63bb0d
		d.stk = s.next
Packit 63bb0d
		s.next = d.free
Packit 63bb0d
		d.free = s
Packit 63bb0d
	}
Packit 63bb0d
	return s
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Record that after the current element is finished
Packit 63bb0d
// (that element is already pushed on the stack)
Packit 63bb0d
// Token should return EOF until popEOF is called.
Packit 63bb0d
func (d *Decoder) pushEOF() {
Packit 63bb0d
	// Walk down stack to find Start.
Packit 63bb0d
	// It might not be the top, because there might be stkNs
Packit 63bb0d
	// entries above it.
Packit 63bb0d
	start := d.stk
Packit 63bb0d
	for start.kind != stkStart {
Packit 63bb0d
		start = start.next
Packit 63bb0d
	}
Packit 63bb0d
	// The stkNs entries below a start are associated with that
Packit 63bb0d
	// element too; skip over them.
Packit 63bb0d
	for start.next != nil && start.next.kind == stkNs {
Packit 63bb0d
		start = start.next
Packit 63bb0d
	}
Packit 63bb0d
	s := d.free
Packit 63bb0d
	if s != nil {
Packit 63bb0d
		d.free = s.next
Packit 63bb0d
	} else {
Packit 63bb0d
		s = new(stack)
Packit 63bb0d
	}
Packit 63bb0d
	s.kind = stkEOF
Packit 63bb0d
	s.next = start.next
Packit 63bb0d
	start.next = s
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Undo a pushEOF.
Packit 63bb0d
// The element must have been finished, so the EOF should be at the top of the stack.
Packit 63bb0d
func (d *Decoder) popEOF() bool {
Packit 63bb0d
	if d.stk == nil || d.stk.kind != stkEOF {
Packit 63bb0d
		return false
Packit 63bb0d
	}
Packit 63bb0d
	d.pop()
Packit 63bb0d
	return true
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Record that we are starting an element with the given name.
Packit 63bb0d
func (d *Decoder) pushElement(name Name) {
Packit 63bb0d
	s := d.push(stkStart)
Packit 63bb0d
	s.name = name
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Record that we are changing the value of ns[local].
Packit 63bb0d
// The old value is url, ok.
Packit 63bb0d
func (d *Decoder) pushNs(local string, url string, ok bool) {
Packit 63bb0d
	s := d.push(stkNs)
Packit 63bb0d
	s.name.Local = local
Packit 63bb0d
	s.name.Space = url
Packit 63bb0d
	s.ok = ok
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Creates a SyntaxError with the current line number.
Packit 63bb0d
func (d *Decoder) syntaxError(msg string) error {
Packit 63bb0d
	return &SyntaxError{Msg: msg, Line: d.line}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Record that we are ending an element with the given name.
Packit 63bb0d
// The name must match the record at the top of the stack,
Packit 63bb0d
// which must be a pushElement record.
Packit 63bb0d
// After popping the element, apply any undo records from
Packit 63bb0d
// the stack to restore the name translations that existed
Packit 63bb0d
// before we saw this element.
Packit 63bb0d
func (d *Decoder) popElement(t *EndElement) bool {
Packit 63bb0d
	s := d.pop()
Packit 63bb0d
	name := t.Name
Packit 63bb0d
	switch {
Packit 63bb0d
	case s == nil || s.kind != stkStart:
Packit 63bb0d
		d.err = d.syntaxError("unexpected end element </" + name.Local + ">")
Packit 63bb0d
		return false
Packit 63bb0d
	case s.name.Local != name.Local:
Packit 63bb0d
		if !d.Strict {
Packit 63bb0d
			d.needClose = true
Packit 63bb0d
			d.toClose = t.Name
Packit 63bb0d
			t.Name = s.name
Packit 63bb0d
			return true
Packit 63bb0d
		}
Packit 63bb0d
		d.err = d.syntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">")
Packit 63bb0d
		return false
Packit 63bb0d
	case s.name.Space != name.Space:
Packit 63bb0d
		d.err = d.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space +
Packit 63bb0d
			"closed by </" + name.Local + "> in space " + name.Space)
Packit 63bb0d
		return false
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	// Pop stack until a Start or EOF is on the top, undoing the
Packit 63bb0d
	// translations that were associated with the element we just closed.
Packit 63bb0d
	for d.stk != nil && d.stk.kind != stkStart && d.stk.kind != stkEOF {
Packit 63bb0d
		s := d.pop()
Packit 63bb0d
		if s.ok {
Packit 63bb0d
			d.ns[s.name.Local] = s.name.Space
Packit 63bb0d
		} else {
Packit 63bb0d
			delete(d.ns, s.name.Local)
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return true
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// If the top element on the stack is autoclosing and
Packit 63bb0d
// t is not the end tag, invent the end tag.
Packit 63bb0d
func (d *Decoder) autoClose(t Token) (Token, bool) {
Packit 63bb0d
	if d.stk == nil || d.stk.kind != stkStart {
Packit 63bb0d
		return nil, false
Packit 63bb0d
	}
Packit 63bb0d
	name := strings.ToLower(d.stk.name.Local)
Packit 63bb0d
	for _, s := range d.AutoClose {
Packit 63bb0d
		if strings.ToLower(s) == name {
Packit 63bb0d
			// This one should be auto closed if t doesn't close it.
Packit 63bb0d
			et, ok := t.(EndElement)
Packit 63bb0d
			if !ok || et.Name.Local != name {
Packit 63bb0d
				return EndElement{d.stk.name}, true
Packit 63bb0d
			}
Packit 63bb0d
			break
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	return nil, false
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
var errRawToken = errors.New("xml: cannot use RawToken from UnmarshalXML method")
Packit 63bb0d
Packit 63bb0d
// RawToken is like Token but does not verify that
Packit 63bb0d
// start and end elements match and does not translate
Packit 63bb0d
// name space prefixes to their corresponding URLs.
Packit 63bb0d
func (d *Decoder) RawToken() (Token, error) {
Packit 63bb0d
	if d.unmarshalDepth > 0 {
Packit 63bb0d
		return nil, errRawToken
Packit 63bb0d
	}
Packit 63bb0d
	return d.rawToken()
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (d *Decoder) rawToken() (Token, error) {
Packit 63bb0d
	if d.t != nil {
Packit 63bb0d
		return d.t.Token()
Packit 63bb0d
	}
Packit 63bb0d
	if d.err != nil {
Packit 63bb0d
		return nil, d.err
Packit 63bb0d
	}
Packit 63bb0d
	if d.needClose {
Packit 63bb0d
		// The last element we read was self-closing and
Packit 63bb0d
		// we returned just the StartElement half.
Packit 63bb0d
		// Return the EndElement half now.
Packit 63bb0d
		d.needClose = false
Packit 63bb0d
		return EndElement{d.toClose}, nil
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	b, ok := d.getc()
Packit 63bb0d
	if !ok {
Packit 63bb0d
		return nil, d.err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if b != '<' {
Packit 63bb0d
		// Text section.
Packit 63bb0d
		d.ungetc(b)
Packit 63bb0d
		data := d.text(-1, false)
Packit 63bb0d
		if data == nil {
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		return CharData(data), nil
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
		return nil, d.err
Packit 63bb0d
	}
Packit 63bb0d
	switch b {
Packit 63bb0d
	case '/':
Packit 63bb0d
		// </: End element
Packit 63bb0d
		var name Name
Packit 63bb0d
		if name, ok = d.nsname(); !ok {
Packit 63bb0d
			if d.err == nil {
Packit 63bb0d
				d.err = d.syntaxError("expected element name after </")
Packit 63bb0d
			}
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		d.space()
Packit 63bb0d
		if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		if b != '>' {
Packit 63bb0d
			d.err = d.syntaxError("invalid characters between </" + name.Local + " and >")
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		return EndElement{name}, nil
Packit 63bb0d
Packit 63bb0d
	case '?':
Packit 63bb0d
		// 
Packit 63bb0d
		var target string
Packit 63bb0d
		if target, ok = d.name(); !ok {
Packit 63bb0d
			if d.err == nil {
Packit 63bb0d
				d.err = d.syntaxError("expected target name after 
Packit 63bb0d
			}
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		d.space()
Packit 63bb0d
		d.buf.Reset()
Packit 63bb0d
		var b0 byte
Packit 63bb0d
		for {
Packit 63bb0d
			if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			d.buf.WriteByte(b)
Packit 63bb0d
			if b0 == '?' && b == '>' {
Packit 63bb0d
				break
Packit 63bb0d
			}
Packit 63bb0d
			b0 = b
Packit 63bb0d
		}
Packit 63bb0d
		data := d.buf.Bytes()
Packit 63bb0d
		data = data[0 : len(data)-2] // chop ?>
Packit 63bb0d
Packit 63bb0d
		if target == "xml" {
Packit 63bb0d
			content := string(data)
Packit 63bb0d
			ver := procInst("version", content)
Packit 63bb0d
			if ver != "" && ver != "1.0" {
Packit 63bb0d
				d.err = fmt.Errorf("xml: unsupported version %q; only version 1.0 is supported", ver)
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			enc := procInst("encoding", content)
Packit 63bb0d
			if enc != "" && enc != "utf-8" && enc != "UTF-8" && !strings.EqualFold(enc, "utf-8") {
Packit 63bb0d
				if d.CharsetReader == nil {
Packit 63bb0d
					d.err = fmt.Errorf("xml: encoding %q declared but Decoder.CharsetReader is nil", enc)
Packit 63bb0d
					return nil, d.err
Packit 63bb0d
				}
Packit 63bb0d
				newr, err := d.CharsetReader(enc, d.r.(io.Reader))
Packit 63bb0d
				if err != nil {
Packit 63bb0d
					d.err = fmt.Errorf("xml: opening charset %q: %v", enc, err)
Packit 63bb0d
					return nil, d.err
Packit 63bb0d
				}
Packit 63bb0d
				if newr == nil {
Packit 63bb0d
					panic("CharsetReader returned a nil Reader for charset " + enc)
Packit 63bb0d
				}
Packit 63bb0d
				d.switchToReader(newr)
Packit 63bb0d
			}
Packit 63bb0d
		}
Packit 63bb0d
		return ProcInst{target, data}, nil
Packit 63bb0d
Packit 63bb0d
	case '!':
Packit 63bb0d
		// 
Packit 63bb0d
		if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		switch b {
Packit 63bb0d
		case '-': // 
Packit 63bb0d
			// Probably 
Packit 63bb0d
			if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			if b != '-' {
Packit 63bb0d
				d.err = d.syntaxError("invalid sequence 
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			// Look for terminator.
Packit 63bb0d
			d.buf.Reset()
Packit 63bb0d
			var b0, b1 byte
Packit 63bb0d
			for {
Packit 63bb0d
				if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
					return nil, d.err
Packit 63bb0d
				}
Packit 63bb0d
				d.buf.WriteByte(b)
Packit 63bb0d
				if b0 == '-' && b1 == '-' {
Packit 63bb0d
					if b != '>' {
Packit 63bb0d
						d.err = d.syntaxError(
Packit 63bb0d
							`invalid sequence "--" not allowed in comments`)
Packit 63bb0d
						return nil, d.err
Packit 63bb0d
					}
Packit 63bb0d
					break
Packit 63bb0d
				}
Packit 63bb0d
				b0, b1 = b1, b
Packit 63bb0d
			}
Packit 63bb0d
			data := d.buf.Bytes()
Packit 63bb0d
			data = data[0 : len(data)-3] // chop -->
Packit 63bb0d
			return Comment(data), nil
Packit 63bb0d
Packit 63bb0d
		case '[': // 
Packit 63bb0d
			// Probably 
Packit 63bb0d
			for i := 0; i < 6; i++ {
Packit 63bb0d
				if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
					return nil, d.err
Packit 63bb0d
				}
Packit 63bb0d
				if b != "CDATA["[i] {
Packit 63bb0d
					d.err = d.syntaxError("invalid 
Packit 63bb0d
					return nil, d.err
Packit 63bb0d
				}
Packit 63bb0d
			}
Packit 63bb0d
			// Have .
Packit 63bb0d
			data := d.text(-1, true)
Packit 63bb0d
			if data == nil {
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			return CharData(data), nil
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		// Probably a directive: , , etc.
Packit 63bb0d
		// We don't care, but accumulate for caller. Quoted angle
Packit 63bb0d
		// brackets do not count for nesting.
Packit 63bb0d
		d.buf.Reset()
Packit 63bb0d
		d.buf.WriteByte(b)
Packit 63bb0d
		inquote := uint8(0)
Packit 63bb0d
		depth := 0
Packit 63bb0d
		for {
Packit 63bb0d
			if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			if inquote == 0 && b == '>' && depth == 0 {
Packit 63bb0d
				break
Packit 63bb0d
			}
Packit 63bb0d
		HandleB:
Packit 63bb0d
			d.buf.WriteByte(b)
Packit 63bb0d
			switch {
Packit 63bb0d
			case b == inquote:
Packit 63bb0d
				inquote = 0
Packit 63bb0d
Packit 63bb0d
			case inquote != 0:
Packit 63bb0d
				// in quotes, no special action
Packit 63bb0d
Packit 63bb0d
			case b == '\'' || b == '"':
Packit 63bb0d
				inquote = b
Packit 63bb0d
Packit 63bb0d
			case b == '>' && inquote == 0:
Packit 63bb0d
				depth--
Packit 63bb0d
Packit 63bb0d
			case b == '<' && inquote == 0:
Packit 63bb0d
				// Look for 
Packit 63bb0d
				s := "!--"
Packit 63bb0d
				for i := 0; i < len(s); i++ {
Packit 63bb0d
					if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
						return nil, d.err
Packit 63bb0d
					}
Packit 63bb0d
					if b != s[i] {
Packit 63bb0d
						for j := 0; j < i; j++ {
Packit 63bb0d
							d.buf.WriteByte(s[j])
Packit 63bb0d
						}
Packit 63bb0d
						depth++
Packit 63bb0d
						goto HandleB
Packit 63bb0d
					}
Packit 63bb0d
				}
Packit 63bb0d
Packit 63bb0d
				// Remove < that was written above.
Packit 63bb0d
				d.buf.Truncate(d.buf.Len() - 1)
Packit 63bb0d
Packit 63bb0d
				// Look for terminator.
Packit 63bb0d
				var b0, b1 byte
Packit 63bb0d
				for {
Packit 63bb0d
					if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
						return nil, d.err
Packit 63bb0d
					}
Packit 63bb0d
					if b0 == '-' && b1 == '-' && b == '>' {
Packit 63bb0d
						break
Packit 63bb0d
					}
Packit 63bb0d
					b0, b1 = b1, b
Packit 63bb0d
				}
Packit 63bb0d
			}
Packit 63bb0d
		}
Packit 63bb0d
		return Directive(d.buf.Bytes()), nil
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	// Must be an open element like 
Packit 63bb0d
	d.ungetc(b)
Packit 63bb0d
Packit 63bb0d
	var (
Packit 63bb0d
		name  Name
Packit 63bb0d
		empty bool
Packit 63bb0d
		attr  []Attr
Packit 63bb0d
	)
Packit 63bb0d
	if name, ok = d.nsname(); !ok {
Packit 63bb0d
		if d.err == nil {
Packit 63bb0d
			d.err = d.syntaxError("expected element name after <")
Packit 63bb0d
		}
Packit 63bb0d
		return nil, d.err
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	attr = []Attr{}
Packit 63bb0d
	for {
Packit 63bb0d
		d.space()
Packit 63bb0d
		if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		if b == '/' {
Packit 63bb0d
			empty = true
Packit 63bb0d
			if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			if b != '>' {
Packit 63bb0d
				d.err = d.syntaxError("expected /> in element")
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			break
Packit 63bb0d
		}
Packit 63bb0d
		if b == '>' {
Packit 63bb0d
			break
Packit 63bb0d
		}
Packit 63bb0d
		d.ungetc(b)
Packit 63bb0d
Packit 63bb0d
		a := Attr{}
Packit 63bb0d
		if a.Name, ok = d.nsname(); !ok {
Packit 63bb0d
			if d.err == nil {
Packit 63bb0d
				d.err = d.syntaxError("expected attribute name in element")
Packit 63bb0d
			}
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		d.space()
Packit 63bb0d
		if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
			return nil, d.err
Packit 63bb0d
		}
Packit 63bb0d
		if b != '=' {
Packit 63bb0d
			if d.Strict {
Packit 63bb0d
				d.err = d.syntaxError("attribute name without = in element")
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			d.ungetc(b)
Packit 63bb0d
			a.Value = a.Name.Local
Packit 63bb0d
		} else {
Packit 63bb0d
			d.space()
Packit 63bb0d
			data := d.attrval()
Packit 63bb0d
			if data == nil {
Packit 63bb0d
				return nil, d.err
Packit 63bb0d
			}
Packit 63bb0d
			a.Value = string(data)
Packit 63bb0d
		}
Packit 63bb0d
		attr = append(attr, a)
Packit 63bb0d
	}
Packit 63bb0d
	if empty {
Packit 63bb0d
		d.needClose = true
Packit 63bb0d
		d.toClose = name
Packit 63bb0d
	}
Packit 63bb0d
	return StartElement{name, attr}, nil
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func (d *Decoder) attrval() []byte {
Packit 63bb0d
	b, ok := d.mustgetc()
Packit 63bb0d
	if !ok {
Packit 63bb0d
		return nil
Packit 63bb0d
	}
Packit 63bb0d
	// Handle quoted attribute values
Packit 63bb0d
	if b == '"' || b == '\'' {
Packit 63bb0d
		return d.text(int(b), false)
Packit 63bb0d
	}
Packit 63bb0d
	// Handle unquoted attribute values for strict parsers
Packit 63bb0d
	if d.Strict {
Packit 63bb0d
		d.err = d.syntaxError("unquoted or missing attribute value in element")
Packit 63bb0d
		return nil
Packit 63bb0d
	}
Packit 63bb0d
	// Handle unquoted attribute values for unstrict parsers
Packit 63bb0d
	d.ungetc(b)
Packit 63bb0d
	d.buf.Reset()
Packit 63bb0d
	for {
Packit 63bb0d
		b, ok = d.mustgetc()
Packit 63bb0d
		if !ok {
Packit 63bb0d
			return nil
Packit 63bb0d
		}
Packit 63bb0d
		// https://www.w3.org/TR/REC-html40/intro/sgmltut.html#h-3.2.2
Packit 63bb0d
		if 'a' <= b && b <= 'z' || 'A' <= b && b <= 'Z' ||
Packit 63bb0d
			'0' <= b && b <= '9' || b == '_' || b == ':' || b == '-' {
Packit 63bb0d
			d.buf.WriteByte(b)
Packit 63bb0d
		} else {
Packit 63bb0d
			d.ungetc(b)
Packit 63bb0d
			break
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	return d.buf.Bytes()
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Skip spaces if any
Packit 63bb0d
func (d *Decoder) space() {
Packit 63bb0d
	for {
Packit 63bb0d
		b, ok := d.getc()
Packit 63bb0d
		if !ok {
Packit 63bb0d
			return
Packit 63bb0d
		}
Packit 63bb0d
		switch b {
Packit 63bb0d
		case ' ', '\r', '\n', '\t':
Packit 63bb0d
		default:
Packit 63bb0d
			d.ungetc(b)
Packit 63bb0d
			return
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Read a single byte.
Packit 63bb0d
// If there is no byte to read, return ok==false
Packit 63bb0d
// and leave the error in d.err.
Packit 63bb0d
// Maintain line number.
Packit 63bb0d
func (d *Decoder) getc() (b byte, ok bool) {
Packit 63bb0d
	if d.err != nil {
Packit 63bb0d
		return 0, false
Packit 63bb0d
	}
Packit 63bb0d
	if d.nextByte >= 0 {
Packit 63bb0d
		b = byte(d.nextByte)
Packit 63bb0d
		d.nextByte = -1
Packit 63bb0d
	} else {
Packit 63bb0d
		b, d.err = d.r.ReadByte()
Packit 63bb0d
		if d.err != nil {
Packit 63bb0d
			return 0, false
Packit 63bb0d
		}
Packit 63bb0d
		if d.saved != nil {
Packit 63bb0d
			d.saved.WriteByte(b)
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	if b == '\n' {
Packit 63bb0d
		d.line++
Packit 63bb0d
	}
Packit 63bb0d
	d.offset++
Packit 63bb0d
	return b, true
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// InputOffset returns the input stream byte offset of the current decoder position.
Packit 63bb0d
// The offset gives the location of the end of the most recently returned token
Packit 63bb0d
// and the beginning of the next token.
Packit 63bb0d
func (d *Decoder) InputOffset() int64 {
Packit 63bb0d
	return d.offset
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Return saved offset.
Packit 63bb0d
// If we did ungetc (nextByte >= 0), have to back up one.
Packit 63bb0d
func (d *Decoder) savedOffset() int {
Packit 63bb0d
	n := d.saved.Len()
Packit 63bb0d
	if d.nextByte >= 0 {
Packit 63bb0d
		n--
Packit 63bb0d
	}
Packit 63bb0d
	return n
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Must read a single byte.
Packit 63bb0d
// If there is no byte to read,
Packit 63bb0d
// set d.err to SyntaxError("unexpected EOF")
Packit 63bb0d
// and return ok==false
Packit 63bb0d
func (d *Decoder) mustgetc() (b byte, ok bool) {
Packit 63bb0d
	if b, ok = d.getc(); !ok {
Packit 63bb0d
		if d.err == io.EOF {
Packit 63bb0d
			d.err = d.syntaxError("unexpected EOF")
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	return
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Unread a single byte.
Packit 63bb0d
func (d *Decoder) ungetc(b byte) {
Packit 63bb0d
	if b == '\n' {
Packit 63bb0d
		d.line--
Packit 63bb0d
	}
Packit 63bb0d
	d.nextByte = int(b)
Packit 63bb0d
	d.offset--
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
var entity = map[string]int{
Packit 63bb0d
	"lt":   '<',
Packit 63bb0d
	"gt":   '>',
Packit 63bb0d
	"amp":  '&',
Packit 63bb0d
	"apos": '\'',
Packit 63bb0d
	"quot": '"',
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Read plain text section (XML calls it character data).
Packit 63bb0d
// If quote >= 0, we are in a quoted string and need to find the matching quote.
Packit 63bb0d
// If cdata == true, we are in a .
Packit 63bb0d
// On failure return nil and leave the error in d.err.
Packit 63bb0d
func (d *Decoder) text(quote int, cdata bool) []byte {
Packit 63bb0d
	var b0, b1 byte
Packit 63bb0d
	var trunc int
Packit 63bb0d
	d.buf.Reset()
Packit 63bb0d
Input:
Packit 63bb0d
	for {
Packit 63bb0d
		b, ok := d.getc()
Packit 63bb0d
		if !ok {
Packit 63bb0d
			if cdata {
Packit 63bb0d
				if d.err == io.EOF {
Packit 63bb0d
					d.err = d.syntaxError("unexpected EOF in CDATA section")
Packit 63bb0d
				}
Packit 63bb0d
				return nil
Packit 63bb0d
			}
Packit 63bb0d
			break Input
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		// .
Packit 63bb0d
		// It is an error for ]]> to appear in ordinary text.
Packit 63bb0d
		if b0 == ']' && b1 == ']' && b == '>' {
Packit 63bb0d
			if cdata {
Packit 63bb0d
				trunc = 2
Packit 63bb0d
				break Input
Packit 63bb0d
			}
Packit 63bb0d
			d.err = d.syntaxError("unescaped ]]> not in CDATA section")
Packit 63bb0d
			return nil
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		// Stop reading text if we see a <.
Packit 63bb0d
		if b == '<' && !cdata {
Packit 63bb0d
			if quote >= 0 {
Packit 63bb0d
				d.err = d.syntaxError("unescaped < inside quoted string")
Packit 63bb0d
				return nil
Packit 63bb0d
			}
Packit 63bb0d
			d.ungetc('<')
Packit 63bb0d
			break Input
Packit 63bb0d
		}
Packit 63bb0d
		if quote >= 0 && b == byte(quote) {
Packit 63bb0d
			break Input
Packit 63bb0d
		}
Packit 63bb0d
		if b == '&' && !cdata {
Packit 63bb0d
			// Read escaped character expression up to semicolon.
Packit 63bb0d
			// XML in all its glory allows a document to define and use
Packit 63bb0d
			// its own character names with  directives.
Packit 63bb0d
			// Parsers are required to recognize lt, gt, amp, apos, and quot
Packit 63bb0d
			// even if they have not been declared.
Packit 63bb0d
			before := d.buf.Len()
Packit 63bb0d
			d.buf.WriteByte('&')
Packit 63bb0d
			var ok bool
Packit 63bb0d
			var text string
Packit 63bb0d
			var haveText bool
Packit 63bb0d
			if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
				return nil
Packit 63bb0d
			}
Packit 63bb0d
			if b == '#' {
Packit 63bb0d
				d.buf.WriteByte(b)
Packit 63bb0d
				if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
					return nil
Packit 63bb0d
				}
Packit 63bb0d
				base := 10
Packit 63bb0d
				if b == 'x' {
Packit 63bb0d
					base = 16
Packit 63bb0d
					d.buf.WriteByte(b)
Packit 63bb0d
					if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
						return nil
Packit 63bb0d
					}
Packit 63bb0d
				}
Packit 63bb0d
				start := d.buf.Len()
Packit 63bb0d
				for '0' <= b && b <= '9' ||
Packit 63bb0d
					base == 16 && 'a' <= b && b <= 'f' ||
Packit 63bb0d
					base == 16 && 'A' <= b && b <= 'F' {
Packit 63bb0d
					d.buf.WriteByte(b)
Packit 63bb0d
					if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
						return nil
Packit 63bb0d
					}
Packit 63bb0d
				}
Packit 63bb0d
				if b != ';' {
Packit 63bb0d
					d.ungetc(b)
Packit 63bb0d
				} else {
Packit 63bb0d
					s := string(d.buf.Bytes()[start:])
Packit 63bb0d
					d.buf.WriteByte(';')
Packit 63bb0d
					n, err := strconv.ParseUint(s, base, 64)
Packit 63bb0d
					if err == nil && n <= unicode.MaxRune {
Packit 63bb0d
						text = string(n)
Packit 63bb0d
						haveText = true
Packit 63bb0d
					}
Packit 63bb0d
				}
Packit 63bb0d
			} else {
Packit 63bb0d
				d.ungetc(b)
Packit 63bb0d
				if !d.readName() {
Packit 63bb0d
					if d.err != nil {
Packit 63bb0d
						return nil
Packit 63bb0d
					}
Packit 63bb0d
				}
Packit 63bb0d
				if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
					return nil
Packit 63bb0d
				}
Packit 63bb0d
				if b != ';' {
Packit 63bb0d
					d.ungetc(b)
Packit 63bb0d
				} else {
Packit 63bb0d
					name := d.buf.Bytes()[before+1:]
Packit 63bb0d
					d.buf.WriteByte(';')
Packit 63bb0d
					if isName(name) {
Packit 63bb0d
						s := string(name)
Packit 63bb0d
						if r, ok := entity[s]; ok {
Packit 63bb0d
							text = string(r)
Packit 63bb0d
							haveText = true
Packit 63bb0d
						} else if d.Entity != nil {
Packit 63bb0d
							text, haveText = d.Entity[s]
Packit 63bb0d
						}
Packit 63bb0d
					}
Packit 63bb0d
				}
Packit 63bb0d
			}
Packit 63bb0d
Packit 63bb0d
			if haveText {
Packit 63bb0d
				d.buf.Truncate(before)
Packit 63bb0d
				d.buf.Write([]byte(text))
Packit 63bb0d
				b0, b1 = 0, 0
Packit 63bb0d
				continue Input
Packit 63bb0d
			}
Packit 63bb0d
			if !d.Strict {
Packit 63bb0d
				b0, b1 = 0, 0
Packit 63bb0d
				continue Input
Packit 63bb0d
			}
Packit 63bb0d
			ent := string(d.buf.Bytes()[before:])
Packit 63bb0d
			if ent[len(ent)-1] != ';' {
Packit 63bb0d
				ent += " (no semicolon)"
Packit 63bb0d
			}
Packit 63bb0d
			d.err = d.syntaxError("invalid character entity " + ent)
Packit 63bb0d
			return nil
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		// We must rewrite unescaped \r and \r\n into \n.
Packit 63bb0d
		if b == '\r' {
Packit 63bb0d
			d.buf.WriteByte('\n')
Packit 63bb0d
		} else if b1 == '\r' && b == '\n' {
Packit 63bb0d
			// Skip \r\n--we already wrote \n.
Packit 63bb0d
		} else {
Packit 63bb0d
			d.buf.WriteByte(b)
Packit 63bb0d
		}
Packit 63bb0d
Packit 63bb0d
		b0, b1 = b1, b
Packit 63bb0d
	}
Packit 63bb0d
	data := d.buf.Bytes()
Packit 63bb0d
	data = data[0 : len(data)-trunc]
Packit 63bb0d
Packit 63bb0d
	// Inspect each rune for being a disallowed character.
Packit 63bb0d
	buf := data
Packit 63bb0d
	for len(buf) > 0 {
Packit 63bb0d
		r, size := utf8.DecodeRune(buf)
Packit 63bb0d
		if r == utf8.RuneError && size == 1 {
Packit 63bb0d
			d.err = d.syntaxError("invalid UTF-8")
Packit 63bb0d
			return nil
Packit 63bb0d
		}
Packit 63bb0d
		buf = buf[size:]
Packit 63bb0d
		if !isInCharacterRange(r) {
Packit 63bb0d
			d.err = d.syntaxError(fmt.Sprintf("illegal character code %U", r))
Packit 63bb0d
			return nil
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	return data
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Decide whether the given rune is in the XML Character Range, per
Packit 63bb0d
// the Char production of https://www.xml.com/axml/testaxml.htm,
Packit 63bb0d
// Section 2.2 Characters.
Packit 63bb0d
func isInCharacterRange(r rune) (inrange bool) {
Packit 63bb0d
	return r == 0x09 ||
Packit 63bb0d
		r == 0x0A ||
Packit 63bb0d
		r == 0x0D ||
Packit 63bb0d
		r >= 0x20 && r <= 0xD7FF ||
Packit 63bb0d
		r >= 0xE000 && r <= 0xFFFD ||
Packit 63bb0d
		r >= 0x10000 && r <= 0x10FFFF
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Get name space name: name with a : stuck in the middle.
Packit 63bb0d
// The part before the : is the name space identifier.
Packit 63bb0d
func (d *Decoder) nsname() (name Name, ok bool) {
Packit 63bb0d
	s, ok := d.name()
Packit 63bb0d
	if !ok {
Packit 63bb0d
		return
Packit 63bb0d
	}
Packit 63bb0d
	i := strings.Index(s, ":")
Packit 63bb0d
	if i < 0 {
Packit 63bb0d
		name.Local = s
Packit 63bb0d
	} else {
Packit 63bb0d
		name.Space = s[0:i]
Packit 63bb0d
		name.Local = s[i+1:]
Packit 63bb0d
	}
Packit 63bb0d
	return name, true
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Get name: /first(first|second)*/
Packit 63bb0d
// Do not set d.err if the name is missing (unless unexpected EOF is received):
Packit 63bb0d
// let the caller provide better context.
Packit 63bb0d
func (d *Decoder) name() (s string, ok bool) {
Packit 63bb0d
	d.buf.Reset()
Packit 63bb0d
	if !d.readName() {
Packit 63bb0d
		return "", false
Packit 63bb0d
	}
Packit 63bb0d
Packit 63bb0d
	// Now we check the characters.
Packit 63bb0d
	b := d.buf.Bytes()
Packit 63bb0d
	if !isName(b) {
Packit 63bb0d
		d.err = d.syntaxError("invalid XML name: " + string(b))
Packit 63bb0d
		return "", false
Packit 63bb0d
	}
Packit 63bb0d
	return string(b), true
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Read a name and append its bytes to d.buf.
Packit 63bb0d
// The name is delimited by any single-byte character not valid in names.
Packit 63bb0d
// All multi-byte characters are accepted; the caller must check their validity.
Packit 63bb0d
func (d *Decoder) readName() (ok bool) {
Packit 63bb0d
	var b byte
Packit 63bb0d
	if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
		return
Packit 63bb0d
	}
Packit 63bb0d
	if b < utf8.RuneSelf && !isNameByte(b) {
Packit 63bb0d
		d.ungetc(b)
Packit 63bb0d
		return false
Packit 63bb0d
	}
Packit 63bb0d
	d.buf.WriteByte(b)
Packit 63bb0d
Packit 63bb0d
	for {
Packit 63bb0d
		if b, ok = d.mustgetc(); !ok {
Packit 63bb0d
			return
Packit 63bb0d
		}
Packit 63bb0d
		if b < utf8.RuneSelf && !isNameByte(b) {
Packit 63bb0d
			d.ungetc(b)
Packit 63bb0d
			break
Packit 63bb0d
		}
Packit 63bb0d
		d.buf.WriteByte(b)
Packit 63bb0d
	}
Packit 63bb0d
	return true
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func isNameByte(c byte) bool {
Packit 63bb0d
	return 'A' <= c && c <= 'Z' ||
Packit 63bb0d
		'a' <= c && c <= 'z' ||
Packit 63bb0d
		'0' <= c && c <= '9' ||
Packit 63bb0d
		c == '_' || c == ':' || c == '.' || c == '-'
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func isName(s []byte) bool {
Packit 63bb0d
	if len(s) == 0 {
Packit 63bb0d
		return false
Packit 63bb0d
	}
Packit 63bb0d
	c, n := utf8.DecodeRune(s)
Packit 63bb0d
	if c == utf8.RuneError && n == 1 {
Packit 63bb0d
		return false
Packit 63bb0d
	}
Packit 63bb0d
	if !unicode.Is(first, c) {
Packit 63bb0d
		return false
Packit 63bb0d
	}
Packit 63bb0d
	for n < len(s) {
Packit 63bb0d
		s = s[n:]
Packit 63bb0d
		c, n = utf8.DecodeRune(s)
Packit 63bb0d
		if c == utf8.RuneError && n == 1 {
Packit 63bb0d
			return false
Packit 63bb0d
		}
Packit 63bb0d
		if !unicode.Is(first, c) && !unicode.Is(second, c) {
Packit 63bb0d
			return false
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	return true
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
func isNameString(s string) bool {
Packit 63bb0d
	if len(s) == 0 {
Packit 63bb0d
		return false
Packit 63bb0d
	}
Packit 63bb0d
	c, n := utf8.DecodeRuneInString(s)
Packit 63bb0d
	if c == utf8.RuneError && n == 1 {
Packit 63bb0d
		return false
Packit 63bb0d
	}
Packit 63bb0d
	if !unicode.Is(first, c) {
Packit 63bb0d
		return false
Packit 63bb0d
	}
Packit 63bb0d
	for n < len(s) {
Packit 63bb0d
		s = s[n:]
Packit 63bb0d
		c, n = utf8.DecodeRuneInString(s)
Packit 63bb0d
		if c == utf8.RuneError && n == 1 {
Packit 63bb0d
			return false
Packit 63bb0d
		}
Packit 63bb0d
		if !unicode.Is(first, c) && !unicode.Is(second, c) {
Packit 63bb0d
			return false
Packit 63bb0d
		}
Packit 63bb0d
	}
Packit 63bb0d
	return true
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// These tables were generated by cut and paste from Appendix B of
Packit 63bb0d
// the XML spec at https://www.xml.com/axml/testaxml.htm
Packit 63bb0d
// and then reformatting. First corresponds to (Letter | '_' | ':')
Packit 63bb0d
// and second corresponds to NameChar.
Packit 63bb0d
Packit 63bb0d
var first = &unicode.RangeTable{
Packit 63bb0d
	R16: []unicode.Range16{
Packit 63bb0d
		{0x003A, 0x003A, 1},
Packit 63bb0d
		{0x0041, 0x005A, 1},
Packit 63bb0d
		{0x005F, 0x005F, 1},
Packit 63bb0d
		{0x0061, 0x007A, 1},
Packit 63bb0d
		{0x00C0, 0x00D6, 1},
Packit 63bb0d
		{0x00D8, 0x00F6, 1},
Packit 63bb0d
		{0x00F8, 0x00FF, 1},
Packit 63bb0d
		{0x0100, 0x0131, 1},
Packit 63bb0d
		{0x0134, 0x013E, 1},
Packit 63bb0d
		{0x0141, 0x0148, 1},
Packit 63bb0d
		{0x014A, 0x017E, 1},
Packit 63bb0d
		{0x0180, 0x01C3, 1},
Packit 63bb0d
		{0x01CD, 0x01F0, 1},
Packit 63bb0d
		{0x01F4, 0x01F5, 1},
Packit 63bb0d
		{0x01FA, 0x0217, 1},
Packit 63bb0d
		{0x0250, 0x02A8, 1},
Packit 63bb0d
		{0x02BB, 0x02C1, 1},
Packit 63bb0d
		{0x0386, 0x0386, 1},
Packit 63bb0d
		{0x0388, 0x038A, 1},
Packit 63bb0d
		{0x038C, 0x038C, 1},
Packit 63bb0d
		{0x038E, 0x03A1, 1},
Packit 63bb0d
		{0x03A3, 0x03CE, 1},
Packit 63bb0d
		{0x03D0, 0x03D6, 1},
Packit 63bb0d
		{0x03DA, 0x03E0, 2},
Packit 63bb0d
		{0x03E2, 0x03F3, 1},
Packit 63bb0d
		{0x0401, 0x040C, 1},
Packit 63bb0d
		{0x040E, 0x044F, 1},
Packit 63bb0d
		{0x0451, 0x045C, 1},
Packit 63bb0d
		{0x045E, 0x0481, 1},
Packit 63bb0d
		{0x0490, 0x04C4, 1},
Packit 63bb0d
		{0x04C7, 0x04C8, 1},
Packit 63bb0d
		{0x04CB, 0x04CC, 1},
Packit 63bb0d
		{0x04D0, 0x04EB, 1},
Packit 63bb0d
		{0x04EE, 0x04F5, 1},
Packit 63bb0d
		{0x04F8, 0x04F9, 1},
Packit 63bb0d
		{0x0531, 0x0556, 1},
Packit 63bb0d
		{0x0559, 0x0559, 1},
Packit 63bb0d
		{0x0561, 0x0586, 1},
Packit 63bb0d
		{0x05D0, 0x05EA, 1},
Packit 63bb0d
		{0x05F0, 0x05F2, 1},
Packit 63bb0d
		{0x0621, 0x063A, 1},
Packit 63bb0d
		{0x0641, 0x064A, 1},
Packit 63bb0d
		{0x0671, 0x06B7, 1},
Packit 63bb0d
		{0x06BA, 0x06BE, 1},
Packit 63bb0d
		{0x06C0, 0x06CE, 1},
Packit 63bb0d
		{0x06D0, 0x06D3, 1},
Packit 63bb0d
		{0x06D5, 0x06D5, 1},
Packit 63bb0d
		{0x06E5, 0x06E6, 1},
Packit 63bb0d
		{0x0905, 0x0939, 1},
Packit 63bb0d
		{0x093D, 0x093D, 1},
Packit 63bb0d
		{0x0958, 0x0961, 1},
Packit 63bb0d
		{0x0985, 0x098C, 1},
Packit 63bb0d
		{0x098F, 0x0990, 1},
Packit 63bb0d
		{0x0993, 0x09A8, 1},
Packit 63bb0d
		{0x09AA, 0x09B0, 1},
Packit 63bb0d
		{0x09B2, 0x09B2, 1},
Packit 63bb0d
		{0x09B6, 0x09B9, 1},
Packit 63bb0d
		{0x09DC, 0x09DD, 1},
Packit 63bb0d
		{0x09DF, 0x09E1, 1},
Packit 63bb0d
		{0x09F0, 0x09F1, 1},
Packit 63bb0d
		{0x0A05, 0x0A0A, 1},
Packit 63bb0d
		{0x0A0F, 0x0A10, 1},
Packit 63bb0d
		{0x0A13, 0x0A28, 1},
Packit 63bb0d
		{0x0A2A, 0x0A30, 1},
Packit 63bb0d
		{0x0A32, 0x0A33, 1},
Packit 63bb0d
		{0x0A35, 0x0A36, 1},
Packit 63bb0d
		{0x0A38, 0x0A39, 1},
Packit 63bb0d
		{0x0A59, 0x0A5C, 1},
Packit 63bb0d
		{0x0A5E, 0x0A5E, 1},
Packit 63bb0d
		{0x0A72, 0x0A74, 1},
Packit 63bb0d
		{0x0A85, 0x0A8B, 1},
Packit 63bb0d
		{0x0A8D, 0x0A8D, 1},
Packit 63bb0d
		{0x0A8F, 0x0A91, 1},
Packit 63bb0d
		{0x0A93, 0x0AA8, 1},
Packit 63bb0d
		{0x0AAA, 0x0AB0, 1},
Packit 63bb0d
		{0x0AB2, 0x0AB3, 1},
Packit 63bb0d
		{0x0AB5, 0x0AB9, 1},
Packit 63bb0d
		{0x0ABD, 0x0AE0, 0x23},
Packit 63bb0d
		{0x0B05, 0x0B0C, 1},
Packit 63bb0d
		{0x0B0F, 0x0B10, 1},
Packit 63bb0d
		{0x0B13, 0x0B28, 1},
Packit 63bb0d
		{0x0B2A, 0x0B30, 1},
Packit 63bb0d
		{0x0B32, 0x0B33, 1},
Packit 63bb0d
		{0x0B36, 0x0B39, 1},
Packit 63bb0d
		{0x0B3D, 0x0B3D, 1},
Packit 63bb0d
		{0x0B5C, 0x0B5D, 1},
Packit 63bb0d
		{0x0B5F, 0x0B61, 1},
Packit 63bb0d
		{0x0B85, 0x0B8A, 1},
Packit 63bb0d
		{0x0B8E, 0x0B90, 1},
Packit 63bb0d
		{0x0B92, 0x0B95, 1},
Packit 63bb0d
		{0x0B99, 0x0B9A, 1},
Packit 63bb0d
		{0x0B9C, 0x0B9C, 1},
Packit 63bb0d
		{0x0B9E, 0x0B9F, 1},
Packit 63bb0d
		{0x0BA3, 0x0BA4, 1},
Packit 63bb0d
		{0x0BA8, 0x0BAA, 1},
Packit 63bb0d
		{0x0BAE, 0x0BB5, 1},
Packit 63bb0d
		{0x0BB7, 0x0BB9, 1},
Packit 63bb0d
		{0x0C05, 0x0C0C, 1},
Packit 63bb0d
		{0x0C0E, 0x0C10, 1},
Packit 63bb0d
		{0x0C12, 0x0C28, 1},
Packit 63bb0d
		{0x0C2A, 0x0C33, 1},
Packit 63bb0d
		{0x0C35, 0x0C39, 1},
Packit 63bb0d
		{0x0C60, 0x0C61, 1},
Packit 63bb0d
		{0x0C85, 0x0C8C, 1},
Packit 63bb0d
		{0x0C8E, 0x0C90, 1},
Packit 63bb0d
		{0x0C92, 0x0CA8, 1},
Packit 63bb0d
		{0x0CAA, 0x0CB3, 1},
Packit 63bb0d
		{0x0CB5, 0x0CB9, 1},
Packit 63bb0d
		{0x0CDE, 0x0CDE, 1},
Packit 63bb0d
		{0x0CE0, 0x0CE1, 1},
Packit 63bb0d
		{0x0D05, 0x0D0C, 1},
Packit 63bb0d
		{0x0D0E, 0x0D10, 1},
Packit 63bb0d
		{0x0D12, 0x0D28, 1},
Packit 63bb0d
		{0x0D2A, 0x0D39, 1},
Packit 63bb0d
		{0x0D60, 0x0D61, 1},
Packit 63bb0d
		{0x0E01, 0x0E2E, 1},
Packit 63bb0d
		{0x0E30, 0x0E30, 1},
Packit 63bb0d
		{0x0E32, 0x0E33, 1},
Packit 63bb0d
		{0x0E40, 0x0E45, 1},
Packit 63bb0d
		{0x0E81, 0x0E82, 1},
Packit 63bb0d
		{0x0E84, 0x0E84, 1},
Packit 63bb0d
		{0x0E87, 0x0E88, 1},
Packit 63bb0d
		{0x0E8A, 0x0E8D, 3},
Packit 63bb0d
		{0x0E94, 0x0E97, 1},
Packit 63bb0d
		{0x0E99, 0x0E9F, 1},
Packit 63bb0d
		{0x0EA1, 0x0EA3, 1},
Packit 63bb0d
		{0x0EA5, 0x0EA7, 2},
Packit 63bb0d
		{0x0EAA, 0x0EAB, 1},
Packit 63bb0d
		{0x0EAD, 0x0EAE, 1},
Packit 63bb0d
		{0x0EB0, 0x0EB0, 1},
Packit 63bb0d
		{0x0EB2, 0x0EB3, 1},
Packit 63bb0d
		{0x0EBD, 0x0EBD, 1},
Packit 63bb0d
		{0x0EC0, 0x0EC4, 1},
Packit 63bb0d
		{0x0F40, 0x0F47, 1},
Packit 63bb0d
		{0x0F49, 0x0F69, 1},
Packit 63bb0d
		{0x10A0, 0x10C5, 1},
Packit 63bb0d
		{0x10D0, 0x10F6, 1},
Packit 63bb0d
		{0x1100, 0x1100, 1},
Packit 63bb0d
		{0x1102, 0x1103, 1},
Packit 63bb0d
		{0x1105, 0x1107, 1},
Packit 63bb0d
		{0x1109, 0x1109, 1},
Packit 63bb0d
		{0x110B, 0x110C, 1},
Packit 63bb0d
		{0x110E, 0x1112, 1},
Packit 63bb0d
		{0x113C, 0x1140, 2},
Packit 63bb0d
		{0x114C, 0x1150, 2},
Packit 63bb0d
		{0x1154, 0x1155, 1},
Packit 63bb0d
		{0x1159, 0x1159, 1},
Packit 63bb0d
		{0x115F, 0x1161, 1},
Packit 63bb0d
		{0x1163, 0x1169, 2},
Packit 63bb0d
		{0x116D, 0x116E, 1},
Packit 63bb0d
		{0x1172, 0x1173, 1},
Packit 63bb0d
		{0x1175, 0x119E, 0x119E - 0x1175},
Packit 63bb0d
		{0x11A8, 0x11AB, 0x11AB - 0x11A8},
Packit 63bb0d
		{0x11AE, 0x11AF, 1},
Packit 63bb0d
		{0x11B7, 0x11B8, 1},
Packit 63bb0d
		{0x11BA, 0x11BA, 1},
Packit 63bb0d
		{0x11BC, 0x11C2, 1},
Packit 63bb0d
		{0x11EB, 0x11F0, 0x11F0 - 0x11EB},
Packit 63bb0d
		{0x11F9, 0x11F9, 1},
Packit 63bb0d
		{0x1E00, 0x1E9B, 1},
Packit 63bb0d
		{0x1EA0, 0x1EF9, 1},
Packit 63bb0d
		{0x1F00, 0x1F15, 1},
Packit 63bb0d
		{0x1F18, 0x1F1D, 1},
Packit 63bb0d
		{0x1F20, 0x1F45, 1},
Packit 63bb0d
		{0x1F48, 0x1F4D, 1},
Packit 63bb0d
		{0x1F50, 0x1F57, 1},
Packit 63bb0d
		{0x1F59, 0x1F5B, 0x1F5B - 0x1F59},
Packit 63bb0d
		{0x1F5D, 0x1F5D, 1},
Packit 63bb0d
		{0x1F5F, 0x1F7D, 1},
Packit 63bb0d
		{0x1F80, 0x1FB4, 1},
Packit 63bb0d
		{0x1FB6, 0x1FBC, 1},
Packit 63bb0d
		{0x1FBE, 0x1FBE, 1},
Packit 63bb0d
		{0x1FC2, 0x1FC4, 1},
Packit 63bb0d
		{0x1FC6, 0x1FCC, 1},
Packit 63bb0d
		{0x1FD0, 0x1FD3, 1},
Packit 63bb0d
		{0x1FD6, 0x1FDB, 1},
Packit 63bb0d
		{0x1FE0, 0x1FEC, 1},
Packit 63bb0d
		{0x1FF2, 0x1FF4, 1},
Packit 63bb0d
		{0x1FF6, 0x1FFC, 1},
Packit 63bb0d
		{0x2126, 0x2126, 1},
Packit 63bb0d
		{0x212A, 0x212B, 1},
Packit 63bb0d
		{0x212E, 0x212E, 1},
Packit 63bb0d
		{0x2180, 0x2182, 1},
Packit 63bb0d
		{0x3007, 0x3007, 1},
Packit 63bb0d
		{0x3021, 0x3029, 1},
Packit 63bb0d
		{0x3041, 0x3094, 1},
Packit 63bb0d
		{0x30A1, 0x30FA, 1},
Packit 63bb0d
		{0x3105, 0x312C, 1},
Packit 63bb0d
		{0x4E00, 0x9FA5, 1},
Packit 63bb0d
		{0xAC00, 0xD7A3, 1},
Packit 63bb0d
	},
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
var second = &unicode.RangeTable{
Packit 63bb0d
	R16: []unicode.Range16{
Packit 63bb0d
		{0x002D, 0x002E, 1},
Packit 63bb0d
		{0x0030, 0x0039, 1},
Packit 63bb0d
		{0x00B7, 0x00B7, 1},
Packit 63bb0d
		{0x02D0, 0x02D1, 1},
Packit 63bb0d
		{0x0300, 0x0345, 1},
Packit 63bb0d
		{0x0360, 0x0361, 1},
Packit 63bb0d
		{0x0387, 0x0387, 1},
Packit 63bb0d
		{0x0483, 0x0486, 1},
Packit 63bb0d
		{0x0591, 0x05A1, 1},
Packit 63bb0d
		{0x05A3, 0x05B9, 1},
Packit 63bb0d
		{0x05BB, 0x05BD, 1},
Packit 63bb0d
		{0x05BF, 0x05BF, 1},
Packit 63bb0d
		{0x05C1, 0x05C2, 1},
Packit 63bb0d
		{0x05C4, 0x0640, 0x0640 - 0x05C4},
Packit 63bb0d
		{0x064B, 0x0652, 1},
Packit 63bb0d
		{0x0660, 0x0669, 1},
Packit 63bb0d
		{0x0670, 0x0670, 1},
Packit 63bb0d
		{0x06D6, 0x06DC, 1},
Packit 63bb0d
		{0x06DD, 0x06DF, 1},
Packit 63bb0d
		{0x06E0, 0x06E4, 1},
Packit 63bb0d
		{0x06E7, 0x06E8, 1},
Packit 63bb0d
		{0x06EA, 0x06ED, 1},
Packit 63bb0d
		{0x06F0, 0x06F9, 1},
Packit 63bb0d
		{0x0901, 0x0903, 1},
Packit 63bb0d
		{0x093C, 0x093C, 1},
Packit 63bb0d
		{0x093E, 0x094C, 1},
Packit 63bb0d
		{0x094D, 0x094D, 1},
Packit 63bb0d
		{0x0951, 0x0954, 1},
Packit 63bb0d
		{0x0962, 0x0963, 1},
Packit 63bb0d
		{0x0966, 0x096F, 1},
Packit 63bb0d
		{0x0981, 0x0983, 1},
Packit 63bb0d
		{0x09BC, 0x09BC, 1},
Packit 63bb0d
		{0x09BE, 0x09BF, 1},
Packit 63bb0d
		{0x09C0, 0x09C4, 1},
Packit 63bb0d
		{0x09C7, 0x09C8, 1},
Packit 63bb0d
		{0x09CB, 0x09CD, 1},
Packit 63bb0d
		{0x09D7, 0x09D7, 1},
Packit 63bb0d
		{0x09E2, 0x09E3, 1},
Packit 63bb0d
		{0x09E6, 0x09EF, 1},
Packit 63bb0d
		{0x0A02, 0x0A3C, 0x3A},
Packit 63bb0d
		{0x0A3E, 0x0A3F, 1},
Packit 63bb0d
		{0x0A40, 0x0A42, 1},
Packit 63bb0d
		{0x0A47, 0x0A48, 1},
Packit 63bb0d
		{0x0A4B, 0x0A4D, 1},
Packit 63bb0d
		{0x0A66, 0x0A6F, 1},
Packit 63bb0d
		{0x0A70, 0x0A71, 1},
Packit 63bb0d
		{0x0A81, 0x0A83, 1},
Packit 63bb0d
		{0x0ABC, 0x0ABC, 1},
Packit 63bb0d
		{0x0ABE, 0x0AC5, 1},
Packit 63bb0d
		{0x0AC7, 0x0AC9, 1},
Packit 63bb0d
		{0x0ACB, 0x0ACD, 1},
Packit 63bb0d
		{0x0AE6, 0x0AEF, 1},
Packit 63bb0d
		{0x0B01, 0x0B03, 1},
Packit 63bb0d
		{0x0B3C, 0x0B3C, 1},
Packit 63bb0d
		{0x0B3E, 0x0B43, 1},
Packit 63bb0d
		{0x0B47, 0x0B48, 1},
Packit 63bb0d
		{0x0B4B, 0x0B4D, 1},
Packit 63bb0d
		{0x0B56, 0x0B57, 1},
Packit 63bb0d
		{0x0B66, 0x0B6F, 1},
Packit 63bb0d
		{0x0B82, 0x0B83, 1},
Packit 63bb0d
		{0x0BBE, 0x0BC2, 1},
Packit 63bb0d
		{0x0BC6, 0x0BC8, 1},
Packit 63bb0d
		{0x0BCA, 0x0BCD, 1},
Packit 63bb0d
		{0x0BD7, 0x0BD7, 1},
Packit 63bb0d
		{0x0BE7, 0x0BEF, 1},
Packit 63bb0d
		{0x0C01, 0x0C03, 1},
Packit 63bb0d
		{0x0C3E, 0x0C44, 1},
Packit 63bb0d
		{0x0C46, 0x0C48, 1},
Packit 63bb0d
		{0x0C4A, 0x0C4D, 1},
Packit 63bb0d
		{0x0C55, 0x0C56, 1},
Packit 63bb0d
		{0x0C66, 0x0C6F, 1},
Packit 63bb0d
		{0x0C82, 0x0C83, 1},
Packit 63bb0d
		{0x0CBE, 0x0CC4, 1},
Packit 63bb0d
		{0x0CC6, 0x0CC8, 1},
Packit 63bb0d
		{0x0CCA, 0x0CCD, 1},
Packit 63bb0d
		{0x0CD5, 0x0CD6, 1},
Packit 63bb0d
		{0x0CE6, 0x0CEF, 1},
Packit 63bb0d
		{0x0D02, 0x0D03, 1},
Packit 63bb0d
		{0x0D3E, 0x0D43, 1},
Packit 63bb0d
		{0x0D46, 0x0D48, 1},
Packit 63bb0d
		{0x0D4A, 0x0D4D, 1},
Packit 63bb0d
		{0x0D57, 0x0D57, 1},
Packit 63bb0d
		{0x0D66, 0x0D6F, 1},
Packit 63bb0d
		{0x0E31, 0x0E31, 1},
Packit 63bb0d
		{0x0E34, 0x0E3A, 1},
Packit 63bb0d
		{0x0E46, 0x0E46, 1},
Packit 63bb0d
		{0x0E47, 0x0E4E, 1},
Packit 63bb0d
		{0x0E50, 0x0E59, 1},
Packit 63bb0d
		{0x0EB1, 0x0EB1, 1},
Packit 63bb0d
		{0x0EB4, 0x0EB9, 1},
Packit 63bb0d
		{0x0EBB, 0x0EBC, 1},
Packit 63bb0d
		{0x0EC6, 0x0EC6, 1},
Packit 63bb0d
		{0x0EC8, 0x0ECD, 1},
Packit 63bb0d
		{0x0ED0, 0x0ED9, 1},
Packit 63bb0d
		{0x0F18, 0x0F19, 1},
Packit 63bb0d
		{0x0F20, 0x0F29, 1},
Packit 63bb0d
		{0x0F35, 0x0F39, 2},
Packit 63bb0d
		{0x0F3E, 0x0F3F, 1},
Packit 63bb0d
		{0x0F71, 0x0F84, 1},
Packit 63bb0d
		{0x0F86, 0x0F8B, 1},
Packit 63bb0d
		{0x0F90, 0x0F95, 1},
Packit 63bb0d
		{0x0F97, 0x0F97, 1},
Packit 63bb0d
		{0x0F99, 0x0FAD, 1},
Packit 63bb0d
		{0x0FB1, 0x0FB7, 1},
Packit 63bb0d
		{0x0FB9, 0x0FB9, 1},
Packit 63bb0d
		{0x20D0, 0x20DC, 1},
Packit 63bb0d
		{0x20E1, 0x3005, 0x3005 - 0x20E1},
Packit 63bb0d
		{0x302A, 0x302F, 1},
Packit 63bb0d
		{0x3031, 0x3035, 1},
Packit 63bb0d
		{0x3099, 0x309A, 1},
Packit 63bb0d
		{0x309D, 0x309E, 1},
Packit 63bb0d
		{0x30FC, 0x30FE, 1},
Packit 63bb0d
	},
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// HTMLEntity is an entity map containing translations for the
Packit 63bb0d
// standard HTML entity characters.
Packit 63bb0d
//
Packit 63bb0d
// See the Decoder.Strict and Decoder.Entity fields' documentation.
Packit 63bb0d
var HTMLEntity map[string]string = htmlEntity
Packit 63bb0d
Packit 63bb0d
var htmlEntity = map[string]string{
Packit 63bb0d
	/*
Packit 63bb0d
		hget http://www.w3.org/TR/html4/sgml/entities.html |
Packit 63bb0d
		ssam '
Packit 63bb0d
			,y /\>/ x/\<(.|\n)+/ s/\n/ /g
Packit 63bb0d
			,x v/^\<!ENTITY/d
Packit 63bb0d
			,s/\<!ENTITY ([^ ]+) .*U\+([0-9A-F][0-9A-F][0-9A-F][0-9A-F]) .+/	"\1": "\\u\2",/g
Packit 63bb0d
		'
Packit 63bb0d
	*/
Packit 63bb0d
	"nbsp":     "\u00A0",
Packit 63bb0d
	"iexcl":    "\u00A1",
Packit 63bb0d
	"cent":     "\u00A2",
Packit 63bb0d
	"pound":    "\u00A3",
Packit 63bb0d
	"curren":   "\u00A4",
Packit 63bb0d
	"yen":      "\u00A5",
Packit 63bb0d
	"brvbar":   "\u00A6",
Packit 63bb0d
	"sect":     "\u00A7",
Packit 63bb0d
	"uml":      "\u00A8",
Packit 63bb0d
	"copy":     "\u00A9",
Packit 63bb0d
	"ordf":     "\u00AA",
Packit 63bb0d
	"laquo":    "\u00AB",
Packit 63bb0d
	"not":      "\u00AC",
Packit 63bb0d
	"shy":      "\u00AD",
Packit 63bb0d
	"reg":      "\u00AE",
Packit 63bb0d
	"macr":     "\u00AF",
Packit 63bb0d
	"deg":      "\u00B0",
Packit 63bb0d
	"plusmn":   "\u00B1",
Packit 63bb0d
	"sup2":     "\u00B2",
Packit 63bb0d
	"sup3":     "\u00B3",
Packit 63bb0d
	"acute":    "\u00B4",
Packit 63bb0d
	"micro":    "\u00B5",
Packit 63bb0d
	"para":     "\u00B6",
Packit 63bb0d
	"middot":   "\u00B7",
Packit 63bb0d
	"cedil":    "\u00B8",
Packit 63bb0d
	"sup1":     "\u00B9",
Packit 63bb0d
	"ordm":     "\u00BA",
Packit 63bb0d
	"raquo":    "\u00BB",
Packit 63bb0d
	"frac14":   "\u00BC",
Packit 63bb0d
	"frac12":   "\u00BD",
Packit 63bb0d
	"frac34":   "\u00BE",
Packit 63bb0d
	"iquest":   "\u00BF",
Packit 63bb0d
	"Agrave":   "\u00C0",
Packit 63bb0d
	"Aacute":   "\u00C1",
Packit 63bb0d
	"Acirc":    "\u00C2",
Packit 63bb0d
	"Atilde":   "\u00C3",
Packit 63bb0d
	"Auml":     "\u00C4",
Packit 63bb0d
	"Aring":    "\u00C5",
Packit 63bb0d
	"AElig":    "\u00C6",
Packit 63bb0d
	"Ccedil":   "\u00C7",
Packit 63bb0d
	"Egrave":   "\u00C8",
Packit 63bb0d
	"Eacute":   "\u00C9",
Packit 63bb0d
	"Ecirc":    "\u00CA",
Packit 63bb0d
	"Euml":     "\u00CB",
Packit 63bb0d
	"Igrave":   "\u00CC",
Packit 63bb0d
	"Iacute":   "\u00CD",
Packit 63bb0d
	"Icirc":    "\u00CE",
Packit 63bb0d
	"Iuml":     "\u00CF",
Packit 63bb0d
	"ETH":      "\u00D0",
Packit 63bb0d
	"Ntilde":   "\u00D1",
Packit 63bb0d
	"Ograve":   "\u00D2",
Packit 63bb0d
	"Oacute":   "\u00D3",
Packit 63bb0d
	"Ocirc":    "\u00D4",
Packit 63bb0d
	"Otilde":   "\u00D5",
Packit 63bb0d
	"Ouml":     "\u00D6",
Packit 63bb0d
	"times":    "\u00D7",
Packit 63bb0d
	"Oslash":   "\u00D8",
Packit 63bb0d
	"Ugrave":   "\u00D9",
Packit 63bb0d
	"Uacute":   "\u00DA",
Packit 63bb0d
	"Ucirc":    "\u00DB",
Packit 63bb0d
	"Uuml":     "\u00DC",
Packit 63bb0d
	"Yacute":   "\u00DD",
Packit 63bb0d
	"THORN":    "\u00DE",
Packit 63bb0d
	"szlig":    "\u00DF",
Packit 63bb0d
	"agrave":   "\u00E0",
Packit 63bb0d
	"aacute":   "\u00E1",
Packit 63bb0d
	"acirc":    "\u00E2",
Packit 63bb0d
	"atilde":   "\u00E3",
Packit 63bb0d
	"auml":     "\u00E4",
Packit 63bb0d
	"aring":    "\u00E5",
Packit 63bb0d
	"aelig":    "\u00E6",
Packit 63bb0d
	"ccedil":   "\u00E7",
Packit 63bb0d
	"egrave":   "\u00E8",
Packit 63bb0d
	"eacute":   "\u00E9",
Packit 63bb0d
	"ecirc":    "\u00EA",
Packit 63bb0d
	"euml":     "\u00EB",
Packit 63bb0d
	"igrave":   "\u00EC",
Packit 63bb0d
	"iacute":   "\u00ED",
Packit 63bb0d
	"icirc":    "\u00EE",
Packit 63bb0d
	"iuml":     "\u00EF",
Packit 63bb0d
	"eth":      "\u00F0",
Packit 63bb0d
	"ntilde":   "\u00F1",
Packit 63bb0d
	"ograve":   "\u00F2",
Packit 63bb0d
	"oacute":   "\u00F3",
Packit 63bb0d
	"ocirc":    "\u00F4",
Packit 63bb0d
	"otilde":   "\u00F5",
Packit 63bb0d
	"ouml":     "\u00F6",
Packit 63bb0d
	"divide":   "\u00F7",
Packit 63bb0d
	"oslash":   "\u00F8",
Packit 63bb0d
	"ugrave":   "\u00F9",
Packit 63bb0d
	"uacute":   "\u00FA",
Packit 63bb0d
	"ucirc":    "\u00FB",
Packit 63bb0d
	"uuml":     "\u00FC",
Packit 63bb0d
	"yacute":   "\u00FD",
Packit 63bb0d
	"thorn":    "\u00FE",
Packit 63bb0d
	"yuml":     "\u00FF",
Packit 63bb0d
	"fnof":     "\u0192",
Packit 63bb0d
	"Alpha":    "\u0391",
Packit 63bb0d
	"Beta":     "\u0392",
Packit 63bb0d
	"Gamma":    "\u0393",
Packit 63bb0d
	"Delta":    "\u0394",
Packit 63bb0d
	"Epsilon":  "\u0395",
Packit 63bb0d
	"Zeta":     "\u0396",
Packit 63bb0d
	"Eta":      "\u0397",
Packit 63bb0d
	"Theta":    "\u0398",
Packit 63bb0d
	"Iota":     "\u0399",
Packit 63bb0d
	"Kappa":    "\u039A",
Packit 63bb0d
	"Lambda":   "\u039B",
Packit 63bb0d
	"Mu":       "\u039C",
Packit 63bb0d
	"Nu":       "\u039D",
Packit 63bb0d
	"Xi":       "\u039E",
Packit 63bb0d
	"Omicron":  "\u039F",
Packit 63bb0d
	"Pi":       "\u03A0",
Packit 63bb0d
	"Rho":      "\u03A1",
Packit 63bb0d
	"Sigma":    "\u03A3",
Packit 63bb0d
	"Tau":      "\u03A4",
Packit 63bb0d
	"Upsilon":  "\u03A5",
Packit 63bb0d
	"Phi":      "\u03A6",
Packit 63bb0d
	"Chi":      "\u03A7",
Packit 63bb0d
	"Psi":      "\u03A8",
Packit 63bb0d
	"Omega":    "\u03A9",
Packit 63bb0d
	"alpha":    "\u03B1",
Packit 63bb0d
	"beta":     "\u03B2",
Packit 63bb0d
	"gamma":    "\u03B3",
Packit 63bb0d
	"delta":    "\u03B4",
Packit 63bb0d
	"epsilon":  "\u03B5",
Packit 63bb0d
	"zeta":     "\u03B6",
Packit 63bb0d
	"eta":      "\u03B7",
Packit 63bb0d
	"theta":    "\u03B8",
Packit 63bb0d
	"iota":     "\u03B9",
Packit 63bb0d
	"kappa":    "\u03BA",
Packit 63bb0d
	"lambda":   "\u03BB",
Packit 63bb0d
	"mu":       "\u03BC",
Packit 63bb0d
	"nu":       "\u03BD",
Packit 63bb0d
	"xi":       "\u03BE",
Packit 63bb0d
	"omicron":  "\u03BF",
Packit 63bb0d
	"pi":       "\u03C0",
Packit 63bb0d
	"rho":      "\u03C1",
Packit 63bb0d
	"sigmaf":   "\u03C2",
Packit 63bb0d
	"sigma":    "\u03C3",
Packit 63bb0d
	"tau":      "\u03C4",
Packit 63bb0d
	"upsilon":  "\u03C5",
Packit 63bb0d
	"phi":      "\u03C6",
Packit 63bb0d
	"chi":      "\u03C7",
Packit 63bb0d
	"psi":      "\u03C8",
Packit 63bb0d
	"omega":    "\u03C9",
Packit 63bb0d
	"thetasym": "\u03D1",
Packit 63bb0d
	"upsih":    "\u03D2",
Packit 63bb0d
	"piv":      "\u03D6",
Packit 63bb0d
	"bull":     "\u2022",
Packit 63bb0d
	"hellip":   "\u2026",
Packit 63bb0d
	"prime":    "\u2032",
Packit 63bb0d
	"Prime":    "\u2033",
Packit 63bb0d
	"oline":    "\u203E",
Packit 63bb0d
	"frasl":    "\u2044",
Packit 63bb0d
	"weierp":   "\u2118",
Packit 63bb0d
	"image":    "\u2111",
Packit 63bb0d
	"real":     "\u211C",
Packit 63bb0d
	"trade":    "\u2122",
Packit 63bb0d
	"alefsym":  "\u2135",
Packit 63bb0d
	"larr":     "\u2190",
Packit 63bb0d
	"uarr":     "\u2191",
Packit 63bb0d
	"rarr":     "\u2192",
Packit 63bb0d
	"darr":     "\u2193",
Packit 63bb0d
	"harr":     "\u2194",
Packit 63bb0d
	"crarr":    "\u21B5",
Packit 63bb0d
	"lArr":     "\u21D0",
Packit 63bb0d
	"uArr":     "\u21D1",
Packit 63bb0d
	"rArr":     "\u21D2",
Packit 63bb0d
	"dArr":     "\u21D3",
Packit 63bb0d
	"hArr":     "\u21D4",
Packit 63bb0d
	"forall":   "\u2200",
Packit 63bb0d
	"part":     "\u2202",
Packit 63bb0d
	"exist":    "\u2203",
Packit 63bb0d
	"empty":    "\u2205",
Packit 63bb0d
	"nabla":    "\u2207",
Packit 63bb0d
	"isin":     "\u2208",
Packit 63bb0d
	"notin":    "\u2209",
Packit 63bb0d
	"ni":       "\u220B",
Packit 63bb0d
	"prod":     "\u220F",
Packit 63bb0d
	"sum":      "\u2211",
Packit 63bb0d
	"minus":    "\u2212",
Packit 63bb0d
	"lowast":   "\u2217",
Packit 63bb0d
	"radic":    "\u221A",
Packit 63bb0d
	"prop":     "\u221D",
Packit 63bb0d
	"infin":    "\u221E",
Packit 63bb0d
	"ang":      "\u2220",
Packit 63bb0d
	"and":      "\u2227",
Packit 63bb0d
	"or":       "\u2228",
Packit 63bb0d
	"cap":      "\u2229",
Packit 63bb0d
	"cup":      "\u222A",
Packit 63bb0d
	"int":      "\u222B",
Packit 63bb0d
	"there4":   "\u2234",
Packit 63bb0d
	"sim":      "\u223C",
Packit 63bb0d
	"cong":     "\u2245",
Packit 63bb0d
	"asymp":    "\u2248",
Packit 63bb0d
	"ne":       "\u2260",
Packit 63bb0d
	"equiv":    "\u2261",
Packit 63bb0d
	"le":       "\u2264",
Packit 63bb0d
	"ge":       "\u2265",
Packit 63bb0d
	"sub":      "\u2282",
Packit 63bb0d
	"sup":      "\u2283",
Packit 63bb0d
	"nsub":     "\u2284",
Packit 63bb0d
	"sube":     "\u2286",
Packit 63bb0d
	"supe":     "\u2287",
Packit 63bb0d
	"oplus":    "\u2295",
Packit 63bb0d
	"otimes":   "\u2297",
Packit 63bb0d
	"perp":     "\u22A5",
Packit 63bb0d
	"sdot":     "\u22C5",
Packit 63bb0d
	"lceil":    "\u2308",
Packit 63bb0d
	"rceil":    "\u2309",
Packit 63bb0d
	"lfloor":   "\u230A",
Packit 63bb0d
	"rfloor":   "\u230B",
Packit 63bb0d
	"lang":     "\u2329",
Packit 63bb0d
	"rang":     "\u232A",
Packit 63bb0d
	"loz":      "\u25CA",
Packit 63bb0d
	"spades":   "\u2660",
Packit 63bb0d
	"clubs":    "\u2663",
Packit 63bb0d
	"hearts":   "\u2665",
Packit 63bb0d
	"diams":    "\u2666",
Packit 63bb0d
	"quot":     "\u0022",
Packit 63bb0d
	"amp":      "\u0026",
Packit 63bb0d
	"lt":       "\u003C",
Packit 63bb0d
	"gt":       "\u003E",
Packit 63bb0d
	"OElig":    "\u0152",
Packit 63bb0d
	"oelig":    "\u0153",
Packit 63bb0d
	"Scaron":   "\u0160",
Packit 63bb0d
	"scaron":   "\u0161",
Packit 63bb0d
	"Yuml":     "\u0178",
Packit 63bb0d
	"circ":     "\u02C6",
Packit 63bb0d
	"tilde":    "\u02DC",
Packit 63bb0d
	"ensp":     "\u2002",
Packit 63bb0d
	"emsp":     "\u2003",
Packit 63bb0d
	"thinsp":   "\u2009",
Packit 63bb0d
	"zwnj":     "\u200C",
Packit 63bb0d
	"zwj":      "\u200D",
Packit 63bb0d
	"lrm":      "\u200E",
Packit 63bb0d
	"rlm":      "\u200F",
Packit 63bb0d
	"ndash":    "\u2013",
Packit 63bb0d
	"mdash":    "\u2014",
Packit 63bb0d
	"lsquo":    "\u2018",
Packit 63bb0d
	"rsquo":    "\u2019",
Packit 63bb0d
	"sbquo":    "\u201A",
Packit 63bb0d
	"ldquo":    "\u201C",
Packit 63bb0d
	"rdquo":    "\u201D",
Packit 63bb0d
	"bdquo":    "\u201E",
Packit 63bb0d
	"dagger":   "\u2020",
Packit 63bb0d
	"Dagger":   "\u2021",
Packit 63bb0d
	"permil":   "\u2030",
Packit 63bb0d
	"lsaquo":   "\u2039",
Packit 63bb0d
	"rsaquo":   "\u203A",
Packit 63bb0d
	"euro":     "\u20AC",
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// HTMLAutoClose is the set of HTML elements that
Packit 63bb0d
// should be considered to close automatically.
Packit 63bb0d
//
Packit 63bb0d
// See the Decoder.Strict and Decoder.Entity fields' documentation.
Packit 63bb0d
var HTMLAutoClose []string = htmlAutoClose
Packit 63bb0d
Packit 63bb0d
var htmlAutoClose = []string{
Packit 63bb0d
	/*
Packit 63bb0d
		hget http://www.w3.org/TR/html4/loose.dtd |
Packit 63bb0d
		9 sed -n 's/
Packit 63bb0d
	*/
Packit 63bb0d
	"basefont",
Packit 63bb0d
	"br",
Packit 63bb0d
	"area",
Packit 63bb0d
	"link",
Packit 63bb0d
	"img",
Packit 63bb0d
	"param",
Packit 63bb0d
	"hr",
Packit 63bb0d
	"input",
Packit 63bb0d
	"col",
Packit 63bb0d
	"frame",
Packit 63bb0d
	"isindex",
Packit 63bb0d
	"base",
Packit 63bb0d
	"meta",
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
var (
Packit 63bb0d
	escQuot = []byte(""") // shorter than """
Packit 63bb0d
	escApos = []byte("'") // shorter than "'"
Packit 63bb0d
	escAmp  = []byte("&")
Packit 63bb0d
	escLT   = []byte("<")
Packit 63bb0d
	escGT   = []byte(">")
Packit 63bb0d
	escTab  = []byte("	")
Packit 63bb0d
	escNL   = []byte("
")
Packit 63bb0d
	escCR   = []byte("
")
Packit 63bb0d
	escFFFD = []byte("\uFFFD") // Unicode replacement character
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
// EscapeText writes to w the properly escaped XML equivalent
Packit 63bb0d
// of the plain text data s.
Packit 63bb0d
func EscapeText(w io.Writer, s []byte) error {
Packit 63bb0d
	return escapeText(w, s, true)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// escapeText writes to w the properly escaped XML equivalent
Packit 63bb0d
// of the plain text data s. If escapeNewline is true, newline
Packit 63bb0d
// characters will be escaped.
Packit 63bb0d
func escapeText(w io.Writer, s []byte, escapeNewline bool) error {
Packit 63bb0d
	var esc []byte
Packit 63bb0d
	last := 0
Packit 63bb0d
	for i := 0; i < len(s); {
Packit 63bb0d
		r, width := utf8.DecodeRune(s[i:])
Packit 63bb0d
		i += width
Packit 63bb0d
		switch r {
Packit 63bb0d
		case '"':
Packit 63bb0d
			esc = escQuot
Packit 63bb0d
		case '\'':
Packit 63bb0d
			esc = escApos
Packit 63bb0d
		case '&':
Packit 63bb0d
			esc = escAmp
Packit 63bb0d
		case '<':
Packit 63bb0d
			esc = escLT
Packit 63bb0d
		case '>':
Packit 63bb0d
			esc = escGT
Packit 63bb0d
		case '\t':
Packit 63bb0d
			esc = escTab
Packit 63bb0d
		case '\n':
Packit 63bb0d
			if !escapeNewline {
Packit 63bb0d
				continue
Packit 63bb0d
			}
Packit 63bb0d
			esc = escNL
Packit 63bb0d
		case '\r':
Packit 63bb0d
			esc = escCR
Packit 63bb0d
		default:
Packit 63bb0d
			if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
Packit 63bb0d
				esc = escFFFD
Packit 63bb0d
				break
Packit 63bb0d
			}
Packit 63bb0d
			continue
Packit 63bb0d
		}
Packit 63bb0d
		if _, err := w.Write(s[last : i-width]); err != nil {
Packit 63bb0d
			return err
Packit 63bb0d
		}
Packit 63bb0d
		if _, err := w.Write(esc); err != nil {
Packit 63bb0d
			return err
Packit 63bb0d
		}
Packit 63bb0d
		last = i
Packit 63bb0d
	}
Packit 63bb0d
	_, err := w.Write(s[last:])
Packit 63bb0d
	return err
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// EscapeString writes to p the properly escaped XML equivalent
Packit 63bb0d
// of the plain text data s.
Packit 63bb0d
func (p *printer) EscapeString(s string) {
Packit 63bb0d
	var esc []byte
Packit 63bb0d
	last := 0
Packit 63bb0d
	for i := 0; i < len(s); {
Packit 63bb0d
		r, width := utf8.DecodeRuneInString(s[i:])
Packit 63bb0d
		i += width
Packit 63bb0d
		switch r {
Packit 63bb0d
		case '"':
Packit 63bb0d
			esc = escQuot
Packit 63bb0d
		case '\'':
Packit 63bb0d
			esc = escApos
Packit 63bb0d
		case '&':
Packit 63bb0d
			esc = escAmp
Packit 63bb0d
		case '<':
Packit 63bb0d
			esc = escLT
Packit 63bb0d
		case '>':
Packit 63bb0d
			esc = escGT
Packit 63bb0d
		case '\t':
Packit 63bb0d
			esc = escTab
Packit 63bb0d
		case '\n':
Packit 63bb0d
			esc = escNL
Packit 63bb0d
		case '\r':
Packit 63bb0d
			esc = escCR
Packit 63bb0d
		default:
Packit 63bb0d
			if !isInCharacterRange(r) || (r == 0xFFFD && width == 1) {
Packit 63bb0d
				esc = escFFFD
Packit 63bb0d
				break
Packit 63bb0d
			}
Packit 63bb0d
			continue
Packit 63bb0d
		}
Packit 63bb0d
		p.WriteString(s[last : i-width])
Packit 63bb0d
		p.Write(esc)
Packit 63bb0d
		last = i
Packit 63bb0d
	}
Packit 63bb0d
	p.WriteString(s[last:])
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// Escape is like EscapeText but omits the error return value.
Packit 63bb0d
// It is provided for backwards compatibility with Go 1.0.
Packit 63bb0d
// Code targeting Go 1.1 or later should use EscapeText.
Packit 63bb0d
func Escape(w io.Writer, s []byte) {
Packit 63bb0d
	EscapeText(w, s)
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
var (
Packit 63bb0d
	cdataStart  = []byte("
Packit 63bb0d
	cdataEnd    = []byte("]]>")
Packit 63bb0d
	cdataEscape = []byte("]]]]>")
Packit 63bb0d
)
Packit 63bb0d
Packit 63bb0d
// emitCDATA writes to w the CDATA-wrapped plain text data s.
Packit 63bb0d
// It escapes CDATA directives nested in s.
Packit 63bb0d
func emitCDATA(w io.Writer, s []byte) error {
Packit 63bb0d
	if len(s) == 0 {
Packit 63bb0d
		return nil
Packit 63bb0d
	}
Packit 63bb0d
	if _, err := w.Write(cdataStart); err != nil {
Packit 63bb0d
		return err
Packit 63bb0d
	}
Packit 63bb0d
	for {
Packit 63bb0d
		i := bytes.Index(s, cdataEnd)
Packit 63bb0d
		if i >= 0 && i+len(cdataEnd) <= len(s) {
Packit 63bb0d
			// Found a nested CDATA directive end.
Packit 63bb0d
			if _, err := w.Write(s[:i]); err != nil {
Packit 63bb0d
				return err
Packit 63bb0d
			}
Packit 63bb0d
			if _, err := w.Write(cdataEscape); err != nil {
Packit 63bb0d
				return err
Packit 63bb0d
			}
Packit 63bb0d
			i += len(cdataEnd)
Packit 63bb0d
		} else {
Packit 63bb0d
			if _, err := w.Write(s); err != nil {
Packit 63bb0d
				return err
Packit 63bb0d
			}
Packit 63bb0d
			break
Packit 63bb0d
		}
Packit 63bb0d
		s = s[i:]
Packit 63bb0d
	}
Packit 63bb0d
	_, err := w.Write(cdataEnd)
Packit 63bb0d
	return err
Packit 63bb0d
}
Packit 63bb0d
Packit 63bb0d
// procInst parses the `param="..."` or `param='...'`
Packit 63bb0d
// value out of the provided string, returning "" if not found.
Packit 63bb0d
func procInst(param, s string) string {
Packit 63bb0d
	// TODO: this parsing is somewhat lame and not exact.
Packit 63bb0d
	// It works for all actual cases, though.
Packit 63bb0d
	param = param + "="
Packit 63bb0d
	idx := strings.Index(s, param)
Packit 63bb0d
	if idx == -1 {
Packit 63bb0d
		return ""
Packit 63bb0d
	}
Packit 63bb0d
	v := s[idx+len(param):]
Packit 63bb0d
	if v == "" {
Packit 63bb0d
		return ""
Packit 63bb0d
	}
Packit 63bb0d
	if v[0] != '\'' && v[0] != '"' {
Packit 63bb0d
		return ""
Packit 63bb0d
	}
Packit 63bb0d
	idx = strings.IndexRune(v[1:], rune(v[0]))
Packit 63bb0d
	if idx == -1 {
Packit 63bb0d
		return ""
Packit 63bb0d
	}
Packit 63bb0d
	return v[1 : idx+1]
Packit 63bb0d
}