~juju-qa/ubuntu/xenial/juju/xenial-2.0-beta3

« back to all changes in this revision

Viewing changes to src/github.com/chai2010/gettext-go/gettext/fs.go

  • Committer: Martin Packman
  • Date: 2016-03-30 19:31:08 UTC
  • mfrom: (1.1.41)
  • Revision ID: martin.packman@canonical.com-20160330193108-h9iz3ak334uk0z5r
Merge new upstream source 2.0~beta3

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2013 ChaiShushan <chaishushan{AT}gmail.com>. All rights reserved.
2
 
// Use of this source code is governed by a BSD-style
3
 
// license that can be found in the LICENSE file.
4
 
 
5
 
package gettext
6
 
 
7
 
import (
8
 
        "archive/zip"
9
 
        "bytes"
10
 
        "fmt"
11
 
        "io/ioutil"
12
 
        "log"
13
 
        "os"
14
 
        "strings"
15
 
)
16
 
 
17
 
type fileSystem struct {
18
 
        FsName    string
19
 
        FsRoot    string
20
 
        FsZipData []byte
21
 
        LocaleMap map[string]bool
22
 
}
23
 
 
24
 
func newFileSystem(path string, data []byte) *fileSystem {
25
 
        fs := &fileSystem{
26
 
                FsName:    path,
27
 
                FsZipData: data,
28
 
        }
29
 
        if err := fs.init(); err != nil {
30
 
                log.Printf("gettext-go: invalid domain, err = %v", err)
31
 
        }
32
 
        return fs
33
 
}
34
 
 
35
 
func (p *fileSystem) init() error {
36
 
        zipName := func(name string) string {
37
 
                if x := strings.LastIndexAny(name, `\/`); x != -1 {
38
 
                        name = name[x+1:]
39
 
                }
40
 
                name = strings.TrimSuffix(name, ".zip")
41
 
                return name
42
 
        }
43
 
 
44
 
        // zip data
45
 
        if len(p.FsZipData) != 0 {
46
 
                p.FsRoot = zipName(p.FsName)
47
 
                p.LocaleMap = p.lsZip(p.FsZipData)
48
 
                return nil
49
 
        }
50
 
 
51
 
        // local dir or zip file
52
 
        fi, err := os.Stat(p.FsName)
53
 
        if err != nil {
54
 
                return err
55
 
        }
56
 
 
57
 
        // local dir
58
 
        if fi.IsDir() {
59
 
                p.FsRoot = p.FsName
60
 
                p.LocaleMap = p.lsDir(p.FsName)
61
 
                return nil
62
 
        }
63
 
 
64
 
        // local zip file
65
 
        p.FsZipData, err = ioutil.ReadFile(p.FsName)
66
 
        if err != nil {
67
 
                return err
68
 
        }
69
 
        p.FsRoot = zipName(p.FsName)
70
 
        p.LocaleMap = p.lsZip(p.FsZipData)
71
 
        return nil
72
 
}
73
 
 
74
 
func (p *fileSystem) LoadMessagesFile(domain, local, ext string) ([]byte, error) {
75
 
        if len(p.FsZipData) == 0 {
76
 
                trName := p.makeMessagesFileName(domain, local, ext)
77
 
                rcData, err := ioutil.ReadFile(trName)
78
 
                if err != nil {
79
 
                        return nil, err
80
 
                }
81
 
                return rcData, nil
82
 
        } else {
83
 
                r, err := zip.NewReader(bytes.NewReader(p.FsZipData), int64(len(p.FsZipData)))
84
 
                if err != nil {
85
 
                        return nil, err
86
 
                }
87
 
 
88
 
                trName := p.makeMessagesFileName(domain, local, ext)
89
 
                for _, f := range r.File {
90
 
                        if f.Name != trName {
91
 
                                continue
92
 
                        }
93
 
                        rc, err := f.Open()
94
 
                        if err != nil {
95
 
                                return nil, err
96
 
                        }
97
 
                        rcData, err := ioutil.ReadAll(rc)
98
 
                        rc.Close()
99
 
                        return rcData, err
100
 
                }
101
 
                return nil, fmt.Errorf("not found")
102
 
        }
103
 
}
104
 
 
105
 
func (p *fileSystem) LoadResourceFile(domain, local, name string) ([]byte, error) {
106
 
        if len(p.FsZipData) == 0 {
107
 
                rcName := p.makeResourceFileName(domain, local, name)
108
 
                rcData, err := ioutil.ReadFile(rcName)
109
 
                if err != nil {
110
 
                        return nil, err
111
 
                }
112
 
                return rcData, nil
113
 
        } else {
114
 
                r, err := zip.NewReader(bytes.NewReader(p.FsZipData), int64(len(p.FsZipData)))
115
 
                if err != nil {
116
 
                        return nil, err
117
 
                }
118
 
 
119
 
                rcName := p.makeResourceFileName(domain, local, name)
120
 
                for _, f := range r.File {
121
 
                        if f.Name != rcName {
122
 
                                continue
123
 
                        }
124
 
                        rc, err := f.Open()
125
 
                        if err != nil {
126
 
                                return nil, err
127
 
                        }
128
 
                        rcData, err := ioutil.ReadAll(rc)
129
 
                        rc.Close()
130
 
                        return rcData, err
131
 
                }
132
 
                return nil, fmt.Errorf("not found")
133
 
        }
134
 
}
135
 
 
136
 
func (p *fileSystem) makeMessagesFileName(domain, local, ext string) string {
137
 
        return fmt.Sprintf("%s/%s/LC_MESSAGES/%s%s", p.FsRoot, local, domain, ext)
138
 
}
139
 
 
140
 
func (p *fileSystem) makeResourceFileName(domain, local, name string) string {
141
 
        return fmt.Sprintf("%s/%s/LC_RESOURCE/%s/%s", p.FsRoot, local, domain, name)
142
 
}
143
 
 
144
 
func (p *fileSystem) lsZip(data []byte) map[string]bool {
145
 
        r, err := zip.NewReader(bytes.NewReader(data), int64(len(data)))
146
 
        if err != nil {
147
 
                return nil
148
 
        }
149
 
        ssMap := make(map[string]bool)
150
 
        for _, f := range r.File {
151
 
                if x := strings.Index(f.Name, "LC_MESSAGES"); x != -1 {
152
 
                        s := strings.TrimRight(f.Name[:x], `\/`)
153
 
                        if x = strings.LastIndexAny(s, `\/`); x != -1 {
154
 
                                s = s[x+1:]
155
 
                        }
156
 
                        if s != "" {
157
 
                                ssMap[s] = true
158
 
                        }
159
 
                        continue
160
 
                }
161
 
                if x := strings.Index(f.Name, "LC_RESOURCE"); x != -1 {
162
 
                        s := strings.TrimRight(f.Name[:x], `\/`)
163
 
                        if x = strings.LastIndexAny(s, `\/`); x != -1 {
164
 
                                s = s[x+1:]
165
 
                        }
166
 
                        if s != "" {
167
 
                                ssMap[s] = true
168
 
                        }
169
 
                        continue
170
 
                }
171
 
        }
172
 
        return ssMap
173
 
}
174
 
 
175
 
func (p *fileSystem) lsDir(path string) map[string]bool {
176
 
        list, err := ioutil.ReadDir(path)
177
 
        if err != nil {
178
 
                return nil
179
 
        }
180
 
        ssMap := make(map[string]bool)
181
 
        for _, dir := range list {
182
 
                if dir.IsDir() {
183
 
                        ssMap[dir.Name()] = true
184
 
                }
185
 
        }
186
 
        return ssMap
187
 
}