corefoundation 0.2.0 → 0.3.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CF
4
+ module Refinements
5
+ # Patches for ruby Integer
6
+ refine Integer do
7
+ # Converts the Integer to a {CF::Number} using {CF::Number.from_i}
8
+ # @return [CF::Number]
9
+ def to_cf
10
+ CF::Number.from_i(self)
11
+ end
12
+ end
13
+
14
+ # Patches for ruby Float
15
+ refine Float do
16
+ # Converts the Float to a {CF::Number} using {CF::Number.from_f}
17
+ # @return [CF::Number]
18
+ def to_cf
19
+ CF::Number.from_f(self)
20
+ end
21
+ end
22
+
23
+ # Patches for ruby Array
24
+ refine Array do
25
+ # Converts the Array to an immutable {CF::Array} by calling `to_cf` on each element it contains
26
+ # @return [CF::Number]
27
+ def to_cf
28
+ CF::Array.immutable(collect(&:to_cf))
29
+ end
30
+ end
31
+
32
+ # Patches for ruby TrueClass
33
+ refine TrueClass do
34
+ # Returns a CF::Boolean object representing true
35
+ # @return [CF::Boolean]
36
+ def to_cf
37
+ CF::Boolean::TRUE
38
+ end
39
+ end
40
+
41
+ # Patches for ruby FalseClass
42
+ refine FalseClass do
43
+ # Returns a CF::Boolean object representing false
44
+ # @return [CF::Boolean]
45
+ def to_cf
46
+ CF::Boolean::FALSE
47
+ end
48
+ end
49
+
50
+ # Patches for ruby String
51
+ refine String do
52
+ # Returns a {CF::String} or {CF::Data} representing the string.
53
+ # If {#binary?} returns true a {CF::Data} is returned, if not a {CF::String} is returned
54
+ #
55
+ # If you want a {CF::Data} with the contents of a non binary string, use {#to_cf_data}
56
+ #
57
+ # @return [CF::String, CF::Data]
58
+ def to_cf
59
+ binary? ? to_cf_data : to_cf_string
60
+ end
61
+
62
+ # @!method binary?
63
+ #
64
+ # used to determine whether {#to_cf} should return a {CF::String} or a {CF::Data}.
65
+ # This simply checks whether the encoding is ascii-8bit or not.
66
+ #
67
+ # @return whether the string is handled as binary data or not
68
+ #
69
+ def binary?
70
+ encoding == Encoding::ASCII_8BIT
71
+ end
72
+
73
+ # @param [optional, Boolean, Encoding] bin
74
+ # If you pass `true` then `Encoding::ASCII_BIT` is used, if you pass `false` then `Encoding::UTF_8`
75
+ def binary!(bin = true)
76
+ if bin == true
77
+ force_encoding Encoding::ASCII_8BIT
78
+ else
79
+ # default to utf-8
80
+ force_encoding(bin == false ? "UTF-8" : bin)
81
+ end
82
+ self
83
+ end
84
+
85
+ # Returns a {CF::String} representing the string
86
+ # @return [CF::String]
87
+ def to_cf_string
88
+ CF::String.from_string self
89
+ end
90
+
91
+ # Returns a {CF::Data} representing the string
92
+ # @return [CF::Data]
93
+ def to_cf_data
94
+ CF::Data.from_string self
95
+ end
96
+ end
97
+
98
+ # Patches for ruby Time
99
+ refine Time do
100
+ # Returns a {CF::Date} representing the time.
101
+ # @return [CF::Date]
102
+ def to_cf
103
+ CF::Date.from_time(self)
104
+ end
105
+ end
106
+
107
+ # Patches for ruby Hash
108
+ refine Hash do
109
+ # Converts the Hash to an mutable {CF::Dictionary} by calling `to_cf` on each key and value it contains
110
+ # @return [CF::Dictionary]
111
+ def to_cf
112
+ transform_keys! &:to_s # Convert all keys to strings
113
+ CF::Dictionary.mutable.tap do |r|
114
+ each do |k, v|
115
+ r[k.to_cf] = v.to_cf
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,24 @@
1
+ require "singleton"
2
+
3
+ module CF
4
+ module Register
5
+ def self.included base
6
+ base.extend self
7
+ end
8
+
9
+ def register_type(type_name)
10
+ CF.attach_function "#{type_name}GetTypeID", [], :cftypeid
11
+ type_map[CF.send("#{type_name}GetTypeID")] = self
12
+ end
13
+
14
+ private
15
+
16
+ def klass_from_cf_type(cftyperef)
17
+ klass = type_map[CF.CFGetTypeID(cftyperef)]
18
+ raise TypeError, "No class registered for cf type #{cftyperef.inspect}" unless klass
19
+
20
+ klass
21
+ end
22
+
23
+ end
24
+ end
@@ -20,26 +20,15 @@ module CF
20
20
  # The cfstring encoding for UTF8
