Initialize Tizen 2.3
[framework/web/wrt-commons.git] / modules / utils / src / mime_type_utils.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 #include <stddef.h>
17 #include <set>
18 #include <dpl/assert.h>
19 #include <vector>
20
21 #include <map>
22 #include <xdgmime.h>
23
24 #include <dpl/utils/mime_type_utils.h>
25
26 const std::set<DPL::String>& MimeTypeUtils::getMimeTypesSupportedForIcon()
27 {
28     static std::set<DPL::String> set;
29     DPL::String (*s)(const std::string&) = DPL::FromASCIIString;
30     if (set.empty()) {
31         set.insert(s("image/gif"));
32         set.insert(s("image/png"));
33         set.insert(s("image/vnd.microsoft.icon"));
34         set.insert(s("image/svg+xml"));
35         set.insert(s("image/jpeg"));
36     }
37     return set;
38 }
39
40 const std::set<DPL::String>& MimeTypeUtils::getMimeTypesSupportedForStartFile()
41 {
42     static std::set<DPL::String> set;
43     DPL::String (*s)(const std::string&) = DPL::FromASCIIString;
44     if (set.empty()) {
45         set.insert(s("text/html"));
46         set.insert(s("application/xhtml+xml"));
47         set.insert(s("image/svg+xml"));
48     }
49     return set;
50 }
51
52 bool MimeTypeUtils::isMimeTypeSupportedForStartFile(const DPL::String& mimeType)
53 {
54     return getMimeTypesSupportedForStartFile().count(stripMimeParameters(
55                                                          mimeType)) > 0;
56 }
57
58 const MimeTypeUtils::FileIdentificationMap& MimeTypeUtils::
59     getFileIdentificationMap()
60 {
61     static FileIdentificationMap map;
62     DPL::String (*s)(const std::string&) = DPL::FromASCIIString;
63     if (map.empty()) {
64         map[s(".html")] = s("text/html");
65         map[s(".htm")] = s("text/html");
66         map[s(".css")] = s("text/css");
67         map[s(".js")] = s("application/javascript");
68         map[s(".xml")] = s("application/xml");
69         map[s(".txt")] = s("text/plain");
70         map[s(".wav")] = s("audio/x-wav");
71         map[s(".xhtml")] = s("application/xhtml+xml");
72         map[s(".xht")] = s("application/xhtml+xml");
73         map[s(".gif")] = s("image/gif");
74         map[s(".png")] = s("image/png");
75         map[s(".ico")] = s("image/vnd.microsoft.icon");
76         map[s(".svg")] = s("image/svg+xml");
77         map[s(".jpg")] = s("image/jpeg");
78     }
79     return map;
80 }
81
82 bool MimeTypeUtils::isMimeTypeSupportedForIcon(const DPL::String& mimeType)
83 {
84     return getMimeTypesSupportedForIcon().count(stripMimeParameters(mimeType))
85            > 0;
86 }
87
88 DPL::String MimeTypeUtils::stripMimeParameters(const DPL::String& mimeType)
89 {
90     size_t parametersStart = mimeType.find_first_of(L';');
91     if (parametersStart != DPL::String::npos) {
92         return mimeType.substr(0, parametersStart);
93     } else {
94         return mimeType;
95     }
96 }
97
98 MimeTypeUtils::MimeAttributes MimeTypeUtils::getMimeAttributes(
99     const DPL::String& mimeType)
100 {
101     MimeAttributes attributes;
102     std::vector<DPL::String> tokens;
103     DPL::Tokenize(mimeType, L";=", std::back_inserter(tokens));
104     for (unsigned int i = 1; i < tokens.size(); i += 2) {
105         attributes[tokens[i]] = tokens[i + 1];
106     }
107     return attributes;
108 }
109
110 bool MimeTypeUtils::isValidIcon(const DPL::String& path)
111 {
112     return getMimeTypesSupportedForIcon().count(identifyFileMimeType(path)) > 0;
113 }
114
115 bool MimeTypeUtils::isValidStartFile(
116     const DPL::String& path,
117     const DPL::OptionalString&
118     providedMimeType)
119 {
120     DPL::String mimeType = (!!providedMimeType) ? stripMimeParameters(
121             *providedMimeType) : identifyFileMimeType(path);
122     return getMimeTypesSupportedForStartFile().count(mimeType) > 0;
123 }
124
125 DPL::String MimeTypeUtils::getFileNameFromPath(const DPL::String& path)
126 {
127     size_t lastSlashPos = path.find_last_of(L'/');
128     return path.substr(lastSlashPos + 1);
129 }
130
131 DPL::String MimeTypeUtils::identifyFileMimeType(const DPL::String& path)
132 {
133     DPL::String name = getFileNameFromPath(path); //step 4
134
135     if (name.size() == 0) {
136         ThrowMsg(Exception::InvalidFileName, "Path should contain a file name.");
137     }
138
139     size_t lastFullStop = name.find_last_of(L'.');
140     if (lastFullStop != 0 && lastFullStop != DPL::String::npos) { //step 5
141         DPL::String extension = name.substr(lastFullStop); //step 6 & 7
142         if (extension.size() > 0) { //step 8
143             //step 9
144             std::transform(extension.begin(), extension.end(),
145                            extension.begin(), ::towlower);
146             FileIdentificationMap::const_iterator it =
147                 getFileIdentificationMap().find(extension);
148             if (it != getFileIdentificationMap().end()) {
149                 return it->second;
150             }
151         }
152     }
153
154     // step 10 - sniff
155     std::string filePath = DPL::ToUTF8String(path);
156
157     std::string mime = xdg_mime_get_mime_type_for_file(filePath.c_str(), 0);
158     if (!mime.empty()) {
159         return DPL::FromASCIIString(mime);
160     }
161     return DPL::FromASCIIString("application/sniff");
162 }