ffi-icu 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +9 -2
- data/README.md +15 -5
- data/lib/ffi-icu/lib.rb +9 -5
- data/lib/ffi-icu/time_formatting.rb +44 -7
- data/lib/ffi-icu/version.rb +1 -1
- data/spec/time_spec.rb +14 -1
- data/spec/transliteration_spec.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2066f9d1a113f07fb761d2c97f742e6cad8dde11b26c0e4d1da2ed8a85567297
|
4
|
+
data.tar.gz: e6df31c42fc3e518d8d19a98dec0b5aeed37ae90da3fd7570f32ef58397d531d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf39178c2893939c57a8e7810d407da635ceff9b4cc5ddbe60360df53a0bf7f35b17d8f4036cf001d85edf4fa83efd8f4ed1b91d6cdb21e54d52810f536bf7ce
|
7
|
+
data.tar.gz: ee8c887487e3c3a0c0511e7017753b4801da3fc6a73e4d476211452026fd0ae3d8ae0d4c35be9eb5ed8827df8b757bc985dc5f5eafc77a12c872ca37347e9924
|
data/.travis.yml
CHANGED
@@ -1,13 +1,20 @@
|
|
1
1
|
language: ruby
|
2
2
|
os: linux
|
3
|
-
dist:
|
3
|
+
dist: focal
|
4
|
+
|
5
|
+
arch:
|
6
|
+
- amd64
|
7
|
+
- arm64
|
4
8
|
|
5
9
|
rvm:
|
6
|
-
- 2.5
|
7
10
|
- 2.6
|
8
11
|
- 2.7
|
12
|
+
- 3.0
|
9
13
|
- ruby-head
|
10
14
|
|
11
15
|
before_script:
|
12
16
|
- sudo apt-get install -y libicu-dev
|
13
17
|
|
18
|
+
jobs:
|
19
|
+
allow_failures:
|
20
|
+
- arch: arm64
|
data/README.md
CHANGED
@@ -16,7 +16,7 @@ Dependencies
|
|
16
16
|
ICU.
|
17
17
|
|
18
18
|
If you get messages that the library or functions are not found, you can
|
19
|
-
set some environment
|
19
|
+
set some environment variables to tell ffi-icu where to find it, e.g.:
|
20
20
|
|
21
21
|
$ export FFI_ICU_LIB="icui18n.so"
|
22
22
|
$ export FFI_ICU_VERSION_SUFFIX="_3_8"
|
@@ -109,14 +109,24 @@ Examples:
|
|
109
109
|
f #=> "12.11.15 15:21"
|
110
110
|
|
111
111
|
# reusable formatting objects
|
112
|
-
|
113
|
-
|
112
|
+
formatter = ICU::TimeFormatting.create(:locale => 'cs_CZ', :zone => 'Europe/Prague', :date => :long, :time => :none)
|
113
|
+
formatter.format(Time.now) #=> "25. února 2015"
|
114
114
|
```
|
115
115
|
|
116
116
|
```ruby
|
117
117
|
# reusable formatting objects
|
118
|
-
|
119
|
-
|
118
|
+
formatter = ICU::TimeFormatting.create(:locale => 'cs_CZ', :zone => 'Europe/Prague', :date => :long, :time => :none)
|
119
|
+
formatter.parse("25. února 2015") #=> Wed Feb 25 00:00:00 +0100 2015
|
120
|
+
```
|
121
|
+
|
122
|
+
For skeleton formatting, visit the [Unicode date field symbol table](https://unicode-org.github.io/icu/userguide/format_parse/datetime/#date-field-symbol-table) page to help find the pattern characters to use.
|
123
|
+
|
124
|
+
```ruby
|
125
|
+
formatter = ICU::TimeFormatting.create(:locale => 'cs_CZ', :date => :pattern, :time => :pattern, :skeleton => 'MMMMY')
|
126
|
+
formatter.format(Time.now) #=> "únor 2015"
|
127
|
+
|
128
|
+
formatter = ICU::TimeFormatting.create(:locale => 'cs_CZ', :date => :pattern, :time => :pattern, :skeleton => 'Y')
|
129
|
+
formatter.format(Time.now) #=> "2015"
|
120
130
|
```
|
121
131
|
|
122
132
|
Tested on:
|
data/lib/ffi-icu/lib.rb
CHANGED
@@ -425,11 +425,12 @@ module ICU
|
|
425
425
|
attach_function :unum_set_attribute, "unum_setAttribute#{suffix}", [:pointer, :number_format_attribute, :int32_t], :void
|
426
426
|
# date
|
427
427
|
enum :date_format_style, [
|
428
|
-
:
|
429
|
-
:
|
430
|
-
:
|
431
|
-
:
|
432
|
-
:
|
428
|
+
:pattern, -2,
|
429
|
+
:none, -1,
|
430
|
+
:full, 0,
|
431
|
+
:long, 1,
|
432
|
+
:medium, 2,
|
433
|
+
:short, 3,
|
433
434
|
]
|
434
435
|
attach_function :udat_open, "udat_open#{suffix}", [:date_format_style, :date_format_style, :string, :pointer, :int32_t, :pointer, :int32_t, :pointer ], :pointer
|
435
436
|
attach_function :udat_close, "unum_close#{suffix}", [:pointer], :void
|
@@ -437,6 +438,9 @@ module ICU
|
|
437
438
|
attach_function :udat_parse, "udat_parse#{suffix}", [:pointer, :pointer, :int32_t, :pointer, :pointer], :double
|
438
439
|
attach_function :udat_toPattern, "udat_toPattern#{suffix}", [:pointer, :bool , :pointer, :int32_t , :pointer], :int32_t
|
439
440
|
attach_function :udat_applyPattern, "udat_applyPattern#{suffix}", [:pointer, :bool , :pointer, :int32_t ], :void
|
441
|
+
# skeleton pattern
|
442
|
+
attach_function :udatpg_open, "udatpg_open#{suffix}", [:string, :pointer], :pointer
|
443
|
+
attach_function :udatpg_getBestPattern, "udatpg_getBestPattern#{suffix}", [:pointer, :pointer, :int32_t, :pointer, :int32_t, :pointer], :int32_t
|
440
444
|
# tz
|
441
445
|
attach_function :ucal_setDefaultTimeZone, "ucal_setDefaultTimeZone#{suffix}", [:pointer, :pointer], :int32_t
|
442
446
|
attach_function :ucal_getDefaultTimeZone, "ucal_getDefaultTimeZone#{suffix}", [:pointer, :int32_t, :pointer], :int32_t
|
@@ -65,21 +65,31 @@ module ICU
|
|
65
65
|
|
66
66
|
private
|
67
67
|
|
68
|
-
def make_formatter(time_style, date_style, locale, time_zone_str)
|
69
|
-
time_zone
|
70
|
-
|
68
|
+
def make_formatter(time_style, date_style, locale, time_zone_str, skeleton)
|
69
|
+
time_zone = nil
|
70
|
+
tz_len = 0
|
71
|
+
pattern_len = -1
|
72
|
+
pattern_ptr = FFI::MemoryPointer.new(4)
|
73
|
+
|
71
74
|
if time_zone_str
|
72
75
|
time_zone = UCharPointer.from_string(time_zone_str)
|
73
|
-
|
76
|
+
tz_len = time_zone_str.size
|
74
77
|
else
|
75
78
|
Lib.check_error { | error|
|
76
79
|
i_len = 150
|
77
80
|
time_zone = UCharPointer.new(i_len)
|
78
|
-
|
81
|
+
tz_len = Lib.ucal_getDefaultTimeZone(time_zone, i_len, error)
|
79
82
|
}
|
80
83
|
end
|
81
84
|
|
82
|
-
|
85
|
+
if skeleton
|
86
|
+
date_style = :pattern
|
87
|
+
time_style = :pattern
|
88
|
+
|
89
|
+
pattern_len, pattern_ptr = skeleton_format(skeleton, locale)
|
90
|
+
end
|
91
|
+
|
92
|
+
ptr = Lib.check_error { | error| Lib.udat_open(time_style, date_style, locale, time_zone, tz_len, pattern_ptr, pattern_len, error) }
|
83
93
|
FFI::AutoPointer.new(ptr, Lib.method(:udat_close))
|
84
94
|
end
|
85
95
|
end
|
@@ -91,7 +101,9 @@ module ICU
|
|
91
101
|
locale = options[:locale] || 'C'
|
92
102
|
tz_style = options[:tz_style]
|
93
103
|
time_zone = options[:zone]
|
94
|
-
|
104
|
+
skeleton = options[:skeleton]
|
105
|
+
|
106
|
+
@f = make_formatter(time_style, date_style, locale, time_zone, skeleton)
|
95
107
|
if tz_style
|
96
108
|
f0 = date_format(true)
|
97
109
|
f1 = update_tz_format(f0, tz_style)
|
@@ -177,6 +189,31 @@ module ICU
|
|
177
189
|
needed_length = Lib.udat_applyPattern(@f, localized, pattern, pattern_len)
|
178
190
|
end
|
179
191
|
end
|
192
|
+
|
193
|
+
def skeleton_format(pattern, locale)
|
194
|
+
pattern = UCharPointer.from_string(pattern)
|
195
|
+
|
196
|
+
needed_length = 0
|
197
|
+
pattern_ptr = UCharPointer.new(needed_length)
|
198
|
+
|
199
|
+
udatpg_ptr = Lib.check_error { |error| Lib.udatpg_open(locale, error) }
|
200
|
+
generator = FFI::AutoPointer.new(udatpg_ptr, Lib.method(:udat_close))
|
201
|
+
|
202
|
+
retried = false
|
203
|
+
|
204
|
+
begin
|
205
|
+
Lib.check_error do |error|
|
206
|
+
needed_length = Lib.udatpg_getBestPattern(generator, pattern, pattern.size, pattern_ptr, needed_length, error)
|
207
|
+
end
|
208
|
+
|
209
|
+
return needed_length, pattern_ptr
|
210
|
+
rescue BufferOverflowError
|
211
|
+
raise BufferOverflowError, "needed: #{needed_length}" if retried
|
212
|
+
pattern_ptr = pattern_ptr.resized_to needed_length
|
213
|
+
retried = true
|
214
|
+
retry
|
215
|
+
end
|
216
|
+
end
|
180
217
|
end # DateTimeFormatter
|
181
218
|
end # Formatting
|
182
219
|
end # ICU
|
data/lib/ffi-icu/version.rb
CHANGED
data/spec/time_spec.rb
CHANGED
@@ -59,7 +59,7 @@ module ICU
|
|
59
59
|
expect(f2.format(t8)).to eq("3/29/08#{en_sep} 6:38:24 AM #{en_tz}")
|
60
60
|
end
|
61
61
|
|
62
|
-
f3 = TimeFormatting.create(:locale => 'de_DE', :zone => 'Africa/Dakar
|
62
|
+
f3 = TimeFormatting.create(:locale => 'de_DE', :zone => 'Africa/Dakar', :date => :short , :time => :long)
|
63
63
|
ge_sep = ""
|
64
64
|
if cldr_version >= "27.0.1"
|
65
65
|
ge_sep = ","
|
@@ -82,6 +82,19 @@ module ICU
|
|
82
82
|
expect(f3.format(t7)).to eq("29.03.08#{ge_sep} 02:37:23 GMT")
|
83
83
|
expect(f3.format(t8)).to eq("29.03.08#{ge_sep} 03:38:24 GMT")
|
84
84
|
end
|
85
|
+
|
86
|
+
context 'skeleton pattern' do
|
87
|
+
f4 = TimeFormatting.create(:locale => 'fr_FR', :date => :pattern, :time => :pattern, :skeleton => 'MMMy')
|
88
|
+
|
89
|
+
it 'check format' do
|
90
|
+
expect(f4.format(t0)).to eq("nov. 2008")
|
91
|
+
expect(f4.format(t1)).to eq("oct. 2008")
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'check date_format' do
|
95
|
+
expect(f4.date_format(true)).to eq("MMM y")
|
96
|
+
end
|
97
|
+
end
|
85
98
|
end
|
86
99
|
end
|
87
100
|
end
|
@@ -9,7 +9,7 @@ module ICU
|
|
9
9
|
[
|
10
10
|
["Any-Hex", "abcde", "\\u0061\\u0062\\u0063\\u0064\\u0065"],
|
11
11
|
["Lower", "ABC", "abc"],
|
12
|
-
["
|
12
|
+
["Han-Latin", "雙屬性集合之空間分群演算法-應用於地理資料", "shuāng shǔ xìng jí hé zhī kōng jiān fēn qún yǎn suàn fǎ-yīng yòng yú de lǐ zī liào"],
|
13
13
|
["Devanagari-Latin", "दौलत", "daulata"]
|
14
14
|
].each do |id, input, output|
|
15
15
|
it "should transliterate #{id}" do
|