grosser-fast_gettext 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -58,13 +58,12 @@ then e.g. controllers, so set them inside your application_controller.
58
58
  ...
59
59
 
60
60
  #application_controller.rb
61
- FastGettext.available_locales = ['de','en',...]
62
- FastGettext.text_domain = 'frontend'
63
-
64
61
  class ApplicationController ...
65
62
  include FastGettext
66
63
  before_filter :set_locale
67
64
  def set_locale
65
+ FastGettext.available_locales = ['de','en',...]
66
+ FastGettext.text_domain = 'frontend'
68
67
  sessions[:locale] = I18n.locale = FastGettext.locale = params[:locale] || sessions[:locale] || 'en'
69
68
  end
70
69
 
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :minor: 2
3
- :patch: 2
3
+ :patch: 3
4
4
  :major: 0
@@ -4,7 +4,7 @@ module FastGettext
4
4
  PLURAL_SEPERATOR = "\000"
5
5
 
6
6
  def initialize(file)
7
- @data = GetText::MOFile.open(file, "UTF-8")
7
+ @data = FastGettext::GetText::MOFile.open(file, "UTF-8")
8
8
  make_singular_and_plural_available
9
9
  end
10
10
 
data/vendor/mofile.rb CHANGED
@@ -18,273 +18,275 @@
18
18
  require 'iconv'
19
19
  require 'stringio'
20
20
 
21
- module GetText
22
- class MOFile < Hash
23
- class InvalidFormat < RuntimeError; end;
24
-
25
- attr_reader :filename
26
-
27
- Header = Struct.new(:magic,
28
- :revision,
29
- :nstrings,
30
- :orig_table_offset,
31
- :translated_table_offset,
32
- :hash_table_size,
33
- :hash_table_offset)
34
-
35
- # The following are only used in .mo files
36
- # with minor revision >= 1.
37
- class HeaderRev1 < Header
38
- attr_accessor :n_sysdep_segments,
39
- :sysdep_segments_offset,
40
- :n_sysdep_strings,
41
- :orig_sysdep_tab_offset,
42
- :trans_sysdep_tab_offset
43
- end
44
-
45
- MAGIC_BIG_ENDIAN = "\x95\x04\x12\xde"
46
- MAGIC_LITTLE_ENDIAN = "\xde\x12\x04\x95"
21
+ module FastGettext
22
+ module GetText
23
+ class MOFile < Hash
24
+ class InvalidFormat < RuntimeError; end;
25
+
26
+ attr_reader :filename
27
+
28
+ Header = Struct.new(:magic,
29
+ :revision,
30
+ :nstrings,
31
+ :orig_table_offset,
32
+ :translated_table_offset,
33
+ :hash_table_size,
34
+ :hash_table_offset)
35
+
36
+ # The following are only used in .mo files
37
+ # with minor revision >= 1.
38
+ class HeaderRev1 < Header
39
+ attr_accessor :n_sysdep_segments,
40
+ :sysdep_segments_offset,
41
+ :n_sysdep_strings,
42
+ :orig_sysdep_tab_offset,
43
+ :trans_sysdep_tab_offset
44
+ end
47
45
 
48
- def self.open(arg = nil, output_charset = nil)
49
- result = self.new(output_charset)
50
- result.load(arg)
51
- end
46
+ MAGIC_BIG_ENDIAN = "\x95\x04\x12\xde"
47
+ MAGIC_LITTLE_ENDIAN = "\xde\x12\x04\x95"
52
48
 
53
- def initialize(output_charset = nil)
54
- @filename = nil
55
- @last_modified = nil
56
- @little_endian = true
57
- @output_charset = output_charset
58
- super()
59
- end
49
+ def self.open(arg = nil, output_charset = nil)
50
+ result = self.new(output_charset)
51
+ result.load(arg)
52
+ end
60
53
 
