ruby-magic 0.0.1
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 +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
|