1 /*
2  * Copyright (c) 2021 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 #include "res_desc.h"
16 #include "hilog_wrapper.h"
17 #include "securec.h"
18 #include "utils/common.h"
19 #include "utils/string_utils.h"
20 
21 namespace OHOS {
22 namespace Global {
23 namespace Resource {
GetScreenDensityStr() const24 std::string KeyParam::GetScreenDensityStr() const
25 {
26     std::string ret("not_screen_density");
27     if (type_ == KeyType::SCREEN_DENSITY) {
28         switch (value_) {
29             case ScreenDensity::SCREEN_DENSITY_SDPI:
30                 ret = std::string(RE_120_STR);
31                 break;
32             case ScreenDensity::SCREEN_DENSITY_MDPI:
33                 ret = std::string(RE_160_STR);
34                 break;
35             case ScreenDensity::SCREEN_DENSITY_LDPI:
36                 ret = std::string(RE_240_STR);
37                 break;
38             case ScreenDensity::SCREEN_DENSITY_XLDPI:
39                 ret = std::string(RE_320_STR);
40                 break;
41             case ScreenDensity::SCREEN_DENSITY_XXLDPI:
42                 ret = std::string(RE_480_STR);
43                 break;
44             case ScreenDensity::SCREEN_DENSITY_XXXLDPI:
45                 ret = std::string(RE_640_STR);
46                 break;
47             default:
48                 break;
49         }
50     }
51     return ret;
52 }
GetDeviceTypeStr() const53 std::string KeyParam::GetDeviceTypeStr() const
54 {
55     std::string ret("not_device_type");
56     if (type_ == KeyType::DEVICETYPE) {
57         switch (value_) {
58             case DeviceType::DEVICE_PHONE:
59                 ret = std::string(PHONE_STR);
60                 break;
61             case DeviceType::DEVICE_TABLET:
62                 ret = std::string(TABLET_STR);
63                 break;
64             case DeviceType::DEVICE_CAR:
65                 ret = std::string(CAR_STR);
66                 break;
67             case DeviceType::DEVICE_PAD:
68                 ret = std::string(PAD_STR);
69                 break;
70             case DeviceType::DEVICE_TV:
71                 ret = std::string(TV_STR);
72                 break;
73             case DeviceType::DEVICE_WEARABLE:
74                 ret = std::string(WEARABLE_STR);
75                 break;
76             default:
77                 break;
78         }
79     }
80     return ret;
81 }
ConvertToStr() const82 const std::string KeyParam::ConvertToStr() const
83 {
84     if ((type_ == KeyType::LANGUAGES) || (type_ == KeyType::REGION) || (type_ == KeyType::SCRIPT)) {
85         char tmp[4];
86         char tmp2[5];
87         errno_t eret = memcpy_s(tmp, sizeof(tmp), &value_, 4);
88         if (eret != EOK) {
89             HILOG_ERROR("memcpy_s error : %d", eret);
90         }
91         int j = 0;
92         // 4 means langauages/region/script key value max length
93         for (int i = 0; i < 4; ++i) {
94             // 3 means reverse temp value to temp2
95             if (tmp[3 - i]) {
96                 tmp2[j++] = tmp[3 - i];
97             }
98         }
99         tmp2[j] = '\0';
100         return std::string(tmp2);
101     }
102     if (type_ == KeyType::DIRECTION) {
103         return std::string((value_ == 0) ? VERTICAL : HORIZONTAL);
104     }
105     if (type_ == KeyType::DEVICETYPE) {
106         return GetDeviceTypeStr();
107     }
108     if (type_ == KeyType::SCREEN_DENSITY) {
109         return GetScreenDensityStr();
110     }
111     return std::string();
112 }
113 
ToString() const114 std::string KeyParam::ToString() const
115 {
116     std::string ret = FormatString("[type:%d, value:%u", type_, value_);
117     if (str_.length() > 0) {
118         ret.append(FormatString(", str:%s", str_.c_str()));
119     }
120     ret.append("]");
121     return ret;
122 }
123 
124 // IdItem
125 
126 std::map<ResType, std::string> IdItem::resTypeStrList;
127 
128 bool IdItem::sInit = IdItem::Init();
129 
Init()130 bool IdItem::Init()
131 {
132     resTypeStrList.insert(make_pair(ResType::STRING, std::string("string")));
133     resTypeStrList.insert(make_pair(ResType::BOOLEAN, std::string("boolean")));
134     resTypeStrList.insert(make_pair(ResType::COLOR, std::string("color")));
135     resTypeStrList.insert(make_pair(ResType::FLOAT, std::string("float")));
136     resTypeStrList.insert(make_pair(ResType::INTEGER, std::string("integer")));
137     resTypeStrList.insert(make_pair(ResType::PATTERN, std::string("pattern")));
138     resTypeStrList.insert(make_pair(ResType::THEME, std::string("theme")));
139     resTypeStrList.insert(make_pair(ResType::MEDIA, std::string("media")));
140     return true;
141 }
142 
HaveParent() const143 bool IdItem::HaveParent() const
144 {
145     if (!(resType_ == THEME || resType_ == PATTERN)) {
146         return false;
147     }
148     // the values_ storage map(key, value) and parent ref
149     // if have parent, size would be odd number
150     return (values_.size() % 2 == 1);
151 }
152 
IsRef(const std::string & value,ResType & resType,int & id)153 bool IdItem::IsRef(const std::string &value, ResType &resType, int &id)
154 {
155     const char *it = value.c_str();
156     const char *st = it;
157     if (*st != '$') {
158         return false;
159     }
160     auto index = value.find(":");
161     // there are atleast one letter between '$' and ':'
162     if (index == std::string::npos || index < 2) {
163         return false;
164     }
165     std::string typeStr;
166     std::string idStr;
167     typeStr.assign(it + 1, index - 1);
168     idStr.assign(it + index + 1, value.size() - index);
169 
170     int idd = atoi(idStr.c_str());
171     if (idd <= 0) {
172         return false;
173     }
174 
175     for (auto iit = resTypeStrList.begin(); iit != resTypeStrList.end(); ++iit) {
176         auto tValue = iit->second;
177         auto type = iit->first;
178         if (typeStr == tValue) {
179             id = idd;
180             resType = type;
181             return true;
182         }
183     }
184 
185     return false;
186 }
187 
ToString() const188 std::string IdItem::ToString() const
189 {
190     std::string ret = FormatString(
191         "[size:%u, resType:%d, id:%u, valueLen:%u, isArray:%d, name:'%s', value:",
192         size_, resType_, id_, valueLen_, isArray_, name_.c_str());
193     if (isArray_) {
194         ret.append("[");
195         for (size_t i = 0; i < values_.size(); ++i) {
196             ret.append(FormatString("'%s',", values_[i].c_str()));
197         }
198         ret.append("]");
199     } else {
200         ret.append(FormatString("'%s'", value_.c_str()));
201     }
202     ret.append("]");
203     return ret;
204 }
205 
~IdParam()206 IdParam::~IdParam()
207 {
208     delete (idItem_);
209 }
210 
ToString() const211 std::string IdParam::ToString() const
212 {
213     return FormatString("[id:%u, offset:%u, data:%s]", id_, offset_,
214         idItem_->ToString().c_str());
215 }
216 
~ResId()217 ResId::~ResId()
218 {
219     for (size_t i = 0; i < idParams_.size(); ++i) {
220         auto ptr = idParams_[i];
221         delete (ptr);
222     }
223 }
224 
ToString() const225 std::string ResId::ToString() const
226 {
227     std::string ret = FormatString("idcount:%u, ", count_);
228     for (size_t i = 0; i < idParams_.size(); ++i) {
229         ret.append(idParams_[i]->ToString());
230     }
231     return ret;
232 }
233 
~ResKey()234 ResKey::~ResKey()
235 {
236     HILOG_DEBUG("~ResKey()");
237     for (size_t i = 0; i < keyParams_.size(); ++i) {
238         auto ptr = keyParams_[i];
239         delete (ptr);
240     }
241     delete (resId_);
242 }
243 
ToString() const244 std::string ResKey::ToString() const
245 {
246     std::string ret = FormatString("offset:%u, keyParamsCount:%u, keyParams:", offset_, keyParamsCount_);
247     for (uint32_t i = 0; i < keyParamsCount_; ++i) {
248         ret.append(keyParams_[i]->ToString());
249     }
250     ret.append("\nid: ");
251     ret.append(resId_->ToString());
252     return ret;
253 }
254 
ResDesc()255 ResDesc::ResDesc() : resHeader_(nullptr)
256 {}
257 
~ResDesc()258 ResDesc::~ResDesc()
259 {
260     HILOG_DEBUG("~ResDesc()");
261     delete (resHeader_);
262     for (size_t i = 0; i < keys_.size(); ++i) {
263         auto ptr = keys_[i];
264         delete (ptr);
265     }
266 }
267 
ToString() const268 std::string ResDesc::ToString() const
269 {
270     if (resHeader_ == nullptr) {
271         return "empty";
272     }
273     std::string ret = FormatString("version:%s, length:%u, keyCount:%u\n",
274         resHeader_->version_, resHeader_->length_, resHeader_->keyCount_);
275     for (size_t i = 0; i < keys_.size(); ++i) {
276         ret.append(keys_[i]->ToString());
277         ret.append("\n");
278     }
279     return ret;
280 }
281 } // namespace Resource
282 } // namespace Global
283 } // namespace OHOS
284