114cf0368Sopenharmony_ci/*
214cf0368Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
314cf0368Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
414cf0368Sopenharmony_ci * you may not use this file except in compliance with the License.
514cf0368Sopenharmony_ci * You may obtain a copy of the License at
614cf0368Sopenharmony_ci *
714cf0368Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
814cf0368Sopenharmony_ci *
914cf0368Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1014cf0368Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1114cf0368Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1214cf0368Sopenharmony_ci * See the License for the specific language governing permissions and
1314cf0368Sopenharmony_ci * limitations under the License.
1414cf0368Sopenharmony_ci */
1514cf0368Sopenharmony_ci
1614cf0368Sopenharmony_ci#ifndef UDMF_TLV_UTIL_H
1714cf0368Sopenharmony_ci#define UDMF_TLV_UTIL_H
1814cf0368Sopenharmony_ci
1914cf0368Sopenharmony_ci
2014cf0368Sopenharmony_ci#include <utility>
2114cf0368Sopenharmony_ci#include <vector>
2214cf0368Sopenharmony_ci#include "unified_types.h"
2314cf0368Sopenharmony_ci#include "unified_data.h"
2414cf0368Sopenharmony_ci#include "unified_key.h"
2514cf0368Sopenharmony_ci#include "tlv_object.h"
2614cf0368Sopenharmony_ci#include "unified_record.h"
2714cf0368Sopenharmony_ci
2814cf0368Sopenharmony_ci
2914cf0368Sopenharmony_cinamespace OHOS {
3014cf0368Sopenharmony_cinamespace TLVUtil {
3114cf0368Sopenharmony_ciusing namespace OHOS::UDMF;
3214cf0368Sopenharmony_ci
3314cf0368Sopenharmony_citemplate <typename T> bool API_EXPORT ReadTlv(T &output, TLVObject &data, TAG tag);
3414cf0368Sopenharmony_ci
3514cf0368Sopenharmony_citemplate <typename T> size_t API_EXPORT CountBufferSize(const T &input, TLVObject &data);
3614cf0368Sopenharmony_citemplate <typename T> bool API_EXPORT Writing(const T &input, TLVObject &data, TAG tag);
3714cf0368Sopenharmony_citemplate <typename T> bool API_EXPORT Reading(T &output, TLVObject &data, const TLVHead &head);
3814cf0368Sopenharmony_ci
3914cf0368Sopenharmony_citemplate <typename... _Types> size_t API_EXPORT CountBufferSize(const std::variant<_Types...> &input, TLVObject &data);
4014cf0368Sopenharmony_citemplate <typename... _Types> bool API_EXPORT Writing(const std::variant<_Types...> &input, TLVObject &data, TAG tag);
4114cf0368Sopenharmony_citemplate <typename... _Types>
4214cf0368Sopenharmony_cibool API_EXPORT Reading(std::variant<_Types...> &output, TLVObject &data, const TLVHead &head);
4314cf0368Sopenharmony_ci
4414cf0368Sopenharmony_citemplate <typename T> size_t API_EXPORT CountBufferSize(const std::shared_ptr<T> &input, TLVObject &data);
4514cf0368Sopenharmony_citemplate <typename T> bool API_EXPORT Writing(const std::shared_ptr<T> &input, TLVObject &data, TAG tag);
4614cf0368Sopenharmony_citemplate <typename T> bool API_EXPORT Reading(std::shared_ptr<T> &output, TLVObject &data, const TLVHead &head);
4714cf0368Sopenharmony_ci
4814cf0368Sopenharmony_citemplate <typename T> size_t API_EXPORT CountBufferSize(const std::vector<T> &input, TLVObject &data);
4914cf0368Sopenharmony_citemplate <typename T> bool API_EXPORT Writing(const std::vector<T> &input, TLVObject &data, TAG tag);
5014cf0368Sopenharmony_citemplate <typename T> bool API_EXPORT Reading(std::vector<T> &output, TLVObject &data, const TLVHead &head);
5114cf0368Sopenharmony_ci
5214cf0368Sopenharmony_citemplate <typename T, typename R> size_t API_EXPORT CountBufferSize(const std::map<T, R> &input, TLVObject &data);
5314cf0368Sopenharmony_citemplate <typename T, typename R> bool API_EXPORT Writing(const std::map<T, R> &input, TLVObject &data, TAG tag);
5414cf0368Sopenharmony_citemplate <typename T, typename R> bool API_EXPORT Reading(std::map<T, R> &output, TLVObject &data, const TLVHead &head);
5514cf0368Sopenharmony_ci
5614cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const std::nullptr_t &input, TLVObject &data);
5714cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const std::nullptr_t &input, TLVObject &data, TAG tag);
5814cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(std::nullptr_t &output, TLVObject &data, const TLVHead &head);
5914cf0368Sopenharmony_ci
6014cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const std::monostate &input, TLVObject &data);
6114cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const std::monostate &input, TLVObject &data, TAG tag);
6214cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(std::monostate &output, TLVObject &data, const TLVHead &head);
6314cf0368Sopenharmony_ci
6414cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const std::string &input, TLVObject &data);
6514cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const std::string &input, TLVObject &data, TAG tag);
6614cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(std::string &output, TLVObject &data, const TLVHead &head);
6714cf0368Sopenharmony_ci
6814cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const std::vector<uint8_t> &input, TLVObject &data);
6914cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const std::vector<uint8_t> &input, TLVObject &data, TAG tag);
7014cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(std::vector<uint8_t> &output, TLVObject &data, const TLVHead &head);
7114cf0368Sopenharmony_ci
7214cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const UDType &input, TLVObject &data);
7314cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const UDType &input, TLVObject &data, TAG tag);
7414cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(UDType &output, TLVObject &data, const TLVHead &head);
7514cf0368Sopenharmony_ci
7614cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const DataStatus &input, TLVObject &data);
7714cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const DataStatus &input, TLVObject &data, TAG tag);
7814cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(DataStatus &output, TLVObject &data, const TLVHead &head);
7914cf0368Sopenharmony_ci
8014cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const Object &input, TLVObject &data);
8114cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const Object &input, TLVObject &data, TAG tag);
8214cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(Object &output, TLVObject &data, const TLVHead &head);
8314cf0368Sopenharmony_ci
8414cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const UnifiedKey &input, TLVObject &data);
8514cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const UnifiedKey &input, TLVObject &data, TAG tag);
8614cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(UnifiedKey &output, TLVObject &data, const TLVHead &head);
8714cf0368Sopenharmony_ci
8814cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const UnifiedData &input, TLVObject &data);
8914cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const UnifiedData &input, TLVObject &data, TAG tag);
9014cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(UnifiedData &output, TLVObject &data, const TLVHead &head);
9114cf0368Sopenharmony_ci
9214cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const UnifiedRecord &input, TLVObject &data);
9314cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const UnifiedRecord &input, TLVObject &data, TAG tag);
9414cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(UnifiedRecord &output, TLVObject &data, const TLVHead &head);
9514cf0368Sopenharmony_ci
9614cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const Runtime &input, TLVObject &data);
9714cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const Runtime &input, TLVObject &data, TAG tag);
9814cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(Runtime &output, TLVObject &data, const TLVHead &head);
9914cf0368Sopenharmony_ci
10014cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const Privilege &input, TLVObject &data);
10114cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const Privilege &input, TLVObject &data, TAG tag);
10214cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(Privilege &output, TLVObject &data, const TLVHead &head);
10314cf0368Sopenharmony_ci
10414cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data);
10514cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::Media::PixelMap> &input, TLVObject &data, TAG tag);
10614cf0368Sopenharmony_citemplate <>
10714cf0368Sopenharmony_cibool API_EXPORT Reading(std::shared_ptr<OHOS::Media::PixelMap> &output, TLVObject &data, const TLVHead &head);
10814cf0368Sopenharmony_ci
10914cf0368Sopenharmony_citemplate <> size_t API_EXPORT CountBufferSize(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data);
11014cf0368Sopenharmony_citemplate <> bool API_EXPORT Writing(const std::shared_ptr<OHOS::AAFwk::Want> &input, TLVObject &data, TAG tag);
11114cf0368Sopenharmony_citemplate <> bool API_EXPORT Reading(std::shared_ptr<OHOS::AAFwk::Want> &output, TLVObject &data, const TLVHead &head);
11214cf0368Sopenharmony_ci
11314cf0368Sopenharmony_citemplate <typename T> bool ReadTlv(T &output, TLVObject &data, TAG tag)
11414cf0368Sopenharmony_ci{
11514cf0368Sopenharmony_ci    while (data.GetCursor() < data.GetTotal()) {
11614cf0368Sopenharmony_ci        TLVHead head{};
11714cf0368Sopenharmony_ci        if (!data.ReadHead(head)) {
11814cf0368Sopenharmony_ci            return false;
11914cf0368Sopenharmony_ci        }
12014cf0368Sopenharmony_ci        if (head.tag != static_cast<uint16_t>(tag)) {
12114cf0368Sopenharmony_ci            data.Skip(head);
12214cf0368Sopenharmony_ci            continue;
12314cf0368Sopenharmony_ci        }
12414cf0368Sopenharmony_ci        if (!Reading(output, data, head)) {
12514cf0368Sopenharmony_ci            return false;
12614cf0368Sopenharmony_ci        }
12714cf0368Sopenharmony_ci    }
12814cf0368Sopenharmony_ci    return true;
12914cf0368Sopenharmony_ci}
13014cf0368Sopenharmony_ci
13114cf0368Sopenharmony_citemplate <typename T> void InitWhenFirst(T input, TLVObject &data)
13214cf0368Sopenharmony_ci{
13314cf0368Sopenharmony_ci    if (data.GetCursor() == data.GetTotal()) {
13414cf0368Sopenharmony_ci        CountBufferSize(input, data);
13514cf0368Sopenharmony_ci        data.UpdateSize();
13614cf0368Sopenharmony_ci    }
13714cf0368Sopenharmony_ci}
13814cf0368Sopenharmony_ci
13914cf0368Sopenharmony_citemplate <typename T> size_t CountBufferSize(const T &input, TLVObject &data)
14014cf0368Sopenharmony_ci{
14114cf0368Sopenharmony_ci    return data.CountBasic(input);
14214cf0368Sopenharmony_ci}
14314cf0368Sopenharmony_ci
14414cf0368Sopenharmony_citemplate <typename T> bool Writing(const T &input, TLVObject &data, TAG tag)
14514cf0368Sopenharmony_ci{
14614cf0368Sopenharmony_ci    InitWhenFirst(input, data);
14714cf0368Sopenharmony_ci    return data.WriteBasic(tag, input);
14814cf0368Sopenharmony_ci}
14914cf0368Sopenharmony_ci
15014cf0368Sopenharmony_citemplate <typename T> bool Reading(T &output, TLVObject &data, const TLVHead &head)
15114cf0368Sopenharmony_ci{
15214cf0368Sopenharmony_ci    return data.ReadBasic(output, head);
15314cf0368Sopenharmony_ci}
15414cf0368Sopenharmony_ci
15514cf0368Sopenharmony_citemplate <typename T> size_t CountBufferSize(const std::shared_ptr<T> &input, TLVObject &data)
15614cf0368Sopenharmony_ci{
15714cf0368Sopenharmony_ci    if (input == nullptr) {
15814cf0368Sopenharmony_ci        return data.CountHead();
15914cf0368Sopenharmony_ci    }
16014cf0368Sopenharmony_ci    return CountBufferSize(*input, data);
16114cf0368Sopenharmony_ci}
16214cf0368Sopenharmony_ci
16314cf0368Sopenharmony_citemplate <typename T> bool Writing(const std::shared_ptr<T> &input, TLVObject &data, TAG tag)
16414cf0368Sopenharmony_ci{
16514cf0368Sopenharmony_ci    if (input == nullptr) {
16614cf0368Sopenharmony_ci        return false;
16714cf0368Sopenharmony_ci    }
16814cf0368Sopenharmony_ci    InitWhenFirst(input, data);
16914cf0368Sopenharmony_ci    return Writing(*input, data, tag);
17014cf0368Sopenharmony_ci}
17114cf0368Sopenharmony_ci
17214cf0368Sopenharmony_citemplate <typename T> bool Reading(std::shared_ptr<T> &output, TLVObject &data, const TLVHead &head)
17314cf0368Sopenharmony_ci{
17414cf0368Sopenharmony_ci    if (output == nullptr) {
17514cf0368Sopenharmony_ci        output = std::make_shared<T>();
17614cf0368Sopenharmony_ci    }
17714cf0368Sopenharmony_ci    return Reading(*output, data, head);
17814cf0368Sopenharmony_ci}
17914cf0368Sopenharmony_ci
18014cf0368Sopenharmony_citemplate <typename T> size_t CountBufferSize(const std::vector<T> &input, TLVObject &data)
18114cf0368Sopenharmony_ci{
18214cf0368Sopenharmony_ci    auto size = data.CountHead() + data.CountBasic(input.size());
18314cf0368Sopenharmony_ci    for (auto item : input) {
18414cf0368Sopenharmony_ci        size += CountBufferSize(item, data);
18514cf0368Sopenharmony_ci    }
18614cf0368Sopenharmony_ci    return size;
18714cf0368Sopenharmony_ci}
18814cf0368Sopenharmony_ci
18914cf0368Sopenharmony_citemplate <typename T> bool Writing(const std::vector<T> &input, TLVObject &data, TAG tag)
19014cf0368Sopenharmony_ci{
19114cf0368Sopenharmony_ci    InitWhenFirst(input, data);
19214cf0368Sopenharmony_ci    auto tagCursor = data.GetCursor();
19314cf0368Sopenharmony_ci    data.OffsetHead();
19414cf0368Sopenharmony_ci    if (!data.WriteBasic(TAG::TAG_VECTOR_SIZE, input.size())) {
19514cf0368Sopenharmony_ci        return false;
19614cf0368Sopenharmony_ci    }
19714cf0368Sopenharmony_ci    if (!input.empty()) {
19814cf0368Sopenharmony_ci        for (auto item : input) {
19914cf0368Sopenharmony_ci            if (!Writing(item, data, TAG::TAG_VECTOR_ITEM)) {
20014cf0368Sopenharmony_ci                return false;
20114cf0368Sopenharmony_ci            }
20214cf0368Sopenharmony_ci        }
20314cf0368Sopenharmony_ci    }
20414cf0368Sopenharmony_ci    return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
20514cf0368Sopenharmony_ci}
20614cf0368Sopenharmony_ci
20714cf0368Sopenharmony_citemplate <typename T> bool Reading(std::vector<T> &output, TLVObject &data, const TLVHead &head)
20814cf0368Sopenharmony_ci{
20914cf0368Sopenharmony_ci    auto endCursor = data.GetCursor() + head.len;
21014cf0368Sopenharmony_ci    while (data.GetCursor() < endCursor) {
21114cf0368Sopenharmony_ci        TLVHead itemHead{};
21214cf0368Sopenharmony_ci        if (!data.ReadHead(itemHead)) {
21314cf0368Sopenharmony_ci            return false;
21414cf0368Sopenharmony_ci        }
21514cf0368Sopenharmony_ci        if (itemHead.tag == static_cast<uint16_t>(TAG::TAG_VECTOR_ITEM)) {
21614cf0368Sopenharmony_ci            T item{};
21714cf0368Sopenharmony_ci            if (!Reading(item, data, itemHead)) {
21814cf0368Sopenharmony_ci                return false;
21914cf0368Sopenharmony_ci            }
22014cf0368Sopenharmony_ci            output.push_back(std::move(item));
22114cf0368Sopenharmony_ci            continue;
22214cf0368Sopenharmony_ci        }
22314cf0368Sopenharmony_ci        if (!data.Skip(itemHead)) {
22414cf0368Sopenharmony_ci            return false;
22514cf0368Sopenharmony_ci        }
22614cf0368Sopenharmony_ci    }
22714cf0368Sopenharmony_ci    return true;
22814cf0368Sopenharmony_ci}
22914cf0368Sopenharmony_ci
23014cf0368Sopenharmony_citemplate <typename T, typename R> size_t CountBufferSize(const std::map<T, R> &input, TLVObject &data)
23114cf0368Sopenharmony_ci{
23214cf0368Sopenharmony_ci    auto size = data.CountHead();
23314cf0368Sopenharmony_ci    for (auto item : input) {
23414cf0368Sopenharmony_ci        size += data.CountHead() + CountBufferSize(item.first, data) + CountBufferSize(item.second, data);
23514cf0368Sopenharmony_ci    }
23614cf0368Sopenharmony_ci    return size;
23714cf0368Sopenharmony_ci}
23814cf0368Sopenharmony_ci
23914cf0368Sopenharmony_citemplate <typename T, typename R> bool Writing(const std::map<T, R> &input, TLVObject &data, TAG tag)
24014cf0368Sopenharmony_ci{
24114cf0368Sopenharmony_ci    InitWhenFirst(input, data);
24214cf0368Sopenharmony_ci    auto tagCursor = data.GetCursor();
24314cf0368Sopenharmony_ci    data.OffsetHead();
24414cf0368Sopenharmony_ci    if (!input.empty()) {
24514cf0368Sopenharmony_ci        for (auto item : input) {
24614cf0368Sopenharmony_ci            auto pairCursor = data.GetCursor();
24714cf0368Sopenharmony_ci            data.OffsetHead();
24814cf0368Sopenharmony_ci            if (!TLVUtil::Writing(item.first, data, TAG::TAG_MAP_KEY)) {
24914cf0368Sopenharmony_ci                return false;
25014cf0368Sopenharmony_ci            }
25114cf0368Sopenharmony_ci            if (!TLVUtil::Writing(item.second, data, TAG::TAG_MAP_VALUE)) {
25214cf0368Sopenharmony_ci                return false;
25314cf0368Sopenharmony_ci            }
25414cf0368Sopenharmony_ci            if (!data.WriteBackHead(static_cast<uint16_t>(TAG::TAG_MAP_PAIR), pairCursor,
25514cf0368Sopenharmony_ci                data.GetCursor() - pairCursor - sizeof(TLVHead))) {
25614cf0368Sopenharmony_ci                return false;
25714cf0368Sopenharmony_ci            }
25814cf0368Sopenharmony_ci        }
25914cf0368Sopenharmony_ci    }
26014cf0368Sopenharmony_ci    return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
26114cf0368Sopenharmony_ci}
26214cf0368Sopenharmony_ci
26314cf0368Sopenharmony_citemplate <typename T, typename R> bool Reading(std::map<T, R> &output, TLVObject &data, const TLVHead &head)
26414cf0368Sopenharmony_ci{
26514cf0368Sopenharmony_ci    auto endCursor = data.GetCursor() + head.len;
26614cf0368Sopenharmony_ci    while (data.GetCursor() < endCursor) {
26714cf0368Sopenharmony_ci        TLVHead headPair{};
26814cf0368Sopenharmony_ci        if (!data.ReadHead(headPair)) {
26914cf0368Sopenharmony_ci            return false;
27014cf0368Sopenharmony_ci        }
27114cf0368Sopenharmony_ci        if (headPair.tag != static_cast<uint16_t>(TAG::TAG_MAP_PAIR)) {
27214cf0368Sopenharmony_ci            return false;
27314cf0368Sopenharmony_ci        }
27414cf0368Sopenharmony_ci        TLVHead headKey{};
27514cf0368Sopenharmony_ci        if (!data.ReadHead(headKey) || headKey.tag != static_cast<uint16_t>(TAG::TAG_MAP_KEY)) {
27614cf0368Sopenharmony_ci            return false;
27714cf0368Sopenharmony_ci        }
27814cf0368Sopenharmony_ci        T itemKey{};
27914cf0368Sopenharmony_ci        if (!Reading(itemKey, data, headKey)) {
28014cf0368Sopenharmony_ci            return false;
28114cf0368Sopenharmony_ci        }
28214cf0368Sopenharmony_ci        TLVHead headValue{};
28314cf0368Sopenharmony_ci        if (!data.ReadHead(headValue) || headValue.tag != static_cast<uint16_t>(TAG::TAG_MAP_VALUE)) {
28414cf0368Sopenharmony_ci            return false;
28514cf0368Sopenharmony_ci        }
28614cf0368Sopenharmony_ci        R itemValue{};
28714cf0368Sopenharmony_ci        if (!Reading(itemValue, data, headValue)) {
28814cf0368Sopenharmony_ci            return false;
28914cf0368Sopenharmony_ci        }
29014cf0368Sopenharmony_ci        output.emplace(std::move(itemKey), std::move(itemValue));
29114cf0368Sopenharmony_ci    }
29214cf0368Sopenharmony_ci    return true;
29314cf0368Sopenharmony_ci}
29414cf0368Sopenharmony_ci
29514cf0368Sopenharmony_citemplate <typename _InTp> size_t CountVariant(TLVObject &data, uint32_t step, const _InTp &intput)
29614cf0368Sopenharmony_ci{
29714cf0368Sopenharmony_ci    return 0;
29814cf0368Sopenharmony_ci}
29914cf0368Sopenharmony_ci
30014cf0368Sopenharmony_citemplate <typename _InTp, typename _First, typename... _Rest>
30114cf0368Sopenharmony_cisize_t CountVariant(TLVObject &data, uint32_t step, const _InTp &input)
30214cf0368Sopenharmony_ci{
30314cf0368Sopenharmony_ci    if (step == input.index()) {
30414cf0368Sopenharmony_ci        return CountBufferSize(std::get<_First>(input), data);
30514cf0368Sopenharmony_ci    }
30614cf0368Sopenharmony_ci    return CountVariant<_InTp, _Rest...>(data, step + 1, input);
30714cf0368Sopenharmony_ci}
30814cf0368Sopenharmony_ci
30914cf0368Sopenharmony_citemplate <typename... _Types> size_t CountBufferSize(const std::variant<_Types...> &input, TLVObject &data)
31014cf0368Sopenharmony_ci{
31114cf0368Sopenharmony_ci    if (input.index() > size_t(std::numeric_limits<uint32_t>::max())) {
31214cf0368Sopenharmony_ci        return 0;
31314cf0368Sopenharmony_ci    }
31414cf0368Sopenharmony_ci    uint32_t index = static_cast<uint32_t>(input.index());
31514cf0368Sopenharmony_ci    return data.CountHead() + data.CountBasic(index) + CountVariant<decltype(input), _Types...>(data, 0, input);
31614cf0368Sopenharmony_ci}
31714cf0368Sopenharmony_ci
31814cf0368Sopenharmony_citemplate <typename _InTp> bool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag)
31914cf0368Sopenharmony_ci{
32014cf0368Sopenharmony_ci    return true;
32114cf0368Sopenharmony_ci}
32214cf0368Sopenharmony_ci
32314cf0368Sopenharmony_citemplate <typename _InTp, typename _First, typename... _Rest>
32414cf0368Sopenharmony_cibool WriteVariant(TLVObject &data, uint32_t step, const _InTp &input, TAG tag)
32514cf0368Sopenharmony_ci{
32614cf0368Sopenharmony_ci    if (step == input.index()) {
32714cf0368Sopenharmony_ci        auto val = std::get<_First>(input);
32814cf0368Sopenharmony_ci        return Writing(val, data, tag);
32914cf0368Sopenharmony_ci    }
33014cf0368Sopenharmony_ci    return WriteVariant<_InTp, _Rest...>(data, step + 1, input, tag);
33114cf0368Sopenharmony_ci}
33214cf0368Sopenharmony_ci
33314cf0368Sopenharmony_citemplate <typename... _Types> bool Writing(const std::variant<_Types...> &input, TLVObject &data, TAG tag)
33414cf0368Sopenharmony_ci{
33514cf0368Sopenharmony_ci    InitWhenFirst(input, data);
33614cf0368Sopenharmony_ci    auto tagCursor = data.GetCursor();
33714cf0368Sopenharmony_ci    data.OffsetHead();
33814cf0368Sopenharmony_ci    uint32_t index = input.index();
33914cf0368Sopenharmony_ci    if (!data.WriteBasic(TAG::TAG_VARIANT_INDEX, index)) {
34014cf0368Sopenharmony_ci        return false;
34114cf0368Sopenharmony_ci    }
34214cf0368Sopenharmony_ci    if (!WriteVariant<decltype(input), _Types...>(data, 0, input, TAG::TAG_VARIANT_ITEM)) {
34314cf0368Sopenharmony_ci        return false;
34414cf0368Sopenharmony_ci    }
34514cf0368Sopenharmony_ci    return data.WriteBackHead(static_cast<uint16_t>(tag), tagCursor, data.GetCursor() - tagCursor - sizeof(TLVHead));
34614cf0368Sopenharmony_ci}
34714cf0368Sopenharmony_ci
34814cf0368Sopenharmony_citemplate <typename _OutTp> bool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head)
34914cf0368Sopenharmony_ci{
35014cf0368Sopenharmony_ci    return true;
35114cf0368Sopenharmony_ci}
35214cf0368Sopenharmony_ci
35314cf0368Sopenharmony_citemplate <typename _OutTp, typename _First, typename... _Rest>
35414cf0368Sopenharmony_cibool ReadVariant(TLVObject &data, uint32_t step, uint32_t index, _OutTp &value, TLVHead head)
35514cf0368Sopenharmony_ci{
35614cf0368Sopenharmony_ci    if (step == index) {
35714cf0368Sopenharmony_ci        _First output{};
35814cf0368Sopenharmony_ci        auto success = Reading(output, data, head);
35914cf0368Sopenharmony_ci        value = output;
36014cf0368Sopenharmony_ci        return success;
36114cf0368Sopenharmony_ci    }
36214cf0368Sopenharmony_ci    return ReadVariant<_OutTp, _Rest...>(data, step + 1, index, value, head);
36314cf0368Sopenharmony_ci}
36414cf0368Sopenharmony_ci
36514cf0368Sopenharmony_citemplate <typename... _Types> bool Reading(std::variant<_Types...> &output, TLVObject &data, const TLVHead &head)
36614cf0368Sopenharmony_ci{
36714cf0368Sopenharmony_ci    uint32_t index = 0;
36814cf0368Sopenharmony_ci    auto endCursor = data.GetCursor() + head.len;
36914cf0368Sopenharmony_ci    while (data.GetCursor() < endCursor) {
37014cf0368Sopenharmony_ci        TLVHead headItem{};
37114cf0368Sopenharmony_ci        if (!data.ReadHead(headItem)) {
37214cf0368Sopenharmony_ci            return false;
37314cf0368Sopenharmony_ci        }
37414cf0368Sopenharmony_ci        if (headItem.tag == static_cast<uint16_t>(TAG::TAG_VARIANT_INDEX)) {
37514cf0368Sopenharmony_ci            if (!Reading(index, data, headItem)) {
37614cf0368Sopenharmony_ci                return false;
37714cf0368Sopenharmony_ci            }
37814cf0368Sopenharmony_ci        } else {
37914cf0368Sopenharmony_ci            return ReadVariant<decltype(output), _Types...>(data, 0, index, output, headItem);
38014cf0368Sopenharmony_ci        }
38114cf0368Sopenharmony_ci    }
38214cf0368Sopenharmony_ci    return true;
38314cf0368Sopenharmony_ci}
38414cf0368Sopenharmony_ci} // namespace TLVUtil
38514cf0368Sopenharmony_ci} // namespace OHOS
38614cf0368Sopenharmony_ci#endif // UDMF_TLV_UTIL_H
387