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 "preferences_helper.h"
16fc223305Sopenharmony_ci
17fc223305Sopenharmony_ci#include <string>
18fc223305Sopenharmony_ci#include <variant>
19fc223305Sopenharmony_ci#include <vector>
20fc223305Sopenharmony_ci#include <map>
21fc223305Sopenharmony_ci
22fc223305Sopenharmony_ci#include "ffi_remote_data.h"
23fc223305Sopenharmony_ci#include "securec.h"
24fc223305Sopenharmony_ci#include "preferences.h"
25fc223305Sopenharmony_ci#include "preferences_errno.h"
26fc223305Sopenharmony_ci#include "preferences_impl.h"
27fc223305Sopenharmony_ci#include "preferences_value.h"
28fc223305Sopenharmony_ci#include "preferences_utils.h"
29fc223305Sopenharmony_ci#include "preferences_errno.h"
30fc223305Sopenharmony_ci#include "preferences_log.h"
31fc223305Sopenharmony_ci
32fc223305Sopenharmony_ciusing namespace OHOS::Preferences;
33fc223305Sopenharmony_ciusing namespace OHOS::FFI;
34fc223305Sopenharmony_ciusing namespace OHOS::NativePreferences;
35fc223305Sopenharmony_ci
36fc223305Sopenharmony_cinamespace OHOS::Preferences {
37fc223305Sopenharmony_cistd::tuple<int32_t, std::string> GetInstancePath(OHOS::AbilityRuntime::Context* context, const std::string &name,
38fc223305Sopenharmony_ci    const std::string &dataGroupId)
39fc223305Sopenharmony_ci{
40fc223305Sopenharmony_ci    std::string path;
41fc223305Sopenharmony_ci    if (context == nullptr) {
42fc223305Sopenharmony_ci        LOGE("The context is nullptr.");
43fc223305Sopenharmony_ci        return {E_ERROR, path};
44fc223305Sopenharmony_ci    }
45fc223305Sopenharmony_ci    int32_t errcode = 0;
46fc223305Sopenharmony_ci    auto tempContext = std::make_shared<HelperAysncContext>();
47fc223305Sopenharmony_ci    tempContext->bundleName = context->GetBundleName();
48fc223305Sopenharmony_ci    tempContext->name = name;
49fc223305Sopenharmony_ci    std::string preferencesDir;
50fc223305Sopenharmony_ci    errcode = context->GetSystemPreferencesDir(dataGroupId, false, preferencesDir);
51fc223305Sopenharmony_ci    if (errcode != 0) {
52fc223305Sopenharmony_ci        return {errcode, path};
53fc223305Sopenharmony_ci    }
54fc223305Sopenharmony_ci    tempContext->path = preferencesDir.append("/").append(tempContext->name);
55fc223305Sopenharmony_ci    return {E_OK, tempContext->path};
56fc223305Sopenharmony_ci}
57fc223305Sopenharmony_ci
58fc223305Sopenharmony_ciPreferencesImpl::PreferencesImpl(OHOS::AbilityRuntime::Context* context,
59fc223305Sopenharmony_ci    const std::string& name, const std::string& dataGroupId, int32_t* errCode)
60fc223305Sopenharmony_ci{
61fc223305Sopenharmony_ci    if (context == nullptr) {
62fc223305Sopenharmony_ci        LOGE("Failed to get native context instance");
63fc223305Sopenharmony_ci        *errCode = -1;
64fc223305Sopenharmony_ci        return;
65fc223305Sopenharmony_ci    }
66fc223305Sopenharmony_ci    auto [code, path] = GetInstancePath(context, name, dataGroupId);
67fc223305Sopenharmony_ci    if (code != E_OK) {
68fc223305Sopenharmony_ci        *errCode = code;
69fc223305Sopenharmony_ci        return;
70fc223305Sopenharmony_ci    }
71fc223305Sopenharmony_ci    NativePreferences::Options options(path, context->GetBundleName(), dataGroupId);
72fc223305Sopenharmony_ci    int err;
73fc223305Sopenharmony_ci    auto proxy = PreferencesHelper::GetPreferences(options, err);
74fc223305Sopenharmony_ci    *errCode = err;
75fc223305Sopenharmony_ci    if (err != E_OK) {
76fc223305Sopenharmony_ci        LOGE("Failed to get underlying preferences instance.");
77fc223305Sopenharmony_ci        return;
78fc223305Sopenharmony_ci    }
79fc223305Sopenharmony_ci    preferences = proxy;
80fc223305Sopenharmony_ci    if (preferences == nullptr) {
81fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
82fc223305Sopenharmony_ci        return;
83fc223305Sopenharmony_ci    }
84fc223305Sopenharmony_ci}
85fc223305Sopenharmony_ci
86fc223305Sopenharmony_ciint32_t PreferencesImpl::DeletePreferences(OHOS::AbilityRuntime::Context* context, const std::string &name,
87fc223305Sopenharmony_ci    const std::string &dataGroupId)
88fc223305Sopenharmony_ci{
89fc223305Sopenharmony_ci    auto [code, path] = GetInstancePath(context, name, dataGroupId);
90fc223305Sopenharmony_ci    if (code != E_OK) {
91fc223305Sopenharmony_ci        return code;
92fc223305Sopenharmony_ci    }
93fc223305Sopenharmony_ci    int errCode = PreferencesHelper::DeletePreferences(path);
94fc223305Sopenharmony_ci    if (errCode != E_OK) {
95fc223305Sopenharmony_ci        return errCode;
96fc223305Sopenharmony_ci    }
97fc223305Sopenharmony_ci    return 0;
98fc223305Sopenharmony_ci}
99fc223305Sopenharmony_ci
100fc223305Sopenharmony_ciint32_t PreferencesImpl::RemovePreferencesFromCache(OHOS::AbilityRuntime::Context* context, const std::string &name,
101fc223305Sopenharmony_ci    const std::string &dataGroupId)
102fc223305Sopenharmony_ci{
103fc223305Sopenharmony_ci    auto [code, path] = GetInstancePath(context, name, dataGroupId);
104fc223305Sopenharmony_ci    if (code != 0) {
105fc223305Sopenharmony_ci        return code;
106fc223305Sopenharmony_ci    }
107fc223305Sopenharmony_ci    int errCode = PreferencesHelper::RemovePreferencesFromCache(path);
108fc223305Sopenharmony_ci    if (errCode != E_OK) {
109fc223305Sopenharmony_ci        return errCode;
110fc223305Sopenharmony_ci    }
111fc223305Sopenharmony_ci    return E_OK;
112fc223305Sopenharmony_ci}
113fc223305Sopenharmony_ci
114fc223305Sopenharmony_civoid PreferencesImpl::Flush()
115fc223305Sopenharmony_ci{
116fc223305Sopenharmony_ci    if (preferences == nullptr) {
117fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
118fc223305Sopenharmony_ci        return;
119fc223305Sopenharmony_ci    }
120fc223305Sopenharmony_ci    preferences->FlushSync();
121fc223305Sopenharmony_ci    return;
122fc223305Sopenharmony_ci}
123fc223305Sopenharmony_ci
124fc223305Sopenharmony_civoid PreferencesImpl::Clear()
125fc223305Sopenharmony_ci{
126fc223305Sopenharmony_ci    if (preferences == nullptr) {
127fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
128fc223305Sopenharmony_ci        return;
129fc223305Sopenharmony_ci    }
130fc223305Sopenharmony_ci    preferences->Clear();
131fc223305Sopenharmony_ci    return;
132fc223305Sopenharmony_ci}
133fc223305Sopenharmony_ci
134fc223305Sopenharmony_ciint32_t PreferencesImpl::Delete(const std::string &key)
135fc223305Sopenharmony_ci{
136fc223305Sopenharmony_ci    if (preferences == nullptr) {
137fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
138fc223305Sopenharmony_ci        return E_ERROR;
139fc223305Sopenharmony_ci    }
140fc223305Sopenharmony_ci    int errCode = preferences->Delete(key);
141fc223305Sopenharmony_ci    return errCode;
142fc223305Sopenharmony_ci}
143fc223305Sopenharmony_ci
144fc223305Sopenharmony_cibool PreferencesImpl::HasKey(const std::string &key)
145fc223305Sopenharmony_ci{
146fc223305Sopenharmony_ci    if (preferences == nullptr) {
147fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
148fc223305Sopenharmony_ci        return false;
149fc223305Sopenharmony_ci    }
150fc223305Sopenharmony_ci    bool result = preferences->HasKey(key);
151fc223305Sopenharmony_ci    return result;
152fc223305Sopenharmony_ci}
153fc223305Sopenharmony_ci
154fc223305Sopenharmony_ciOHOS::FFI::RuntimeType* PreferencesImpl::GetRuntimeType()
155fc223305Sopenharmony_ci{
156fc223305Sopenharmony_ci    return GetClassType();
157fc223305Sopenharmony_ci}
158fc223305Sopenharmony_ci
159fc223305Sopenharmony_ciOHOS::FFI::RuntimeType* PreferencesImpl::GetClassType()
160fc223305Sopenharmony_ci{
161fc223305Sopenharmony_ci    static OHOS::FFI::RuntimeType runtimeType =
162fc223305Sopenharmony_ci        OHOS::FFI::RuntimeType::Create<OHOS::FFI::FFIData>("PreferencesImpl");
163fc223305Sopenharmony_ci    return &runtimeType;
164fc223305Sopenharmony_ci}
165fc223305Sopenharmony_ci
166fc223305Sopenharmony_cistatic bool IsSameFunction(const std::function<void(std::string)> *f1, const std::function<void(std::string)> *f2)
167fc223305Sopenharmony_ci{
168fc223305Sopenharmony_ci    return f1 == f2;
169fc223305Sopenharmony_ci}
170fc223305Sopenharmony_ci
171fc223305Sopenharmony_ciRegisterMode PreferencesImpl::ConvertToRegisterMode(const std::string &mode)
172fc223305Sopenharmony_ci{
173fc223305Sopenharmony_ci    return (mode == strChange) ? RegisterMode::LOCAL_CHANGE : RegisterMode::MULTI_PRECESS_CHANGE;
174fc223305Sopenharmony_ci}
175fc223305Sopenharmony_ci
176fc223305Sopenharmony_cistatic PreferencesValue CValueTypeToNativeValue(const ValueType &value)
177fc223305Sopenharmony_ci{
178fc223305Sopenharmony_ci    NativePreferences::PreferencesValue preferencesValue = NativePreferences::PreferencesValue(-1);
179fc223305Sopenharmony_ci    switch (value.tag) {
180fc223305Sopenharmony_ci        case TYPE_INT: {
181fc223305Sopenharmony_ci            preferencesValue = NativePreferences::PreferencesValue(value.integer);
182fc223305Sopenharmony_ci            break;
183fc223305Sopenharmony_ci        }
184fc223305Sopenharmony_ci        case TYPE_DOU: {
185fc223305Sopenharmony_ci            preferencesValue = NativePreferences::PreferencesValue(value.float64);
186fc223305Sopenharmony_ci            break;
187fc223305Sopenharmony_ci        }
188fc223305Sopenharmony_ci        case TYPE_STR: {
189fc223305Sopenharmony_ci            preferencesValue = NativePreferences::PreferencesValue(std::string(value.string));
190fc223305Sopenharmony_ci            break;
191fc223305Sopenharmony_ci        }
192fc223305Sopenharmony_ci        case TYPE_BOOL: {
193fc223305Sopenharmony_ci            preferencesValue = NativePreferences::PreferencesValue(value.boolean);
194fc223305Sopenharmony_ci            break;
195fc223305Sopenharmony_ci        }
196fc223305Sopenharmony_ci        case TYPE_BOOLARR: {
197fc223305Sopenharmony_ci            std::vector<bool> bools = std::vector<bool>();
198fc223305Sopenharmony_ci            for (int64_t i = 0; i < value.boolArray.size; i++) {
199fc223305Sopenharmony_ci                bools.push_back(value.boolArray.head[i]);
200fc223305Sopenharmony_ci            }
201fc223305Sopenharmony_ci            preferencesValue = NativePreferences::PreferencesValue(bools);
202fc223305Sopenharmony_ci            break;
203fc223305Sopenharmony_ci        }
204fc223305Sopenharmony_ci        case TYPE_DOUARR: {
205fc223305Sopenharmony_ci            std::vector<double> doubles = std::vector<double>();
206fc223305Sopenharmony_ci            for (int64_t i = 0; i < value.doubleArray.size; i++) {
207fc223305Sopenharmony_ci                doubles.push_back(value.doubleArray.head[i]);
208fc223305Sopenharmony_ci            }
209fc223305Sopenharmony_ci            preferencesValue = NativePreferences::PreferencesValue(doubles);
210fc223305Sopenharmony_ci            break;
211fc223305Sopenharmony_ci        }
212fc223305Sopenharmony_ci        case TYPE_STRARR: {
213fc223305Sopenharmony_ci            std::vector<std::string> strings = std::vector<std::string>();
214fc223305Sopenharmony_ci            for (int64_t i = 0; i < value.stringArray.size; i++) {
215fc223305Sopenharmony_ci                strings.push_back(value.stringArray.head[i]);
216fc223305Sopenharmony_ci            }
217fc223305Sopenharmony_ci            preferencesValue = NativePreferences::PreferencesValue(strings);
218fc223305Sopenharmony_ci            break;
219fc223305Sopenharmony_ci        }
220fc223305Sopenharmony_ci        default:
221fc223305Sopenharmony_ci            preferencesValue = NativePreferences::PreferencesValue(-1);
222fc223305Sopenharmony_ci            break;
223fc223305Sopenharmony_ci    }
224fc223305Sopenharmony_ci    return preferencesValue;
225fc223305Sopenharmony_ci}
226fc223305Sopenharmony_ci
227fc223305Sopenharmony_cistatic void FreeValueType(ValueType &v)
228fc223305Sopenharmony_ci{
229fc223305Sopenharmony_ci    switch (v.tag) {
230fc223305Sopenharmony_ci        case TYPE_STR: {
231fc223305Sopenharmony_ci            free(v.string);
232fc223305Sopenharmony_ci            break;
233fc223305Sopenharmony_ci        }
234fc223305Sopenharmony_ci        case TYPE_BOOLARR: {
235fc223305Sopenharmony_ci            free(v.boolArray.head);
236fc223305Sopenharmony_ci            break;
237fc223305Sopenharmony_ci        }
238fc223305Sopenharmony_ci        case TYPE_DOUARR: {
239fc223305Sopenharmony_ci            free(v.doubleArray.head);
240fc223305Sopenharmony_ci            break;
241fc223305Sopenharmony_ci        }
242fc223305Sopenharmony_ci        case TYPE_STRARR: {
243fc223305Sopenharmony_ci            for (int64_t i = 0; i < v.stringArray.size; i++) {
244fc223305Sopenharmony_ci                free(v.stringArray.head[i]);
245fc223305Sopenharmony_ci            }
246fc223305Sopenharmony_ci            free(v.stringArray.head);
247fc223305Sopenharmony_ci            break;
248fc223305Sopenharmony_ci        }
249fc223305Sopenharmony_ci        default:
250fc223305Sopenharmony_ci            break;
251fc223305Sopenharmony_ci    }
252fc223305Sopenharmony_ci}
253fc223305Sopenharmony_ci
254fc223305Sopenharmony_cistatic void FreeValueTypes(ValueType *v, int count)
255fc223305Sopenharmony_ci{
256fc223305Sopenharmony_ci    for (int i = 0; i < count; i++) {
257fc223305Sopenharmony_ci        FreeValueType(v[i]);
258fc223305Sopenharmony_ci    }
259fc223305Sopenharmony_ci}
260fc223305Sopenharmony_ci
261fc223305Sopenharmony_cistatic CArrDouble VectorToDoubleArray(const std::vector<double> &doubles, int32_t &code)
262fc223305Sopenharmony_ci{
263fc223305Sopenharmony_ci    if (doubles.size() == 0) {
264fc223305Sopenharmony_ci        return CArrDouble{0};
265fc223305Sopenharmony_ci    }
266fc223305Sopenharmony_ci    double* head = static_cast<double*>(malloc(doubles.size() * sizeof(double)));
267fc223305Sopenharmony_ci    if (head == nullptr) {
268fc223305Sopenharmony_ci        code = E_ERROR;
269fc223305Sopenharmony_ci        return CArrDouble{0};
270fc223305Sopenharmony_ci    }
271fc223305Sopenharmony_ci    for (unsigned long i = 0; i < doubles.size(); i++) {
272fc223305Sopenharmony_ci        head[i] = doubles[i];
273fc223305Sopenharmony_ci    }
274fc223305Sopenharmony_ci    CArrDouble doubleArray = { head, doubles.size() };
275fc223305Sopenharmony_ci    return doubleArray;
276fc223305Sopenharmony_ci}
277fc223305Sopenharmony_ci
278fc223305Sopenharmony_cistatic CArrBool VectorToBoolArray(std::vector<bool> &bools, int32_t &code)
279fc223305Sopenharmony_ci{
280fc223305Sopenharmony_ci    if (bools.size() == 0) {
281fc223305Sopenharmony_ci        return CArrBool{0};
282fc223305Sopenharmony_ci    }
283fc223305Sopenharmony_ci    bool* head = static_cast<bool*>(malloc(bools.size() * sizeof(bool)));
284fc223305Sopenharmony_ci    if (head == nullptr) {
285fc223305Sopenharmony_ci        code = E_ERROR;
286fc223305Sopenharmony_ci        return CArrBool{0};
287fc223305Sopenharmony_ci    }
288fc223305Sopenharmony_ci    for (unsigned long i = 0; i < bools.size(); i++) {
289fc223305Sopenharmony_ci        head[i] = bools[i];
290fc223305Sopenharmony_ci    }
291fc223305Sopenharmony_ci    CArrBool boolArray = { head, bools.size() };
292fc223305Sopenharmony_ci    return boolArray;
293fc223305Sopenharmony_ci}
294fc223305Sopenharmony_ci
295fc223305Sopenharmony_cistatic void FreeCharPointer(char** ptr, int count)
296fc223305Sopenharmony_ci{
297fc223305Sopenharmony_ci    for (int i = 0; i < count; i++) {
298fc223305Sopenharmony_ci        free(ptr[i]);
299fc223305Sopenharmony_ci    }
300fc223305Sopenharmony_ci}
301fc223305Sopenharmony_ci
302fc223305Sopenharmony_cistatic char** VectorToCharPointer(std::vector<std::string> &vec, int32_t &code)
303fc223305Sopenharmony_ci{
304fc223305Sopenharmony_ci    if (vec.size() == 0) {
305fc223305Sopenharmony_ci        return nullptr;
306fc223305Sopenharmony_ci    }
307fc223305Sopenharmony_ci    char** result = static_cast<char**>(malloc(sizeof(char*) * vec.size()));
308fc223305Sopenharmony_ci    if (result == nullptr) {
309fc223305Sopenharmony_ci        code = E_ERROR;
310fc223305Sopenharmony_ci        return nullptr;
311fc223305Sopenharmony_ci    }
312fc223305Sopenharmony_ci    for (size_t i = 0; i < vec.size(); i++) {
313fc223305Sopenharmony_ci        result[i] = MallocCString(vec[i]);
314fc223305Sopenharmony_ci        if (result[i] == nullptr) {
315fc223305Sopenharmony_ci            FreeCharPointer(result, i);
316fc223305Sopenharmony_ci            free(result);
317fc223305Sopenharmony_ci            code = E_ERROR;
318fc223305Sopenharmony_ci            return nullptr;
319fc223305Sopenharmony_ci        }
320fc223305Sopenharmony_ci    }
321fc223305Sopenharmony_ci    return result;
322fc223305Sopenharmony_ci}
323fc223305Sopenharmony_ci
324fc223305Sopenharmony_cistatic CArrStr VectorToStringArray(std::vector<std::string> &strings, int32_t &code)
325fc223305Sopenharmony_ci{
326fc223305Sopenharmony_ci    CArrStr strArray;
327fc223305Sopenharmony_ci    strArray.size = static_cast<int64_t>(strings.size());
328fc223305Sopenharmony_ci    strArray.head = VectorToCharPointer(strings, code);
329fc223305Sopenharmony_ci    if (code != E_OK) {
330fc223305Sopenharmony_ci        return CArrStr{0};
331fc223305Sopenharmony_ci    }
332fc223305Sopenharmony_ci    return strArray;
333fc223305Sopenharmony_ci}
334fc223305Sopenharmony_ci
335fc223305Sopenharmony_cistatic ValueType NativeValueToCValueType(const PreferencesValue &pValue, int32_t &code)
336fc223305Sopenharmony_ci{
337fc223305Sopenharmony_ci    ValueType v = {0};
338fc223305Sopenharmony_ci    if (pValue.IsInt()) {
339fc223305Sopenharmony_ci        v.integer = (int64_t)std::get<int>(pValue.value_);
340fc223305Sopenharmony_ci        v.tag = TYPE_INT;
341fc223305Sopenharmony_ci    } else if (pValue.IsLong()) {
342fc223305Sopenharmony_ci        v.integer = std::get<int64_t>(pValue.value_);
343fc223305Sopenharmony_ci        v.tag = TYPE_INT;
344fc223305Sopenharmony_ci    } else if (pValue.IsFloat()) {
345fc223305Sopenharmony_ci        v.float64 = (double)std::get<float>(pValue.value_);
346fc223305Sopenharmony_ci        v.tag = TYPE_DOU;
347fc223305Sopenharmony_ci    } else if (pValue.IsDouble()) {
348fc223305Sopenharmony_ci        v.float64 = std::get<double>(pValue.value_);
349fc223305Sopenharmony_ci        v.tag = TYPE_DOU;
350fc223305Sopenharmony_ci    } else if (pValue.IsString()) {
351fc223305Sopenharmony_ci        auto pValueStr = std::get<std::string>(pValue.value_);
352fc223305Sopenharmony_ci        char* pValueChar = MallocCString(pValueStr);
353fc223305Sopenharmony_ci        v.string = pValueChar;
354fc223305Sopenharmony_ci        v.tag = TYPE_STR;
355fc223305Sopenharmony_ci    } else if (pValue.IsBool()) {
356fc223305Sopenharmony_ci        v.boolean = std::get<bool>(pValue.value_);
357fc223305Sopenharmony_ci        v.tag = TYPE_BOOL;
358fc223305Sopenharmony_ci    } else if (pValue.IsBoolArray()) {
359fc223305Sopenharmony_ci        auto boolVector = std::get<std::vector<bool>>(pValue.value_);
360fc223305Sopenharmony_ci        v.boolArray = VectorToBoolArray(boolVector, code);
361fc223305Sopenharmony_ci        v.tag = TYPE_BOOLARR;
362fc223305Sopenharmony_ci    } else if (pValue.IsDoubleArray()) {
363fc223305Sopenharmony_ci        auto doubleVector = std::get<std::vector<double>>(pValue.value_);
364fc223305Sopenharmony_ci        v.doubleArray = VectorToDoubleArray(doubleVector, code);
365fc223305Sopenharmony_ci        v.tag = TYPE_DOUARR;
366fc223305Sopenharmony_ci    } else if (pValue.IsStringArray()) {
367fc223305Sopenharmony_ci        auto stringVector = std::get<std::vector<std::string>>(pValue.value_);
368fc223305Sopenharmony_ci        v.stringArray = VectorToStringArray(stringVector, code);
369fc223305Sopenharmony_ci        v.tag = TYPE_STRARR;
370fc223305Sopenharmony_ci    } else {
371fc223305Sopenharmony_ci        v.tag = -1;
372fc223305Sopenharmony_ci    }
373fc223305Sopenharmony_ci    return v;
374fc223305Sopenharmony_ci}
375fc223305Sopenharmony_ci
376fc223305Sopenharmony_cistatic ValueTypes NativeValuesToCValueTypes(const std::map<std::string, PreferencesValue> &objects, int32_t &code)
377fc223305Sopenharmony_ci{
378fc223305Sopenharmony_ci    ValueTypes valueTypes = {0};
379fc223305Sopenharmony_ci    valueTypes.size = static_cast<int64_t>(objects.size());
380fc223305Sopenharmony_ci    valueTypes.key = static_cast<char**>(malloc(valueTypes.size * sizeof(char*)));
381fc223305Sopenharmony_ci    if (valueTypes.key == nullptr) {
382fc223305Sopenharmony_ci        code = E_ERROR;
383fc223305Sopenharmony_ci        return valueTypes;
384fc223305Sopenharmony_ci    }
385fc223305Sopenharmony_ci    valueTypes.head = static_cast<ValueType*>(malloc(valueTypes.size * sizeof(ValueType)));
386fc223305Sopenharmony_ci    if (valueTypes.head == nullptr) {
387fc223305Sopenharmony_ci        free(valueTypes.key);
388fc223305Sopenharmony_ci        code = E_ERROR;
389fc223305Sopenharmony_ci        return valueTypes;
390fc223305Sopenharmony_ci    }
391fc223305Sopenharmony_ci    int i = 0;
392fc223305Sopenharmony_ci    for (auto const& [key, value] : objects) {
393fc223305Sopenharmony_ci        valueTypes.key[i] = MallocCString(key);
394fc223305Sopenharmony_ci        if (valueTypes.key[i] == nullptr) {
395fc223305Sopenharmony_ci            FreeCharPointer(valueTypes.key, i);
396fc223305Sopenharmony_ci            FreeValueTypes(valueTypes.head, i);
397fc223305Sopenharmony_ci            free(valueTypes.key);
398fc223305Sopenharmony_ci            free(valueTypes.head);
399fc223305Sopenharmony_ci            code = E_ERROR;
400fc223305Sopenharmony_ci            return valueTypes;
401fc223305Sopenharmony_ci        }
402fc223305Sopenharmony_ci        valueTypes.head[i] = NativeValueToCValueType(value, code);
403fc223305Sopenharmony_ci        if (code != E_OK) {
404fc223305Sopenharmony_ci            free(valueTypes.key[i]);
405fc223305Sopenharmony_ci            FreeCharPointer(valueTypes.key, i);
406fc223305Sopenharmony_ci            FreeValueTypes(valueTypes.head, i);
407fc223305Sopenharmony_ci            free(valueTypes.key);
408fc223305Sopenharmony_ci            free(valueTypes.head);
409fc223305Sopenharmony_ci            code = E_ERROR;
410fc223305Sopenharmony_ci            return valueTypes;
411fc223305Sopenharmony_ci        }
412fc223305Sopenharmony_ci        i++;
413fc223305Sopenharmony_ci    }
414fc223305Sopenharmony_ci    return valueTypes;
415fc223305Sopenharmony_ci}
416fc223305Sopenharmony_ci
417fc223305Sopenharmony_ciValueType PreferencesImpl::Get(const std::string &key, const ValueType &defValue)
418fc223305Sopenharmony_ci{
419fc223305Sopenharmony_ci    if (preferences == nullptr) {
420fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
421fc223305Sopenharmony_ci        return ValueType{0};
422fc223305Sopenharmony_ci    }
423fc223305Sopenharmony_ci    PreferencesValue p = CValueTypeToNativeValue(defValue);
424fc223305Sopenharmony_ci    int32_t err = E_OK;
425fc223305Sopenharmony_ci    ValueType v = NativeValueToCValueType(preferences->Get(key, p), err);
426fc223305Sopenharmony_ci    if (err != E_OK) {
427fc223305Sopenharmony_ci        return ValueType{0};
428fc223305Sopenharmony_ci    }
429fc223305Sopenharmony_ci    return v;
430fc223305Sopenharmony_ci}
431fc223305Sopenharmony_ci
432fc223305Sopenharmony_ciint32_t PreferencesImpl::Put(const std::string &key, const ValueType &value)
433fc223305Sopenharmony_ci{
434fc223305Sopenharmony_ci    if (preferences == nullptr) {
435fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
436fc223305Sopenharmony_ci        return E_ERROR;
437fc223305Sopenharmony_ci    }
438fc223305Sopenharmony_ci    return preferences->Put(key, CValueTypeToNativeValue(value));
439fc223305Sopenharmony_ci}
440fc223305Sopenharmony_ci
441fc223305Sopenharmony_ciValueTypes PreferencesImpl::GetAll()
442fc223305Sopenharmony_ci{
443fc223305Sopenharmony_ci    if (preferences == nullptr) {
444fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
445fc223305Sopenharmony_ci        return ValueTypes{0};
446fc223305Sopenharmony_ci    }
447fc223305Sopenharmony_ci    int32_t err = E_OK;
448fc223305Sopenharmony_ci    ValueTypes vs = NativeValuesToCValueTypes(preferences->GetAll(), err);
449fc223305Sopenharmony_ci    if (err != E_OK) {
450fc223305Sopenharmony_ci        return ValueTypes{0};
451fc223305Sopenharmony_ci    }
452fc223305Sopenharmony_ci    return vs;
453fc223305Sopenharmony_ci}
454fc223305Sopenharmony_ci
455fc223305Sopenharmony_ciint32_t PreferencesImpl::RegisterObserver(const std::string &mode, std::function<void(std::string)> *callback,
456fc223305Sopenharmony_ci    const std::function<void(std::string)>& callbackRef)
457fc223305Sopenharmony_ci{
458fc223305Sopenharmony_ci    std::lock_guard<std::mutex> lck(listMutex_);
459fc223305Sopenharmony_ci    auto observer = std::make_shared<CJPreferencesObserver>(callback, callbackRef);
460fc223305Sopenharmony_ci    if (preferences == nullptr) {
461fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
462fc223305Sopenharmony_ci        return E_ERROR;
463fc223305Sopenharmony_ci    }
464fc223305Sopenharmony_ci    int errCode = preferences->RegisterObserver(observer, ConvertToRegisterMode(mode));
465fc223305Sopenharmony_ci    if (errCode != E_OK) {
466fc223305Sopenharmony_ci        return errCode;
467fc223305Sopenharmony_ci    }
468fc223305Sopenharmony_ci    auto &observers = (ConvertToRegisterMode(mode) == RegisterMode::LOCAL_CHANGE) ?
469fc223305Sopenharmony_ci                        localObservers_ : multiProcessObservers_;
470fc223305Sopenharmony_ci    observers.push_back(observer);
471fc223305Sopenharmony_ci    return E_OK;
472fc223305Sopenharmony_ci}
473fc223305Sopenharmony_ci
474fc223305Sopenharmony_ciint32_t PreferencesImpl::UnRegisterObserver(const std::string &mode, std::function<void(std::string)> *callback)
475fc223305Sopenharmony_ci{
476fc223305Sopenharmony_ci    std::lock_guard<std::mutex> lck(listMutex_);
477fc223305Sopenharmony_ci    auto &observers = (ConvertToRegisterMode(mode) == RegisterMode::LOCAL_CHANGE) ?
478fc223305Sopenharmony_ci                        localObservers_ : multiProcessObservers_;
479fc223305Sopenharmony_ci    auto it = observers.begin();
480fc223305Sopenharmony_ci    if (preferences == nullptr) {
481fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
482fc223305Sopenharmony_ci        return E_ERROR;
483fc223305Sopenharmony_ci    }
484fc223305Sopenharmony_ci    while (it != observers.end()) {
485fc223305Sopenharmony_ci        if (IsSameFunction(callback, (*it)->m_callback)) {
486fc223305Sopenharmony_ci            int errCode = preferences->UnRegisterObserver(*it, ConvertToRegisterMode(mode));
487fc223305Sopenharmony_ci            if (errCode != E_OK) {
488fc223305Sopenharmony_ci                return errCode;
489fc223305Sopenharmony_ci            }
490fc223305Sopenharmony_ci            it = observers.erase(it);
491fc223305Sopenharmony_ci            break; // specified observer is current iterator
492fc223305Sopenharmony_ci        }
493fc223305Sopenharmony_ci        ++it;
494fc223305Sopenharmony_ci    }
495fc223305Sopenharmony_ci    return E_OK;
496fc223305Sopenharmony_ci}
497fc223305Sopenharmony_ci
498fc223305Sopenharmony_ciint32_t PreferencesImpl::UnRegisteredAllObservers(const std::string &mode)
499fc223305Sopenharmony_ci{
500fc223305Sopenharmony_ci    std::lock_guard<std::mutex> lck(listMutex_);
501fc223305Sopenharmony_ci    auto &observers = (ConvertToRegisterMode(mode) == RegisterMode::LOCAL_CHANGE) ?
502fc223305Sopenharmony_ci                        localObservers_ : multiProcessObservers_;
503fc223305Sopenharmony_ci    bool hasFailed = false;
504fc223305Sopenharmony_ci    int errCode;
505fc223305Sopenharmony_ci    if (preferences == nullptr) {
506fc223305Sopenharmony_ci        LOGE("The preferences is nullptr.");
507fc223305Sopenharmony_ci        return E_ERROR;
508fc223305Sopenharmony_ci    }
509fc223305Sopenharmony_ci    for (auto &observer : observers) {
510fc223305Sopenharmony_ci        errCode = preferences->UnRegisterObserver(observer, ConvertToRegisterMode(mode));
511fc223305Sopenharmony_ci        if (errCode != E_OK) {
512fc223305Sopenharmony_ci            hasFailed = true;
513fc223305Sopenharmony_ci        }
514fc223305Sopenharmony_ci    }
515fc223305Sopenharmony_ci    observers.clear();
516fc223305Sopenharmony_ci    return hasFailed ? E_ERROR : E_OK;
517fc223305Sopenharmony_ci}
518fc223305Sopenharmony_ci
519fc223305Sopenharmony_ciCJPreferencesObserver::CJPreferencesObserver(std::function<void(std::string)> *callback,
520fc223305Sopenharmony_ci    const std::function<void(std::string)>& callbackRef)
521fc223305Sopenharmony_ci{
522fc223305Sopenharmony_ci    if (callback == nullptr) {
523fc223305Sopenharmony_ci        LOGI("WARNING: nullptr");
524fc223305Sopenharmony_ci    }
525fc223305Sopenharmony_ci    m_callback = callback;
526fc223305Sopenharmony_ci    m_callbackRef = callbackRef;
527fc223305Sopenharmony_ci}
528fc223305Sopenharmony_ci
529fc223305Sopenharmony_civoid CJPreferencesObserver::OnChange(const std::string &key)
530fc223305Sopenharmony_ci{
531fc223305Sopenharmony_ci    m_callbackRef(key);
532fc223305Sopenharmony_ci}
533fc223305Sopenharmony_ci}
534