1 /*
2 * Copyright (C) 2024 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 <iostream>
17 #include "fragment_metadata.h"
18 #include "image_log.h"
19 #include "image_utils.h"
20 #include "media_errors.h"
21
22 #undef LOG_DOMAIN
23 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
24
25 #undef LOG_TAG
26 #define LOG_TAG "FragmentMetadata"
27
28 namespace OHOS {
29 namespace Media {
30 const static uint64_t MAX_FRAGMENT_MAP_META_COUNT = 10;
31 const static uint64_t MAX_FRAGMENT_MAP_META_LENGTH = 100;
FragmentMetadata()32 FragmentMetadata::FragmentMetadata() {}
33
FragmentMetadata(const FragmentMetadata & fragmentMetadata)34 FragmentMetadata::FragmentMetadata(const FragmentMetadata& fragmentMetadata)
35 {
36 if (fragmentMetadata.properties_ != nullptr) {
37 properties_ = std::make_shared<ImageMetadata::PropertyMap>(*fragmentMetadata.properties_);
38 }
39 }
40
~FragmentMetadata()41 FragmentMetadata::~FragmentMetadata() {}
42
IsValidKey(const std::string & key)43 static bool IsValidKey(const std::string &key)
44 {
45 return FRAGMENT_METADATA_KEYS.find(key) != FRAGMENT_METADATA_KEYS.end();
46 }
47
GetValue(const std::string & key,std::string & value) const48 int FragmentMetadata::GetValue(const std::string &key, std::string &value) const
49 {
50 if (properties_ == nullptr) {
51 IMAGE_LOGE("%{public}s properties is nullptr.", __func__);
52 return ERR_IMAGE_INVALID_PARAMETER;
53 }
54 if (!IsValidKey(key)) {
55 IMAGE_LOGE("Key is not supported.");
56 return ERR_IMAGE_INVALID_PARAMETER;
57 }
58 auto it = properties_->find(key);
59 if (it != properties_->end()) {
60 value = it->second;
61 return SUCCESS;
62 }
63 IMAGE_LOGE("key is not found in properties: %{public}s", key.c_str());
64 return ERR_IMAGE_INVALID_PARAMETER;
65 }
66
SetValue(const std::string & key,const std::string & value)67 bool FragmentMetadata::SetValue(const std::string &key, const std::string &value)
68 {
69 if (!IsValidKey(key)) {
70 IMAGE_LOGE("Key is not supported.");
71 return false;
72 }
73 uint32_t casted;
74 if (!ImageUtils::StrToUint32(value, casted)) {
75 IMAGE_LOGE("Invalid value: %{public}s.", value.c_str());
76 return false;
77 }
78 if (properties_ == nullptr) {
79 IMAGE_LOGE("SetValue: properties_ is nullptr");
80 return false;
81 }
82 if (properties_->size() >= MAX_FRAGMENT_MAP_META_COUNT) {
83 IMAGE_LOGE("Failed to set value, the size of metadata properties exceeds the maximum limit %{public}llu.",
84 static_cast<unsigned long long>(MAX_FRAGMENT_MAP_META_COUNT));
85 return false;
86 }
87 if (key.length() > MAX_FRAGMENT_MAP_META_LENGTH || value.length() > MAX_FRAGMENT_MAP_META_LENGTH) {
88 IMAGE_LOGE("Failed to set value, the length of fragment string exceeds the maximum limit %{public}llu.",
89 static_cast<unsigned long long>(MAX_FRAGMENT_MAP_META_LENGTH));
90 return false;
91 }
92 (*properties_)[key] = value;
93 return true;
94 }
95
RemoveEntry(const std::string & key)96 bool FragmentMetadata::RemoveEntry(const std::string &key)
97 {
98 if (properties_ == nullptr) {
99 IMAGE_LOGE("%{public}s properties is nullptr.", __func__);
100 return false;
101 }
102 if (!IsValidKey(key)) {
103 IMAGE_LOGE("Key is not supported.");
104 return false;
105 }
106 auto it = properties_->find(key);
107 if (it != properties_->end()) {
108 properties_->erase(it);
109 IMAGE_LOGD("RemoveEntry for key: %{public}s", key.c_str());
110 return true;
111 } else {
112 IMAGE_LOGE("RemoveEntry failed, key is not found in properties: %{public}s", key.c_str());
113 return false;
114 }
115 }
116
GetAllProperties()117 const ImageMetadata::PropertyMapPtr FragmentMetadata::GetAllProperties()
118 {
119 return properties_;
120 }
121
CloneMetadata()122 std::shared_ptr<ImageMetadata> FragmentMetadata::CloneMetadata()
123 {
124 if (properties_->size() > MAX_FRAGMENT_MAP_META_COUNT) {
125 IMAGE_LOGE("Failed to clone, the size of metadata properties exceeds the maximum limit %{public}llu.",
126 static_cast<unsigned long long>(MAX_FRAGMENT_MAP_META_COUNT));
127 return nullptr;
128 }
129 return std::make_shared<FragmentMetadata>(*this);
130 }
131
Marshalling(Parcel & parcel) const132 bool FragmentMetadata::Marshalling(Parcel &parcel) const
133 {
134 if (properties_ == nullptr) {
135 IMAGE_LOGE("%{public}s properties is nullptr.", __func__);
136 return false;
137 }
138 if (properties_->size() > MAX_FRAGMENT_MAP_META_COUNT) {
139 IMAGE_LOGE("The number of metadata properties exceeds the maximum limit.");
140 return false;
141 }
142 if (!parcel.WriteUint64(properties_->size())) {
143 return false;
144 }
145 for (const auto &pair : *properties_) {
146 if (!IsValidKey(pair.first)) {
147 IMAGE_LOGE("The key of fragmentmetadata is invalid.");
148 return false;
149 }
150 uint32_t casted;
151 if (!ImageUtils::StrToUint32(pair.second, casted)) {
152 IMAGE_LOGE("The Value of fragmentmetadata is invalid.");
153 return false;
154 }
155 if (pair.first.length() > MAX_FRAGMENT_MAP_META_LENGTH || pair.second.length() > MAX_FRAGMENT_MAP_META_LENGTH) {
156 IMAGE_LOGE("The length of fragment string exceeds the maximum limit.");
157 return false;
158 }
159 if (!parcel.WriteString(pair.first)) {
160 return false;
161 }
162 if (!parcel.WriteString(pair.second)) {
163 return false;
164 }
165 }
166 return true;
167 }
168
Unmarshalling(Parcel & parcel)169 FragmentMetadata *FragmentMetadata::Unmarshalling(Parcel &parcel)
170 {
171 PICTURE_ERR error;
172 FragmentMetadata* dstFragmentMetadata = FragmentMetadata::Unmarshalling(parcel, error);
173 if (dstFragmentMetadata == nullptr || error.errorCode != SUCCESS) {
174 IMAGE_LOGE("unmarshalling failed errorCode:%{public}d, errorInfo:%{public}s",
175 error.errorCode, error.errorInfo.c_str());
176 }
177 return dstFragmentMetadata;
178 }
179
Unmarshalling(Parcel & parcel,PICTURE_ERR & error)180 FragmentMetadata *FragmentMetadata::Unmarshalling(Parcel &parcel, PICTURE_ERR &error)
181 {
182 std::unique_ptr<FragmentMetadata> fragmentMetadataPtr = std::make_unique<FragmentMetadata>();
183 uint64_t size;
184 if (!parcel.ReadUint64(size)) {
185 return nullptr;
186 }
187 if (size > MAX_FRAGMENT_MAP_META_COUNT) {
188 return nullptr;
189 }
190 if (fragmentMetadataPtr->properties_ == nullptr) {
191 IMAGE_LOGE("Unmarshalling: fragmentMetadataPtr->properties_ is nullptr");
192 return nullptr;
193 }
194 for (uint64_t i = 0; i < size; ++i) {
195 std::string key;
196 std::string value;
197 if (!parcel.ReadString(key)) {
198 return nullptr;
199 }
200 if (!parcel.ReadString(value)) {
201 return nullptr;
202 }
203 if (!IsValidKey(key)) {
204 IMAGE_LOGE("The key of fragmentmetadata is invalid.");
205 return nullptr;
206 }
207 uint32_t casted;
208 if (!ImageUtils::StrToUint32(value, casted)) {
209 IMAGE_LOGE("The Value of fragmentmetadata is invalid.");
210 return nullptr;
211 }
212 if (key.length() > MAX_FRAGMENT_MAP_META_LENGTH || value.length() > MAX_FRAGMENT_MAP_META_LENGTH) {
213 IMAGE_LOGE("The length of fragment string exceeds the maximum limit.");
214 return nullptr;
215 }
216 fragmentMetadataPtr->properties_->insert(std::make_pair(key, value));
217 }
218 return fragmentMetadataPtr.release();
219 }
220
221 } // namespace Media
222 } // namespace OHOS