Class: FileMagic

Inherits:
Object
  • Object
show all
Defined in:
lib/filemagic.rb,
lib/filemagic/version.rb,
ext/filemagic.c

Defined Under Namespace

Modules: Ext, Version Classes: FileMagicError

Constant Summary collapse

MAGIC_FLAGS =

Map abbreviated flag names to their values (:name => Constant).

[
  :none,               # No flags
  :debug,              # Turn on debugging
  :symlink,            # Follow symlinks
  :compress,           # Check inside compressed files
  :devices,            # Look at the contents of devices
  :mime_type,          # Return only the MIME type
  :continue,           # Return all matches
  :check,              # Print warnings to stderr
  :preserve_atime,     # Restore access time on exit
  :raw,                # Don't translate unprint chars
  :error,              # Handle ENOENT etc as real errors
  :mime_encoding,      # Return only the MIME encoding
  :mime,               # MAGIC_MIME_TYPE | MAGIC_MIME_ENCODING
  :no_check_compress,  # Don't check for compressed files
  :no_check_tar,       # Don't check for tar files
  :no_check_soft,      # Don't check magic entries
  :no_check_apptype,   # Don't check application type
  :no_check_elf,       # Don't check for elf details
  :no_check_ascii,     # Don't check for ascii files
  :no_check_troff,     # Don't check ascii/troff
  :no_check_tokens,    # Don't check ascii/tokens
  :no_check_fortran    # Don't check ascii/fortran
].inject({}) { |flags, flag|
  const = "MAGIC_#{flag.to_s.upcase}"
  flags.update(flag => const_defined?(const) && const_get(const))
}
VERSION =
Version.to_s
MAGIC_NONE =
INT2FIX(MAGIC_NONE)
MAGIC_DEBUG =
INT2FIX(MAGIC_DEBUG)
INT2FIX(MAGIC_SYMLINK)
MAGIC_COMPRESS =
INT2FIX(MAGIC_COMPRESS)
MAGIC_DEVICES =
INT2FIX(MAGIC_DEVICES)
MAGIC_MIME_TYPE =
INT2FIX(MAGIC_MIME_TYPE)
MAGIC_CONTINUE =
INT2FIX(MAGIC_CONTINUE)
MAGIC_CHECK =
INT2FIX(MAGIC_CHECK)
MAGIC_PRESERVE_ATIME =
INT2FIX(MAGIC_PRESERVE_ATIME)
MAGIC_RAW =
INT2FIX(MAGIC_RAW)
MAGIC_ERROR =
INT2FIX(MAGIC_ERROR)
MAGIC_MIME_ENCODING =
INT2FIX(MAGIC_MIME_ENCODING)
MAGIC_MIME =
INT2FIX(MAGIC_MIME)
MAGIC_NO_CHECK_COMPRESS =
INT2FIX(MAGIC_NO_CHECK_COMPRESS)
MAGIC_NO_CHECK_TAR =
INT2FIX(MAGIC_NO_CHECK_TAR)
MAGIC_NO_CHECK_SOFT =
INT2FIX(MAGIC_NO_CHECK_SOFT)
MAGIC_NO_CHECK_APPTYPE =
INT2FIX(MAGIC_NO_CHECK_APPTYPE)
MAGIC_NO_CHECK_ELF =
INT2FIX(MAGIC_NO_CHECK_ELF)
MAGIC_NO_CHECK_ASCII =
INT2FIX(MAGIC_NO_CHECK_ASCII)
MAGIC_NO_CHECK_TROFF =
INT2FIX(MAGIC_NO_CHECK_TROFF)
MAGIC_NO_CHECK_TOKENS =
INT2FIX(MAGIC_NO_CHECK_TOKENS)
MAGIC_NO_CHECK_FORTRAN =
INT2FIX(MAGIC_NO_CHECK_FORTRAN)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*flags) ⇒ FileMagic

The actual processing happens in #new.



116
117
118
119
120
121
# File 'lib/filemagic.rb', line 116

def initialize(*flags)
  fm_initialize(*flags)

  @flags  = *flags
  @closed = false
