1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677 |
- // Copyright 2012 The Go Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package vcs
- import (
- "encoding/xml"
- "fmt"
- "io"
- "strings"
- )
- // charsetReader returns a reader for the given charset. Currently
- // it only supports UTF-8 and ASCII. Otherwise, it returns a meaningful
- // error which is printed by go get, so the user can find why the package
- // wasn't downloaded if the encoding is not supported. Note that, in
- // order to reduce potential errors, ASCII is treated as UTF-8 (i.e. characters
- // greater than 0x7f are not rejected).
- func charsetReader(charset string, input io.Reader) (io.Reader, error) {
- switch strings.ToLower(charset) {
- case "ascii":
- return input, nil
- default:
- return nil, fmt.Errorf("can't decode XML document using charset %q", charset)
- }
- }
- // parseMetaGoImports returns meta imports from the HTML in r.
- // Parsing ends at the end of the <head> section or the beginning of the <body>.
- func parseMetaGoImports(r io.Reader) (imports []metaImport, err error) {
- d := xml.NewDecoder(r)
- d.CharsetReader = charsetReader
- d.Strict = false
- var t xml.Token
- for {
- t, err = d.Token()
- if err != nil {
- if err == io.EOF || len(imports) > 0 {
- err = nil
- }
- return
- }
- if e, ok := t.(xml.StartElement); ok && strings.EqualFold(e.Name.Local, "body") {
- return
- }
- if e, ok := t.(xml.EndElement); ok && strings.EqualFold(e.Name.Local, "head") {
- return
- }
- e, ok := t.(xml.StartElement)
- if !ok || !strings.EqualFold(e.Name.Local, "meta") {
- continue
- }
- if attrValue(e.Attr, "name") != "go-import" {
- continue
- }
- if f := strings.Fields(attrValue(e.Attr, "content")); len(f) == 3 {
- imports = append(imports, metaImport{
- Prefix: f[0],
- VCS: f[1],
- RepoRoot: f[2],
- })
- }
- }
- }
- // attrValue returns the attribute value for the case-insensitive key
- // `name', or the empty string if nothing is found.
- func attrValue(attrs []xml.Attr, name string) string {
- for _, a := range attrs {
- if strings.EqualFold(a.Name.Local, name) {
- return a.Value
- }
- }
- return ""
- }
|