21
21
  UTF8 = 0x08000100 #From cfstring.h
22
22
 
23
- # workaround for ruby 1.8.7 compat
24
- HAS_ENCODING = "foo".respond_to? "encode"
25
-
26
23
  # Creates a string from a ruby string
27
24
  # The string must be convertable to UTF-8
28
25
  #
29
26
  # @param [String] s
30
27
  # @return [CF::String]
31
- def self.from_string(s, src_encoding='UTF-8')
32
- if HAS_ENCODING
33
- s_utf = s.encode('UTF-8')
34
- else
35
- begin
36
- s_utf = Iconv.conv('UTF-8', src_encoding, s.to_s)
37
- rescue Iconv::IllegalSequence => e
38
- return nil
39
- end
40
- end
28
+ def self.from_string(s)
29
+ s_utf = s.encode("UTF-8")
41
30
  raw = CF.CFStringCreateWithBytes(nil, s_utf, s_utf.bytesize, UTF8, 0)
42
- raw.null? ? nil : new(raw).release_on_gc
31
+ raw.null? ? nil : new(raw)
43
32
  end
44
33
 
45
34
  # Returns the length, in unicode characters of the string
@@ -65,27 +54,15 @@ module CF
65
54
  range[:location] = 0
66
55
  range[:length] = length
67
56
  buffer = FFI::MemoryPointer.new(:char, max_size)
68
-
69
57
  cfindex = CF.find_type(:cfindex)
70
58
  bytes_used_buffer = FFI::MemoryPointer.new(cfindex)
71
59
 
72
60
  CF.CFStringGetBytes(self, range, UTF8, 0, 0, buffer, max_size, bytes_used_buffer)
61
+ len = bytes_used_buffer.send(cfindex == CF.find_type(:long_long) ? :read_long_long : :read_long)
73
62
 
74
- bytes_used = if cfindex == CF.find_type(:long_long)
75
- bytes_used_buffer.read_long_long
76
- else
77
- bytes_used_buffer.read_long
78
- end
79
-
80
- if HAS_ENCODING
81
- buffer.read_string(bytes_used).force_encoding(Encoding::UTF_8)
82
- else
83
- buffer.read_string(bytes_used)
84
- end
63
+ buffer.read_string(len).force_encoding(Encoding::UTF_8)
85
64
  end
86
-
87
- alias_method :to_ruby, :to_s
88
-
65
+ alias to_ruby to_s
89
66
  end
90
67
 
91
68
  end
@@ -1,4 +1,4 @@
1
1
  module CF
2
2
  # The current version string
3
- VERSION = "0.2.0"
3
+ VERSION = "0.3.4"
4
4
  end
