summaryrefslogtreecommitdiffstats
path: root/lib/efl/eet.rb
blob: a3a4eba4f8bff644027bacb8267c17ef29c8ad72 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#! /usr/bin/env ruby
# -*- coding: UTF-8 -*-
#
require 'ffi'
#
module EFL
    module EET
        #
        MAJOR = 0
        MINOR = 0
        REVISION = 1
        VERSION = [MAJOR,MINOR,REVISION].join '.'
        #
        class Error < Exception
            ERROR_NONE=0
            ERROR_BAD_OBJECT=1
            ERROR_EMPTY=2
            ERROR_NOT_WRITABLE=3
            ERROR_OUT_OF_MEMORY=4
            ERROR_WRITE_ERROR=5
            ERROR_WRITE_ERROR_FILE_TOO_BIG=6
            ERROR_WRITE_ERROR_IO_ERROR=7
            ERROR_WRITE_ERROR_OUT_OF_SPACE=8
            ERROR_WRITE_ERROR_FILE_CLOSED=9
            ERROR_MMAP_FAILED=10
            ERROR_X509_ENCODING_FAILED=11
            ERROR_SIGNATURE_FAILED=12
            ERROR_INVALID_SIGNATURE=13
            ERROR_NOT_SIGNED=14
            ERROR_NOT_IMPLEMENTED=15
            ERROR_PRNG_NOT_SEEDED=16
            ERROR_ENCRYPT_FAILED=17
            ERROR_DECRYPT_FAILED=18
            #
            MSGS = {
                0=>'No error, it\'s all fine!',
                1=>' Given object or handle is NULL or invalid',
                2=>'There was nothing to do',
                3=>'Could not write to file or fine is #FILE_MODE_READ',
                4=>'Could not allocate memory',
                5=>'Failed to write data to destination',
                6=>'Failed to write file since it is too big',
                7=>'Failed to write since generic Input/Output error',
                8=>'Failed to write due out of space',
                9=>'Failed to write because file was closed',
                10=>'Could not mmap file',
                11=>'Could not encode using X509',
                12=>'Could not validate signature',
                13=>'Signature is invalid',
                14=>'File or contents are not signed',
                15=>'Function is not implemented',
                16=>'Could not introduce random seed',
                17=>'Could not encrypt contents',
                18=>'Could not decrypt contents',
            }
            #
        end
        #
        extend FFI::Library
        #
        ffi_lib 'eet'
        functions = [
            [ :eet_init, [ ], :int ],
            [ :eet_shutdown, [], :int ],
            [ :eet_clearcache, [], :void ],
            [ :eet_open, [:string, :int], :pointer ],
            [ :eet_mode_get, [:pointer], :int ],
            [ :eet_close, [:pointer], :int ],
            [ :eet_write, [:pointer, :string, :pointer, :int, :int], :int ],
            [ :eet_read, [:pointer, :string, :pointer], :pointer ],
        ].each do |func|
            begin
                attach_function *func
            rescue Object => e
                puts "Could not attach #{func} #{e.message}"
            end
        end
        #
        def self.init
            eet_init
        end
        #
        def self.shutdown
            eet_shutdown
        end
        #
        def self.clearcache
            eet_clearcache
        end
        #
        FILE_MODE_INVALID = -1
        FILE_MODE_READ = 0
        FILE_MODE_WRITE = 1
        FILE_MODE_READ_WRITE  = 2
        #
        def self.open path, mode=FILE_MODE_READ, &blk
            if blk
                f = eet_open path, mode
                raise Exception.new "Unable to open file #{path}" if f.nil?
                yield EETFile.new f
                eet_close f
            else
                f = eet_open path, mode
                return EETFile.new f unless f.nil?
            end
        end
        #
        class EETFile
            #
            def initialize ptr
                @ptr=ptr
            end
            private :initialize
            #
            def close
                EET.eet_close @ptr
                @ptr=nil
            end
            #
            def mode_get
                EET.eet_mode_get @ptr
            end
            #
            def write key, data, compress=false
                EET.eet_write @ptr, key, FFI::MemoryPointer.from_string(data), data.bytesize, ( compress ? 1 : 0 )
            end
            #
            def read key
                ptr = FFI::MemoryPointer.new(:int)
                data = EET.eet_read @ptr, key, ptr
                s = ptr.read_int
                ptr.free
                return nil if s==0
                ( data.null? ? nil : data.read_string[0..s-1] )
            end
            #
        end
    end
end
#