132a6e48fSopenharmony_ci/*
232a6e48fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
332a6e48fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
432a6e48fSopenharmony_ci * you may not use this file except in compliance with the License.
532a6e48fSopenharmony_ci * You may obtain a copy of the License at
632a6e48fSopenharmony_ci *
732a6e48fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
832a6e48fSopenharmony_ci *
932a6e48fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1032a6e48fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1132a6e48fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1232a6e48fSopenharmony_ci * See the License for the specific language governing permissions and
1332a6e48fSopenharmony_ci * limitations under the License.
1432a6e48fSopenharmony_ci */
1532a6e48fSopenharmony_ci
1632a6e48fSopenharmony_ci#include "buffer_extra_data_impl.h"
1732a6e48fSopenharmony_ci#include <message_parcel.h>
1832a6e48fSopenharmony_ci#include "buffer_log.h"
1932a6e48fSopenharmony_ci
2032a6e48fSopenharmony_cinamespace OHOS {
2132a6e48fSopenharmony_cinamespace {
2232a6e48fSopenharmony_ciconstexpr int32_t BUFFER_EXTRA_DATA_MAGIC = 0x4567;
2332a6e48fSopenharmony_ci} // namespace
2432a6e48fSopenharmony_ci
2532a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ReadFromParcel(MessageParcel &parcel)
2632a6e48fSopenharmony_ci{
2732a6e48fSopenharmony_ci    int32_t magic = 0;
2832a6e48fSopenharmony_ci    if (parcel.ReadInt32(magic) == false || magic != BUFFER_EXTRA_DATA_MAGIC) {
2932a6e48fSopenharmony_ci        BLOGW("read failed, magic: %{public}d", magic);
3032a6e48fSopenharmony_ci        return GSERROR_INTERNAL;
3132a6e48fSopenharmony_ci    }
3232a6e48fSopenharmony_ci
3332a6e48fSopenharmony_ci    int32_t size = parcel.ReadInt32();
3432a6e48fSopenharmony_ci    if (size > SURFACE_MAX_USER_DATA_COUNT) {
3532a6e48fSopenharmony_ci        BLOGE("ReadFromParcel size: %{public}d", size);
3632a6e48fSopenharmony_ci        return GSERROR_INTERNAL;
3732a6e48fSopenharmony_ci    }
3832a6e48fSopenharmony_ci
3932a6e48fSopenharmony_ci    GSError ret = GSERROR_OK;
4032a6e48fSopenharmony_ci    for (int32_t i = 0; i < size; i++) {
4132a6e48fSopenharmony_ci        auto key = parcel.ReadString();
4232a6e48fSopenharmony_ci        auto type = static_cast<ExtraDataType>(parcel.ReadInt32());
4332a6e48fSopenharmony_ci        switch (type) {
4432a6e48fSopenharmony_ci            case ExtraDataType::i32: {
4532a6e48fSopenharmony_ci                ret = ExtraSet(key, type, parcel.ReadInt32());
4632a6e48fSopenharmony_ci                break;
4732a6e48fSopenharmony_ci            }
4832a6e48fSopenharmony_ci            case ExtraDataType::i64: {
4932a6e48fSopenharmony_ci                ret = ExtraSet(key, type, parcel.ReadInt64());
5032a6e48fSopenharmony_ci                break;
5132a6e48fSopenharmony_ci            }
5232a6e48fSopenharmony_ci            case ExtraDataType::f64: {
5332a6e48fSopenharmony_ci                ret = ExtraSet(key, type, parcel.ReadDouble());
5432a6e48fSopenharmony_ci                break;
5532a6e48fSopenharmony_ci            }
5632a6e48fSopenharmony_ci            case ExtraDataType::string: {
5732a6e48fSopenharmony_ci                ret = ExtraSet(key, type, parcel.ReadString());
5832a6e48fSopenharmony_ci                break;
5932a6e48fSopenharmony_ci            }
6032a6e48fSopenharmony_ci            default: break;
6132a6e48fSopenharmony_ci        }
6232a6e48fSopenharmony_ci
6332a6e48fSopenharmony_ci        if (ret != GSERROR_OK) {
6432a6e48fSopenharmony_ci            BLOGE("ExtraSet failed, ret %{public}d", ret);
6532a6e48fSopenharmony_ci            break;
6632a6e48fSopenharmony_ci        }
6732a6e48fSopenharmony_ci    }
6832a6e48fSopenharmony_ci    return ret;
6932a6e48fSopenharmony_ci}
7032a6e48fSopenharmony_ci
7132a6e48fSopenharmony_ciGSError BufferExtraDataImpl::WriteToParcel(MessageParcel &parcel)
7232a6e48fSopenharmony_ci{
7332a6e48fSopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mtx_);
7432a6e48fSopenharmony_ci    if (!parcel.WriteInt32(BUFFER_EXTRA_DATA_MAGIC) || !parcel.WriteInt32(datas_.size())) {
7532a6e48fSopenharmony_ci        return GSERROR_BINDER;
7632a6e48fSopenharmony_ci    }
7732a6e48fSopenharmony_ci    bool ipcRet = true;
7832a6e48fSopenharmony_ci    for (const auto &[key, data] : datas_) {
7932a6e48fSopenharmony_ci        if (!parcel.WriteString(key) || !parcel.WriteInt32(static_cast<int32_t>(data.type))) {
8032a6e48fSopenharmony_ci            return GSERROR_BINDER;
8132a6e48fSopenharmony_ci        }
8232a6e48fSopenharmony_ci        switch (data.type) {
8332a6e48fSopenharmony_ci            case ExtraDataType::i32: {
8432a6e48fSopenharmony_ci                int32_t i32 = -1;
8532a6e48fSopenharmony_ci                auto pVal = std::any_cast<int32_t>(&data.val);
8632a6e48fSopenharmony_ci                if (pVal != nullptr) {
8732a6e48fSopenharmony_ci                    i32 = *pVal;
8832a6e48fSopenharmony_ci                }
8932a6e48fSopenharmony_ci                ipcRet = parcel.WriteInt32(i32);
9032a6e48fSopenharmony_ci                break;
9132a6e48fSopenharmony_ci            }
9232a6e48fSopenharmony_ci            case ExtraDataType::i64: {
9332a6e48fSopenharmony_ci                int64_t i64 = -1;
9432a6e48fSopenharmony_ci                auto pVal = std::any_cast<int64_t>(&data.val);
9532a6e48fSopenharmony_ci                if (pVal != nullptr) {
9632a6e48fSopenharmony_ci                    i64 = *pVal;
9732a6e48fSopenharmony_ci                }
9832a6e48fSopenharmony_ci                ipcRet = parcel.WriteInt64(i64);
9932a6e48fSopenharmony_ci                break;
10032a6e48fSopenharmony_ci            }
10132a6e48fSopenharmony_ci            case ExtraDataType::f64: {
10232a6e48fSopenharmony_ci                double f64 = -1;
10332a6e48fSopenharmony_ci                auto pVal = std::any_cast<double>(&data.val);
10432a6e48fSopenharmony_ci                if (pVal != nullptr) {
10532a6e48fSopenharmony_ci                    f64 = *pVal;
10632a6e48fSopenharmony_ci                }
10732a6e48fSopenharmony_ci                ipcRet = parcel.WriteDouble(f64);
10832a6e48fSopenharmony_ci                break;
10932a6e48fSopenharmony_ci            }
11032a6e48fSopenharmony_ci            case ExtraDataType::string: {
11132a6e48fSopenharmony_ci                std::string string = "-1";
11232a6e48fSopenharmony_ci                auto pVal = std::any_cast<std::string>(&data.val);
11332a6e48fSopenharmony_ci                if (pVal != nullptr) {
11432a6e48fSopenharmony_ci                    string = *pVal;
11532a6e48fSopenharmony_ci                }
11632a6e48fSopenharmony_ci                ipcRet = parcel.WriteString(string);
11732a6e48fSopenharmony_ci                break;
11832a6e48fSopenharmony_ci            }
11932a6e48fSopenharmony_ci            default:
12032a6e48fSopenharmony_ci                break;
12132a6e48fSopenharmony_ci        }
12232a6e48fSopenharmony_ci    }
12332a6e48fSopenharmony_ci    return ipcRet ? GSERROR_OK : GSERROR_BINDER;
12432a6e48fSopenharmony_ci}
12532a6e48fSopenharmony_ci
12632a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraGet(const std::string &key, int32_t &value) const
12732a6e48fSopenharmony_ci{
12832a6e48fSopenharmony_ci    return ExtraGet<int32_t>(key, ExtraDataType::i32, value);
12932a6e48fSopenharmony_ci}
13032a6e48fSopenharmony_ci
13132a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraGet(const std::string &key, int64_t &value) const
13232a6e48fSopenharmony_ci{
13332a6e48fSopenharmony_ci    return ExtraGet<int64_t>(key, ExtraDataType::i64, value);
13432a6e48fSopenharmony_ci}
13532a6e48fSopenharmony_ci
13632a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraGet(const std::string &key, double &value) const
13732a6e48fSopenharmony_ci{
13832a6e48fSopenharmony_ci    return ExtraGet<double>(key, ExtraDataType::f64, value);
13932a6e48fSopenharmony_ci}
14032a6e48fSopenharmony_ci
14132a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraGet(const std::string &key, std::string &value) const
14232a6e48fSopenharmony_ci{
14332a6e48fSopenharmony_ci    return ExtraGet<std::string>(key, ExtraDataType::string, value);
14432a6e48fSopenharmony_ci}
14532a6e48fSopenharmony_ci
14632a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraSet(const std::string &key, int32_t value)
14732a6e48fSopenharmony_ci{
14832a6e48fSopenharmony_ci    return ExtraSet(key, ExtraDataType::i32, value);
14932a6e48fSopenharmony_ci}
15032a6e48fSopenharmony_ci
15132a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraSet(const std::string &key, int64_t value)
15232a6e48fSopenharmony_ci{
15332a6e48fSopenharmony_ci    return ExtraSet(key, ExtraDataType::i64, value);
15432a6e48fSopenharmony_ci}
15532a6e48fSopenharmony_ci
15632a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraSet(const std::string &key, double value)
15732a6e48fSopenharmony_ci{
15832a6e48fSopenharmony_ci    return ExtraSet(key, ExtraDataType::f64, value);
15932a6e48fSopenharmony_ci}
16032a6e48fSopenharmony_ci
16132a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraSet(const std::string &key, const std::string& value)
16232a6e48fSopenharmony_ci{
16332a6e48fSopenharmony_ci    return ExtraSet(key, ExtraDataType::string, value);
16432a6e48fSopenharmony_ci}
16532a6e48fSopenharmony_ci
16632a6e48fSopenharmony_citemplate<class T>
16732a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraGet(const std::string &key, ExtraDataType type, T &value) const
16832a6e48fSopenharmony_ci{
16932a6e48fSopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mtx_);
17032a6e48fSopenharmony_ci    auto it = datas_.find(key);
17132a6e48fSopenharmony_ci    if (it == datas_.end()) {
17232a6e48fSopenharmony_ci        return GSERROR_NO_ENTRY;
17332a6e48fSopenharmony_ci    }
17432a6e48fSopenharmony_ci    if (it->second.type != type) {
17532a6e48fSopenharmony_ci        return GSERROR_TYPE_ERROR;
17632a6e48fSopenharmony_ci    }
17732a6e48fSopenharmony_ci    auto pVal = std::any_cast<T>(&it->second.val);
17832a6e48fSopenharmony_ci    if (pVal == nullptr) {
17932a6e48fSopenharmony_ci        return GSERROR_TYPE_ERROR;
18032a6e48fSopenharmony_ci    }
18132a6e48fSopenharmony_ci    value = *pVal;
18232a6e48fSopenharmony_ci    return GSERROR_OK;
18332a6e48fSopenharmony_ci}
18432a6e48fSopenharmony_ci
18532a6e48fSopenharmony_ciGSError BufferExtraDataImpl::ExtraSet(const std::string &key, ExtraDataType type, const std::any& val)
18632a6e48fSopenharmony_ci{
18732a6e48fSopenharmony_ci    std::lock_guard<std::mutex> lockGuard(mtx_);
18832a6e48fSopenharmony_ci    auto it = datas_.find(key);
18932a6e48fSopenharmony_ci    if (it == datas_.end() && datas_.size() > SURFACE_MAX_USER_DATA_COUNT) {
19032a6e48fSopenharmony_ci        BLOGW("SurfaceBuffer has too many extra data, cannot save one more!!!");
19132a6e48fSopenharmony_ci        return GSERROR_OUT_OF_RANGE;
19232a6e48fSopenharmony_ci    }
19332a6e48fSopenharmony_ci    datas_[key].type = type;
19432a6e48fSopenharmony_ci    datas_[key].val = val;
19532a6e48fSopenharmony_ci    return GSERROR_OK;
19632a6e48fSopenharmony_ci}
19732a6e48fSopenharmony_ci} // namespace OHOS
198