@@ -1,13 +1,38 @@
1
- require 'ffi'
2
- require 'iconv' if RUBY_VERSION < "1.9"
3
-
4
- require 'corefoundation/base'
5
- require 'corefoundation/null'
6
- require 'corefoundation/string'
7
- require 'corefoundation/array'
8
- require 'corefoundation/boolean'
9
- require 'corefoundation/data'
10
- require 'corefoundation/dictionary'
11
- require 'corefoundation/number'
12
- require 'corefoundation/date'
13
- require 'corefoundation/extensions'
1
+ require "ffi" unless defined?(FFI)
2
+
3
+ module CF
4
+ extend FFI::Library
5
+ ffi_lib '/System/Library/Frameworks/CoreFoundation.framework/CoreFoundation'
6
+
7
+ if FFI::Platform::ARCH == 'x86_64'
8
+ typedef :long_long, :cfindex
9
+ typedef :long_long, :cfcomparisonresult
10
+ typedef :ulong_long, :cfoptionflags
11
+ typedef :ulong_long, :cftypeid
12
+ typedef :ulong_long, :cfhashcode
13
+ else
14
+ typedef :long, :cfindex
15
+ typedef :long, :cfcomparisonresult
16
+ typedef :ulong, :cfoptionflags
17
+ typedef :ulong, :cftypeid
18
+ typedef :ulong, :cfhashcode
19
+ end
20
+
21
+ typedef :pointer, :cftyperef
22
+ end
23
+
24
+ require_relative 'corefoundation/refinements'
25
+ require_relative 'corefoundation/memory'
26
+ require_relative 'corefoundation/register'
27
+ require_relative 'corefoundation/base'
28
+ require_relative 'corefoundation/null'
29
+ require_relative 'corefoundation/range'
30
+ require_relative 'corefoundation/string'
31
+ require_relative 'corefoundation/array'
32
+ require_relative 'corefoundation/boolean'
33
+ require_relative 'corefoundation/data'
34
+ require_relative 'corefoundation/dictionary'
35
+ require_relative 'corefoundation/number'
36
+ require_relative 'corefoundation/date'
37
+ require_relative 'corefoundation/exceptions'
38
+ require_relative 'corefoundation/preferences'
metadata CHANGED
@@ -1,182 +1,133 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: corefoundation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
5
- prerelease:
4
+ version: 0.3.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Frederick Cheung
9
- autorequire:
8
+ - Chef Software, Inc.
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-06 00:00:00.000000000 Z
12
+ date: 2021-09-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
16
- version_requirements: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ! '>='
19
- - !ruby/object:Gem::Version
20
- version: !binary |-
21
- MA==
22
- none: false
23
16
  requirement: !ruby/object:Gem::Requirement
24
17
  requirements:
25
- - - ! '>='
18
+ - - ">="
26
19
  - !ruby/object:Gem::Version
27
- version: !binary |-
28
- MA==
29
- none: false
30
- prerelease: false
20
+ version: 1.15.0
31
21
  type: :runtime
32
- - !ruby/object:Gem::Dependency
33
- name: rspec
22
+ prerelease: false
34
23
  version_requirements: !ruby/object:Gem::Requirement
35
24
  requirements:
36
- - - ~>
25
+ - - ">="
37
26
  - !ruby/object:Gem::Version
38
- version: '2.10'
39
- none: false
27
+ version: 1.15.0
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
40
30
  requirement: !ruby/object:Gem::Requirement
41
31
  requirements:
42
- - - ~>
32
+ - - ">="
43
33
  - !ruby/object:Gem::Version
44
- version: '2.10'
45
- none: false
46
- prerelease: false
34
+ version: '3.0'
47
35
  type: :development
48
- - !ruby/object:Gem::Dependency
49
- name: rake
36
+ prerelease: false
50
37
  version_requirements: !ruby/object:Gem::Requirement
51
38
  requirements:
52
- - - ! '>='
39
+ - - ">="
53
40
  - !ruby/object:Gem::Version
54
- version: !binary |-
55
- MA==
56
- none: false
41
+ version: '3.0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
57
44
  requirement: !ruby/object:Gem::Requirement
58
45
  requirements:
59
- - - ! '>='
46
+ - - ">="
60
47
  - !ruby/object:Gem::Version
61
- version: !binary |-
62
- MA==
63
- none: false
64
- prerelease: false
48
+ version: '0'
65
49
  type: :development
66
- - !ruby/object:Gem::Dependency
67
- name: yard
50
+ prerelease: false
68
51
  version_requirements: !ruby/object:Gem::Requirement
69
52
  requirements:
70
- - - ! '>='
53
+ - - ">="
71
54
  - !ruby/object:Gem::Version
72
- version: !binary |-
73
- MA==
74
- none: false
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: chefstyle
75
58
  requirement: !ruby/object:Gem::Requirement
76
59
  requirements:
77
- - - ! '>='
60
+ - - '='
78
61
  - !ruby/object:Gem::Version
79
- version: !binary |-
80
- MA==
81
- none: false
82
- prerelease: false
62
+ version: 2.0.9
83
63
  type: :development
84
- - !ruby/object:Gem::Dependency
85
- name: redcarpet
64
+ prerelease: false
86
65
  version_requirements: !ruby/object:Gem::Requirement
87
66
  requirements:
88
- - - ! '>='
67
+ - - '='
89
68
  - !ruby/object:Gem::Version
90
- version: !binary |-
91
- MA==
92
- none: false
69
+ version: 2.0.9
70
+ - !ruby/object:Gem::Dependency
71
+ name: yard
93
72
  requirement: !ruby/object:Gem::Requirement
94
73
  requirements:
95
- - - ! '>='
74
+ - - ">="
96
75
  - !ruby/object:Gem::Version