61
- def update!
62
- if FileTest.exist?(@filename)
63
- st = File.stat(@filename)
64
- load(@filename) unless (@last_modified == [st.ctime, st.mtime])
65
- else
66
- warn "#{@filename} was lost." if $DEBUG
67
- clear
54
+ def initialize(output_charset = nil)
55
+ @filename = nil
56
+ @last_modified = nil
57
+ @little_endian = true
58
+ @output_charset = output_charset
59
+ super()
68
60
  end
69
- self
70
- end
71
61
 
72
- def load(arg)
73
- if arg.kind_of? String
74
- begin
75
- st = File.stat(arg)
76
- @last_modified = [st.ctime, st.mtime]
77
- rescue Exception
62
+ def update!
63
+ if FileTest.exist?(@filename)
64
+ st = File.stat(@filename)
65
+ load(@filename) unless (@last_modified == [st.ctime, st.mtime])
66
+ else
67
+ warn "#{@filename} was lost." if $DEBUG
68
+ clear
78
69
  end
79
- load_from_file(arg)
80
- else
81
- load_from_stream(arg)
70
+ self
82
71
  end
83
- @filename = arg
84
- self
85
- end
86
72
 
87
- def load_from_stream(io)
88
- magic = io.read(4)
89
- case magic
90
- when MAGIC_BIG_ENDIAN
91
- @little_endian = false
92
- when MAGIC_LITTLE_ENDIAN
93
- @little_endian = true
94
- else
95
- raise InvalidFormat.new(sprintf("Unknown signature %s", magic.dump))
73
+ def load(arg)
74
+ if arg.kind_of? String
75
+ begin
76
+ st = File.stat(arg)
77
+ @last_modified = [st.ctime, st.mtime]
78
+ rescue Exception
79
+ end
80
+ load_from_file(arg)
81
+ else
82
+ load_from_stream(arg)
83
+ end
84
+ @filename = arg
85
+ self
96
86
  end
97
87
 
98
- endian_type6 = @little_endian ? 'V6' : 'N6'
99
- endian_type_astr = @little_endian ? 'V*' : 'N*'
88
+ def load_from_stream(io)
89
+ magic = io.read(4)
90
+ case magic
91
+ when MAGIC_BIG_ENDIAN
92
+ @little_endian = false
93
+ when MAGIC_LITTLE_ENDIAN
94
+ @little_endian = true
95
+ else
96
+ raise InvalidFormat.new(sprintf("Unknown signature %s", magic.dump))
97
+ end
100
98
 
101
- header = HeaderRev1.new(magic, *(io.read(4 * 6).unpack(endian_type6)))
99
+ endian_type6 = @little_endian ? 'V6' : 'N6'
100
+ endian_type_astr = @little_endian ? 'V*' : 'N*'
102
101
 
103
- if header.revision == 1
104
- # FIXME: It doesn't support sysdep correctly.
105
- header.n_sysdep_segments = io.read(4).unpack(endian_type6)
106
- header.sysdep_segments_offset = io.read(4).unpack(endian_type6)
107
- header.n_sysdep_strings = io.read(4).unpack(endian_type6)
108
- header.orig_sysdep_tab_offset = io.read(4).unpack(endian_type6)
109
- header.trans_sysdep_tab_offset = io.read(4).unpack(endian_type6)
110
- elsif header.revision > 1
111
- raise InvalidFormat.new(sprintf("file format revision %d isn't supported", header.revision))
112
- end
113
- io.pos = header.orig_table_offset
114
- orig_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
102
+ header = HeaderRev1.new(magic, *(io.read(4 * 6).unpack(endian_type6)))
115
103
 
116
- io.pos = header.translated_table_offset
117
- trans_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
104
+ if header.revision == 1
105
+ # FIXME: It doesn't support sysdep correctly.
106
+ header.n_sysdep_segments = io.read(4).unpack(endian_type6)
107
+ header.sysdep_segments_offset = io.read(4).unpack(endian_type6)
108
+ header.n_sysdep_strings = io.read(4).unpack(endian_type6)
109
+ header.orig_sysdep_tab_offset = io.read(4).unpack(endian_type6)
110
+ header.trans_sysdep_tab_offset = io.read(4).unpack(endian_type6)
111
+ elsif header.revision > 1
112
+ raise InvalidFormat.new(sprintf("file format revision %d isn't supported", header.revision))
113
+ end
114
+ io.pos = header.orig_table_offset
115
+ orig_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
118
116
 
