content_type 2.1.2 → 2.1.3

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.
Files changed (4) hide show
  1. data/README +1 -0
  2. data/Rakefile +2 -2
  3. data/ext/content_type.c +24 -1
  4. metadata +3 -3
data/README CHANGED
@@ -16,6 +16,7 @@ SYNOPSIS
16
16
  irb> require 'content_type'
17
17
  irb> File.content_type('file.pdf') #=> "application/pdf"
18
18
  irb> File.open('file.doc').content_type #=> "application/msword"
19
+ irb> "hi".content_type #=> "text/plain"
19
20
  irb> ContentType.new('file.jpg').content_type #=> "image/jpeg"
20
21
 
21
22
  DESCRIPTION
data/Rakefile CHANGED
@@ -29,8 +29,8 @@ Jeweler::Tasks.new do |s|
29
29
  s.email = 'dsturnbull@me.com'
30
30
  s.homepage = 'http://github.com/dsturnbull/content_type'
31
31
  s.description =<<-eod
32
- Provides ContentType#content_type, File#content_type and
33
- File::content_type methods to determine mime type
32
+ Provides ContentType#content_type, File#content_type, File::content_type
33
+ and String#content_type methods to determine mime type
34
34
  eod
35
35
  s.executables = []
36
36
  s.authors = ['David Turnbull']
data/ext/content_type.c CHANGED
@@ -4,19 +4,27 @@
4
4
  #include <sys/stat.h>
5
5
  #include <stdbool.h>
6
6
 
7
+ // see libmagic(3)
7
8
  #define MAGIC_OPTIONS MAGIC_SYMLINK | MAGIC_MIME_TYPE | MAGIC_PRESERVE_ATIME
9
+
10
+ // presume file extensions are at max 16 chars. this is fine for now since
11
+ // only microsoft crap is overridden.
8
12
  #define MAX_EXT_LEN 16
9
13
 
14
+ // ContentType prototypes
10
15
  VALUE content_type = Qnil;
11
16
  VALUE content_type_initialize(VALUE self, VALUE path);
12
17
  VALUE content_type_content_type(VALUE self);
13
18
 
19
+ // File prototypes
14
20
  VALUE file_content_type_wrap(VALUE self, VALUE path);
15
21
  VALUE file_content_type(VALUE self);
16
22
  VALUE file_singleton_content_type(VALUE self, VALUE path);
17
23
 
24
+ // String prototypes
18
25
  VALUE string_content_type(VALUE self);
19
26
 
27
+ // internal prototypes
20
28
  bool content_type_file_ext(VALUE self, char *ext);
21
29
  void magic_fail(const char *error);
22
30
 
@@ -41,6 +49,7 @@ const char *content_type_ext_overrides[][2] = {
41
49
  { "xltx", "application/vnd.openxmlformats-officedocument.spreadsheetml.template" },
42
50
  };
43
51
 
52
+ // Init_content_type - initialize the extension
44
53
  void
45
54
  Init_content_type()
46
55
  {
@@ -64,6 +73,8 @@ Init_content_type()
64
73
  rb_define_method(rb_cString, "content_type", string_content_type, 0);
65
74
  }
66
75
 
76
+ // content_type_initialize - initialize the object and check file path exists
77
+ //
67
78
  // iv @content_type, @filepath and @processed are available in all variations
68
79
  // because each implementation creates a ContentType obj through here
69
80
  // (except String#content_type)
@@ -85,7 +96,7 @@ content_type_initialize(VALUE self, VALUE path)
85
96
  return self;
86
97
  }
87
98
 
88
- // content_type_file_ext
99
+ // content_type_file_ext - return the file extension of the file
89
100
  bool
90
101
  content_type_file_ext(VALUE self, char *ext)
91
102
  {
@@ -115,6 +126,7 @@ content_type_file_ext(VALUE self, char *ext)
115
126
  return false;
116
127
  }
117
128
 
129
+ // content_type_content_type - check for hardcoded extensions or use libmagic
118
130
  VALUE