97
- version: !binary |-
98
- MA==
99
- none: false
100
- prerelease: false
76
+ version: '0'
101
77
  type: :development
102
- description: ! 'FFI based Ruby wrappers for Core Foundation '
103
- email: frederick.cheung@gmail.com
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ description: Ruby wrapper for macOS Core Foundation framework
85
+ email:
86
+ - frederick.cheung@gmail.com
87
+ - oss@chef.io
104
88
  executables: []
105
89
  extensions: []
106
90
  extra_rdoc_files: []
107
91
  files:
108
- - !binary |-
109
- bGliL2NvcmVmb3VuZGF0aW9uLnJi
110
- - !binary |-
111
- bGliL2NvcmVmb3VuZGF0aW9uL2FycmF5LnJi
112
- - !binary |-
113
- bGliL2NvcmVmb3VuZGF0aW9uL2Jhc2UucmI=
114
- - !binary |-
115
- bGliL2NvcmVmb3VuZGF0aW9uL2Jvb2xlYW4ucmI=
116
- - !binary |-
117
- bGliL2NvcmVmb3VuZGF0aW9uL2RhdGEucmI=
118
- - !binary |-
119
- bGliL2NvcmVmb3VuZGF0aW9uL2RhdGUucmI=
120
- - !binary |-
121
- bGliL2NvcmVmb3VuZGF0aW9uL2RpY3Rpb25hcnkucmI=
122
- - !binary |-
123
- bGliL2NvcmVmb3VuZGF0aW9uL2V4dGVuc2lvbnMucmI=
124
- - !binary |-
125
- bGliL2NvcmVmb3VuZGF0aW9uL251bGwucmI=
126
- - !binary |-
127
- bGliL2NvcmVmb3VuZGF0aW9uL251bWJlci5yYg==
128
- - !binary |-
129
- bGliL2NvcmVmb3VuZGF0aW9uL3N0cmluZy5yYg==
130
- - !binary |-
131
- bGliL2NvcmVmb3VuZGF0aW9uL3ZlcnNpb24ucmI=
132
- - !binary |-
133
- c3BlYy9hcnJheV9zcGVjLnJi
134
- - !binary |-
135
- c3BlYy9ib29sZWFuX3NwZWMucmI=
136
- - !binary |-
137
- c3BlYy9kYXRhX3NwZWMucmI=
138
- - !binary |-
139
- c3BlYy9kYXRlX3NwZWMucmI=
140
- - !binary |-
141
- c3BlYy9kaWN0aW9uYXJ5X3NwZWMucmI=
142
- - !binary |-
143
- c3BlYy9leHRlbnNpb25zX3NwZWMucmI=
144
- - !binary |-
145
- c3BlYy9udWxsX3NwZWMucmI=
146
- - !binary |-
147
- c3BlYy9udW1iZXJfc3BlYy5yYg==
148
- - !binary |-
149
- c3BlYy9zcGVjX2hlbHBlci5yYg==
150
- - !binary |-
151
- c3BlYy9zdHJpbmdfc3BlYy5yYg==
152
- - README.md
153
92
  - LICENSE
154
- - CHANGELOG
155
- homepage: http://github.com/fcheung/corefoundation
93
+ - lib/corefoundation.rb
94
+ - lib/corefoundation/array.rb
95
+ - lib/corefoundation/base.rb
96
+ - lib/corefoundation/boolean.rb
97
+ - lib/corefoundation/data.rb
98
+ - lib/corefoundation/date.rb
99
+ - lib/corefoundation/dictionary.rb
100
+ - lib/corefoundation/exceptions.rb
101
+ - lib/corefoundation/memory.rb
102
+ - lib/corefoundation/null.rb
103
+ - lib/corefoundation/number.rb
104
+ - lib/corefoundation/preferences.rb
105
+ - lib/corefoundation/range.rb
106
+ - lib/corefoundation/refinements.rb
107
+ - lib/corefoundation/register.rb
108
+ - lib/corefoundation/string.rb
109
+ - lib/corefoundation/version.rb
110
+ homepage: http://github.com/chef/corefoundation
156
111
  licenses:
157
112
  - MIT
158
- post_install_message:
113
+ metadata: {}
114
+ post_install_message:
159
115
  rdoc_options: []
160
116
  require_paths:
161
117
  - lib
162
118
  required_ruby_version: !ruby/object:Gem::Requirement
163
119
  requirements:
