|
26 | 26 | #include <iostream> |
27 | 27 | #include <iomanip> |
28 | 28 | #include <map> |
| 29 | +#include <string_view> |
29 | 30 |
|
30 | 31 | #include <zlib.h> |
31 | 32 | #include <magic.h> |
32 | 33 |
|
33 | | -/* Init file extensions hash */ |
34 | | -static std::map<std::string, std::string> _create_extMimeTypes() |
35 | | -{ |
36 | | - std::map<std::string, std::string> extMimeTypes; |
37 | | - extMimeTypes["HTML"] = "text/html"; |
38 | | - extMimeTypes["html"] = "text/html"; |
39 | | - extMimeTypes["HTM"] = "text/html"; |
40 | | - extMimeTypes["htm"] = "text/html"; |
41 | | - extMimeTypes["PNG"] = "image/png"; |
42 | | - extMimeTypes["png"] = "image/png"; |
43 | | - extMimeTypes["TIFF"] = "image/tiff"; |
44 | | - extMimeTypes["tiff"] = "image/tiff"; |
45 | | - extMimeTypes["TIF"] = "image/tiff"; |
46 | | - extMimeTypes["tif"] = "image/tiff"; |
47 | | - extMimeTypes["JPEG"] = "image/jpeg"; |
48 | | - extMimeTypes["jpeg"] = "image/jpeg"; |
49 | | - extMimeTypes["JPG"] = "image/jpeg"; |
50 | | - extMimeTypes["jpg"] = "image/jpeg"; |
51 | | - extMimeTypes["GIF"] = "image/gif"; |
52 | | - extMimeTypes["gif"] = "image/gif"; |
53 | | - extMimeTypes["SVG"] = "image/svg+xml"; |
54 | | - extMimeTypes["svg"] = "image/svg+xml"; |
55 | | - extMimeTypes["TXT"] = "text/plain"; |
56 | | - extMimeTypes["txt"] = "text/plain"; |
57 | | - extMimeTypes["XML"] = "text/xml"; |
58 | | - extMimeTypes["xml"] = "text/xml"; |
59 | | - extMimeTypes["EPUB"] = "application/epub+zip"; |
60 | | - extMimeTypes["epub"] = "application/epub+zip"; |
61 | | - extMimeTypes["PDF"] = "application/pdf"; |
62 | | - extMimeTypes["pdf"] = "application/pdf"; |
63 | | - extMimeTypes["OGG"] = "audio/ogg"; |
64 | | - extMimeTypes["ogg"] = "audio/ogg"; |
65 | | - extMimeTypes["OGV"] = "video/ogg"; |
66 | | - extMimeTypes["ogv"] = "video/ogg"; |
67 | | - extMimeTypes["JS"] = "application/javascript"; |
68 | | - extMimeTypes["js"] = "application/javascript"; |
69 | | - extMimeTypes["JSON"] = "application/json"; |
70 | | - extMimeTypes["json"] = "application/json"; |
71 | | - extMimeTypes["CSS"] = "text/css"; |
72 | | - extMimeTypes["css"] = "text/css"; |
73 | | - extMimeTypes["otf"] = "font/otf"; |
74 | | - extMimeTypes["OTF"] = "font/otf"; |
75 | | - extMimeTypes["sfnt"] = "font/sfnt"; |
76 | | - extMimeTypes["SFNT"] = "font/sfnt"; |
77 | | - extMimeTypes["eot"] = "application/vnd.ms-fontobject"; |
78 | | - extMimeTypes["EOT"] = "application/vnd.ms-fontobject"; |
79 | | - extMimeTypes["ttf"] = "font/ttf"; |
80 | | - extMimeTypes["TTF"] = "font/ttf"; |
81 | | - extMimeTypes["collection"] = "font/collection"; |
82 | | - extMimeTypes["COLLECTION"] = "font/collection"; |
83 | | - extMimeTypes["woff"] = "font/woff"; |
84 | | - extMimeTypes["WOFF"] = "font/woff"; |
85 | | - extMimeTypes["woff2"] = "font/woff2"; |
86 | | - extMimeTypes["WOFF2"] = "font/woff2"; |
87 | | - extMimeTypes["vtt"] = "text/vtt"; |
88 | | - extMimeTypes["VTT"] = "text/vtt"; |
89 | | - extMimeTypes["webm"] = "video/webm"; |
90 | | - extMimeTypes["WEBM"] = "video/webm"; |
91 | | - extMimeTypes["webp"] = "image/webp"; |
92 | | - extMimeTypes["WEBP"] = "image/webp"; |
93 | | - extMimeTypes["mp4"] = "video/mp4"; |
94 | | - extMimeTypes["MP4"] = "video/mp4"; |
95 | | - extMimeTypes["doc"] = "application/msword"; |
96 | | - extMimeTypes["DOC"] = "application/msword"; |
97 | | - extMimeTypes["docx"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; |
98 | | - extMimeTypes["DOCX"] = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; |
99 | | - extMimeTypes["ppt"] = "application/vnd.ms-powerpoint"; |
100 | | - extMimeTypes["PPT"] = "application/vnd.ms-powerpoint"; |
101 | | - extMimeTypes["odt"] = "application/vnd.oasis.opendocument.text"; |
102 | | - extMimeTypes["ODT"] = "application/vnd.oasis.opendocument.text"; |
103 | | - extMimeTypes["odp"] = "application/vnd.oasis.opendocument.text"; |
104 | | - extMimeTypes["ODP"] = "application/vnd.oasis.opendocument.text"; |
105 | | - extMimeTypes["zip"] = "application/zip"; |
106 | | - extMimeTypes["ZIP"] = "application/zip"; |
107 | | - extMimeTypes["wasm"] = "application/wasm"; |
108 | | - extMimeTypes["WASM"] = "application/wasm"; |
109 | | - |
110 | | - return extMimeTypes; |
111 | | -} |
| 34 | +// adapted from cppreference example implementation of lexicographical_compare |
| 35 | +struct tolower_str_comparator { |
| 36 | + using UChar_t = unsigned char; |
| 37 | + |
| 38 | + static constexpr UChar_t toLower(const UChar_t c) noexcept { |
| 39 | + constexpr UChar_t offset {'a' - 'A'}; |
| 40 | + return (c <= 'Z' && c >= 'A') ? c + offset : c; |
| 41 | + } |
| 42 | + |
| 43 | + static constexpr bool charCompare(const UChar_t lhs, const UChar_t rhs) noexcept { |
| 44 | + return toLower(lhs) < toLower(rhs); |
| 45 | + } |
112 | 46 |
|
113 | | -static std::map<std::string, std::string> extMimeTypes = _create_extMimeTypes(); |
| 47 | + constexpr bool operator() (const std::string_view lhs, const std::string_view rhs) const noexcept { |
| 48 | + auto first1 = lhs.cbegin(); |
| 49 | + const auto last1 = lhs.cend(); |
| 50 | + auto first2 = rhs.cbegin(); |
| 51 | + const auto last2 = rhs.cend(); |
| 52 | + |
| 53 | + for (; (first1 != last1) && (first2 != last2); ++first1, ++first2) { |
| 54 | + if (charCompare(*first1, *first2)) { |
| 55 | + return true; |
| 56 | + } |
| 57 | + if (charCompare(*first2, *first1)) { |
| 58 | + return false; |
| 59 | + } |
| 60 | + } |
| 61 | + return (first1 == last1) && (first2 != last2); |
| 62 | + } |
| 63 | +}; |
| 64 | + |
| 65 | +using MimeMap_t = std::map<std::string, const std::string, tolower_str_comparator>; |
| 66 | + |
| 67 | +static const MimeMap_t extMimeTypes { |
| 68 | + {"html", "text/html"}, |
| 69 | + {"htm", "text/html"}, |
| 70 | + {"png", "image/png"}, |
| 71 | + {"tiff", "image/tiff"}, |
| 72 | + {"tif", "image/tiff"}, |
| 73 | + {"jpeg", "image/jpeg"}, |
| 74 | + {"jpg", "image/jpeg"}, |
| 75 | + {"gif", "image/gif"}, |
| 76 | + {"svg", "image/svg+xml"}, |
| 77 | + {"txt", "text/plain"}, |
| 78 | + {"xml", "text/xml"}, |
| 79 | + {"epub", "application/epub+zip"}, |
| 80 | + {"pdf", "application/pdf"}, |
| 81 | + {"ogg", "audio/ogg"}, |
| 82 | + {"ogv", "video/ogg"}, |
| 83 | + {"js", "application/javascript"}, |
| 84 | + {"json", "application/json"}, |
| 85 | + {"css", "text/css"}, |
| 86 | + {"otf", "font/otf"}, |
| 87 | + {"sfnt", "font/sfnt"}, |
| 88 | + {"eot", "application/vnd.ms-fontobject"}, |
| 89 | + {"ttf", "font/ttf"}, |
| 90 | + {"collection", "font/collection"}, |
| 91 | + {"woff", "font/woff"}, |
| 92 | + {"woff2", "font/woff2"}, |
| 93 | + {"vtt", "text/vtt"}, |
| 94 | + {"webm", "video/webm"}, |
| 95 | + {"webp", "image/webp"}, |
| 96 | + {"mp4", "video/mp4"}, |
| 97 | + {"doc", "application/msword"}, |
| 98 | + {"docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"}, |
| 99 | + {"ppt", "application/vnd.ms-powerpoint"}, |
| 100 | + {"odt", "application/vnd.oasis.opendocument.text"}, |
| 101 | + {"odp", "application/vnd.oasis.opendocument.text"}, |
| 102 | + {"zip", "application/zip"}, |
| 103 | + {"wasm", "application/wasm"}, |
| 104 | +}; |
114 | 105 |
|
115 | 106 | static std::map<std::string, std::string> fileMimeTypes; |
116 | 107 |
|
@@ -162,7 +153,7 @@ inline bool seemsToBeHtml(const std::string& path) |
162 | 153 | if (path.find_last_of(".") != std::string::npos) { |
163 | 154 | std::string mimeType = path.substr(path.find_last_of(".") + 1); |
164 | 155 | if (extMimeTypes.find(mimeType) != extMimeTypes.end()) { |
165 | | - return "text/html" == extMimeTypes[mimeType]; |
| 156 | + return "text/html" == extMimeTypes.at(mimeType); |
166 | 157 | } |
167 | 158 | } |
168 | 159 |
|
|
0 commit comments