119
131
  content_type_content_type(VALUE self)
120
132
  {
@@ -125,6 +137,7 @@ content_type_content_type(VALUE self)
125
137
  char ext[MAX_EXT_LEN]; // TODO dynamicly sized
126
138
  int i;
127
139
 
140
+ // check for hardcoded extension overrides first
128
141
  if (content_type_file_ext(self, ext))
129
142
  for (i = sizeof(content_type_ext_overrides) / sizeof(char *) / 2 - 1;
130
143
  i >= 0; i--) {
@@ -134,12 +147,14 @@ content_type_content_type(VALUE self)
134
147
 
135
148
  if ((memcmp(ext, o_ext, strlen(o_ext))) == 0) {
136
149
  ct = rb_str_new2(o_mime);
150
+ // memoize
137
151
  rb_iv_set(self, "@content_type", ct);
138
152
  rb_iv_set(self, "@processed", Qtrue);
139
153
  return ct;
140
154
  }
141
155
  }
142
156
 
157
+ // otherwise use libmagic to get the mime type
143
158
  if (rb_iv_get(self, "@processed"))
144
159
  return rb_iv_get(self, "@content_type");
145
160
 
@@ -153,6 +168,8 @@ content_type_content_type(VALUE self)
153
168
  magic_fail("file");
154
169
 
155
170
  ct = rb_str_new(mime, strlen(mime));
171
+
172
+ // memoize
156
173
  rb_iv_set(self, "@content_type", ct);
157
174
  rb_iv_set(self, "@processed", Qtrue);
158
175
  magic_close(mh);
@@ -160,6 +177,7 @@ content_type_content_type(VALUE self)
160
177
  return ct;
161
178
  }
162
179
 
180
+ // file_content_type_wrap - pass file path into ContentType#content_type
163
181
  VALUE
164
182
  file_content_type_wrap(VALUE self, VALUE path)
165
183
  {
@@ -172,18 +190,21 @@ file_content_type_wrap(VALUE self, VALUE path)
172
190
  return rb_funcall(ct, rb_intern("content_type"), 0);
173
191
  }
174
192
 
193
+ // file_content_type - provide File#content_type
175
194
  VALUE
176
195
  file_content_type(VALUE self)
177
196
  {
178
197
  return file_content_type_wrap(self, rb_funcall(self, rb_intern("path"), 0));
179
198
  }
180
199
 
200
+ // file_singleton_content_type - provide File.content_type
181
201
  VALUE
182
202
  file_singleton_content_type(VALUE self, VALUE path)
183
203
  {
184
204
  return file_content_type_wrap(self, path);
185
205
  }
186
206
 
207
+ // string_content_type - pass the string as a buffer to libmagic
187
208
  VALUE
188
209
  string_content_type(VALUE self)
189
210
  {
@@ -209,6 +230,7 @@ string_content_type(VALUE self)
209
230
  return ct;
210
231
  }
211
232
 
233
+ // magic_fail - raise exceptions
212
234
  void
213
235
  magic_fail(const char *error)
214
236
  {
@@ -219,3 +241,4 @@ magic_fail(const char *error)
219
241
  sprintf((char *)error_message, format, error);
220
242
  rb_raise(rb_const_get(rb_cObject, rb_intern("RuntimeError")), error_message);
221
243
  }
244
+
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 2
7
7
  - 1
8
- - 2
9
- version: 2.1.2
8
+ - 3
9
+ version: 2.1.3
10
10
  platform: ruby
11
11
  authors:
12
12
  - David Turnbull
@@ -18,7 +18,7 @@ date: 2010-04-10 00:00:00 +10:00
18
18
  default_executable:
19
19
  dependencies: []
20
20
 
21
- description: " Provides ContentType#content_type, File#content_type and\n File::content_type methods to determine mime type\n"
21
+ description: " Provides ContentType#content_type, File#content_type, File::content_type\n and String#content_type methods to determine mime type\n"
22
22
  email: dsturnbull@me.com
23
23
  executables: []
24
24