119
- original_strings = Array.new(header.nstrings)
120
- for i in 0...header.nstrings
121
- io.pos = orig_table_data[i * 2 + 1]
122
- original_strings[i] = io.read(orig_table_data[i * 2 + 0])
123
- end
117
+ io.pos = header.translated_table_offset
118
+ trans_table_data = io.read((4 * 2) * header.nstrings).unpack(endian_type_astr)
124
119
 
125
- clear
126
- for i in 0...header.nstrings
127
- io.pos = trans_table_data[i * 2 + 1]
128
- str = io.read(trans_table_data[i * 2 + 0])
129
-
130
- if (! original_strings[i]) || original_strings[i] == ""
131
- if str
132
- @charset = nil
133
- @nplurals = nil
134
- @plural = nil
135
- str.each_line{|line|
136
- if /^Content-Type:/i =~ line and /charset=((?:\w|-)+)/i =~ line
137
- @charset = $1
138
- elsif /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line
139
- @nplurals = $1
140
- @plural = $2
141
- end
142
- break if @charset and @nplurals
143
- }
144
- @nplurals = "1" unless @nplurals
145
- @plural = "0" unless @plural
146
- end
147
- else
148
- if @output_charset
149
- begin
150
- str = Iconv.conv(@output_charset, @charset, str) if @charset
151
- rescue Iconv::Failure
152
- if $DEBUG
153
- warn "@charset = ", @charset
154
- warn"@output_charset = ", @output_charset
155
- warn "msgid = ", original_strings[i]
156
- warn "msgstr = ", str
120
+ original_strings = Array.new(header.nstrings)
121
+ for i in 0...header.nstrings
122
+ io.pos = orig_table_data[i * 2 + 1]
123
+ original_strings[i] = io.read(orig_table_data[i * 2 + 0])
124
+ end
125
+
126
+ clear
127
+ for i in 0...header.nstrings
128
+ io.pos = trans_table_data[i * 2 + 1]
129
+ str = io.read(trans_table_data[i * 2 + 0])
130
+
131
+ if (! original_strings[i]) || original_strings[i] == ""
132
+ if str
133
+ @charset = nil
134
+ @nplurals = nil
135
+ @plural = nil
136
+ str.each_line{|line|
137
+ if /^Content-Type:/i =~ line and /charset=((?:\w|-)+)/i =~ line
138
+ @charset = $1
139
+ elsif /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line
140
+ @nplurals = $1
141
+ @plural = $2
142
+ end
143
+ break if @charset and @nplurals
144
+ }
145
+ @nplurals = "1" unless @nplurals
146
+ @plural = "0" unless @plural
147
+ end
148
+ else
149
+ if @output_charset
150
+ begin
151
+ str = Iconv.conv(@output_charset, @charset, str) if @charset
152
+ rescue Iconv::Failure
153
+ if $DEBUG
154
+ warn "@charset = ", @charset
155
+ warn"@output_charset = ", @output_charset
156
+ warn "msgid = ", original_strings[i]
157
+ warn "msgstr = ", str
158
+ end
157
159
  end
158
160
  end
159
161
  end
162
+ self[original_strings[i]] = str.freeze
160
163
  end
161
- self[original_strings[i]] = str.freeze
164
+ self
162
165
  end
163
- self
164
- end
165
166
 
166
- # Is this number a prime number ?
167
- # http://apidock.com/ruby/Prime
168
- def prime?(number)
169
- ('1' * number) !~ /^1?$|^(11+?)\1+$/
170
- end
171
-
172
- def next_prime(seed)
173
- require 'mathn'
174
- prime = Prime.new
175
- while current = prime.succ
176
- return current if current > seed
167
+ # Is this number a prime number ?
168
+ # http://apidock.com/ruby/Prime
169
+ def prime?(number)
170
+ ('1' * number) !~ /^1?$|^(11+?)\1+$/
177
171
  end
