forked from kapmahc/stardict
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathifo.go
143 lines (112 loc) · 2.39 KB
/
ifo.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package stardict
import (
"bufio"
"errors"
"io"
"os"
"strconv"
"strings"
)
const (
I_bookname = "bookname"
I_wordcount = "wordcount"
I_description = "description"
I_idxfilesize = "idxfilesize"
I_sametypesequence = "sametypesequence"
I_idxoffsetbits = "idxoffsetbits"
)
// Info contains dictionary options
type Info struct {
Options map[string]string
Version string
Is64 bool
disabled bool
}
func (info Info) DictName() string {
return info.Options[I_bookname]
}
// EntryCount returns number of words in the dictionary
func (info Info) EntryCount() (int, error) {
num, err := strconv.ParseUint(info.Options[I_wordcount], 10, 64)
if err != nil {
return 0, err
}
return int(num), nil
}
func (info Info) Description() string {
return info.Options[I_description]
}
func (info Info) IndexFileSize() uint64 {
num, _ := strconv.ParseUint(info.Options[I_idxfilesize], 10, 64)
return num
}
func (info Info) MaxIdxBytes() int {
if info.Is64 {
return 8
}
return 4
}
func decodeOption(str string) (key string, value string, err error) {
a := strings.Split(str, "=")
if len(a) < 2 {
return "", "", errors.New("Invalid file format: " + str)
}
return a[0], a[1], nil
}
// ReadInfo reads ifo file and collects dictionary options
func ReadInfo(filename string) (info *Info, err error) {
reader, err := os.Open(filename)
if err != nil {
return
}
defer closeCloser(reader)
r := bufio.NewReader(reader)
_, err = r.ReadString('\n')
if err != nil {
return
}
version, err := r.ReadString('\n')
if err != nil {
return
}
key, value, err := decodeOption(version[:len(version)-1])
if err != nil {
return
}
if key != "version" {
err = errors.New("version missing (should be on second line)")
return
}
if value != "2.4.2" && value != "3.0.0" {
err = errors.New("stardict version should be either 2.4.2 or 3.0.0")
return
}
info = &Info{}
info.Version = value
info.Options = make(map[string]string)
for {
option, err := r.ReadString('\n')
if err != nil && err != io.EOF {
return info, err
}
if err == io.EOF && len(option) == 0 {
break
}
key, value, err = decodeOption(option[:len(option)-1])
if err != nil {
return info, err
}
info.Options[key] = value
if err == io.EOF {
break
}
}
if bits, ok := info.Options[I_idxoffsetbits]; ok {
if bits == "64" {
info.Is64 = true
}
} else {
info.Is64 = false
}
return
}