summaryrefslogtreecommitdiffstats
path: root/lib/efl/eet.rb
blob: 5e93fd93494b83cb75af7f0609448a674d8772c4 (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
#! /usr/bin/env ruby
# -*- coding: UTF-8 -*-
#
require 'ffi'
#
module EFL
    module EET
        #
        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
        #
        FILE_MODE_INVALID = -1
        FILE_MODE_READ = 0
        FILE_MODE_WRITE = 1
        FILE_MODE_READ_WRITE  = 2
        #
        class << self
            #
            alias init eet_init
            alias shutdown eet_shutdown
            alias clearcache eet_clearcache
            #
            def 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
        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
#
# EOF