aws-crt 0.1.0.pre-universal-java

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0175a6264fedc03295be6b56c4c76e70fc2dea4edda65ae939df66d96d8146d5
4
+ data.tar.gz: 49d44971aca4cd84fdcc9b5b1294af1ea49150ec3ae0528a77ac4b3da9395790
5
+ SHA512:
6
+ metadata.gz: 9b7b82e8f54a88af5987a0654eb6a51d37c38f08e71db7e7bf5bdb42be15285867d762c912a8953872aebb7ca435c9f329d680b29b74d7d6dc1a6f8105795c65
7
+ data.tar.gz: a1787f1f7ec926213ce6121af83890f74b0dab4448bbf7c8d7aad5c44103f79d5a8517e2d1a694a8953ee54b1c4a7f9d60ee718ccdd53dfcc5ef60a9a7af89b6
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0.pre
Binary file
Binary file
Binary file
Binary file
data/lib/aws-crt.rb ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'aws-crt/platforms'
4
+ require_relative 'aws-crt/native'
5
+ require_relative 'aws-crt/errors'
6
+ require_relative 'aws-crt/managed_native'
7
+ require_relative 'aws-crt/io'
8
+
9
+ # Top level Amazon Web Services (AWS) namespace
10
+ module Aws
11
+ # Top level namespace for all common runtime (CRT) functionality
12
+ module Crt
13
+ # Ensure native init() is called when gem loads
14
+ Aws::Crt::Native.init
15
+ end
16
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Crt
5
+ # Base class for CRT Errors
6
+ class Error < StandardError
7
+ end
8
+
9
+ # CRT Errors - includes utilities for mapping errors from CRT to
10
+ # Ruby Exceptions
11
+ module Errors
12
+ @const_set_mutex = Mutex.new
13
+
14
+ AWS_TO_RUBY_ERROR_MAP = {
15
+ 'AWS_ERROR_INVALID_INDEX' => IndexError,
16
+ 'AWS_ERROR_OOM' => NoMemoryError,
17
+ 'AWS_ERROR_UNIMPLEMENTED' => NotImplementedError,
18
+ 'AWS_ERROR_INVALID_ARGUMENT' => ArgumentError,
19
+ 'AWS_ERROR_SYS_CALL_FAILURE' => SystemCallError,
20
+ 'AWS_ERROR_DIVIDE_BY_ZERO' => ZeroDivisionError,
21
+ 'AWS_ERROR_HASHTBL_ITEM_NOT_FOUND' => KeyError
22
+ }.freeze
23
+
24
+ def self.raise_last_error
25
+ error_code = Aws::Crt::Native.last_error
26
+ return if error_code.zero?
27
+
28
+ error_name = Aws::Crt::Native.error_name(error_code)
29
+ msg = Aws::Crt::Native.error_debug_str(error_code)
30
+ Aws::Crt::Native.reset_error
31
+ raise error_class(error_name), msg
32
+ end
33
+
34
+ # Get the error class for a given error_name
35
+ def self.error_class(error_name)
36
+ if AWS_TO_RUBY_ERROR_MAP.include? error_name
37
+ return AWS_TO_RUBY_ERROR_MAP[error_name]
38
+ end
39
+
40
+ constant = error_class_constant(error_name)
41
+ if error_const_set?(constant)
42
+ # modeled error class exist
43
+ # set code attribute
44
+ const_get(constant)
45
+
46
+ else
47
+ add_error_constant(constant)
48
+ end
49
+ end
50
+
51
+ # Convert an error code to an error class name/constant.
52
+ # This requires filtering non-safe characters from the constant
53
+ # name and ensuring it begins with an uppercase letter.
54
+ def self.error_class_constant(error_name)
55
+ error_name.to_s.gsub(/AWS_ERROR_/, '').split('_').map(&:capitalize).join
56
+ end
57
+
58
+ def self.add_error_constant(constant)
59
+ @const_set_mutex.synchronize do
60
+ # Ensure the const was not defined while blocked by the mutex
61
+ if error_const_set?(constant)
62
+ const_get(constant)
63
+ else
64
+ error_class = Class.new(Aws::Crt::Error)
65
+ const_set(constant, error_class)
66
+ end
67
+ end
68
+ end
69
+
70
+ def self.error_const_set?(constant)
71
+ # Purposefully not using #const_defined? as that method returns true
72
+ # for constants not defined directly in the current module.
73
+ constants.include?(constant.to_sym)
74
+ end
75
+ end
76
+ end
77
+ end
data/lib/aws-crt/io.rb ADDED
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Crt
5
+ # High level Ruby abstractions for CRT IO functionality
6
+ module IO
7
+ # A collection of event-loops.
8
+ # An event-loop is a thread for doing async work, such as I/O.
9
+ # Classes that need to do async work will ask the EventLoopGroup
10
+ # for an event-loop to use.
11
+ class EventLoopGroup
12
+ include Aws::Crt::ManagedNative
13
+ native_destroy Aws::Crt::Native.method(:event_loop_group_release)
14
+
15
+ def initialize(max_threads = nil)
16
+ unless max_threads.nil? ||
17
+ (max_threads.is_a?(Integer) && max_threads.positive?)
18
+ raise ArgumentError, 'max_threads must be nil or positive Integer'
19
+ end
20
+
21
+ # Ruby uses nil to request default values, native code uses 0
22
+ max_threads = 0 if max_threads.nil?
23
+
24
+ manage_native do
25
+ Aws::Crt::Native.event_loop_group_new(max_threads)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Crt
5
+ # A mixin module for generic managed native functionality
6
+ # Example:
7
+ #
8
+ # class C
9
+ # include Aws::Crt::ManagedNative
10
+ # native_destroy Aws::Crt::Native.method(:test_struct_destroy)
11
+ #
12
+ # def initialize
13
+ # manage_native { Aws::Crt::Native::test_struct_new() }
14
+ # end
15
+ #
16
+ # def use_native
17
+ # Aws::Crt::Native::test_method(native) #use that getter for native
18
+ # end
19
+ # end
20
+ module ManagedNative
21
+ def self.included(sub_class)
22
+ sub_class.extend(ClassMethods)
23
+ end
24
+
25
+ # expects a block that returns a :pointer to the native resource
26
+ # that this class manages
27
+ def manage_native(&block)
28
+ # check that a destructor has been registered
29
+ unless self.class.instance_variable_get('@destructor')
30
+ raise 'No native destructor registered. use native_destroy to ' \
31
+ 'set the method used to cleanup the native object this ' \
32
+ 'class manages.'
33
+ end
34
+ native = block.call
35
+ @native = FFI::AutoPointer.new(native, self.class.method(:on_release))
36
+ end
37
+
38
+ # @param [Boolean] safe (true) - raise an exception if the native object
39
+ # is not set (has been freed or never created)
40
+ # @return [FFI:Pointer]
41
+ def native(safe: true)
42
+ raise '@native is unset or has been freed.' if safe && !@native
43
+
44
+ @native
45
+ end
46
+
47
+ # @return [Boolean]
48
+ def native_set?
49
+ !!@native
50
+ end
51
+
52
+ # Immediately release this instance's attachment to the underlying
53
+ # resources, without waiting for the garbage collector.
54
+ # Note that underlying resources will remain alive until nothing
55
+ # else is using them.
56
+ def release
57
+ return unless @native
58
+
59
+ @native.free
60
+ @native = nil
61
+ end
62
+
63
+ # ClassMethods for ManagedNative
64
+ module ClassMethods
65
+ # Register the method used to cleanup the native object this class
66
+ # manages. Must be a method, use object.method(:method_name).
67
+ #
68
+ # Example:
69
+ # native_destroy Aws::Crt::Native.method(:test_release)
70
+ def native_destroy(destructor)
71
+ unless destructor.is_a?(Method)
72
+ raise ArgumentError, 'destructor must be a Method. ' \
73
+ 'Use object.method(:method_name)'
74
+ end
75
+ @destructor = destructor
76
+ end
77
+
78
+ # Do not call directly
79
+ # method passed to FFI Autopointer to call the destructor
80
+ def on_release(native)
81
+ @destructor.call(native)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ module Aws
5
+ module Crt
6
+ # FFI Bindings to native CRT functions
7
+ module Native
8
+ extend FFI::Library
9
+
10
+ ffi_lib [crt_bin_path(local_platform), 'libaws-crt']
11
+
12
+ # aws_byte_cursor binding
13
+ class ByteCursor < FFI::Struct
14
+ layout :len, :size_t,
15
+ :ptr, :pointer
16
+
17
+ def to_s
18
+ return unless (self[:len]).positive? && !(self[:ptr]).null?
19
+
20
+ self[:ptr].read_string(self[:len])
21
+ end
22
+ end
23
+
24
+ # Managed PropertyList Struct (for outputs)
25
+ class PropertyList < FFI::ManagedStruct
26
+ layout :len, :size_t,
27
+ :names, :pointer,
28
+ :values, :pointer
29
+
30
+ def props
31
+ return nil if to_ptr.null?
32
+
33
+ return {} unless (self[:len]).positive?
34
+
35
+ out = {}
36
+ names_p = self[:names].get_array_of_pointer(0, self[:len])
37
+ values_p = self[:values].get_array_of_pointer(0, self[:len])
38
+ names_p.zip(values_p).each do |name_p, value_p|
39
+ out[name_p.read_string.dup] = value_p.read_string.dup
40
+ end
41
+ out
42
+ end
43
+
44
+ def self.release(ptr)
45
+ Aws::Crt::Native.aws_crt_property_list_release(ptr)
46
+ end
47
+ end
48
+
49
+ # Given a ruby hash (string -> string), return two native arrays:
50
+ # char** (:pointer) AND a list of all of the FFI::MemoryPointers
51
+ # that must be kept around to avoid GC
52
+ def self.hash_to_native_arrays(hash)
53
+ key_array, keys_p = array_to_native(hash.keys)
54
+ value_array, values_p = array_to_native(hash.values)
55
+ [key_array, value_array, keys_p + values_p]
56
+ end
57
+
58
+ # Given a ruby array of strings, return a native array: char** and
59
+ # the FFI::MemoryPointers (these need to be pined for the length the
60
+ # native memory will be used to avoid GC)
61
+ def self.array_to_native(array)
62
+ native = FFI::MemoryPointer.new(:pointer, array.size)
63
+ pointers = array.map do |s|
64
+ FFI::MemoryPointer.from_string(s.to_s)
65
+ end
66
+ native.write_array_of_pointer(pointers)
67
+ [native, pointers]
68
+ end
69
+
70
+ # Extends FFI::attach_function
71
+ #
72
+ # 1. Allows us to only supply the aws_crt C name and removes
73
+ # the aws_crt.
74
+ # 2. Wraps the call in an error-raise checker (unless options[:raise]
75
+ # = false)
76
+ # 3. Creates a bang method that does not do automatic error checking.
77
+ def self.attach_function(c_name, params, returns, options = {})
78
+ ruby_name = c_name.to_s.sub(/aws_crt_/, '').to_sym
79
+ raise_errors = options.fetch(:raise, true)
80
+ options.delete(:raise)
81
+ unless raise_errors
82
+ return super(ruby_name, c_name, params, returns, options)
83
+ end
84
+
85
+ bang_name = "#{ruby_name}!"
86
+
87
+ super(ruby_name, c_name, params, returns, options)
88
+ alias_method(bang_name, ruby_name)
89
+
90
+ define_method(ruby_name) do |*args, &block|
91
+ res = public_send(bang_name, *args, &block)
92
+ # functions that return void cannot fail
93
+ return unless res
94
+
95
+ # for functions that return int, non-zero indicates failure
96
+ Errors.raise_last_error if res.is_a?(Integer) && res != 0
97
+
98
+ # for functions that return pointer, NULL indicates failure
99
+ Errors.raise_last_error if res.is_a?(FFI::Pointer) && res.null?
100
+
101
+ res
102
+ end
103
+
104
+ module_function ruby_name
105
+ module_function bang_name
106
+ end
107
+
108
+ # Core API
109
+ attach_function :aws_crt_init, [], :void, raise: false
110
+ attach_function :aws_crt_last_error, [], :int, raise: false
111
+ attach_function :aws_crt_error_str, [:int], :string, raise: false
112
+ attach_function :aws_crt_error_name, [:int], :string, raise: false
113
+ attach_function :aws_crt_error_debug_str, [:int], :string, raise: false
114
+ attach_function :aws_crt_reset_error, [], :void, raise: false
115
+
116
+ attach_function :aws_crt_thread_join_all_managed, [], :int
117
+
118
+ # IO API
119
+ attach_function :aws_crt_event_loop_group_new, [:uint16], :pointer
120
+ attach_function :aws_crt_event_loop_group_release, [:pointer], :void
121
+
122
+ # Auth API
123
+ attach_function :aws_crt_credentials_new, %i[string string string uint64], :pointer
124
+ attach_function :aws_crt_credentials_release, [:pointer], :void
125
+ attach_function :aws_crt_credentials_get_access_key_id, [:pointer], ByteCursor.by_value
126
+ attach_function :aws_crt_credentials_get_secret_access_key, [:pointer], ByteCursor.by_value
127
+ attach_function :aws_crt_credentials_get_session_token, [:pointer], ByteCursor.by_value
128
+ attach_function :aws_crt_credentials_get_expiration_timepoint_seconds, [:pointer], :uint64
129
+
130
+ enum :signing_algorithm, %i[sigv4 sigv4a]
131
+ enum :signature_type, %i[http_request_headers http_request_query_params
132
+ http_request_chunk http_request_event]
133
+ enum :signed_body_header_type, %i[sbht_none sbht_content_sha256]
134
+ callback :should_sign_header_fn, [ByteCursor.by_ref, :pointer], :bool
135
+ attach_function :aws_crt_signing_config_new, %i[signing_algorithm signature_type string string string uint64 pointer signed_body_header_type should_sign_header_fn bool bool bool uint64], :pointer
136
+ attach_function :aws_crt_signing_config_release, [:pointer], :void
137
+ attach_function :aws_crt_signing_config_is_signing_synchronous, [:pointer], :bool, raise: false
138
+
139
+ attach_function :aws_crt_signable_new, [], :pointer
140
+ attach_function :aws_crt_signable_release, [:pointer], :void
141
+ attach_function :aws_crt_signable_set_property, %i[pointer string string], :int
142
+ attach_function :aws_crt_signable_get_property, %i[pointer string], :string, raise: false
143
+ attach_function :aws_crt_signable_append_property_list, %i[pointer string string string], :int
144
+ attach_function :aws_crt_signable_set_property_list, %i[pointer string size_t pointer pointer], :int
145
+
146
+ callback :signing_complete_fn, %i[pointer int pointer], :void
147
+ attach_function :aws_crt_sign_request_synchronous, %i[pointer pointer signing_complete_fn], :int
148
+ attach_function :aws_crt_verify_sigv4a_signing, %i[pointer pointer string string string string], :int
149
+
150
+ attach_function :aws_crt_signing_result_get_property, %i[pointer string], :string, raise: false
151
+ attach_function :aws_crt_signing_result_get_property_list, %i[pointer string], PropertyList.by_ref, raise: false
152
+ attach_function :aws_crt_property_list_release, %i[pointer], :void
153
+
154
+ # Internal testing API
155
+ attach_function :aws_crt_test_error, [:int], :int
156
+ attach_function :aws_crt_test_pointer_error, [], :pointer
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Maps OS name to crt binary name.
4
+ OS_BINARIES = {
5
+ 'darwin' => 'libaws-crt.dylib',
6
+ 'linux' => 'libaws-crt.so',
7
+ 'mingw32' => 'aws-crt.dll'
8
+ }.freeze
9
+
10
+ DEFAULT_BINARY = 'libaws-crt.so'
11
+
12
+ # @return [String] returns Gem::Platform style name for the current system
13
+ # similar to Gem::Platform.local but will return systems host os/cpu
14
+ # for Jruby
15
+ def local_platform
16
+ Gem::Platform.new(host_string)
17
+ end
18
+
19
+ # @return [String] return the file name for the CRT library for the platform
20
+ def crt_bin_name(platform)
21
+ OS_BINARIES[platform.os] || DEFAULT_BINARY
22
+ end
23
+
24
+ # @return [String] return the directory of the CRT library for the platform
25
+ def crt_bin_dir(platform)
26
+ File.expand_path("../../bin/#{platform.cpu}", File.dirname(__FILE__))
27
+ end
28
+
29
+ # @return [String] return the path to the CRT library for the platform
30
+ def crt_bin_path(platform)
31
+ File.expand_path(crt_bin_name(platform), crt_bin_dir(platform))
32
+ end
33
+
34
+ # @return [String] generate a string that be used with Gem::Platform
35
+ def host_string
36
+ "#{host_cpu}-#{host_os}"
37
+ end
38
+
39
+ # @return [String] host cpu, even on jruby
40
+ def host_cpu
41
+ case RbConfig::CONFIG['host_cpu']
42
+ when /86_64/
43
+ 'x86_64'
44
+ when /86/
45
+ 'x86'
46
+ else
47
+ RbConfig::CONFIG['host_cpu']
48
+ end
49
+ end
50
+
51
+ # @return [String] host os, even on jruby
52
+ def host_os
53
+ case RbConfig::CONFIG['host_os']
54
+ when /darwin/
55
+ 'darwin'
56
+ when /linux/
57
+ 'linux'
58
+ when /mingw|mswin/
59
+ 'mingw32'
60
+ else
61
+ RbConfig::CONFIG['host_os']
62
+ end
63
+ end
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: aws-crt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre
5
+ platform: universal-java
6
+ authors:
7
+ - Amazon Web Services
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-06-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ffi
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email:
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - VERSION
48
+ - bin/x64/aws-crt.dll
49
+ - bin/x64/aws-crt.pdb
50
+ - bin/x86_64/libaws-crt.dylib
51
+ - bin/x86_64/libaws-crt.so
52
+ - lib/aws-crt.rb
53
+ - lib/aws-crt/errors.rb
54
+ - lib/aws-crt/io.rb
55
+ - lib/aws-crt/managed_native.rb
56
+ - lib/aws-crt/native.rb
57
+ - lib/aws-crt/platforms.rb
58
+ homepage: https://github.com/awslabs/aws-crt-ruby
59
+ licenses:
60
+ - Apache-2.0
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '2.5'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.3.1
76
+ requirements: []
77
+ rubygems_version: 3.1.6
78
+ signing_key:
79
+ specification_version: 4
80
+ summary: AWS SDK for Ruby - Common Run Time
81
+ test_files: []