123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- // Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package gettext
- import (
- "archive/zip"
- "bytes"
- "fmt"
- "io/ioutil"
- "log"
- "os"
- "strings"
- )
- type fileSystem struct {
- FsName string
- FsRoot string
- FsZipData []byte
- LocaleMap map[string]bool
- }
- func newFileSystem(path string, data []byte) *fileSystem {
- fs := &fileSystem{
- FsName: path,
- FsZipData: data,
- }
- if err := fs.init(); err != nil {
- log.Printf("gettext-go: invalid domain, err = %v", err)
- }
- return fs
- }
- func (p *fileSystem) init() error {
- zipName := func(name string) string {
- if x := strings.LastIndexAny(name, `\/`); x != -1 {
- name = name[x+1:]
- }
- name = strings.TrimSuffix(name, ".zip")
- return name
- }
- // zip data
- if len(p.FsZipData) != 0 {
- p.FsRoot = zipName(p.FsName)
- p.LocaleMap = p.lsZip(p.FsZipData)
- return nil
- }
- // local dir or zip file
- fi, err := os.Stat(p.FsName)
- if err != nil {
- return err
- }
- // local dir
- if fi.IsDir() {
- p.FsRoot = p.FsName
- p.LocaleMap = p.lsDir(p.FsName)
- return nil
- }
- // local zip file
- p.FsZipData, err = ioutil.ReadFile(p.FsName)
- if err != nil {
- return err
- }
- p.FsRoot = zipName(p.FsName)
- p.LocaleMap = p.lsZip(p.FsZipData)
- return nil
- }
- func (p *fileSystem) LoadMessagesFile(domain, local, ext string) ([]byte, error) {
- if len(p.FsZipData) == 0 {
- trName := p.makeMessagesFileName(domain, local, ext)
- rcData, err := ioutil.ReadFile(trName)
- if err != nil {
- return nil, err
- }
- return rcData, nil
- } else {
- r, err := zip.NewReader(bytes.NewReader(p.FsZipData), int64(len(p.FsZipData)))
- if err != nil {
- return nil, err
- }
- trName := p.makeMessagesFileName(domain, local, ext)
- for _, f := range r.File {
- if f.Name != trName {
- continue
- }
- rc, err := f.Open()
- if err != nil {
- return nil, err
- }
- rcData, err := ioutil.ReadAll(rc)
- rc.Close()
- return rcData, err
- }
- return nil, fmt.Errorf("not found")
- }
- }
- func (p *fileSystem) LoadResourceFile(domain, local, name string) ([]byte, error) {
- if len(p.FsZipData) == 0 {
- rcName := p.makeResourceFileName(domain, local, name)
- rcData, err := ioutil.ReadFile(rcName)
- if err != nil {
- return nil, err
- }
- return rcData, nil
- } else {
- r, err := zip.NewReader(bytes.NewReader(p.FsZipData), int64(len(p.FsZipData)))
- if err != nil {
- return nil, err
- }
- rcName := p.makeResourceFileName(domain, local, name)
- for _, f := range r.File {
- if f.Name != rcName {
- continue
- }
- rc, err := f.Open()
- if err != nil {
- return nil, err
- }
- rcData, err := ioutil.ReadAll(rc)
- rc.Close()
- return rcData, err
- }
- return nil, fmt.Errorf("not found")
- }
- }
- func (p *fileSystem) makeMessagesFileName(domain, local, ext string) string {
- return fmt.Sprintf("%s/%s/LC_MESSAGES/%s%s", p.FsRoot, local, domain, ext)
- }
- func (p *fileSystem) makeResourceFileName(domain, local, name string) string {
- return fmt.Sprintf("%s/%s/LC_RESOURCE/%s/%s", p.FsRoot, local, domain, name)
- }
- func (p *fileSystem) lsZip(data []byte) map[string]bool {
- r, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
- if err != nil {
- return nil
- }
- ssMap := make(map[string]bool)
- for _, f := range r.File {
- if x := strings.Index(f.Name, "LC_MESSAGES"); x != -1 {
- s := strings.TrimRight(f.Name[:x], `\/`)
- if x = strings.LastIndexAny(s, `\/`); x != -1 {
- s = s[x+1:]
- }
- if s != "" {
- ssMap[s] = true
- }
- continue
- }
- if x := strings.Index(f.Name, "LC_RESOURCE"); x != -1 {
- s := strings.TrimRight(f.Name[:x], `\/`)
- if x = strings.LastIndexAny(s, `\/`); x != -1 {
- s = s[x+1:]
- }
- if s != "" {
- ssMap[s] = true
- }
- continue
- }
- }
- return ssMap
- }
- func (p *fileSystem) lsDir(path string) map[string]bool {
- list, err := ioutil.ReadDir(path)
- if err != nil {
- return nil
- }
- ssMap := make(map[string]bool)
- for _, dir := range list {
- if dir.IsDir() {
- ssMap[dir.Name()] = true
- }
- }
- return ssMap
- }
|