178
- end
179
172
 
180
- # From gettext-0.12.1/gettext-runtime/intl/hash-string.h
181
- # Defines the so called `hashpjw' function by P.J. Weinberger
182
- # [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
183
- # 1986, 1987 Bell Telephone Laboratories, Inc.]
184
- HASHWORDBITS = 32
185
- def hash_string(str)
186
- hval = 0
187
- i = 0
188
- str.each_byte do |b|
189
- break if b == '\0'
190
- hval <<= 4
191
- hval += b.to_i
192
- g = hval & (0xf << (HASHWORDBITS - 4))
193
- if (g != 0)
194
- hval ^= g >> (HASHWORDBITS - 8)
195
- hval ^= g
173
+ def next_prime(seed)
174
+ require 'mathn'
175
+ prime = Prime.new
176
+ while current = prime.succ
177
+ return current if current > seed
196
178
  end
197
179
  end
198
- hval
199
- end
200
180
 
201
- def save_to_stream(io)
202
- #Save data as little endian format.
203
- header_size = 4 * 7
204
- table_size = 4 * 2 * size
205
-
206
- hash_table_size = next_prime((size * 4) / 3)
207
- hash_table_size = 3 if hash_table_size <= 2
208
- header = Header.new(
209
- MAGIC_LITTLE_ENDIAN, # magic
210
- 0, # revision
211
- size, # nstrings
212
- header_size, # orig_table_offset
213
- header_size + table_size, # translated_table_offset
214
- hash_table_size, # hash_table_size
215
- header_size + table_size * 2 # hash_table_offset
216
- )
217
- io.write(header.to_a.pack('a4V*'))
218
-
219
- ary = to_a
220
- ary.sort!{|a, b| a[0] <=> b[0]} # sort by original string
221
-
222
- pos = header.hash_table_size * 4 + header.hash_table_offset
223
-
224
- orig_table_data = Array.new()
225
- ary.each{|item, _|
226
- orig_table_data.push(item.size)
227
- orig_table_data.push(pos)
228
- pos += item.size + 1 # +1 is <NUL>
229
- }
230
- io.write(orig_table_data.pack('V*'))
231
-
232
- trans_table_data = Array.new()
233
- ary.each{|_, item|
234
- trans_table_data.push(item.size)
235
- trans_table_data.push(pos)
236
- pos += item.size + 1 # +1 is <NUL>
237
- }
238
- io.write(trans_table_data.pack('V*'))
239
-
240
- hash_tab = Array.new(hash_table_size)
241
- j = 0
242
- ary[0...size].each {|key, _|
243
- hash_val = hash_string(key)
244
- idx = hash_val % hash_table_size
245
- if hash_tab[idx] != nil
246
- incr = 1 + (hash_val % (hash_table_size - 2))
247
- begin
248
- if (idx >= hash_table_size - incr)
249
- idx -= hash_table_size - incr
250
- else
251
- idx += incr
252
- end
253
- end until (hash_tab[idx] == nil)
181
+ # From gettext-0.12.1/gettext-runtime/intl/hash-string.h
182
+ # Defines the so called `hashpjw' function by P.J. Weinberger
183
+ # [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
184
+ # 1986, 1987 Bell Telephone Laboratories, Inc.]
185
+ HASHWORDBITS = 32
186
+ def hash_string(str)
187
+ hval = 0
188
+ i = 0
189
+ str.each_byte do |b|
190
+ break if b == '\0'
191
+ hval <<= 4
192
+ hval += b.to_i
193
+ g = hval & (0xf << (HASHWORDBITS - 4))
194
+ if (g != 0)
195
+ hval ^= g >> (HASHWORDBITS - 8)
196
+ hval ^= g
197
+ end
254
198
  end
255
- hash_tab[idx] = j + 1
256
- j += 1
257
- }
258
- hash_tab.collect!{|i| i ? i : 0}
199
+ hval
200
+ end
201
+
202
+ def save_to_stream(io)
203
+ #Save data as little endian format.
204
+ header_size = 4 * 7
205
+ table_size = 4 * 2 * size
206
+
207
+ hash_table_size = next_prime((size * 4) / 3)
208
+ hash_table_size = 3 if hash_table_size <= 2
209
+ header = Header.new(
210
+ MAGIC_LITTLE_ENDIAN, # magic
211
+ 0, # revision
212
+ size, # nstrings
213
+ header_size, # orig_table_offset
214
+ header_size + table_size, # translated_table_offset
215
+ hash_table_size, # hash_table_size
216
+ header_size + table_size * 2 # hash_table_offset
217
+ )
218
+ io.write(header.to_a.pack('a4V*'))
219
+
220
+ ary = to_a
221
+ ary.sort!{|a, b| a[0] <=> b[0]} # sort by original string
222
+
223
+ pos = header.hash_table_size * 4 + header.hash_table_offset
224
+
225
+ orig_table_data = Array.new()
226
+ ary.each{|item, _|
227
+ orig_table_data.push(item.size)
228
+ orig_table_data.push(pos)
229
+ pos += item.size + 1 # +1 is <NUL>
230
+ }
231
+ io.write(orig_table_data.pack('V*'))
232
+
233
+ trans_table_data = Array.new()
234
+ ary.each{|_, item|
235
+ trans_table_data.push(item.size)
236
+ trans_table_data.push(pos)
237
+ pos += item.size + 1 # +1 is <NUL>
238
+ }
239
+ io.write(trans_table_data.pack('V*'))
240
+
241
+ hash_tab = Array.new(hash_table_size)
242
+ j = 0
243
+ ary[0...size].each {|key, _|
244
+ hash_val = hash_string(key)
245
+ idx = hash_val % hash_table_size
246
+ if hash_tab[idx] != nil
247
+ incr = 1 + (hash_val % (hash_table_size - 2))
248
+ begin
249
+ if (idx >= hash_table_size - incr)
250
+ idx -= hash_table_size - incr
251
+ else
252
+ idx += incr
253
+ end
254
+ end until (hash_tab[idx] == nil)
255
+ end
256
+ hash_tab[idx] = j + 1
257
+ j += 1
258
+ }
259
+ hash_tab.collect!{|i| i ? i : 0}
259
260
 
