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 #include "oh_preferences_value.h"
16 
17 #include "log_print.h"
18 #include "oh_preferences_err_code.h"
19 #include "oh_preferences_impl.h"
20 #include "oh_preferences_value_impl.h"
21 #include "securec.h"
22 
23 using namespace OHOS::PreferencesNdk;
24 
GetSelf(const OH_PreferencesValue * value)25 static OH_PreferencesValueImpl *GetSelf(const OH_PreferencesValue *value)
26 {
27     if (value == nullptr ||
28         !NDKPreferencesUtils::PreferencesStructValidCheck(
29             value->cid, PreferencesNdkStructId::PREFERENCES_OH_VALUE_CID)) {
30         LOG_ERROR("preferences_value invalid, value is null: %{public}d", (value == nullptr));
31         return nullptr;
32     }
33     OH_PreferencesValue *prefValue = const_cast<OH_PreferencesValue *>(value);
34     return static_cast<OH_PreferencesValueImpl *>(prefValue);
35 }
36 
OH_PreferencesPair_GetKey(const OH_PreferencesPair * pairs,uint32_t index)37 const char *OH_PreferencesPair_GetKey(const OH_PreferencesPair *pairs, uint32_t index)
38 {
39     if (pairs == nullptr || index >= pairs[0].maxIndex) {
40         LOG_ERROR("failed to get key from pair, pairs is null or index over limit");
41         return nullptr;
42     }
43 
44     if (!NDKPreferencesUtils::PreferencesStructValidCheck(
45         pairs[index].cid, PreferencesNdkStructId::PREFERENCES_OH_PAIR_CID)) {
46         LOG_ERROR("cid error when get key from pair, cid: %{public}ld", static_cast<long>(pairs[index].cid));
47         return nullptr;
48     }
49     return pairs[index].key;
50 }
51 
OH_PreferencesPair_GetPreferencesValue(const OH_PreferencesPair * pairs,uint32_t index)52 const OH_PreferencesValue *OH_PreferencesPair_GetPreferencesValue(const OH_PreferencesPair *pairs, uint32_t index)
53 {
54     if (pairs == nullptr || index >= pairs[0].maxIndex) {
55         LOG_ERROR("failed to get value from pair, pairs is null or index over limit");
56         return nullptr;
57     }
58 
59     if (!NDKPreferencesUtils::PreferencesStructValidCheck(
60         pairs[index].cid, PreferencesNdkStructId::PREFERENCES_OH_PAIR_CID)) {
61         LOG_ERROR("cid error when get value from pair, cid: %{public}ld", static_cast<long>(pairs[index].cid));
62         return nullptr;
63     }
64     return pairs[index].value;
65 }
66 
OH_PreferencesValue_GetValueType(const OH_PreferencesValue * object)67 Preference_ValueType OH_PreferencesValue_GetValueType(const OH_PreferencesValue *object)
68 {
69     auto self = GetSelf(object);
70     if (self == nullptr) {
71         LOG_ERROR("Preferences GetValueType failed, object is null");
72         return Preference_ValueType::PREFERENCE_TYPE_NULL;
73     }
74     if (self->value_.IsInt()) {
75         return Preference_ValueType::PREFERENCE_TYPE_INT;
76     } else if (self->value_.IsBool()) {
77         return Preference_ValueType::PREFERENCE_TYPE_BOOL;
78     } else if (self->value_.IsString()) {
79         return Preference_ValueType::PREFERENCE_TYPE_STRING;
80     }
81     return Preference_ValueType::PREFERENCE_TYPE_NULL;
82 }
83 
OH_PreferencesValue_GetInt(const OH_PreferencesValue * object,int * value)84 int OH_PreferencesValue_GetInt(const OH_PreferencesValue *object, int *value)
85 {
86     auto self = GetSelf(object);
87     if (self == nullptr || value == nullptr) {
88         LOG_ERROR("Preferences GetInt failed, object is null: %{public}d, value is null: %{public}d, err: %{public}d",
89             (self == nullptr), (value == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM);
90         return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM;
91     }
92     if (self->value_.IsInt()) {
93         *value = (int)(self->value_);
94         return OH_Preferences_ErrCode::PREFERENCES_OK;
95     }
96     LOG_ERROR("Preferences GetInt failed, type error, err: %{public}d",
97         OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND);
98     return OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND;
99 }
100 
OH_PreferencesValue_GetBool(const OH_PreferencesValue * object,bool * value)101 int OH_PreferencesValue_GetBool(const OH_PreferencesValue *object, bool *value)
102 {
103     auto self = GetSelf(object);
104     if (self == nullptr || value == nullptr) {
105         LOG_ERROR("Preferences GetBool failed, object is null: %{public}d, value is null: %{public}d, err: %{public}d",
106             (self == nullptr), (self == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM);
107         return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM;
108     }
109     if (self->value_.IsBool()) {
110         *value = (bool)(self->value_);
111         return OH_Preferences_ErrCode::PREFERENCES_OK;
112     }
113     LOG_ERROR("Preferences GetBool failed, type error, err: %{public}d",
114         OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND);
115     return OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND;
116 }
117 
OH_PreferencesValue_GetString(const OH_PreferencesValue * object,char ** value,uint32_t * valueLen)118 int OH_PreferencesValue_GetString(const OH_PreferencesValue *object, char **value, uint32_t *valueLen)
119 {
120     auto self = GetSelf(object);
121     if (self == nullptr || value == nullptr || valueLen == nullptr) {
122         LOG_ERROR("Preferences GetString failed, object is null: %{public}d, value is null: %{public}d, "
123             "valueLen is null: %{public}d, err: %{public}d", (self == nullptr), (value == nullptr),
124             (valueLen == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM);
125         return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM;
126     }
127     if (self->value_.IsString()) {
128         std::string str = (std::string)(self->value_);
129         size_t strLen = str.size();
130         if (strLen >= SIZE_MAX) {
131             LOG_ERROR("string length overlimit: %{public}zu", strLen);
132             return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM;
133         }
134         void *ptr = malloc(strLen + 1); // free by caller
135         if (ptr == nullptr) {
136             LOG_ERROR("malloc failed when value get string, errno: %{public}d", errno);
137             return OH_Preferences_ErrCode::PREFERENCES_ERROR_MALLOC;
138         }
139         *value = (char *)ptr;
140         int sysErr = memset_s(*value, (strLen + 1), 0, (strLen + 1));
141         if (sysErr != EOK) {
142             LOG_ERROR("memset failed when get string, errCode: %{public}d", sysErr);
143         }
144         if (strLen > 0) {
145             sysErr = memcpy_s(*value, strLen, str.c_str(), strLen);
146             if (sysErr != EOK) {
147                 LOG_ERROR("memcpy failed when value get string, errCode: %{public}d", sysErr);
148                 free(ptr);
149                 return OH_Preferences_ErrCode::PREFERENCES_ERROR_MALLOC;
150             }
151         }
152         *valueLen = strLen + 1;
153         return OH_Preferences_ErrCode::PREFERENCES_OK;
154     }
155     LOG_ERROR("Preferences GetString failed, type error, err: %{public}d",
156         OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND);
157     return OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND;
158 }
159