end

Instance Attribute Details

#flagsObject (readonly)

Returns the value of attribute flags.



34
35
36
# File 'lib/filemagic.rb', line 34

def flags
  @flags
end

#simplified=(value) ⇒ Object (writeonly)

Sets the attribute simplified

Parameters:

  • value

    the value to set the attribute simplified to.



35
36
37
# File 'lib/filemagic.rb', line 35

def simplified=(value)
  @simplified = value
end

Class Method Details

.build_flags(*flags) ⇒ Object

Build the actual flags from the named flags passed as arguments.



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/filemagic.rb', line 95

def build_flags(*flags)
  _flags = *flags

  unless _flags.is_a?(Integer)
    _flags = MAGIC_NONE

    flags.flatten.each { |flag|
      if value = flag.is_a?(Integer) ? flag : MAGIC_FLAGS[flag.to_sym]
        _flags |= value
      else
        raise ArgumentError, "#{value.nil? ? 'no such flag' : 'flag not available'}: #{flag}"
      end
    }
  end

  _flags
end

.clear!Object

Clear our instance cache.



50
51
52
53
# File 'lib/filemagic.rb', line 50

def clear!
  @fm.each_value { |fm| fm.close }
  @fm.clear
end

.fm(*flags) ⇒ Object

Provide a “magic singleton” ;-)



44
45
46
47
# File 'lib/filemagic.rb', line 44

def fm(*flags)
  @fm.delete(flags.to_s) if @fm[flags].closed?
  @fm[flags]
end

.fm_new(flags) ⇒ Object

FileMagic.new



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'ext/filemagic.c', line 52

static VALUE rb_magic_new(VALUE class, VALUE flags) {
  VALUE obj;
  magic_t cookie;

  cookie = magic_open(NUM2INT(flags));
  if (cookie == NULL)
    rb_fatal("out of memory");
  if (magic_load(cookie, NULL) == -1)
    rb_fatal("%s", magic_error(cookie));

  obj = Data_Wrap_Struct(class, 0, rb_magic_free, cookie);
  rb_obj_call_init(obj, 1, &flags);

  return obj;
}

.mime(*flags, &block) ⇒ Object

Just a short-cut ;-)



90
91
92
# File 'lib/filemagic.rb', line 90

def mime(*flags, &block)
  open(:mime, *flags, &block)
end

.new(*flags) ⇒ Object

Allow shorter names for flags; now also takes options.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/filemagic.rb', line 56

def new(*flags)
  warn "warning: FileMagic::new() does not take block; use FileMagic::open() instead" if block_given?

  options = flags.last.is_a?(Hash) ? flags.pop : {}

  fm = fm_new(build_flags(*flags))

  options.each { |option, value|
    if fm.respond_to?(method = "#{option}=")
      fm.send(method, value)
    else
      raise ArgumentError, "illegal option: #{option.inspect}"
    end
  }

  fm
end

.open(*flags) ⇒ Object

Just like #new, but takes an optional block, in which case #close is called at the end.



75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/filemagic.rb', line 75

def open(*flags)
  fm = new(*flags)

  if block_given?
    begin
      yield fm
    ensure
      fm.close
    end
  end

  fm
end

Instance Method Details

#buffer(buffer, simplified = simplified?) ) ⇒ Object

Optionally cut off additional information after mime-type.



136
137
138
# File 'lib/filemagic.rb', line 136

def buffer(buffer, simplified = simplified?)
  simplify_mime(fm_buffer(buffer), simplified)
end

#check(file = "\0") ⇒ Object Also known as: valid?



148
149
150
# File 'lib/filemagic.rb', line 148

def check(file = "\0")
  fm_check(file)
end

#closeObject



123
124
125
126
127
128
# File 'lib/filemagic.rb', line 123

def close
  return if closed?

  fm_close
  @closed = true
end

#closed?Boolean

Returns:

  • (Boolean)


161
162
163
# File 'lib/filemagic.rb', line 161

def closed?
  @closed
end

#compile(file) ⇒ Object



