• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define LOG_TAG "UnifiedRecord"
16 #include "unified_record.h"
17 
18 #include "file.h"
19 #include "getter_system.h"
20 #include "logger.h"
21 
22 namespace OHOS {
23 namespace UDMF {
24 static constexpr UDType FILE_TYPES[] = {FILE, AUDIO, FOLDER, IMAGE, VIDEO};
25 static constexpr const char *FILE_SCHEME = "file";
26 
UnifiedRecord()27 UnifiedRecord::UnifiedRecord()
28 {
29     dataType_ = UD_BUTT;
30 }
31 
UnifiedRecord(UDType type)32 UnifiedRecord::UnifiedRecord(UDType type)
33 {
34     dataType_ = type;
35     utdId_ = UtdUtils::GetUtdIdFromUtdEnum(type);
36 }
37 
UnifiedRecord(UDType type,ValueType value)38 UnifiedRecord::UnifiedRecord(UDType type, ValueType value)
39 {
40     dataType_ = type;
41     utdId_ = UtdUtils::GetUtdIdFromUtdEnum(type);
42     value_ = value;
43     if (std::holds_alternative<std::shared_ptr<Object>>(value_)) {
44         hasObject_ = true;
45     }
46 }
47 
GetType() const48 UDType UnifiedRecord::GetType() const
49 {
50     return this->dataType_;
51 }
52 
GetTypes() const53 std::vector<std::string> UnifiedRecord::GetTypes() const
54 {
55     std::vector<std::string> types;
56     for (auto it = entries_->begin(); it != entries_->end(); it++) {
57         types.push_back(it->first);
58     }
59     types.push_back(utdId_);
60     return types;
61 }
62 
SetType(const UDType & type)63 void UnifiedRecord::SetType(const UDType &type)
64 {
65     dataType_ = type;
66     utdId_ = UtdUtils::GetUtdIdFromUtdEnum(type);
67 }
68 
GetSize()69 int64_t UnifiedRecord::GetSize()
70 {
71     if (std::holds_alternative<std::shared_ptr<Object>>(value_)) {
72         auto value = std::get<std::shared_ptr<Object>>(value_);
73         if (value->value_.size() == 1) {
74             return ObjectUtils::GetValueSize(value_, true) + GetInnerEntriesSize();
75         }
76     }
77     return ObjectUtils::GetValueSize(value_, false) + GetInnerEntriesSize();
78 }
79 
GetUid() const80 std::string UnifiedRecord::GetUid() const
81 {
82     return this->uid_;
83 }
84 
SetUid(const std::string & id)85 void UnifiedRecord::SetUid(const std::string &id)
86 {
87     this->uid_ = id;
88 }
89 
GetValue()90 ValueType UnifiedRecord::GetValue()
91 {
92     return value_;
93 }
94 
SetValue(const ValueType & value)95 void UnifiedRecord::SetValue(const ValueType &value)
96 {
97     value_ = value;
98 }
99 
GetOriginValue() const100 ValueType UnifiedRecord::GetOriginValue() const
101 {
102     return value_;
103 }
104 
HasType(const std::string & utdId) const105 bool UnifiedRecord::HasType(const std::string &utdId) const
106 {
107     if (entries_->find(utdId) != entries_->end()) {
108         return true;
109     }
110     return utdId == utdId_;
111 }
112 
AddEntry(const std::string & utdId,ValueType && value)113 void UnifiedRecord::AddEntry(const std::string &utdId, ValueType &&value)
114 {
115     std::lock_guard<std::recursive_mutex> lock(mutex_);
116     if (utdId == utdId_ || utdId_.empty()) {
117         utdId_ = utdId;
118         value_ = std::move(value);
119         auto udType = static_cast<UDType>(UtdUtils::GetUtdEnumFromUtdId(utdId_));
120         if (udType != UD_BUTT) {
121             dataType_ = udType;
122         } else {
123             dataType_ = APPLICATION_DEFINED_RECORD;
124         }
125     } else {
126         entries_->insert_or_assign(utdId, std::move(value));
127     }
128 }
129 
GetEntry(const std::string & utdId)130 ValueType UnifiedRecord::GetEntry(const std::string &utdId)
131 {
132     std::lock_guard<std::recursive_mutex> lock(mutex_);
133     if (utdId_ == utdId && !(std::holds_alternative<std::monostate>(value_))) {
134         return value_;
135     }
136     auto it = entries_->find(utdId);
137     if (it != entries_->end() && !(std::holds_alternative<std::monostate>(it->second))) {
138         return it->second;
139     }
140     auto getter = GetterSystem::GetInstance().GetGetter(channelName_);
141     if (getter != nullptr && (utdId_ == utdId || it != entries_->end())) {
142         auto value = getter->GetValueByType(dataId_, recordId_, utdId);
143         if (std::holds_alternative<std::monostate>(value)) {
144             LOG_ERROR(UDMF_FRAMEWORK, "get value failed, utdId: %{public}s", utdId.c_str());
145             return std::monostate();
146         }
147         AddEntry(utdId, ValueType(value));
148         return value;
149     }
150     return std::monostate();
151 }
152 
GetEntries()153 std::shared_ptr<std::map<std::string, ValueType>> UnifiedRecord::GetEntries()
154 {
155     auto res = std::make_shared<std::map<std::string, ValueType>>(*entries_);
156     if (!utdId_.empty()) {
157         if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) {
158             InitObject();
159             ValueType value = value_;
160             res->insert_or_assign(utdId_, std::move(value));
161             auto object = std::get<std::shared_ptr<Object>>(value_);
162             value_ = object->value_[VALUE_TYPE];   // restore value_
163         } else {
164             res->insert_or_assign(utdId_, value_);
165         }
166     }
167     return res;
168 }
169 
GetInnerEntries() const170 std::shared_ptr<std::map<std::string, ValueType>> UnifiedRecord::GetInnerEntries() const
171 {
172     return entries_;
173 }
174 
SetInnerEntries(std::shared_ptr<std::map<std::string,ValueType>> entries)175 void UnifiedRecord::SetInnerEntries(std::shared_ptr<std::map<std::string, ValueType>> entries)
176 {
177     entries_ = entries;
178 }
179 
GetInnerEntriesSize() const180 int64_t UnifiedRecord::GetInnerEntriesSize() const
181 {
182     if (entries_ == nullptr) {
183         return 0;
184     }
185     int64_t size = 0;
186     for (auto &entry : *entries_) {
187         size += ObjectUtils::GetValueSize(entry.second, false);
188     }
189     return size;
190 }
191 
GetUtdIds() const192 std::set<std::string> UnifiedRecord::GetUtdIds() const
193 {
194     std::set<std::string> utdIds;
195     if (!utdId_.empty()) {
196         utdIds.emplace(utdId_);
197     }
198     for (const auto& [key, value] : *entries_) {
199         utdIds.emplace(key);
200     }
201     return utdIds;
202 }
203 
SetUtdId(const std::string & utdId)204 void UnifiedRecord::SetUtdId(const std::string& utdId)
205 {
206     utdId_ = utdId;
207 }
208 
GetUtdId() const209 std::string UnifiedRecord::GetUtdId() const
210 {
211     return utdId_;
212 }
213 
SetDataId(uint32_t dataId)214 void UnifiedRecord::SetDataId(uint32_t dataId)
215 {
216     dataId_ = dataId;
217 }
218 
GetDataId() const219 uint32_t UnifiedRecord::GetDataId() const
220 {
221     return dataId_;
222 }
223 
SetRecordId(uint32_t recordId)224 void UnifiedRecord::SetRecordId(uint32_t recordId)
225 {
226     recordId_ = recordId;
227 }
228 
GetRecordId() const229 uint32_t UnifiedRecord::GetRecordId() const
230 {
231     return recordId_;
232 }
233 
SetEntryGetter(const std::vector<std::string> & utdIds,const std::shared_ptr<EntryGetter> & entryGetter)234 void UnifiedRecord::SetEntryGetter(
235     const std::vector<std::string> &utdIds,
236     const std::shared_ptr<EntryGetter> &entryGetter)
237 {
238     for (auto const &utdId : utdIds) {
239         if (HasType(utdId)) {
240             LOG_WARN(UDMF_FRAMEWORK, "already has the utdId: %{public}s", utdId.c_str());
241             continue;
242         }
243         AddEntry(utdId, ValueType());
244     }
245     entryGetter_ = entryGetter;
246 }
247 
GetEntryGetter()248 std::shared_ptr<EntryGetter> UnifiedRecord::GetEntryGetter()
249 {
250     return entryGetter_;
251 }
252 
SetChannelName(const std::string & channelName)253 void UnifiedRecord::SetChannelName(const std::string &channelName)
254 {
255     channelName_ = channelName;
256 }
257 
InitObject()258 void UnifiedRecord::InitObject()
259 {
260     if (!std::holds_alternative<std::shared_ptr<Object>>(value_)) {
261         auto value = value_;
262         value_ = std::make_shared<Object>();
263         auto object = std::get<std::shared_ptr<Object>>(value_);
264         object->value_.insert_or_assign(VALUE_TYPE, std::move(value));
265     }
266 }
267 
HasObject()268 bool UnifiedRecord::HasObject()
269 {
270     return hasObject_;
271 }
272 
HasFileType(std::string & fileUri) const273 bool UnifiedRecord::HasFileType(std::string &fileUri) const
274 {
275     fileUri.clear();
276     if (std::holds_alternative<std::shared_ptr<Object>>(GetOriginValue())) {
277         auto obj = std::get<std::shared_ptr<Object>>(GetOriginValue());
278         if (obj->value_.find(ORI_URI) != obj->value_.end()) {
279             obj->GetValue(ORI_URI, fileUri);
280         }
281     } else if (std::find(std::begin(FILE_TYPES), std::end(FILE_TYPES), GetType()) != std::end(FILE_TYPES)) {
282         auto file = static_cast<const File*>(this);
283         fileUri = file->GetUri();
284     } else {
285         return false;
286     }
287 
288     if (fileUri.empty()) {
289         LOG_ERROR(UDMF_FRAMEWORK, "Get uri empty, plase check the uri.");
290         return false;
291     }
292 #ifndef CROSS_PLATFORM
293     Uri uri(fileUri);
294     std::string scheme = uri.GetScheme();
295     std::transform(scheme.begin(), scheme.end(), scheme.begin(), ::tolower);
296     if (uri.GetAuthority().empty() || scheme != FILE_SCHEME) {
297         LOG_INFO(UDMF_FRAMEWORK, "Get uri authority empty or uri scheme not equals to file.");
298         return false;
299     }
300 #endif
301     return true;
302 }
303 
SetFileUri(const std::string & fileUri)304 void UnifiedRecord::SetFileUri(const std::string &fileUri)
305 {
306     if (std::find(std::begin(FILE_TYPES), std::end(FILE_TYPES), GetType()) != std::end(FILE_TYPES)) {
307         auto file = static_cast<File*>(this);
308         file->SetUri(fileUri);
309     } else if (std::holds_alternative<std::shared_ptr<Object>>(GetOriginValue())) {
310         auto obj = std::get<std::shared_ptr<Object>>(GetOriginValue());
311         obj->value_[ORI_URI] = fileUri;
312     } else {
313         LOG_ERROR(UDMF_FRAMEWORK, "Record has no uri.");
314     }
315 }
316 
317 } // namespace UDMF
318 } // namespace OHOS