1fc223305Sopenharmony_ci/*
2fc223305Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
3fc223305Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4fc223305Sopenharmony_ci * you may not use this file except in compliance with the License.
5fc223305Sopenharmony_ci * You may obtain a copy of the License at
6fc223305Sopenharmony_ci *
7fc223305Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8fc223305Sopenharmony_ci *
9fc223305Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10fc223305Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11fc223305Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12fc223305Sopenharmony_ci * See the License for the specific language governing permissions and
13fc223305Sopenharmony_ci * limitations under the License.
14fc223305Sopenharmony_ci */
15fc223305Sopenharmony_ci#include "oh_preferences_value.h"
16fc223305Sopenharmony_ci
17fc223305Sopenharmony_ci#include "log_print.h"
18fc223305Sopenharmony_ci#include "oh_preferences_err_code.h"
19fc223305Sopenharmony_ci#include "oh_preferences_impl.h"
20fc223305Sopenharmony_ci#include "oh_preferences_value_impl.h"
21fc223305Sopenharmony_ci#include "securec.h"
22fc223305Sopenharmony_ci
23fc223305Sopenharmony_ciusing namespace OHOS::PreferencesNdk;
24fc223305Sopenharmony_ci
25fc223305Sopenharmony_cistatic OH_PreferencesValueImpl *GetSelf(const OH_PreferencesValue *value)
26fc223305Sopenharmony_ci{
27fc223305Sopenharmony_ci    if (value == nullptr ||
28fc223305Sopenharmony_ci        !NDKPreferencesUtils::PreferencesStructValidCheck(
29fc223305Sopenharmony_ci            value->cid, PreferencesNdkStructId::PREFERENCES_OH_VALUE_CID)) {
30fc223305Sopenharmony_ci        LOG_ERROR("preferences_value invalid, value is null: %{public}d", (value == nullptr));
31fc223305Sopenharmony_ci        return nullptr;
32fc223305Sopenharmony_ci    }
33fc223305Sopenharmony_ci    OH_PreferencesValue *prefValue = const_cast<OH_PreferencesValue *>(value);
34fc223305Sopenharmony_ci    return static_cast<OH_PreferencesValueImpl *>(prefValue);
35fc223305Sopenharmony_ci}
36fc223305Sopenharmony_ci
37fc223305Sopenharmony_ciconst char *OH_PreferencesPair_GetKey(const OH_PreferencesPair *pairs, uint32_t index)
38fc223305Sopenharmony_ci{
39fc223305Sopenharmony_ci    if (pairs == nullptr || index >= pairs[0].maxIndex) {
40fc223305Sopenharmony_ci        LOG_ERROR("failed to get key from pair, pairs is null or index over limit");
41fc223305Sopenharmony_ci        return nullptr;
42fc223305Sopenharmony_ci    }
43fc223305Sopenharmony_ci
44fc223305Sopenharmony_ci    if (!NDKPreferencesUtils::PreferencesStructValidCheck(
45fc223305Sopenharmony_ci        pairs[index].cid, PreferencesNdkStructId::PREFERENCES_OH_PAIR_CID)) {
46fc223305Sopenharmony_ci        LOG_ERROR("cid error when get key from pair, cid: %{public}ld", static_cast<long>(pairs[index].cid));
47fc223305Sopenharmony_ci        return nullptr;
48fc223305Sopenharmony_ci    }
49fc223305Sopenharmony_ci    return pairs[index].key;
50fc223305Sopenharmony_ci}
51fc223305Sopenharmony_ci
52fc223305Sopenharmony_ciconst OH_PreferencesValue *OH_PreferencesPair_GetPreferencesValue(const OH_PreferencesPair *pairs, uint32_t index)
53fc223305Sopenharmony_ci{
54fc223305Sopenharmony_ci    if (pairs == nullptr || index >= pairs[0].maxIndex) {
55fc223305Sopenharmony_ci        LOG_ERROR("failed to get value from pair, pairs is null or index over limit");
56fc223305Sopenharmony_ci        return nullptr;
57fc223305Sopenharmony_ci    }
58fc223305Sopenharmony_ci
59fc223305Sopenharmony_ci    if (!NDKPreferencesUtils::PreferencesStructValidCheck(
60fc223305Sopenharmony_ci        pairs[index].cid, PreferencesNdkStructId::PREFERENCES_OH_PAIR_CID)) {
61fc223305Sopenharmony_ci        LOG_ERROR("cid error when get value from pair, cid: %{public}ld", static_cast<long>(pairs[index].cid));
62fc223305Sopenharmony_ci        return nullptr;
63fc223305Sopenharmony_ci    }
64fc223305Sopenharmony_ci    return pairs[index].value;
65fc223305Sopenharmony_ci}
66fc223305Sopenharmony_ci
67fc223305Sopenharmony_ciPreference_ValueType OH_PreferencesValue_GetValueType(const OH_PreferencesValue *object)
68fc223305Sopenharmony_ci{
69fc223305Sopenharmony_ci    auto self = GetSelf(object);
70fc223305Sopenharmony_ci    if (self == nullptr) {
71fc223305Sopenharmony_ci        LOG_ERROR("Preferences GetValueType failed, object is null");
72fc223305Sopenharmony_ci        return Preference_ValueType::PREFERENCE_TYPE_NULL;
73fc223305Sopenharmony_ci    }
74fc223305Sopenharmony_ci    if (self->value_.IsInt()) {
75fc223305Sopenharmony_ci        return Preference_ValueType::PREFERENCE_TYPE_INT;
76fc223305Sopenharmony_ci    } else if (self->value_.IsBool()) {
77fc223305Sopenharmony_ci        return Preference_ValueType::PREFERENCE_TYPE_BOOL;
78fc223305Sopenharmony_ci    } else if (self->value_.IsString()) {
79fc223305Sopenharmony_ci        return Preference_ValueType::PREFERENCE_TYPE_STRING;
80fc223305Sopenharmony_ci    }
81fc223305Sopenharmony_ci    return Preference_ValueType::PREFERENCE_TYPE_NULL;
82fc223305Sopenharmony_ci}
83fc223305Sopenharmony_ci
84fc223305Sopenharmony_ciint OH_PreferencesValue_GetInt(const OH_PreferencesValue *object, int *value)
85fc223305Sopenharmony_ci{
86fc223305Sopenharmony_ci    auto self = GetSelf(object);
87fc223305Sopenharmony_ci    if (self == nullptr || value == nullptr) {
88fc223305Sopenharmony_ci        LOG_ERROR("Preferences GetInt failed, object is null: %{public}d, value is null: %{public}d, err: %{public}d",
89fc223305Sopenharmony_ci            (self == nullptr), (value == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM);
90fc223305Sopenharmony_ci        return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM;
91fc223305Sopenharmony_ci    }
92fc223305Sopenharmony_ci    if (self->value_.IsInt()) {
93fc223305Sopenharmony_ci        *value = (int)(self->value_);
94fc223305Sopenharmony_ci        return OH_Preferences_ErrCode::PREFERENCES_OK;
95fc223305Sopenharmony_ci    }
96fc223305Sopenharmony_ci    LOG_ERROR("Preferences GetInt failed, type error, err: %{public}d",
97fc223305Sopenharmony_ci        OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND);
98fc223305Sopenharmony_ci    return OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND;
99fc223305Sopenharmony_ci}
100fc223305Sopenharmony_ci
101fc223305Sopenharmony_ciint OH_PreferencesValue_GetBool(const OH_PreferencesValue *object, bool *value)
102fc223305Sopenharmony_ci{
103fc223305Sopenharmony_ci    auto self = GetSelf(object);
104fc223305Sopenharmony_ci    if (self == nullptr || value == nullptr) {
105fc223305Sopenharmony_ci        LOG_ERROR("Preferences GetBool failed, object is null: %{public}d, value is null: %{public}d, err: %{public}d",
106fc223305Sopenharmony_ci            (self == nullptr), (self == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM);
107fc223305Sopenharmony_ci        return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM;
108fc223305Sopenharmony_ci    }
109fc223305Sopenharmony_ci    if (self->value_.IsBool()) {
110fc223305Sopenharmony_ci        *value = (bool)(self->value_);
111fc223305Sopenharmony_ci        return OH_Preferences_ErrCode::PREFERENCES_OK;
112fc223305Sopenharmony_ci    }
113fc223305Sopenharmony_ci    LOG_ERROR("Preferences GetBool failed, type error, err: %{public}d",
114fc223305Sopenharmony_ci        OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND);
115fc223305Sopenharmony_ci    return OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND;
116fc223305Sopenharmony_ci}
117fc223305Sopenharmony_ci
118fc223305Sopenharmony_ciint OH_PreferencesValue_GetString(const OH_PreferencesValue *object, char **value, uint32_t *valueLen)
119fc223305Sopenharmony_ci{
120fc223305Sopenharmony_ci    auto self = GetSelf(object);
121fc223305Sopenharmony_ci    if (self == nullptr || value == nullptr || valueLen == nullptr) {
122fc223305Sopenharmony_ci        LOG_ERROR("Preferences GetString failed, object is null: %{public}d, value is null: %{public}d, "
123fc223305Sopenharmony_ci            "valueLen is null: %{public}d, err: %{public}d", (self == nullptr), (value == nullptr),
124fc223305Sopenharmony_ci            (valueLen == nullptr), OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM);
125fc223305Sopenharmony_ci        return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM;
126fc223305Sopenharmony_ci    }
127fc223305Sopenharmony_ci    if (self->value_.IsString()) {
128fc223305Sopenharmony_ci        std::string str = (std::string)(self->value_);
129fc223305Sopenharmony_ci        size_t strLen = str.size();
130fc223305Sopenharmony_ci        if (strLen >= SIZE_MAX) {
131fc223305Sopenharmony_ci            LOG_ERROR("string length overlimit: %{public}zu", strLen);
132fc223305Sopenharmony_ci            return OH_Preferences_ErrCode::PREFERENCES_ERROR_INVALID_PARAM;
133fc223305Sopenharmony_ci        }
134fc223305Sopenharmony_ci        void *ptr = malloc(strLen + 1); // free by caller
135fc223305Sopenharmony_ci        if (ptr == nullptr) {
136fc223305Sopenharmony_ci            LOG_ERROR("malloc failed when value get string, errno: %{public}d", errno);
137fc223305Sopenharmony_ci            return OH_Preferences_ErrCode::PREFERENCES_ERROR_MALLOC;
138fc223305Sopenharmony_ci        }
139fc223305Sopenharmony_ci        *value = (char *)ptr;
140fc223305Sopenharmony_ci        int sysErr = memset_s(*value, (strLen + 1), 0, (strLen + 1));
141fc223305Sopenharmony_ci        if (sysErr != EOK) {
142fc223305Sopenharmony_ci            LOG_ERROR("memset failed when get string, errCode: %{public}d", sysErr);
143fc223305Sopenharmony_ci        }
144fc223305Sopenharmony_ci        if (strLen > 0) {
145fc223305Sopenharmony_ci            sysErr = memcpy_s(*value, strLen, str.c_str(), strLen);
146fc223305Sopenharmony_ci            if (sysErr != EOK) {
147fc223305Sopenharmony_ci                LOG_ERROR("memcpy failed when value get string, errCode: %{public}d", sysErr);
148fc223305Sopenharmony_ci                free(ptr);
149fc223305Sopenharmony_ci                return OH_Preferences_ErrCode::PREFERENCES_ERROR_MALLOC;
150fc223305Sopenharmony_ci            }
151fc223305Sopenharmony_ci        }
152fc223305Sopenharmony_ci        *valueLen = strLen + 1;
153fc223305Sopenharmony_ci        return OH_Preferences_ErrCode::PREFERENCES_OK;
154fc223305Sopenharmony_ci    }
155fc223305Sopenharmony_ci    LOG_ERROR("Preferences GetString failed, type error, err: %{public}d",
156fc223305Sopenharmony_ci        OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND);
157fc223305Sopenharmony_ci    return OH_Preferences_ErrCode::PREFERENCES_ERROR_KEY_NOT_FOUND;
158fc223305Sopenharmony_ci}
159