153
154
155
# File 'lib/filemagic.rb', line 153

def compile(file)
  fm_compile(file)
end

#file(file, simplified = simplified?) ) ⇒ Object

Optionally cut off additional information after mime-type.



131
132
133
# File 'lib/filemagic.rb', line 131

def file(file, simplified = simplified?)
  simplify_mime(fm_file(file), simplified)
end

#fm_buffer(buffer) ⇒ Object

Return a string describing the string buffer



82
83
84
85
86
87
88
89
90
91
92
93
# File 'ext/filemagic.c', line 82

static VALUE rb_magic_buffer(VALUE self, VALUE buffer) {
  int i = RSTRING(buffer)->len;
  const char *m;
  magic_t cookie;

  m = STR2CSTR(buffer);
  GetMagicCookie(self, cookie);
  if ((m = magic_buffer(cookie, m, i)) == NULL)
    rb_raise(rb_FileMagicError, magic_error(cookie));

  return rb_str_new2(m);
}

#fm_check(file) ⇒ Object

Checks validity of a magic database file



107
108
109
110
111
112
113
114
115
116
117
# File 'ext/filemagic.c', line 107

static VALUE rb_magic_check(VALUE self, VALUE file) {
  int retval;
  const char *m;
  magic_t cookie;

  GetMagicCookie(self, cookie);
  m = STR2CSTR(file);
  retval = magic_check(cookie, m);

  return INT2FIX(retval);
}

#fm_closeObject

Frees resources allocated



39
40
41
42
43
44
45
46
47
48
49
# File 'ext/filemagic.c', line 39

static VALUE rb_magic_close(VALUE self) {
  magic_t cookie;

  GetMagicCookie(self, cookie);
  magic_close(cookie);

  /* This keeps rb_magic_free from trying to free closed objects */
  RDATA(self)->data = NULL;

  return Qnil;
}

#fm_compile(file) ⇒ Object

Compiles a magic database file



120
121
122
123
124
125
126
127
128
129
130
# File 'ext/filemagic.c', line 120

static VALUE rb_magic_compile(VALUE self, VALUE file) {
  int retval;
  const char *m;
  magic_t cookie;

  GetMagicCookie(self, cookie);
  m = STR2CSTR(file);
  retval = magic_compile(cookie, m);

  return INT2FIX(retval);
}

#fm_file(file) ⇒ Object

Return a string describing file



69
70
71
72
73
74
75
76
77
78
79
# File 'ext/filemagic.c', line 69

static VALUE rb_magic_file(VALUE self, VALUE file) {
  const char *m;
  magic_t cookie;

  m = STR2CSTR(file);
  GetMagicCookie(self, cookie);
  if ((m = magic_file(cookie, m)) == NULL)
    rb_raise(rb_FileMagicError, magic_error(cookie));

  return rb_str_new2(m);
}

#fm_initialize(flags) ⇒ Object



35
36
# File 'ext/filemagic.c', line 35

static VALUE rb_magic_init(VALUE self, VALUE flags) {
}

#fm_setflags(flags) ⇒ Object

Set flags on the cookie object



96
97
98
99
100
101
102
103
104
# File 'ext/filemagic.c', line 96

static VALUE rb_magic_setflags(VALUE self, VALUE flags) {
  int retval;
  magic_t cookie;

  GetMagicCookie(self, cookie);
  retval = magic_setflags(cookie, NUM2INT(flags));

  return INT2FIX(retval);
}

#inspectObject



165
166
167
168
169
# File 'lib/filemagic.rb', line 165

def inspect
  str = super
  str.insert(-2, ' (closed)') if closed?
  str
end

#setflags(*flags) ⇒ Object Also known as: flags=



140
141
142
143
144
145
# File 'lib/filemagic.rb', line 140

def setflags(*flags)
  previous_flags, @flags = @flags, self.class.build_flags(*flags)
  fm_setflags(@flags)

  previous_flags
end

#simplified?Boolean

Returns:

  • (Boolean)


157
158
159
# File 'lib/filemagic.rb', line 157

def simplified?
  @simplified
end