ffi-icu 0.5.3 → 0.6.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 +4 -4
- data/Gemfile +10 -0
- data/LICENSE +1 -1
- data/README.md +21 -51
- data/Rakefile +4 -5
- data/ffi-icu.gemspec +34 -25
- data/lib/ffi-icu/break_iterator.rb +19 -18
- data/lib/ffi-icu/chardet.rb +12 -13
- data/lib/ffi-icu/collation.rb +62 -59
- data/lib/ffi-icu/duration_formatting.rb +293 -267
- data/lib/ffi-icu/lib/util.rb +10 -10
- data/lib/ffi-icu/lib.rb +273 -202
- data/lib/ffi-icu/locale.rb +12 -8
- data/lib/ffi-icu/normalization.rb +7 -7
- data/lib/ffi-icu/normalizer.rb +14 -8
- data/lib/ffi-icu/number_formatting.rb +41 -27
- data/lib/ffi-icu/time_formatting.rb +116 -93
- data/lib/ffi-icu/transliteration.rb +19 -19
- data/lib/ffi-icu/uchar.rb +14 -17
- data/lib/ffi-icu/version.rb +3 -1
- data/lib/ffi-icu.rb +16 -17
- metadata +35 -71
- data/.document +0 -5
- data/.gitignore +0 -23
- data/.rspec +0 -2
- data/.travis.yml +0 -28
- data/benchmark/detect.rb +0 -14
- data/benchmark/shared.rb +0 -17
- data/build_icu.sh +0 -53
- data/lib/ffi-icu/core_ext/string.rb +0 -9
- data/spec/break_iterator_spec.rb +0 -77
- data/spec/chardet_spec.rb +0 -42
- data/spec/collation_spec.rb +0 -84
- data/spec/duration_formatting_spec.rb +0 -143
- data/spec/lib/version_info_spec.rb +0 -20
- data/spec/lib_spec.rb +0 -63
- data/spec/locale_spec.rb +0 -280
- data/spec/normalization_spec.rb +0 -22
- data/spec/normalizer_spec.rb +0 -57
- data/spec/number_formatting_spec.rb +0 -79
- data/spec/spec_helper.rb +0 -13
- data/spec/time_spec.rb +0 -198
- data/spec/transliteration_spec.rb +0 -36
- data/spec/uchar_spec.rb +0 -34
- data/test.c +0 -56
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 006a4ec712fa21e3d72a80ada32f5d89dd47add0bf007efef2898c055075a37e
|
|
4
|
+
data.tar.gz: b79b4d2b4d4bcf359d58e30c8cf3d3abf1143d2d80fc0b030b19686a11238ed2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4b557fe887c73e55dc6efa966dd9ed29d8f700ec6352fd44b6e7b86a170807089ce98dbca1428be020ff98fe9bfdf9c884e174b24d17176ff3fb75afd9c6e94c
|
|
7
|
+
data.tar.gz: 4d4a6e5c7eb7821814dc3f3a80585da9ee094097352c3a6c4889731f90dc299e32c48e4f3b62c457c516c0968f4f2ef41b78320e881291a3e7a58b1198faeb5b
|
data/Gemfile
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
3
|
gemspec
|
|
4
|
+
|
|
5
|
+
group :development, :test do
|
|
6
|
+
gem 'rake', '>= 12.3.3'
|
|
7
|
+
gem 'rspec', '~> 3.13'
|
|
8
|
+
gem 'rubocop', '~> 1.86'
|
|
9
|
+
gem 'rubocop-minitest', '~> 0.39'
|
|
10
|
+
gem 'rubocop-packaging', '~> 0.6'
|
|
11
|
+
gem 'rubocop-rspec', '~> 3.9'
|
|
12
|
+
gem 'rubocop-rspec_rails', '~> 2.32'
|
|
13
|
+
end
|
data/LICENSE
CHANGED
data/README.md
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
=======
|
|
1
|
+
# ffi-icu
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
FFI wrappers for [International Components for Unicode (ICU)][icu].
|
|
4
|
+
ICU provides comprehensive localization and security features.
|
|
5
|
+
Majority personal computing devices, server operating systems and web browsers use ICU.
|
|
6
|
+
ICU builds on top of Unicode's Common Locale Data Repository (CLDR).
|
|
5
7
|
|
|
6
|
-
Gem
|
|
7
|
-
---
|
|
8
|
+
## Gem
|
|
8
9
|
|
|
9
10
|
[Rubygem](http://rubygems.org/gems/ffi-icu "ffi-icu")
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
```
|
|
13
|
+
gem install ffi-icu
|
|
14
|
+
```
|
|
12
15
|
|
|
13
|
-
Dependencies
|
|
14
|
-
------------
|
|
16
|
+
## Dependencies
|
|
15
17
|
|
|
16
18
|
ICU.
|
|
17
19
|
|
|
18
|
-
If you get messages that the library or functions are not found, you can
|
|
19
|
-
set some environment variables to tell ffi-icu where to find it, e.g.:
|
|
20
|
+
If you get messages that the library or functions are not found, you can set some environment variables to tell ffi-icu where to find it, e.g.:
|
|
20
21
|
|
|
21
22
|
```sh
|
|
22
23
|
$ export FFI_ICU_LIB="icui18n.so"
|
|
@@ -24,11 +25,9 @@ $ export FFI_ICU_VERSION_SUFFIX="_3_8"
|
|
|
24
25
|
$ ruby -r ffi-icu program.rb
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
Features
|
|
28
|
-
========
|
|
28
|
+
# Features
|
|
29
29
|
|
|
30
|
-
Character Encoding Detection
|
|
31
|
-
----------------------------
|
|
30
|
+
## Character Encoding Detection
|
|
32
31
|
|
|
33
32
|
Examples:
|
|
34
33
|
|
|
@@ -45,12 +44,9 @@ detector = ICU::CharDet::Detector.new
|
|
|
45
44
|
detector.detect(str) => #<struct ICU::CharDet::Detector::Match ...>
|
|
46
45
|
```
|
|
47
46
|
|
|
48
|
-
Why not just use rchardet?
|
|
49
|
-
|
|
50
47
|
* speed
|
|
51
48
|
|
|
52
|
-
Locale Sensitive Collation
|
|
53
|
-
--------------------------
|
|
49
|
+
## Locale Sensitive Collation
|
|
54
50
|
|
|
55
51
|
Examples:
|
|
56
52
|
|
|
@@ -67,8 +63,7 @@ collator.greater?("z", "a") #=> true
|
|
|
67
63
|
collator.collate(%w[å æ ø]) #=> ["æ", "ø", "å"]
|
|
68
64
|
```
|
|
69
65
|
|
|
70
|
-
Text Boundary Analysis
|
|
71
|
-
----------------------
|
|
66
|
+
## Text Boundary Analysis
|
|
72
67
|
|
|
73
68
|
Examples:
|
|
74
69
|
|
|
@@ -78,8 +73,7 @@ iterator.text = "This is a sentence."
|
|
|
78
73
|
iterator.to_a #=> [0, 4, 5, 7, 8, 9, 10, 18, 19]
|
|
79
74
|
```
|
|
80
75
|
|
|
81
|
-
Number/Currency Formatting
|
|
82
|
-
--------------------------
|
|
76
|
+
## Number/Currency Formatting
|
|
83
77
|
|
|
84
78
|
Examples:
|
|
85
79
|
|
|
@@ -99,8 +93,7 @@ curf = ICU::NumberFormatting.create('en-US', :currency)
|
|
|
99
93
|
curf.format(1234.56, 'USD') #=> "$1,234.56"
|
|
100
94
|
```
|
|
101
95
|
|
|
102
|
-
Time Formatting/Parsing
|
|
103
|
-
-----------------------
|
|
96
|
+
## Time Formatting/Parsing
|
|
104
97
|
|
|
105
98
|
Examples:
|
|
106
99
|
|
|
@@ -130,8 +123,7 @@ formatter = ICU::TimeFormatting.create(:locale => 'cs_CZ', :date => :pattern, :t
|
|
|
130
123
|
formatter.format(Time.now) #=> "2015"
|
|
131
124
|
```
|
|
132
125
|
|
|
133
|
-
Duration Formatting
|
|
134
|
-
-------------------
|
|
126
|
+
## Duration Formatting
|
|
135
127
|
|
|
136
128
|
```ruby
|
|
137
129
|
# What the various styles look like
|
|
@@ -187,8 +179,7 @@ formatter = ICU::DurationFormatting::DurationFormatter.new(locale: 'ru', style:
|
|
|
187
179
|
formatter.format({hours: 10, minutes: 20, seconds: 30}) #=> "10 ч 20 мин 30 с"
|
|
188
180
|
```
|
|
189
181
|
|
|
190
|
-
Transliteration
|
|
191
|
-
---------------
|
|
182
|
+
## Transliteration
|
|
192
183
|
|
|
193
184
|
Example:
|
|
194
185
|
|
|
@@ -196,8 +187,7 @@ Example:
|
|
|
196
187
|
ICU::Transliteration.transliterate('Traditional-Simplified', '沈從文') # => "沈从文"
|
|
197
188
|
```
|
|
198
189
|
|
|
199
|
-
Locale
|
|
200
|
-
------
|
|
190
|
+
## Locale
|
|
201
191
|
|
|
202
192
|
Examples:
|
|
203
193
|
|
|
@@ -210,24 +200,4 @@ locale.display_name_with_context('en-US', [:length_short]) #=> "English (US)"
|
|
|
210
200
|
locale.display_name_with_context('en-US', [:length_long]) #=> "English (United States)"
|
|
211
201
|
```
|
|
212
202
|
|
|
213
|
-
|
|
214
|
-
=====
|
|
215
|
-
|
|
216
|
-
* Any other useful part of ICU?
|
|
217
|
-
* Windows?!
|
|
218
|
-
|
|
219
|
-
Note on Patches/Pull Requests
|
|
220
|
-
=============================
|
|
221
|
-
|
|
222
|
-
* Fork the project.
|
|
223
|
-
* Make your feature addition or bug fix.
|
|
224
|
-
* Add tests for it. This is important so I don't break it in a
|
|
225
|
-
future version unintentionally.
|
|
226
|
-
* Commit, do not mess with rakefile, version, or history.
|
|
227
|
-
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
|
228
|
-
* Send me a pull request. Bonus points for topic branches.
|
|
229
|
-
|
|
230
|
-
Copyright
|
|
231
|
-
=========
|
|
232
|
-
|
|
233
|
-
Copyright (c) 2010-2015 Jari Bakken. See LICENSE for details.
|
|
203
|
+
[icu]: https://github.com/unicode-org/icu
|
data/Rakefile
CHANGED
|
@@ -15,14 +15,13 @@ RSpec::Core::RakeTask.new(:rcov) do |spec|
|
|
|
15
15
|
spec.rcov = true
|
|
16
16
|
end
|
|
17
17
|
|
|
18
|
-
task :
|
|
18
|
+
task default: :spec
|
|
19
19
|
|
|
20
20
|
begin
|
|
21
|
-
require
|
|
21
|
+
require('yard')
|
|
22
22
|
YARD::Rake::YardocTask.new
|
|
23
23
|
rescue LoadError
|
|
24
|
-
task
|
|
25
|
-
abort
|
|
24
|
+
task(:yardoc) do
|
|
25
|
+
abort('YARD is not available. In order to run yardoc, you must: sudo gem install yard')
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
|
-
|
data/ffi-icu.gemspec
CHANGED
|
@@ -1,26 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Gem::Specification.new do |
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
require_relative 'lib/ffi-icu/version'
|
|
2
|
+
|
|
3
|
+
Gem::Specification.new do |spec|
|
|
4
|
+
spec.name = 'ffi-icu'
|
|
5
|
+
spec.version = ICU::VERSION
|
|
6
|
+
spec.platform = Gem::Platform::RUBY # rely on FFI library, but being platform-independent
|
|
7
|
+
|
|
8
|
+
spec.required_rubygems_version = Gem::Requirement.new('>= 2.5.0')
|
|
9
|
+
spec.authors = ['Erick Guan', 'Damian Nelson']
|
|
10
|
+
spec.licenses = ['MIT']
|
|
11
|
+
spec.summary = 'Ruby FFI wrappers for International Components for Unicode (ICU).'
|
|
12
|
+
spec.description = 'Provides charset detection, transiliteration, locale sensitive collation and more. ' \
|
|
13
|
+
'Depends on libicu. ICU operates on CLDR data.'
|
|
14
|
+
spec.email = 'erickguanst@gmail.com'
|
|
15
|
+
spec.homepage = 'https://github.com/erickguan/ffi-icu'
|
|
16
|
+
|
|
17
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
|
18
|
+
spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/master/CHANGELOG.md"
|
|
19
|
+
|
|
20
|
+
spec.files = Dir['lib/**/*.rb', 'Gemfile', 'ffi-icu.gemspec', 'Rakefile']
|
|
21
|
+
spec.bindir = 'bin'
|
|
22
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
23
|
+
spec.require_paths = ['lib']
|
|
24
|
+
|
|
25
|
+
spec.extra_rdoc_files = ['LICENSE', 'README.md']
|
|
26
|
+
spec.rdoc_options = ['--charset=UTF-8']
|
|
27
|
+
|
|
28
|
+
spec.required_ruby_version = '>= 3.2.0'
|
|
29
|
+
|
|
30
|
+
spec.add_dependency('bigdecimal', '~> 3.1')
|
|
31
|
+
spec.add_dependency('ffi', '~> 1.0', '>= 1.0.9')
|
|
32
|
+
spec.add_dependency('stringio', '~> 3.0')
|
|
33
|
+
|
|
34
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
26
35
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ICU
|
|
2
4
|
class BreakIterator
|
|
3
5
|
include Enumerable
|
|
@@ -8,7 +10,7 @@ module ICU
|
|
|
8
10
|
|
|
9
11
|
def self.available_locales
|
|
10
12
|
(0...Lib.ubrk_countAvailable).map do |idx|
|
|
11
|
-
Lib.ubrk_getAvailable
|
|
13
|
+
Lib.ubrk_getAvailable(idx)
|
|
12
14
|
end
|
|
13
15
|
end
|
|
14
16
|
|
|
@@ -20,25 +22,25 @@ module ICU
|
|
|
20
22
|
def text=(str)
|
|
21
23
|
@text = str
|
|
22
24
|
|
|
23
|
-
Lib.check_error
|
|
24
|
-
Lib.ubrk_setText
|
|
25
|
-
|
|
25
|
+
Lib.check_error do |err|
|
|
26
|
+
Lib.ubrk_setText(@iterator, UCharPointer.from_string(str), str.size, err)
|
|
27
|
+
end
|
|
26
28
|
end
|
|
27
29
|
|
|
28
|
-
def each
|
|
30
|
+
def each
|
|
29
31
|
return to_enum(:each) unless block_given?
|
|
30
32
|
|
|
31
33
|
int = first
|
|
32
34
|
|
|
33
35
|
while int != DONE
|
|
34
|
-
yield
|
|
36
|
+
yield(int)
|
|
35
37
|
int = self.next
|
|
36
38
|
end
|
|
37
39
|
|
|
38
40
|
self
|
|
39
41
|
end
|
|
40
42
|
|
|
41
|
-
def each_substring
|
|
43
|
+
def each_substring
|
|
42
44
|
return to_enum(:each_substring) unless block_given?
|
|
43
45
|
|
|
44
46
|
# each_char needed for 1.8, where String#[] works on bytes, not characters
|
|
@@ -46,7 +48,7 @@ module ICU
|
|
|
46
48
|
low = first
|
|
47
49
|
|
|
48
50
|
while (high = self.next) != DONE
|
|
49
|
-
yield
|
|
51
|
+
yield(chars[low...high].join)
|
|
50
52
|
low = high
|
|
51
53
|
end
|
|
52
54
|
|
|
@@ -58,36 +60,35 @@ module ICU
|
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
def next
|
|
61
|
-
Lib.ubrk_next
|
|
63
|
+
Lib.ubrk_next(@iterator)
|
|
62
64
|
end
|
|
63
65
|
|
|
64
66
|
def previous
|
|
65
|
-
Lib.ubrk_next
|
|
67
|
+
Lib.ubrk_next(@iterator)
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
def first
|
|
69
|
-
Lib.ubrk_first
|
|
71
|
+
Lib.ubrk_first(@iterator)
|
|
70
72
|
end
|
|
71
73
|
|
|
72
74
|
def last
|
|
73
|
-
Lib.ubrk_last
|
|
75
|
+
Lib.ubrk_last(@iterator)
|
|
74
76
|
end
|
|
75
77
|
|
|
76
78
|
def preceding(offset)
|
|
77
|
-
Lib.ubrk_preceding
|
|
79
|
+
Lib.ubrk_preceding(@iterator, Integer(offset))
|
|
78
80
|
end
|
|
79
81
|
|
|
80
82
|
def following(offset)
|
|
81
|
-
Lib.ubrk_following
|
|
83
|
+
Lib.ubrk_following(@iterator, Integer(offset))
|
|
82
84
|
end
|
|
83
85
|
|
|
84
86
|
def current
|
|
85
|
-
Lib.ubrk_current
|
|
87
|
+
Lib.ubrk_current(@iterator)
|
|
86
88
|
end
|
|
87
89
|
|
|
88
90
|
def boundary?(offset)
|
|
89
91
|
Lib.ubrk_isBoundary(@iterator, Integer(offset)) != 0
|
|
90
92
|
end
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
end # ICU
|
|
93
|
+
end
|
|
94
|
+
end
|
data/lib/ffi-icu/chardet.rb
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ICU
|
|
2
4
|
module CharDet
|
|
3
|
-
|
|
4
5
|
def self.detect(string)
|
|
5
|
-
Detector.new.detect
|
|
6
|
+
Detector.new.detect(string)
|
|
6
7
|
end
|
|
7
8
|
|
|
8
9
|
class Detector
|
|
9
10
|
Match = Struct.new(:name, :confidence, :language)
|
|
10
11
|
|
|
11
12
|
def initialize
|
|
12
|
-
ptr = Lib.check_error { |err| Lib.ucsdet_open
|
|
13
|
+
ptr = Lib.check_error { |err| Lib.ucsdet_open(err) }
|
|
13
14
|
@detector = FFI::AutoPointer.new(ptr, Lib.method(:ucsdet_close))
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
def input_filter_enabled?
|
|
17
|
-
Lib.ucsdet_isInputFilterEnabled
|
|
18
|
+
Lib.ucsdet_isInputFilterEnabled(@detector)
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def input_filter_enabled=(bool)
|
|
@@ -23,7 +24,7 @@ module ICU
|
|
|
23
24
|
|
|
24
25
|
def declared_encoding=(str)
|
|
25
26
|
Lib.check_error do |ptr|
|
|
26
|
-
Lib.ucsdet_setDeclaredEncoding(@detector, str, str.
|
|
27
|
+
Lib.ucsdet_setDeclaredEncoding(@detector, str, str.size, ptr)
|
|
27
28
|
end
|
|
28
29
|
end
|
|
29
30
|
|
|
@@ -37,7 +38,7 @@ module ICU
|
|
|
37
38
|
def detect_all(str)
|
|
38
39
|
set_text(str)
|
|
39
40
|
|
|
40
|
-
matches_found_ptr = FFI::MemoryPointer.new
|
|
41
|
+
matches_found_ptr = FFI::MemoryPointer.new(:int32_t)
|
|
41
42
|
array_ptr = Lib.check_error do |status|
|
|
42
43
|
Lib.ucsdet_detectAll(@detector, matches_found_ptr, status)
|
|
43
44
|
end
|
|
@@ -71,14 +72,12 @@ module ICU
|
|
|
71
72
|
result
|
|
72
73
|
end
|
|
73
74
|
|
|
74
|
-
def set_text(text)
|
|
75
|
+
def set_text(text) # rubocop:disable Naming/AccessorMethodName
|
|
75
76
|
Lib.check_error do |status|
|
|
76
77
|
data = FFI::MemoryPointer.from_string(text)
|
|
77
|
-
Lib.ucsdet_setText(@detector, data, text.
|
|
78
|
+
Lib.ucsdet_setText(@detector, data, text.size, status)
|
|
78
79
|
end
|
|
79
80
|
end
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
end # ICU
|
|
84
|
-
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
data/lib/ffi-icu/collation.rb
CHANGED
|
@@ -1,37 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ICU
|
|
2
4
|
module Collation
|
|
3
|
-
|
|
4
5
|
ATTRIBUTES = {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
:french_collation => 0,
|
|
7
|
+
:alternate_handling => 1,
|
|
8
|
+
:case_first => 2,
|
|
9
|
+
:case_level => 3,
|
|
10
|
+
:normalization_mode => 4,
|
|
11
|
+
:strength => 5,
|
|
12
|
+
:hiragana_quaternary_mode => 6,
|
|
13
|
+
:numeric_collation => 7
|
|
13
14
|
}.freeze
|
|
14
15
|
|
|
15
16
|
ATTRIBUTE_VALUES = {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
nil => -1,
|
|
18
|
+
:primary => 0,
|
|
19
|
+
:secondary => 1,
|
|
20
|
+
:default_strength => 2,
|
|
21
|
+
:tertiary => 2,
|
|
22
|
+
:quaternary => 3,
|
|
23
|
+
:identical => 15,
|
|
24
|
+
|
|
25
|
+
false => 16,
|
|
26
|
+
true => 17,
|
|
27
|
+
|
|
28
|
+
:shifted => 20,
|
|
29
|
+
:non_ignorable => 21,
|
|
30
|
+
|
|
31
|
+
:lower_first => 24,
|
|
32
|
+
:upper_first => 25
|
|
32
33
|
}.freeze
|
|
33
34
|
|
|
34
|
-
ATTRIBUTE_VALUES_INVERSE =
|
|
35
|
+
ATTRIBUTE_VALUES_INVERSE = ATTRIBUTE_VALUES.to_h { |k, v| [v, k] }.freeze
|
|
35
36
|
|
|
36
37
|
def self.collate(locale, arr)
|
|
37
38
|
Collator.new(locale).collate(arr)
|
|
@@ -40,7 +41,7 @@ module ICU
|
|
|
40
41
|
def self.keywords
|
|
41
42
|
enum_ptr = Lib.check_error { |error| Lib.ucol_getKeywords(error) }
|
|
42
43
|
keywords = Lib.enum_ptr_to_array(enum_ptr)
|
|
43
|
-
Lib.uenum_close
|
|
44
|
+
Lib.uenum_close(enum_ptr)
|
|
44
45
|
|
|
45
46
|
hash = {}
|
|
46
47
|
keywords.each do |keyword|
|
|
@@ -54,7 +55,7 @@ module ICU
|
|
|
54
55
|
|
|
55
56
|
def self.available_locales
|
|
56
57
|
(0...Lib.ucol_countAvailable).map do |idx|
|
|
57
|
-
Lib.ucol_getAvailable
|
|
58
|
+
Lib.ucol_getAvailable(idx)
|
|
58
59
|
end
|
|
59
60
|
end
|
|
60
61
|
|
|
@@ -73,55 +74,51 @@ module ICU
|
|
|
73
74
|
def compare(a, b)
|
|
74
75
|
Lib.ucol_strcoll(
|
|
75
76
|
@c,
|
|
76
|
-
UCharPointer.from_string(a), a.
|
|
77
|
-
UCharPointer.from_string(b), b.
|
|
77
|
+
UCharPointer.from_string(a), a.size,
|
|
78
|
+
UCharPointer.from_string(b), b.size
|
|
78
79
|
)
|
|
79
80
|
end
|
|
80
81
|
|
|
81
82
|
def greater?(a, b)
|
|
82
|
-
Lib.ucol_greater(@c, UCharPointer.from_string(a), a.
|
|
83
|
-
|
|
83
|
+
Lib.ucol_greater(@c, UCharPointer.from_string(a), a.size,
|
|
84
|
+
UCharPointer.from_string(b), b.size)
|
|
84
85
|
end
|
|
85
86
|
|
|
86
87
|
def greater_or_equal?(a, b)
|
|
87
|
-
Lib.ucol_greaterOrEqual(@c, UCharPointer.from_string(a), a.
|
|
88
|
-
|
|
88
|
+
Lib.ucol_greaterOrEqual(@c, UCharPointer.from_string(a), a.size,
|
|
89
|
+
UCharPointer.from_string(b), b.size)
|
|
89
90
|
end
|
|
90
91
|
|
|
91
92
|
def equal?(*args)
|
|
92
93
|
return super() if args.empty?
|
|
93
94
|
|
|
94
|
-
if args.size != 2
|
|
95
|
-
raise ArgumentError, "wrong number of arguments (#{args.size} for 2)"
|
|
96
|
-
end
|
|
95
|
+
raise(ArgumentError, "wrong number of arguments (#{args.size} for 2)") if args.size != 2
|
|
97
96
|
|
|
98
97
|
a, b = args
|
|
99
98
|
|
|
100
|
-
Lib.ucol_equal(@c, UCharPointer.from_string(a), a.
|
|
101
|
-
|
|
99
|
+
Lib.ucol_equal(@c, UCharPointer.from_string(a), a.size,
|
|
100
|
+
UCharPointer.from_string(b), b.size)
|
|
102
101
|
end
|
|
103
102
|
|
|
104
103
|
def collate(sortable)
|
|
105
|
-
unless sortable.respond_to?(:sort)
|
|
106
|
-
raise ArgumentError, "argument must respond to :sort with arity of 2"
|
|
107
|
-
end
|
|
104
|
+
raise(ArgumentError, 'argument must respond to :sort with arity of 2') unless sortable.respond_to?(:sort)
|
|
108
105
|
|
|
109
|
-
sortable.sort { |a, b| compare
|
|
106
|
+
sortable.sort { |a, b| compare(a, b) }
|
|
110
107
|
end
|
|
111
108
|
|
|
112
109
|
def rules
|
|
113
110
|
@rules ||= begin
|
|
114
111
|
length = FFI::MemoryPointer.new(:int)
|
|
115
112
|
ptr = Lib.ucol_getRules(@c, length)
|
|
116
|
-
ptr.read_array_of_uint16(length.read_int).pack(
|
|
113
|
+
ptr.read_array_of_uint16(length.read_int).pack('U*')
|
|
117
114
|
end
|
|
118
115
|
end
|
|
119
116
|
|
|
120
117
|
def collation_key(string)
|
|
121
118
|
ptr = UCharPointer.from_string(string)
|
|
122
|
-
size = Lib.ucol_getSortKey(@c, ptr, string.
|
|
119
|
+
size = Lib.ucol_getSortKey(@c, ptr, string.size, nil, 0)
|
|
123
120
|
buffer = FFI::MemoryPointer.new(:char, size)
|
|
124
|
-
Lib.ucol_getSortKey(@c, ptr, string.
|
|
121
|
+
Lib.ucol_getSortKey(@c, ptr, string.size, buffer, size)
|
|
125
122
|
buffer.read_bytes(size - 1)
|
|
126
123
|
end
|
|
127
124
|
|
|
@@ -135,22 +132,28 @@ module ICU
|
|
|
135
132
|
Lib.check_error do |error|
|
|
136
133
|
Lib.ucol_setAttribute(@c, ATTRIBUTES[attribute], ATTRIBUTE_VALUES[value], error)
|
|
137
134
|
end
|
|
138
|
-
value
|
|
139
135
|
end
|
|
140
136
|
|
|
141
137
|
# create friendly named methods for setting attributes
|
|
142
138
|
ATTRIBUTES.each_key do |attribute|
|
|
143
|
-
class_eval <<-CODE
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
139
|
+
class_eval <<-CODE, __FILE__, __LINE__ + 1
|
|
140
|
+
# def case_first
|
|
141
|
+
# self[:case_first]
|
|
142
|
+
# end
|
|
143
|
+
#
|
|
144
|
+
# def case_first=(value)
|
|
145
|
+
# self[:case_first] = value
|
|
146
|
+
# end
|
|
147
|
+
|
|
148
|
+
def #{attribute}
|
|
149
|
+
self[:#{attribute}]
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def #{attribute}=(value)
|
|
153
|
+
self[:#{attribute}] = value
|
|
154
|
+
end
|
|
151
155
|
CODE
|
|
152
156
|
end
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
end # ICU
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|