ruby-magic 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/AUTHORS +1 -0
- data/CHANGES +5 -0
- data/CHANGES.rdoc +5 -0
- data/COPYRIGHT +1 -0
- data/LICENSE +202 -0
- data/README +1 -0
- data/README.rdoc +7 -0
- data/Rakefile +78 -0
- data/TODO +21 -0
- data/VERSION +1 -0
- data/bin/magic +33 -0
- data/ext/magic/common.h +90 -0
- data/ext/magic/extconf.rb +115 -0
- data/ext/magic/functions.c +274 -0
- data/ext/magic/functions.h +100 -0
- data/ext/magic/ruby-magic.c +973 -0
- data/ext/magic/ruby-magic.h +244 -0
- data/lib/magic/core/file.rb +124 -0
- data/lib/magic/core/string.rb +76 -0
- data/lib/magic/version.rb +76 -0
- data/lib/magic.rb +204 -0
- data/ruby-magic.gemspec +68 -0
- data/test/test_constants.rb +47 -0
- data/test/test_magic.rb +260 -0
- metadata +153 -0
@@ -0,0 +1,244 @@
|
|
1
|
+
/* :enddoc: */
|
2
|
+
|
3
|
+
/*
|
4
|
+
* ruby-magic.h
|
5
|
+
*
|
6
|
+
* Copyright 2013-2014 Krzysztof Wilczynski
|
7
|
+
*
|
8
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
* you may not use this file except in compliance with the License.
|
10
|
+
* You may obtain a copy of the License at
|
11
|
+
*
|
12
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
*
|
14
|
+
* Unless required by applicable law or agreed to in writing, software
|
15
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
* See the License for the specific language governing permissions and
|
18
|
+
* limitations under the License.
|
19
|
+
*/
|
20
|
+
|
21
|
+
#if !defined(_RUBY_MAGIC_H)
|
22
|
+
#define _RUBY_MAGIC_H 1
|
23
|
+
|
24
|
+
#if defined(__cplusplus)
|
25
|
+
extern "C" {
|
26
|
+
#endif
|
27
|
+
|
28
|
+
#include "common.h"
|
29
|
+
#include "functions.h"
|
30
|
+
|
31
|
+
#define DATA_P(x) (TYPE(x) == T_DATA)
|
32
|
+
#define STRING_P(x) (TYPE(x) == T_STRING)
|
33
|
+
#define ARRAY_P(x) (TYPE(x) == T_ARRAY)
|
34
|
+
|
35
|
+
#if !defined(STR2CSTR)
|
36
|
+
# define STR2CSTR(x) StringValuePtr(x)
|
37
|
+
#endif
|
38
|
+
|
39
|
+
#if !defined(RVAL2CSTR)
|
40
|
+
# define RVAL2CSTR(x) (NIL_P(x) ? NULL : STR2CSTR(x))
|
41
|
+
#endif
|
42
|
+
|
43
|
+
#if !defined(CSTR2RVAL)
|
44
|
+
# define CSTR2RVAL(x) ((x) == NULL ? Qnil : rb_str_new2(x))
|
45
|
+
#endif
|
46
|
+
|
47
|
+
#if !defined(RARRAY_LEN)
|
48
|
+
# define RARRAY_LEN(a) (RARRAY(a)->len)
|
49
|
+
#endif
|
50
|
+
|
51
|
+
#if !defined(RSTRING_LEN)
|
52
|
+
# define RSTRING_LEN(s) (RSTRING(s)->len)
|
53
|
+
#endif
|
54
|
+
|
55
|
+
#if !defined(RSTRING_PTR)
|
56
|
+
# define RSTRING_PTR(s) (RSTRING(s)->ptr)
|
57
|
+
#endif
|
58
|
+
|
59
|
+
#define RSTRING_EMPTY_P(s) (RSTRING_LEN(s) == 0)
|
60
|
+
#define RARRAY_EMPTY_P(a) (RARRAY_LEN(a) == 0)
|
61
|
+
#define RARRAY_FIRST(a) (RARRAY_EMPTY_P(a) ? Qnil : RARRAY_PTR(a)[0])
|
62
|
+
|
63
|
+
#define NOGVL_FUNCTION (VALUE (*)(void *))
|
64
|
+
|
65
|
+
#if defined(HAVE_RB_THREAD_CALL_WITHOUT_GVL) && \
|
66
|
+
defined(HAVE_RUBY_THREAD_H) && HAVE_RUBY_THREAD_H
|
67
|
+
# include <ruby/thread.h>
|
68
|
+
# define NOGVL(f, d) \
|
69
|
+
rb_thread_call_without_gvl((f), (d), RUBY_UBF_IO, NULL)
|
70
|
+
#elif defined(HAVE_RB_THREAD_BLOCKING_REGION)
|
71
|
+
# define NOGVL(f, d) \
|
72
|
+
rb_thread_blocking_region(NOGVL_FUNCTION(f), (d), RUBY_UBF_IO, NULL)
|
73
|
+
#else
|
74
|
+
# include <rubysig.h>
|
75
|
+
static inline VALUE
|
76
|
+
fake_blocking_region(VALUE (*f)(ANYARGS), void *data)
|
77
|
+
{
|
78
|
+
VALUE rv;
|
79
|
+
|
80
|
+
TRAP_BEG;
|
81
|
+
rv = f(data);
|
82
|
+
TRAP_END;
|
83
|
+
|
84
|
+
return rv;
|
85
|
+
}
|
86
|
+
# define NOGVL(f, d) fake_blocking_region(NOGVL_FUNCTION(f), (d))
|
87
|
+
#endif
|
88
|
+
|
89
|
+
#define MAGIC_SYNCHRONIZED(f, d) magic_lock(object, (f), (d))
|
90
|
+
|
91
|
+
#define MAGIC_COOKIE(c) \
|
92
|
+
Data_Get_Struct(object, struct magic_set, (c))
|
93
|
+
|
94
|
+
#define MAGIC_CLOSED_P(o) RTEST(rb_mgc_closed((o)))
|
95
|
+
|
96
|
+
#define MAGIC_GENERIC_ERROR(k, e, m) \
|
97
|
+
do { \
|
98
|
+
VALUE __e_##k = magic_generic_error((k), (e), (m)); \
|
99
|
+
rb_exc_raise(__e_##k); \
|
100
|
+
} while(0)
|
101
|
+
|
102
|
+
#define MAGIC_LIBRARY_ERROR(c) \
|
103
|
+
do { \
|
104
|
+
VALUE __e_library = magic_library_error(rb_mgc_eMagicError, (c)); \
|
105
|
+
rb_exc_raise(__e_library); \
|
106
|
+
} while(0)
|
107
|
+
|
108
|
+
#define CHECK_MAGIC_OPEN(o) \
|
109
|
+
do { \
|
110
|
+
if (MAGIC_CLOSED_P(o)) { \
|
111
|
+
MAGIC_GENERIC_ERROR(rb_mgc_eLibraryError, EFAULT, \
|
112
|
+
error(E_MAGIC_LIBRARY_CLOSED)); \
|
113
|
+
} \
|
114
|
+
} while(0) \
|
115
|
+
|
116
|
+
#define error(t) errors[(t)]
|
117
|
+
|
118
|
+
enum error {
|
119
|
+
E_UNKNOWN = 0,
|
120
|
+
E_NOT_IMPLEMENTED,
|
121
|
+
E_MAGIC_LIBRARY_INITIALIZE,
|
122
|
+
E_MAGIC_LIBRARY_CLOSED,
|
123
|
+
E_FLAG_INVALID_VALUE,
|
124
|
+
E_FLAG_NOT_IMPLEMENTED
|
125
|
+
};
|
126
|
+
|
127
|
+
union file {
|
128
|
+
int fd;
|
129
|
+
const char *path;
|
130
|
+
};
|
131
|
+
|
132
|
+
struct buffer {
|
133
|
+
size_t size;
|
134
|
+
const char *buffer;
|
135
|
+
};
|
136
|
+
|
137
|
+
typedef union file file_t;
|
138
|
+
typedef struct buffer buffer_t;
|
139
|
+
|
140
|
+
struct magic_arguments {
|
141
|
+
int flags;
|
142
|
+
magic_t cookie;
|
143
|
+
union {
|
144
|
+
file_t file;
|
145
|
+
buffer_t buffer;
|
146
|
+
} data;
|
147
|
+
};
|
148
|
+
|
149
|
+
struct magic_exception {
|
150
|
+
int magic_errno;
|
151
|
+
const char *magic_error;
|
152
|
+
VALUE klass;
|
153
|
+
};
|
154
|
+
|
155
|
+
typedef struct magic_arguments magic_arguments_t;
|
156
|
+
typedef struct magic_exception magic_exception_t;
|
157
|
+
|
158
|
+
static const char *errors[] = {
|
159
|
+
"unknown error",
|
160
|
+
"function is not implemented",
|
161
|
+
"failed to initialize Magic library",
|
162
|
+
"Magic library is not open",
|
163
|
+
"unknown or invalid flag specified",
|
164
|
+
"flag is not implemented",
|
165
|
+
NULL
|
166
|
+
};
|
167
|
+
|
168
|
+
inline static VALUE
|
169
|
+
magic_size(VALUE v)
|
170
|
+
{
|
171
|
+
if (ARRAY_P(v) || STRING_P(v)) {
|
172
|
+
return rb_funcall(v, rb_intern("size"), 0, NULL);
|
173
|
+
}
|
174
|
+
|
175
|
+
return Qnil;
|
176
|
+
}
|
177
|
+
|
178
|
+
inline static VALUE
|
179
|
+
magic_shift(VALUE v)
|
180
|
+
{
|
181
|
+
if (ARRAY_P(v)) {
|
182
|
+
return rb_funcall(v, rb_intern("shift"), 0, NULL);
|
183
|
+
}
|
184
|
+
|
185
|
+
return Qnil;
|
186
|
+
}
|
187
|
+
|
188
|
+
inline static VALUE
|
189
|
+
magic_split(VALUE a, VALUE b)
|
190
|
+
{
|
191
|
+
if (STRING_P(a) && STRING_P(b)) {
|
192
|
+
return rb_funcall(a, rb_intern("split"), 1, b);
|
193
|
+
}
|
194
|
+
|
195
|
+
return Qnil;
|
196
|
+
}
|
197
|
+
|
198
|
+
inline static VALUE
|
199
|
+
magic_join(VALUE a, VALUE b)
|
200
|
+
{
|
201
|
+
if (ARRAY_P(a) && STRING_P(b)) {
|
202
|
+
return rb_funcall(a, rb_intern("join"), 1, b);
|
203
|
+
}
|
204
|
+
|
205
|
+
return Qnil;
|
206
|
+
}
|
207
|
+
|
208
|
+
RUBY_EXTERN ID id_at_flags, id_at_path, id_at_mutex;
|
209
|
+
|
210
|
+
RUBY_EXTERN VALUE rb_cMagic;
|
211
|
+
|
212
|
+
RUBY_EXTERN VALUE rb_mgc_eError;
|
213
|
+
RUBY_EXTERN VALUE rb_mgc_eMagicError;
|
214
|
+
RUBY_EXTERN VALUE rb_mgc_eLibraryError;
|
215
|
+
RUBY_EXTERN VALUE rb_mgc_eFlagsError;
|
216
|
+
RUBY_EXTERN VALUE rb_mgc_eNotImplementedError;
|
217
|
+
|
218
|
+
RUBY_EXTERN VALUE rb_mgc_initialize(VALUE object, VALUE arguments);
|
219
|
+
|
220
|
+
RUBY_EXTERN VALUE rb_mgc_close(VALUE object);
|
221
|
+
RUBY_EXTERN VALUE rb_mgc_closed(VALUE object);
|
222
|
+
|
223
|
+
RUBY_EXTERN VALUE rb_mgc_get_path(VALUE object);
|
224
|
+
|
225
|
+
RUBY_EXTERN VALUE rb_mgc_get_flags(VALUE object);
|
226
|
+
RUBY_EXTERN VALUE rb_mgc_set_flags(VALUE object, VALUE value);
|
227
|
+
|
228
|
+
RUBY_EXTERN VALUE rb_mgc_load(VALUE object, VALUE arguments);
|
229
|
+
RUBY_EXTERN VALUE rb_mgc_compile(VALUE object, VALUE arguments);
|
230
|
+
RUBY_EXTERN VALUE rb_mgc_check(VALUE object, VALUE arguments);
|
231
|
+
|
232
|
+
RUBY_EXTERN VALUE rb_mgc_file(VALUE object, VALUE value);
|
233
|
+
RUBY_EXTERN VALUE rb_mgc_buffer(VALUE object, VALUE value);
|
234
|
+
RUBY_EXTERN VALUE rb_mgc_descriptor(VALUE object, VALUE value);
|
235
|
+
|
236
|
+
RUBY_EXTERN VALUE rb_mgc_version(VALUE object);
|
237
|
+
|
238
|
+
#if defined(__cplusplus)
|
239
|
+
}
|
240
|
+
#endif
|
241
|
+
|
242
|
+
#endif /* _RUBY_MAGIC_H */
|
243
|
+
|
244
|
+
/* vim: set ts=8 sw=4 sts=2 et : */
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# :stopdoc:
|
4
|
+
|
5
|
+
#
|
6
|
+
# core/file.rb
|
7
|
+
#
|
8
|
+
# Copyright 2013-2014 Krzysztof Wilczynski
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at
|
13
|
+
#
|
14
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
15
|
+
#
|
16
|
+
# Unless required by applicable law or agreed to in writing, software
|
17
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
18
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
19
|
+
# See the License for the specific language governing permissions and
|
20
|
+
# limitations under the License.
|
21
|
+
#
|
22
|
+
|
23
|
+
# :startdoc:
|
24
|
+
|
25
|
+
#
|
26
|
+
#
|
27
|
+
#
|
28
|
+
class File
|
29
|
+
class << self
|
30
|
+
#
|
31
|
+
# call-seq:
|
32
|
+
# File.magic( path ) -> string, array or nil
|
33
|
+
#
|
34
|
+
# Returns
|
35
|
+
#
|
36
|
+
# Example:
|
37
|
+
#
|
38
|
+
# See also: File::mime and File::type
|
39
|
+
#
|
40
|
+
def magic(path, flags = Magic::NONE)
|
41
|
+
path = path.path if path.respond_to?(:path)
|
42
|
+
path ||= path.to_path if path.respond_to?(:to_path)
|
43
|
+
path ||= path.to_s
|
44
|
+
|
45
|
+
Magic.open(flags) {|mgc| mgc.file(path) }
|
46
|
+
rescue Magic::Error
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# call-seq:
|
51
|
+
# File.mime( path ) -> string, array or nil
|
52
|
+
#
|
53
|
+
# Returns
|
54
|
+
#
|
55
|
+
# Example:
|
56
|
+
#
|
57
|
+
# See also: File::magic and File::type
|
58
|
+
#
|
59
|
+
def mime(path)
|
60
|
+
magic(path, Magic::MIME)
|
61
|
+
end
|
62
|
+
|
63
|
+
#
|
64
|
+
# call-seq:
|
65
|
+
# File.type( path ) -> string, array or nil
|
66
|
+
#
|
67
|
+
# Returns
|
68
|
+
#
|
69
|
+
# Example:
|
70
|
+
#
|
71
|
+
# See also: File::magic and File::mime
|
72
|
+
#
|
73
|
+
def type(path)
|
74
|
+
magic(path, Magic::MIME_TYPE)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# call-seq:
|
80
|
+
# File.magic( path ) -> string, array or nil
|
81
|
+
#
|
82
|
+
# Returns
|
83
|
+
#
|
84
|
+
# Example:
|
85
|
+
#
|
86
|
+
# See also: File#mime and File#type
|
87
|
+
#
|
88
|
+
def magic
|
89
|
+
self.class.magic(self)
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# call-seq:
|
94
|
+
# File.mime( path ) -> string, array or nil
|
95
|
+
#
|
96
|
+
# Returns
|
97
|
+
#
|
98
|
+
# Example:
|
99
|
+
#
|
100
|
+
# See also: File#magic and File#type
|
101
|
+
#
|
102
|
+
def mime
|
103
|
+
self.class.mime(self)
|
104
|
+
end
|
105
|
+
|
106
|
+
#
|
107
|
+
# call-seq:
|
108
|
+
# File.type( path ) -> string, array or nil
|
109
|
+
#
|
110
|
+
# Returns
|
111
|
+
#
|
112
|
+
# Example:
|
113
|
+
#
|
114
|
+
# See also: File#magic and File#mime
|
115
|
+
#
|
116
|
+
def type
|
117
|
+
self.class.type(self)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# :enddoc:
|
122
|
+
|
123
|
+
# vim: set ts=2 sw=2 sts=2 et :
|
124
|
+
# encoding: utf-8
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# :stopdoc:
|
4
|
+
|
5
|
+
#
|
6
|
+
# core/string.rb
|
7
|
+
#
|
8
|
+
# Copyright 2013-2014 Krzysztof Wilczynski
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at
|
13
|
+
#
|
14
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
15
|
+
#
|
16
|
+
# Unless required by applicable law or agreed to in writing, software
|
17
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
18
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
19
|
+
# See the License for the specific language governing permissions and
|
20
|
+
# limitations under the License.
|
21
|
+
#
|
22
|
+
|
23
|
+
# :startdoc:
|
24
|
+
|
25
|
+
#
|
26
|
+
#
|
27
|
+
#
|
28
|
+
class String
|
29
|
+
#
|
30
|
+
# call-seq:
|
31
|
+
# string.magic -> string, array or nil
|
32
|
+
#
|
33
|
+
# Returns
|
34
|
+
#
|
35
|
+
# Example:
|
36
|
+
#
|
37
|
+
# See also: String#mime and String#type
|
38
|
+
#
|
39
|
+
def magic(flags = Magic::NONE)
|
40
|
+
Magic.open(flags) {|mgc| mgc.buffer(self) }
|
41
|
+
rescue Magic::Error
|
42
|
+
end
|
43
|
+
|
44
|
+
#
|
45
|
+
# call-seq:
|
46
|
+
# string.mime -> string, array or nil
|
47
|
+
#
|
48
|
+
# Returns
|
49
|
+
#
|
50
|
+
# Example:
|
51
|
+
#
|
52
|
+
# See also: String#magic and String#type
|
53
|
+
#
|
54
|
+
def mime
|
55
|
+
magic(Magic::MIME)
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# call-seq:
|
60
|
+
# string.type -> string, array or nil
|
61
|
+
#
|
62
|
+
# Returns
|
63
|
+
#
|
64
|
+
# Example:
|
65
|
+
#
|
66
|
+
# See also: String#magic and String#mime
|
67
|
+
#
|
68
|
+
def type
|
69
|
+
magic(Magic::MIME_TYPE)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# :enddoc:
|
74
|
+
|
75
|
+
# vim: set ts=2 sw=2 sts=2 et :
|
76
|
+
# encoding: utf-8
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# :stopdoc:
|
4
|
+
|
5
|
+
#
|
6
|
+
# version.rb
|
7
|
+
#
|
8
|
+
# Copyright 2013-2014 Krzysztof Wilczynski
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at
|
13
|
+
#
|
14
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
15
|
+
#
|
16
|
+
# Unless required by applicable law or agreed to in writing, software
|
17
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
18
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
19
|
+
# See the License for the specific language governing permissions and
|
20
|
+
# limitations under the License.
|
21
|
+
#
|
22
|
+
|
23
|
+
# :startdoc:
|
24
|
+
|
25
|
+
class Magic
|
26
|
+
#
|
27
|
+
# Current version of _Magic_.
|
28
|
+
#
|
29
|
+
VERSION = '0.0.1'
|
30
|
+
|
31
|
+
class << self
|
32
|
+
#
|
33
|
+
# call-seq:
|
34
|
+
# Magic.version_to_a -> array
|
35
|
+
#
|
36
|
+
# Returns
|
37
|
+
#
|
38
|
+
# Example:
|
39
|
+
#
|
40
|
+
# Magic.version_to_a #=> [5, 17]
|
41
|
+
#
|
42
|
+
# Will raise <i>Magic::NotImplementedError</i> exception if, or
|
43
|
+
#
|
44
|
+
# See also: Magic::version_to_s
|
45
|
+
#
|
46
|
+
def version_to_a
|
47
|
+
[self.version / 100, self.version % 100]
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# call-seq:
|
52
|
+
# Magic.version_to_s -> string
|
53
|
+
#
|
54
|
+
# Returns
|
55
|
+
#
|
56
|
+
# Example:
|
57
|
+
#
|
58
|
+
# Magic.version_to_s #=> "5.17"
|
59
|
+
#
|
60
|
+
# Will raise <i>Magic::NotImplementedError</i> exception if, or
|
61
|
+
#
|
62
|
+
# See also: Magic::version_to_a
|
63
|
+
#
|
64
|
+
def version_to_s
|
65
|
+
'%d.%02d' % self.version_to_a
|
66
|
+
end
|
67
|
+
|
68
|
+
alias_method :version_array, :version_to_a
|
69
|
+
alias_method :version_string, :version_to_s
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# :enddoc:
|
74
|
+
|
75
|
+
# vim: set ts=2 sw=2 sts=2 et :
|
76
|
+
# encoding: utf-8
|
data/lib/magic.rb
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
# :stopdoc:
|
4
|
+
|
5
|
+
#
|
6
|
+
# magic.rb
|
7
|
+
#
|
8
|
+
# Copyright 2013-2014 Krzysztof Wilczynski
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at
|
13
|
+
#
|
14
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
15
|
+
#
|
16
|
+
# Unless required by applicable law or agreed to in writing, software
|
17
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
18
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
19
|
+
# See the License for the specific language governing permissions and
|
20
|
+
# limitations under the License.
|
21
|
+
#
|
22
|
+
|
23
|
+
require 'magic/magic'
|
24
|
+
require 'magic/version'
|
25
|
+
require 'magic/core/file'
|
26
|
+
require 'magic/core/string'
|
27
|
+
|
28
|
+
# :startdoc:
|
29
|
+
|
30
|
+
#
|
31
|
+
# File _Magic_ in Ruby.
|
32
|
+
#
|
33
|
+
# Simple interface to _libmagic_ for Ruby Programming Language.
|
34
|
+
#
|
35
|
+
class Magic
|
36
|
+
#
|
37
|
+
# call-seq:
|
38
|
+
# magic.inspect -> string
|
39
|
+
#
|
40
|
+
# Returns
|
41
|
+
#
|
42
|
+
# Example:
|
43
|
+
#
|
44
|
+
# magic = Magic.new #=> #<Magic:0x007fd5258a1108>
|
45
|
+
# magic.inspect #=> "#<Magic:0x007fd5258a1108 @flags=0, @path=[\"/etc/magic\", \"/usr/share/misc/magic\"]>"
|
46
|
+
#
|
47
|
+
def inspect
|
48
|
+
super.insert(-2, self.closed? ? ' (closed)' : '')
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# call-seq:
|
53
|
+
# magic.flags_to_a( names ) -> array
|
54
|
+
#
|
55
|
+
# Returns an +array+
|
56
|
+
#
|
57
|
+
# Example:
|
58
|
+
#
|
59
|
+
# Will raise <i>Magic::LibraryError</i> exception if, or
|
60
|
+
#
|
61
|
+
# See also: Magic#flags
|
62
|
+
#
|
63
|
+
def flags_to_a(names = false)
|
64
|
+
raise LibraryError, "Magic library is not open" if closed?
|
65
|
+
|
66
|
+
n, i = 0, @flags
|
67
|
+
|
68
|
+
flags = []
|
69
|
+
|
70
|
+
return [names ? 'NONE' : 0] if @flags.zero?
|
71
|
+
|
72
|
+
@@flags_map ||= flags_as_map if names
|
73
|
+
|
74
|
+
while i > 0
|
75
|
+
n = 2 ** (Math.log(i) / Math.log(2)).to_i
|
76
|
+
i = i - n
|
77
|
+
flags.insert(0, names ? @@flags_map[n] : n)
|
78
|
+
end
|
79
|
+
|
80
|
+
flags
|
81
|
+
end
|
82
|
+
|
83
|
+
class << self
|
84
|
+
#
|
85
|
+
# call-seq:
|
86
|
+
# Magic.open( flags ) -> self
|
87
|
+
# Magic.open( flags ) {|magic| block } -> string or array
|
88
|
+
#
|
89
|
+
# Returns
|
90
|
+
#
|
91
|
+
# Example:
|
92
|
+
#
|
93
|
+
# See also: Magic::mime, Magic::type, Magic::encoding, Magic::compile and Magic::check
|
94
|
+
#
|
95
|
+
def open(flags = Magic::NONE)
|
96
|
+
magic = Magic.new
|
97
|
+
magic.flags = flags
|
98
|
+
|
99
|
+
if block_given?
|
100
|
+
begin
|
101
|
+
yield magic
|
102
|
+
ensure
|
103
|
+
magic.close
|
104
|
+
end
|
105
|
+
else
|
106
|
+
magic
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
#
|
111
|
+
# call-seq:
|
112
|
+
# Magic.mime -> self
|
113
|
+
# Magic.mime {|magic| block } -> string or array
|
114
|
+
#
|
115
|
+
# Returns
|
116
|
+
#
|
117
|
+
# Example:
|
118
|
+
#
|
119
|
+
# See also: Magic::open, Magic::type, Magic::encoding, Magic::compile and Magic::check
|
120
|
+
#
|
121
|
+
def mime(&block)
|
122
|
+
open(Magic::MIME, &block)
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# call-seq:
|
127
|
+
# Magic.type -> self
|
128
|
+
# Magic.type {|magic| block } -> string or array
|
129
|
+
#
|
130
|
+
# Returns
|
131
|
+
#
|
132
|
+
# Example:
|
133
|
+
#
|
134
|
+
# See also: Magic::open, Magic::mime, Magic::encoding, Magic::compile and Magic::check
|
135
|
+
#
|
136
|
+
def type(&block)
|
137
|
+
open(Magic::MIME_TYPE, &block)
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
# call-seq:
|
142
|
+
# Magic.encoding -> self
|
143
|
+
# Magic.encoding {|magic| block } -> string or array
|
144
|
+
#
|
145
|
+
# Returns
|
146
|
+
#
|
147
|
+
# Example:
|
148
|
+
#
|
149
|
+
# See also: Magic::open, Magic::mime, Magic::type, Magic::compile and Magic::check
|
150
|
+
#
|
151
|
+
def encoding(&block)
|
152
|
+
open(Magic::MIME_ENCODING, &block)
|
153
|
+
end
|
154
|
+
|
155
|
+
#
|
156
|
+
# call-seq:
|
157
|
+
# Magic.compile( path, ... ) -> true
|
158
|
+
# Magic.compile( array ) -> true
|
159
|
+
#
|
160
|
+
# Returns
|
161
|
+
#
|
162
|
+
# Example:
|
163
|
+
#
|
164
|
+
# See also: Magic::open, Magic::mime, Magic::type, Magic::encoding, and Magic::check
|
165
|
+
#
|
166
|
+
def compile(path)
|
167
|
+
open {|m| m.compile(path) }
|
168
|
+
end
|
169
|
+
|
170
|
+
#
|
171
|
+
# call-seq:
|
172
|
+
# Magic.check( path, ... ) -> true or false
|
173
|
+
# Magic.check( array ) -> true or false
|
174
|
+
#
|
175
|
+
# Returns
|
176
|
+
#
|
177
|
+
# Example:
|
178
|
+
#
|
179
|
+
# See also: Magic::open, Magic::mime, Magic::type, Magic::encoding and Magic::compile
|
180
|
+
#
|
181
|
+
def check(path)
|
182
|
+
open {|m| m.check(path) }
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
alias_method :flags_array, :flags_to_a
|
187
|
+
|
188
|
+
private
|
189
|
+
|
190
|
+
def flags_as_map
|
191
|
+
self.class.constants.inject({}) do |flags,constant|
|
192
|
+
value = self.class.const_get(constant)
|
193
|
+
flags[value] = constant.to_s if value.is_a?(Fixnum)
|
194
|
+
flags
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# :enddoc:
|
200
|
+
|
201
|
+
FileMagic = Magic
|
202
|
+
|
203
|
+
# vim: set ts=2 sw=2 sts=2 et :
|
204
|
+
# encoding: utf-8
|