Module: Sodium::FFI::Crypto

Extended by:
FFI::Library
Defined in:
lib/sodium/ffi/crypto.rb,
lib/sodium/ffi/crypto.rb

Constant Summary collapse

CONFIG_PATH =
File.expand_path('../../../../config/nacl_ffi.yml', __FILE__)
CONFIG =
YAML.load_file(CONFIG_PATH)

Class Method Summary collapse

Class Method Details

._install_constant(subclass, family, primitive, name, type) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/sodium/ffi/crypto.rb', line 46

def self._install_constant(subclass, family, primitive, name, type)
  method = _install_function subclass, family, primitive, name, [ type ]

  family = family.to_s.upcase
  name   = name.to_s.upcase
  value  = subclass.send(method)

  self.    const_set("#{family}_#{primitive}_#{name}", value)
  subclass.const_set(name,                             value)
end

._install_constants(subclass, family, primitive, constants) ⇒ Object



36
37
38
39
40
41
42
43
44
# File 'lib/sodium/ffi/crypto.rb', line 36

def self._install_constants(subclass, family, primitive, constants)
  constants = constants.inject(
    :PRIMITIVE => :string
  ) {|hash, constant| hash.update(constant => :size_t) }

  constants.each_pair do |name, type|
    _install_constant(subclass, family, primitive, name, type)
  end
end

._install_default(delegate, configuration) ⇒ Object



8
9
10
11
12
13
14
15
16
# File 'lib/sodium/ffi/crypto.rb', line 8

def self._install_default(delegate, configuration)
  family    = configuration[:family]
  method    = _install_function delegate, family, nil, :PRIMITIVE, [ :string ]
  primitive = delegate.send(method)
rescue FFI::NotFoundError
  primitive = configuration[:primitives].first
ensure
  delegate.const_set :DEFAULT, primitive.to_s.downcase.to_sym
end

._install_function(subclass, family, primitive, name, arguments, &converter) ⇒ Object



63
64
65
66
67
68
69
70
71
72
# File 'lib/sodium/ffi/crypto.rb', line 63

def self._install_function(subclass, family, primitive, name, arguments, &converter)
  imp       = [ family, primitive, name ].compact.join('_').downcase
  meth      = [ 'nacl',            name ].compact.join('_').downcase
  arguments = arguments.map(&:to_sym)

  self.attach_function imp, arguments[0..-2], arguments.last
  self.attach_method   imp, self, subclass, meth, &converter

  meth
end

._install_functions(subclass, family, primitive, methods) ⇒ Object



57
58
59
60
61
# File 'lib/sodium/ffi/crypto.rb', line 57

def self._install_functions(subclass, family, primitive, methods)
  methods.each do |name, arguments|
    _install_function(subclass, family, primitive, name, arguments, &:zero?)
  end
end

._install_primitives(delegate, configuration) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/sodium/ffi/crypto.rb', line 18

def self._install_primitives(delegate, configuration)
  configuration[:primitives].each do |primitive|
    subclass = Class.new(delegate) do
      def self.[](name)
        self.const_get(name)
      end
    end

    delegate.const_set primitive, subclass

    _install_constants subclass, configuration[:family], primitive,
      configuration[:constants]

    _install_functions subclass, configuration[:family], primitive,
      configuration[:functions]
  end
end

._load_class(name) ⇒ Object



81
82
83
# File 'lib/sodium/ffi/crypto.rb', line 81

def self._load_class(name)
  name.split('::').inject(Object) {|klass, part| klass.const_get(part) }
end

._metaclass(klass) ⇒ Object



85
86
87
# File 'lib/sodium/ffi/crypto.rb', line 85

def self._metaclass(klass)
  (class << klass; self; end)
end

.attach_method(implementation, nacl, delegate, method) ⇒ Object



74
75
76
77
78
79
# File 'lib/sodium/ffi/crypto.rb', line 74

def self.attach_method(implementation, nacl, delegate, method)
  self._metaclass(delegate).send :define_method, method do |*a, &b|
    value = nacl.send(implementation, *a, &b)
    block_given? ? yield(value) : value
  end
end