* Update makefile to use dep * Migrate to dep * Fix some deps * Try to find a better version for golang.org/x/net * Try to find a better version for golang.org/x/oauth2
		
			
				
	
	
		
			172 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2013 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 cldr
 | |
| 
 | |
| import (
 | |
| 	"archive/zip"
 | |
| 	"bytes"
 | |
| 	"encoding/xml"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"io/ioutil"
 | |
| 	"log"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"regexp"
 | |
| )
 | |
| 
 | |
| // A Decoder loads an archive of CLDR data.
 | |
| type Decoder struct {
 | |
| 	dirFilter     []string
 | |
| 	sectionFilter []string
 | |
| 	loader        Loader
 | |
| 	cldr          *CLDR
 | |
| 	curLocale     string
 | |
| }
 | |
| 
 | |
| // SetSectionFilter takes a list top-level LDML element names to which
 | |
| // evaluation of LDML should be limited.  It automatically calls SetDirFilter.
 | |
| func (d *Decoder) SetSectionFilter(filter ...string) {
 | |
| 	d.sectionFilter = filter
 | |
| 	// TODO: automatically set dir filter
 | |
| }
 | |
| 
 | |
| // SetDirFilter limits the loading of LDML XML files of the specied directories.
 | |
| // Note that sections may be split across directories differently for different CLDR versions.
 | |
| // For more robust code, use SetSectionFilter.
 | |
| func (d *Decoder) SetDirFilter(dir ...string) {
 | |
| 	d.dirFilter = dir
 | |
| }
 | |
| 
 | |
| // A Loader provides access to the files of a CLDR archive.
 | |
| type Loader interface {
 | |
| 	Len() int
 | |
| 	Path(i int) string
 | |
| 	Reader(i int) (io.ReadCloser, error)
 | |
| }
 | |
| 
 | |
| var fileRe = regexp.MustCompile(".*/(.*)/(.*)\\.xml")
 | |
| 
 | |
| // Decode loads and decodes the files represented by l.
 | |
| func (d *Decoder) Decode(l Loader) (cldr *CLDR, err error) {
 | |
| 	d.cldr = makeCLDR()
 | |
| 	for i := 0; i < l.Len(); i++ {
 | |
| 		fname := l.Path(i)
 | |
| 		if m := fileRe.FindStringSubmatch(fname); m != nil {
 | |
| 			if len(d.dirFilter) > 0 && !in(d.dirFilter, m[1]) {
 | |
| 				continue
 | |
| 			}
 | |
| 			var r io.Reader
 | |
| 			if r, err = l.Reader(i); err == nil {
 | |
| 				err = d.decode(m[1], m[2], r)
 | |
| 			}
 | |
| 			if err != nil {
 | |
| 				return nil, err
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	d.cldr.finalize(d.sectionFilter)
 | |
| 	return d.cldr, nil
 | |
| }
 | |
| 
 | |
| func (d *Decoder) decode(dir, id string, r io.Reader) error {
 | |
| 	var v interface{}
 | |
| 	var l *LDML
 | |
| 	cldr := d.cldr
 | |
| 	switch {
 | |
| 	case dir == "supplemental":
 | |
| 		v = cldr.supp
 | |
| 	case dir == "transforms":
 | |
| 		return nil
 | |
| 	case dir == "bcp47":
 | |
| 		v = cldr.bcp47
 | |
| 	case dir == "validity":
 | |
| 		return nil
 | |
| 	default:
 | |
| 		ok := false
 | |
| 		if v, ok = cldr.locale[id]; !ok {
 | |
| 			l = &LDML{}
 | |
| 			v, cldr.locale[id] = l, l
 | |
| 		}
 | |
| 	}
 | |
| 	x := xml.NewDecoder(r)
 | |
| 	if err := x.Decode(v); err != nil {
 | |
| 		log.Printf("%s/%s: %v", dir, id, err)
 | |
| 		return err
 | |
| 	}
 | |
| 	if l != nil {
 | |
| 		if l.Identity == nil {
 | |
| 			return fmt.Errorf("%s/%s: missing identity element", dir, id)
 | |
| 		}
 | |
| 		// TODO: verify when CLDR bug http://unicode.org/cldr/trac/ticket/8970
 | |
| 		// is resolved.
 | |
| 		// path := strings.Split(id, "_")
 | |
| 		// if lang := l.Identity.Language.Type; lang != path[0] {
 | |
| 		// 	return fmt.Errorf("%s/%s: language was %s; want %s", dir, id, lang, path[0])
 | |
| 		// }
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| type pathLoader []string
 | |
| 
 | |
| func makePathLoader(path string) (pl pathLoader, err error) {
 | |
| 	err = filepath.Walk(path, func(path string, _ os.FileInfo, err error) error {
 | |
| 		pl = append(pl, path)
 | |
| 		return err
 | |
| 	})
 | |
| 	return pl, err
 | |
| }
 | |
| 
 | |
| func (pl pathLoader) Len() int {
 | |
| 	return len(pl)
 | |
| }
 | |
| 
 | |
| func (pl pathLoader) Path(i int) string {
 | |
| 	return pl[i]
 | |
| }
 | |
| 
 | |
| func (pl pathLoader) Reader(i int) (io.ReadCloser, error) {
 | |
| 	return os.Open(pl[i])
 | |
| }
 | |
| 
 | |
| // DecodePath loads CLDR data from the given path.
 | |
| func (d *Decoder) DecodePath(path string) (cldr *CLDR, err error) {
 | |
| 	loader, err := makePathLoader(path)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return d.Decode(loader)
 | |
| }
 | |
| 
 | |
| type zipLoader struct {
 | |
| 	r *zip.Reader
 | |
| }
 | |
| 
 | |
| func (zl zipLoader) Len() int {
 | |
| 	return len(zl.r.File)
 | |
| }
 | |
| 
 | |
| func (zl zipLoader) Path(i int) string {
 | |
| 	return zl.r.File[i].Name
 | |
| }
 | |
| 
 | |
| func (zl zipLoader) Reader(i int) (io.ReadCloser, error) {
 | |
| 	return zl.r.File[i].Open()
 | |
| }
 | |
| 
 | |
| // DecodeZip loads CLDR data from the zip archive for which r is the source.
 | |
| func (d *Decoder) DecodeZip(r io.Reader) (cldr *CLDR, err error) {
 | |
| 	buffer, err := ioutil.ReadAll(r)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	archive, err := zip.NewReader(bytes.NewReader(buffer), int64(len(buffer)))
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return d.Decode(zipLoader{archive})
 | |
| }
 |