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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e1817bf83d85197ea62937c274ff98c71984ef4a432a6f76fc3cca764bf45dc
4
- data.tar.gz: 2a21f2177dc151831fe89782be8cfe53d2f13a6d1038961eb1efe5c3970a27a0
3
+ metadata.gz: 2066f9d1a113f07fb761d2c97f742e6cad8dde11b26c0e4d1da2ed8a85567297
4
+ data.tar.gz: e6df31c42fc3e518d8d19a98dec0b5aeed37ae90da3fd7570f32ef58397d531d
5
5
  SHA512:
6
- metadata.gz: 6fb2d659678226632c485ea24de6e79f7d20ccf7b80b03833f680bb295ae07736957f3a9037ac1d3639b432f6974c279b580767d08315ad005c57cc6be79ed8b
7
- data.tar.gz: 9c49ddef23ae27f88d4eaffbaf0cf42b670e7f07939b7c19b6255a4ac157faae25e8eb5bc973764e767b3b32d40226c4b1cc95772c629fbe4b678d4cff5ebccb
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: xenial
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 varibles to tell ffi-icu where to find it, e.g.:
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
- formater = ICU::TimeFormatting.create(:locale => 'cs_CZ', :zone => 'Europe/Prague', :date => :long , :time => :none)
113
- formater.format(Time.now) #=> "25. února 2015"
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
- formater = ICU::TimeFormatting.create(:locale => 'cs_CZ', :zone => 'Europe/Prague', :date => :long , :time => :none)
119
- formater.parse("25. února 2015") #=> Wed Feb 25 00:00:00 +0100 2015
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
- :none, -1,
429
- :full, 0,
430
- :long, 1,
431
- :medium, 2,
432
- :short, 3,
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 = nil
70
- d_len = 0
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
- d_len = time_zone_str.size
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
- d_len = Lib.ucal_getDefaultTimeZone(time_zone, i_len, error)
81
+ tz_len = Lib.ucal_getDefaultTimeZone(time_zone, i_len, error)
79
82
  }
80
83
  end
81
84
 
82
- ptr = Lib.check_error { | error| Lib.udat_open(time_style, date_style, locale, time_zone, d_len, FFI::MemoryPointer.new(4), -1, error) }
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
- @f = make_formatter(time_style, date_style, locale, time_zone)
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
@@ -1,3 +1,3 @@
1
1
  module ICU
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
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 ', :date => :short , :time => :long)
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
- ["en", "雙屬性集合之空間分群演算法-應用於地理資料", "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"],
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-icu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jari Bakken