ffi-icu 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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