164
- - - ! '>='
120
+ - - ">="
165
121
  - !ruby/object:Gem::Version
166
- version: 1.8.7
167
- none: false
122
+ version: '2.6'
168
123
  required_rubygems_version: !ruby/object:Gem::Requirement
169
124
  requirements:
170
- - - ! '>='
125
+ - - ">="
171
126
  - !ruby/object:Gem::Version
172
- version: !binary |-
173
- MA==
174
- none: false
127
+ version: '0'
175
128
  requirements: []
176
- rubyforge_project:
177
- rubygems_version: 1.8.24
178
- signing_key:
179
- specification_version: 3
180
- summary: Ruby wrapper for OS X corefoundation
129
+ rubygems_version: 3.1.4
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: Ruby wrapper for macOS Core Foundation framework
181
133
  test_files: []
182
- has_rdoc:
data/CHANGELOG DELETED
@@ -1,12 +0,0 @@
1
- # Changelog
2
-
3
-
4
-
5
-
6
- ## 0.2.0 - 2012-12-06
7
- Add support for ruby 1.8.7 [tmaher]
8
-
9
-
10
- ## 0.1.4 - 2012-10-16
11
-
12
- Initial version
data/README.md DELETED
@@ -1,40 +0,0 @@
1
-
2
- CoreFoundation
3
- ==============
4
-
5
- FFI based wrappers for a subset of core foundation: various bits of CFString, CFData, CFArray, CFDictionary are available. Not that useful on its own but a useful building block for writing ffi wrappers of other OS X libraries.
6
-
7
- Although the CF collection classes can store arbitrary pointer sized values this wrapper only supports storing CFTypes.
8
-
9
- The CF namespace has the raw FFI generated method calls but it's usually easier to use the wrapper classes: `CF::String`, `CF::Date`, `CF::Array`, `CF::Dictionary`, `CF::Boolean` which try to present a rubyish view of the world (for example `CF::Array` implements `Enumerable`)
10
-
11
- These implement methods for creating new instances from ruby objects (eg `CF::String.from_string("hello world")`) but you can also pass build them from an `FFI::Pointer`).
12
-
13
- Converting
14
- ===========
15
-
16
- `CF::Base` objects has a `to_ruby` that creates a ruby object of the most approprite type (`String` for `CF::String`, `Time` for `CF::Date`, `Integer` or `Float` for `CF::Number` etc). The collection classes call `to_ruby` on their contents too.
17
-
18
- In addition to the methods on the wrapper classes themselves, the ruby classes are extended with a `to_cf` method. Because CoreFoundation strings aren't arbitrary collections of bytes, `String#to_cf` will return a `CF::Data` if the string has the ASCII-8BIT encoding and a `CF::String` if not.
19
-
20
- If you have an `FFI::Pointer` or a raw address then you can create a wrapper by passing it to `new`, for example `CF::String.new(some_pointer)`. This does *not* check that the pointer is actually a `CFString`. You can use `CF::Base.typecast` to construct an instance of the appropriate subclass, for example `CF::Base.typecast(some_pointer)` would return a `CF::String` if `some_pointer` was in fact a `CFStringRef`.
21
-
22
- Memory Management
23
- =================
24
-
25
- The convenience methods for creating CF objects will release the cf object when they are garbage collected. Methods on the convenience classes will usually retain the result and mark it for releasing when they are garbage collected (for example `CF::Dictionary#[]` retains the returned value). You don't need to do any extra memory management on these.
26
-
27
- If you pass an `FFI::Pointer` to `new` or `typecast` no assumptions are made for you. You should call `retain` or `release` to manage it manually. As an alternative to calling `release` manually, the `release_on_gc` method adds a finalizer to the wrapper that will call `CFRelease` on the Core Foundation object when the wrapper is garbage collected. You will almost certainly crash your ruby interpreter if you overrelease an object and you will leak memory if you overretain one.
28
-
29
- If you use the raw api (eg `CF.CFArrayCreate`) then you're on your own.
30
-
31
-
32
- Compatibility
33
- =============
34
-
35
- Should work in MRI 1.8.7 and above and jruby. Not compatible with rubinius due to rubinius' ffi implementation not supporting certain features. On 1.8.7 the `binary?` and `binary!` methods tag a string's binary-ness with a flag, on 1.9 these methods are just shortcuts for testing whether the encoding is Encoding::ASCII_8BIT
36
-
37
- License
38
- =======
39
-
40
- Released under the MIT license. See LICENSE