xs_mime.h (2056B)
1 /* copyright (c) 2022 - 2025 grunfink et al. / MIT license */ 2 3 #ifndef _XS_MIME_H 4 5 #define _XS_MIME_H 6 7 const char *xs_mime_by_ext(const char *file); 8 9 extern const char *xs_mime_types[]; 10 11 #ifdef XS_IMPLEMENTATION 12 13 /* intentionally brain-dead simple */ 14 /* CAUTION: sorted by extension */ 15 16 const char *xs_mime_types[] = { 17 "3gp", "video/3gpp", 18 "aac", "audio/aac", 19 "apng", "image/apng", 20 "avif", "image/avif", 21 "css", "text/css", 22 "flac", "audio/flac", 23 "flv", "video/flv", 24 "gif", "image/gif", 25 "gmi", "text/gemini", 26 "html", "text/html", 27 "jpeg", "image/jpeg", 28 "jpg", "image/jpeg", 29 "json", "application/json", 30 "m4a", "audio/aac", 31 "m4v", "video/mp4", 32 "md", "text/markdown", 33 "mov", "video/quicktime", 34 "mp3", "audio/mp3", 35 "mp4", "video/mp4", 36 "mpg4", "video/mp4", 37 "oga", "audio/ogg", 38 "ogg", "audio/ogg", 39 "ogv", "video/ogg", 40 "opus", "audio/ogg", 41 "png", "image/png", 42 "svg", "image/svg+xml", 43 "svgz", "image/svg+xml", 44 "txt", "text/plain", 45 "wav", "audio/wav", 46 "webm", "video/webm", 47 "webp", "image/webp", 48 "wma", "audio/wma", 49 "xml", "text/xml", 50 NULL, NULL, 51 }; 52 53 54 const char *xs_mime_by_ext(const char *file) 55 /* returns the MIME type by file extension */ 56 { 57 const char *ext = strrchr(file, '.'); 58 59 if (ext) { 60 xs *uext = xs_tolower_i(xs_dup(ext + 1)); 61 int b = 0; 62 int t = xs_countof(xs_mime_types) / 2 - 2; 63 64 while (t >= b) { 65 int n = (b + t) / 2; 66 const char *p = xs_mime_types[n * 2]; 67 68 int c = strcmp(uext, p); 69 70 if (c < 0) 71 t = n - 1; 72 else 73 if (c > 0) 74 b = n + 1; 75 else 76 return xs_mime_types[(n * 2) + 1]; 77 } 78 } 79 80 return "application/octet-stream"; 81 } 82 83 84 #endif /* XS_IMPLEMENTATION */ 85 86 #endif /* XS_MIME_H */