260
- io.write(hash_tab.pack('V*'))
261
+ io.write(hash_tab.pack('V*'))
261
262
 
262
- ary.each{|item, _| io.write(item); io.write("\0") }
263
- ary.each{|_, item| io.write(item); io.write("\0") }
263
+ ary.each{|item, _| io.write(item); io.write("\0") }
264
+ ary.each{|_, item| io.write(item); io.write("\0") }
264
265
 
265
- self
266
- end
266
+ self
267
+ end
267
268
 
268
- def load_from_file(filename)
269
- @filename = filename
270
- begin
271
- File.open(filename, 'rb'){|f| load_from_stream(f)}
272
- rescue => e
273
- e.set_backtrace("File: #{@filename}")
274
- raise e
269
+ def load_from_file(filename)
270
+ @filename = filename
271
+ begin
272
+ File.open(filename, 'rb'){|f| load_from_stream(f)}
273
+ rescue => e
274
+ e.set_backtrace("File: #{@filename}")
275
+ raise e
276
+ end
275
277
  end
276
- end
277
278
 
278
- def save_to_file(filename)
279
- File.open(filename, 'wb'){|f| save_to_stream(f)}
280
- end
279
+ def save_to_file(filename)
280
+ File.open(filename, 'wb'){|f| save_to_stream(f)}
281
+ end
281
282
 
282
- def set_comment(msgid_or_sym, comment)
283
- #Do nothing
284
- end
283
+ def set_comment(msgid_or_sym, comment)
284
+ #Do nothing
285
+ end
285
286
 
286
287
 
287
- attr_accessor :little_endian, :path, :last_modified
288
- attr_reader :charset, :nplurals, :plural
288
+ attr_accessor :little_endian, :path, :last_modified
289
+ attr_reader :charset, :nplurals, :plural
290
+ end
289
291
  end
290
292
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grosser-fast_gettext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser