1 /*
2 * Copyright (C) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "mimetype_utils.h"
17
18 #include <algorithm>
19 #include <fstream>
20
21 #include "media_log.h"
22 #include "medialibrary_errno.h"
23
24 using std::string;
25 using std::vector;
26 using std::unordered_map;
27 using namespace nlohmann;
28
29 namespace OHOS {
30 namespace Media {
31 using MimeTypeMap = unordered_map<string, vector<string>>;
32
33 MimeTypeMap MimeTypeUtils::mediaJsonMap_;
34 const string MIMETYPE_JSON_PATH = "/system/etc/userfilemanager/userfilemanager_mimetypes.json";
35 const string DEFAULT_MIME_TYPE = "application/octet-stream";
36
37 /**
38 * The format of the target json file:
39 * First floor: Media type string, such as image, video, audio, etc.
40 * Second floor: Mime type string
41 * Third floor: Extension array.
42 */
CreateMapFromJson()43 void MimeTypeUtils::CreateMapFromJson()
44 {
45 std::ifstream jFile(MIMETYPE_JSON_PATH);
46 if (!jFile.is_open()) {
47 MEDIA_ERR_LOG("Failed to open: %{private}s", MIMETYPE_JSON_PATH.c_str());
48 return;
49 }
50 json firstFloorObjs;
51 jFile >> firstFloorObjs;
52 for (auto& firstFloorObj : firstFloorObjs.items()) {
53 json secondFloorJsons = json::parse(firstFloorObj.value().dump(), nullptr, false);
54 for (auto& secondFloorJson : secondFloorJsons.items()) {
55 json thirdFloorJsons = json::parse(secondFloorJson.value().dump(), nullptr, false);
56 // Key: MimeType, Value: Extension array.
57 mediaJsonMap_.insert(std::pair<string, vector<string>>(secondFloorJson.key(), thirdFloorJsons));
58 }
59 }
60 }
61
InitMimeTypeMap()62 int32_t MimeTypeUtils::InitMimeTypeMap()
63 {
64 CreateMapFromJson();
65 if (mediaJsonMap_.empty()) {
66 return E_FAIL;
67 }
68 return E_OK;
69 }
70
GetMimeTypeFromExtension(const string & extension)71 string MimeTypeUtils::GetMimeTypeFromExtension(const string &extension)
72 {
73 return GetMimeTypeFromExtension(extension, mediaJsonMap_);
74 }
75
GetMimeTypeFromExtension(const string & extension,const MimeTypeMap & mimeTypeMap)76 string MimeTypeUtils::GetMimeTypeFromExtension(const string &extension,
77 const MimeTypeMap &mimeTypeMap)
78 {
79 std::string tmp = std::move(extension);
80 std::transform(tmp.begin(), tmp.end(), tmp.begin(), ::tolower);
81 for (auto &item : mimeTypeMap) {
82 for (auto &ext : item.second) {
83 if (ext == tmp) {
84 return item.first;
85 }
86 }
87 }
88 return DEFAULT_MIME_TYPE;
89 }
90
GetMediaTypeFromMimeType(const string & mimeType)91 MediaType MimeTypeUtils::GetMediaTypeFromMimeType(const string &mimeType)
92 {
93 size_t pos = mimeType.find_first_of("/");
94 if (pos == string::npos) {
95 MEDIA_ERR_LOG("Invalid mime type: %{private}s", mimeType.c_str());
96 return MEDIA_TYPE_FILE;
97 }
98 string prefix = mimeType.substr(0, pos);
99 if (prefix == "audio") {
100 return MEDIA_TYPE_AUDIO;
101 } else if (prefix == "video") {
102 return MEDIA_TYPE_VIDEO;
103 } else if (prefix == "image") {
104 return MEDIA_TYPE_IMAGE;
105 } else {
106 return MEDIA_TYPE_FILE;
107 }
108 }
109 }
110 }
111