1c5e268c6Sopenharmony_ci/*
2c5e268c6Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3c5e268c6Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c5e268c6Sopenharmony_ci * you may not use this file except in compliance with the License.
5c5e268c6Sopenharmony_ci * You may obtain a copy of the License at
6c5e268c6Sopenharmony_ci *
7c5e268c6Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8c5e268c6Sopenharmony_ci *
9c5e268c6Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c5e268c6Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c5e268c6Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c5e268c6Sopenharmony_ci * See the License for the specific language governing permissions and
13c5e268c6Sopenharmony_ci * limitations under the License.
14c5e268c6Sopenharmony_ci */
15c5e268c6Sopenharmony_ci
16c5e268c6Sopenharmony_ci#include "map_data_sequenceable.h"
17c5e268c6Sopenharmony_ci#include "hdi_log.h"
18c5e268c6Sopenharmony_ci#include <message_parcel.h>
19c5e268c6Sopenharmony_cinamespace OHOS {
20c5e268c6Sopenharmony_cinamespace HDI {
21c5e268c6Sopenharmony_cinamespace Camera {
22c5e268c6Sopenharmony_cinamespace V1_0 {
23c5e268c6Sopenharmony_ciconstexpr int32_t BUFFER_DATA_MAGIC = 0x4567;
24c5e268c6Sopenharmony_ciconstexpr int32_t BUFFER_MAX_USER_DATA_COUNT = 1000;
25c5e268c6Sopenharmony_ci
26c5e268c6Sopenharmony_cienum ErrorCode : int32_t {
27c5e268c6Sopenharmony_ci    ERROR_OK = 0,
28c5e268c6Sopenharmony_ci    ERROR_INTERNAL = -1,
29c5e268c6Sopenharmony_ci    ERROR_NO_ENTRY = -2,
30c5e268c6Sopenharmony_ci    ERROR_TYPE_ERROR = -3,
31c5e268c6Sopenharmony_ci    ERROR_OUT_OF_RANGE = -4,
32c5e268c6Sopenharmony_ci};
33c5e268c6Sopenharmony_ci
34c5e268c6Sopenharmony_ci#define SET_DATA_FROM_POINTER(data, pointer) do { \
35c5e268c6Sopenharmony_ci    if ((pointer) != nullptr) { \
36c5e268c6Sopenharmony_ci        (data) = *(pointer); \
37c5e268c6Sopenharmony_ci    } \
38c5e268c6Sopenharmony_ci} while (0)
39c5e268c6Sopenharmony_ci
40c5e268c6Sopenharmony_cisptr<MapDataSequenceable> MapDataSequenceable::Unmarshalling(Parcel &parcel)
41c5e268c6Sopenharmony_ci{
42c5e268c6Sopenharmony_ci    int32_t magic;
43c5e268c6Sopenharmony_ci    if (parcel.ReadInt32(magic) == false || magic != BUFFER_DATA_MAGIC) {
44c5e268c6Sopenharmony_ci        HDI_CAMERA_LOGW("read failed, magic is error");
45c5e268c6Sopenharmony_ci        return nullptr;
46c5e268c6Sopenharmony_ci    }
47c5e268c6Sopenharmony_ci
48c5e268c6Sopenharmony_ci    int32_t size = parcel.ReadInt32();
49c5e268c6Sopenharmony_ci    if (size > BUFFER_MAX_USER_DATA_COUNT) {
50c5e268c6Sopenharmony_ci        HDI_CAMERA_LOGE("Too much data obtained from Parcel");
51c5e268c6Sopenharmony_ci        return nullptr;
52c5e268c6Sopenharmony_ci    }
53c5e268c6Sopenharmony_ci    sptr<MapDataSequenceable> sequenceData(new MapDataSequenceable());
54c5e268c6Sopenharmony_ci
55c5e268c6Sopenharmony_ci    int32_t ret = ERROR_OK;
56c5e268c6Sopenharmony_ci    for (int32_t i = 0; i < size; i++) {
57c5e268c6Sopenharmony_ci        auto key = parcel.ReadString();
58c5e268c6Sopenharmony_ci        auto type = static_cast<MapDataType>(parcel.ReadInt32());
59c5e268c6Sopenharmony_ci        switch (type) {
60c5e268c6Sopenharmony_ci            case MapDataType::I32: {
61c5e268c6Sopenharmony_ci                ret = sequenceData->Set(key, type, parcel.ReadInt32());
62c5e268c6Sopenharmony_ci                break;
63c5e268c6Sopenharmony_ci            }
64c5e268c6Sopenharmony_ci            case MapDataType::I64: {
65c5e268c6Sopenharmony_ci                ret = sequenceData->Set(key, type, parcel.ReadInt64());
66c5e268c6Sopenharmony_ci                break;
67c5e268c6Sopenharmony_ci            }
68c5e268c6Sopenharmony_ci            case MapDataType::F64: {
69c5e268c6Sopenharmony_ci                ret = sequenceData->Set(key, type, parcel.ReadDouble());
70c5e268c6Sopenharmony_ci                break;
71c5e268c6Sopenharmony_ci            }
72c5e268c6Sopenharmony_ci            case MapDataType::STRING: {
73c5e268c6Sopenharmony_ci                ret = sequenceData->Set(key, type, parcel.ReadString());
74c5e268c6Sopenharmony_ci                break;
75c5e268c6Sopenharmony_ci            }
76c5e268c6Sopenharmony_ci            default: break;
77c5e268c6Sopenharmony_ci        }
78c5e268c6Sopenharmony_ci
79c5e268c6Sopenharmony_ci        if (ret != ERROR_OK) {
80c5e268c6Sopenharmony_ci            HDI_CAMERA_LOGE("Set extra data failed, return %{public}d", ret);
81c5e268c6Sopenharmony_ci            return nullptr;
82c5e268c6Sopenharmony_ci        }
83c5e268c6Sopenharmony_ci    }
84c5e268c6Sopenharmony_ci    return sequenceData;
85c5e268c6Sopenharmony_ci}
86c5e268c6Sopenharmony_ci
87c5e268c6Sopenharmony_cibool MapDataSequenceable::Marshalling(Parcel &parcel) const
88c5e268c6Sopenharmony_ci{
89c5e268c6Sopenharmony_ci    OHOS::MessageParcel &dataParcel = static_cast<OHOS::MessageParcel &>(parcel);
90c5e268c6Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mtx_);
91c5e268c6Sopenharmony_ci    dataParcel.WriteInt32(BUFFER_DATA_MAGIC);
92c5e268c6Sopenharmony_ci    dataParcel.WriteInt32(datas_.size());
93c5e268c6Sopenharmony_ci    for (const auto &[key, data] : datas_) {
94c5e268c6Sopenharmony_ci        dataParcel.WriteString(key);
95c5e268c6Sopenharmony_ci        dataParcel.WriteInt32(static_cast<int32_t>(data.type));
96c5e268c6Sopenharmony_ci        switch (data.type) {
97c5e268c6Sopenharmony_ci            case MapDataType::I32: {
98c5e268c6Sopenharmony_ci                int32_t i32 = -1;
99c5e268c6Sopenharmony_ci                auto pVal = std::any_cast<int32_t>(&data.val);
100c5e268c6Sopenharmony_ci                SET_DATA_FROM_POINTER(i32, pVal);
101c5e268c6Sopenharmony_ci                dataParcel.WriteInt32(i32);
102c5e268c6Sopenharmony_ci                break;
103c5e268c6Sopenharmony_ci            }
104c5e268c6Sopenharmony_ci            case MapDataType::I64: {
105c5e268c6Sopenharmony_ci                int64_t i64 = -1;
106c5e268c6Sopenharmony_ci                auto pVal = std::any_cast<int64_t>(&data.val);
107c5e268c6Sopenharmony_ci                SET_DATA_FROM_POINTER(i64, pVal);
108c5e268c6Sopenharmony_ci                dataParcel.WriteInt64(i64);
109c5e268c6Sopenharmony_ci                break;
110c5e268c6Sopenharmony_ci            }
111c5e268c6Sopenharmony_ci            case MapDataType::F64: {
112c5e268c6Sopenharmony_ci                double f64 = -1;
113c5e268c6Sopenharmony_ci                auto pVal = std::any_cast<double>(&data.val);
114c5e268c6Sopenharmony_ci                SET_DATA_FROM_POINTER(f64, pVal);
115c5e268c6Sopenharmony_ci                dataParcel.WriteDouble(f64);
116c5e268c6Sopenharmony_ci                break;
117c5e268c6Sopenharmony_ci            }
118c5e268c6Sopenharmony_ci            case MapDataType::STRING: {
119c5e268c6Sopenharmony_ci                std::string string = "-1";
120c5e268c6Sopenharmony_ci                auto pVal = std::any_cast<std::string>(&data.val);
121c5e268c6Sopenharmony_ci                SET_DATA_FROM_POINTER(string, pVal);
122c5e268c6Sopenharmony_ci                dataParcel.WriteString(string);
123c5e268c6Sopenharmony_ci                break;
124c5e268c6Sopenharmony_ci            }
125c5e268c6Sopenharmony_ci            default:
126c5e268c6Sopenharmony_ci                break;
127c5e268c6Sopenharmony_ci        }
128c5e268c6Sopenharmony_ci    }
129c5e268c6Sopenharmony_ci    return true;
130c5e268c6Sopenharmony_ci}
131c5e268c6Sopenharmony_ci
132c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Get(const std::string &key, int32_t &value) const
133c5e268c6Sopenharmony_ci{
134c5e268c6Sopenharmony_ci    return Get<int32_t>(key, MapDataType::I32, value);
135c5e268c6Sopenharmony_ci}
136c5e268c6Sopenharmony_ci
137c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Get(const std::string &key, int64_t &value) const
138c5e268c6Sopenharmony_ci{
139c5e268c6Sopenharmony_ci    return Get<int64_t>(key, MapDataType::I64, value);
140c5e268c6Sopenharmony_ci}
141c5e268c6Sopenharmony_ci
142c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Get(const std::string &key, double &value) const
143c5e268c6Sopenharmony_ci{
144c5e268c6Sopenharmony_ci    return Get<double>(key, MapDataType::F64, value);
145c5e268c6Sopenharmony_ci}
146c5e268c6Sopenharmony_ci
147c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Get(const std::string &key, std::string &value) const
148c5e268c6Sopenharmony_ci{
149c5e268c6Sopenharmony_ci    return Get<std::string>(key, MapDataType::STRING, value);
150c5e268c6Sopenharmony_ci}
151c5e268c6Sopenharmony_ci
152c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Set(const std::string &key, int32_t value)
153c5e268c6Sopenharmony_ci{
154c5e268c6Sopenharmony_ci    return Set(key, MapDataType::I32, value);
155c5e268c6Sopenharmony_ci}
156c5e268c6Sopenharmony_ci
157c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Set(const std::string &key, int64_t value)
158c5e268c6Sopenharmony_ci{
159c5e268c6Sopenharmony_ci    return Set(key, MapDataType::I64, value);
160c5e268c6Sopenharmony_ci}
161c5e268c6Sopenharmony_ci
162c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Set(const std::string &key, double value)
163c5e268c6Sopenharmony_ci{
164c5e268c6Sopenharmony_ci    return Set(key, MapDataType::F64, value);
165c5e268c6Sopenharmony_ci}
166c5e268c6Sopenharmony_ci
167c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Set(const std::string &key, const std::string& value)
168c5e268c6Sopenharmony_ci{
169c5e268c6Sopenharmony_ci    return Set(key, MapDataType::STRING, value);
170c5e268c6Sopenharmony_ci}
171c5e268c6Sopenharmony_ci
172c5e268c6Sopenharmony_citemplate<class T>
173c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Get(const std::string &key, MapDataType type, T &value) const
174c5e268c6Sopenharmony_ci{
175c5e268c6Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mtx_);
176c5e268c6Sopenharmony_ci    auto it = datas_.find(key);
177c5e268c6Sopenharmony_ci    if (it == datas_.end()) {
178c5e268c6Sopenharmony_ci        return ERROR_NO_ENTRY;
179c5e268c6Sopenharmony_ci    }
180c5e268c6Sopenharmony_ci    if (it->second.type != type) {
181c5e268c6Sopenharmony_ci        return ERROR_TYPE_ERROR;
182c5e268c6Sopenharmony_ci    }
183c5e268c6Sopenharmony_ci    auto pVal = std::any_cast<T>(&it->second.val);
184c5e268c6Sopenharmony_ci    if (pVal == nullptr) {
185c5e268c6Sopenharmony_ci        return ERROR_TYPE_ERROR;
186c5e268c6Sopenharmony_ci    }
187c5e268c6Sopenharmony_ci    value = *pVal;
188c5e268c6Sopenharmony_ci    return ERROR_OK;
189c5e268c6Sopenharmony_ci}
190c5e268c6Sopenharmony_ci
191c5e268c6Sopenharmony_ciint32_t MapDataSequenceable::Set(const std::string &key, MapDataType type, const std::any& val)
192c5e268c6Sopenharmony_ci{
193c5e268c6Sopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mtx_);
194c5e268c6Sopenharmony_ci    auto it = datas_.find(key);
195c5e268c6Sopenharmony_ci    if (it == datas_.end() && datas_.size() > BUFFER_MAX_USER_DATA_COUNT) {
196c5e268c6Sopenharmony_ci        HDI_CAMERA_LOGW("SurfaceBuffer has too many extra data, cannot save one more!!!");
197c5e268c6Sopenharmony_ci        return ERROR_OUT_OF_RANGE;
198c5e268c6Sopenharmony_ci    }
199c5e268c6Sopenharmony_ci    datas_[key].type = type;
200c5e268c6Sopenharmony_ci    datas_[key].val = val;
201c5e268c6Sopenharmony_ci    return ERROR_OK;
202c5e268c6Sopenharmony_ci}
203c5e268c6Sopenharmony_ci
204c5e268c6Sopenharmony_ci}
205c5e268c6Sopenharmony_ci}
206c5e268c6Sopenharmony_ci}
207c5e268c6Sopenharmony_ci}