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_OBJECT_H
1714cf0368Sopenharmony_ci#define UDMF_TLV_OBJECT_H
1814cf0368Sopenharmony_ci#include <cstddef>
1914cf0368Sopenharmony_ci#include <type_traits>
2014cf0368Sopenharmony_ci#include "securec.h"
2114cf0368Sopenharmony_ci#include "unified_meta.h"
2214cf0368Sopenharmony_ci#include "endian_converter.h"
2314cf0368Sopenharmony_ci#include "tlv_tag.h"
2414cf0368Sopenharmony_ci
2514cf0368Sopenharmony_cinamespace OHOS {
2614cf0368Sopenharmony_cinamespace UDMF {
2714cf0368Sopenharmony_ci#pragma pack(1)
2814cf0368Sopenharmony_cistruct TLVHead {
2914cf0368Sopenharmony_ci    uint16_t tag;
3014cf0368Sopenharmony_ci    uint32_t len;
3114cf0368Sopenharmony_ci    std::uint8_t value[0];
3214cf0368Sopenharmony_ci};
3314cf0368Sopenharmony_ci#pragma pack()
3414cf0368Sopenharmony_ci
3514cf0368Sopenharmony_ciclass API_EXPORT TLVObject {
3614cf0368Sopenharmony_cipublic:
3714cf0368Sopenharmony_ci    TLVObject() = default;
3814cf0368Sopenharmony_ci    ~TLVObject() = default;
3914cf0368Sopenharmony_ci    explicit TLVObject(std::vector<std::uint8_t> &buffer);
4014cf0368Sopenharmony_ci    void SetFile(std::FILE *file);
4114cf0368Sopenharmony_ci    void UpdateSize();
4214cf0368Sopenharmony_ci    std::vector<std::uint8_t> GetBuffer();
4314cf0368Sopenharmony_ci    size_t GetTotal();
4414cf0368Sopenharmony_ci    size_t GetCursor();
4514cf0368Sopenharmony_ci    size_t OffsetHead();
4614cf0368Sopenharmony_ci    void ResetCursor();
4714cf0368Sopenharmony_ci
4814cf0368Sopenharmony_ci    size_t Count(const std::string &value);
4914cf0368Sopenharmony_ci    size_t Count(const std::vector<uint8_t> &value);
5014cf0368Sopenharmony_ci    size_t Count(const OHOS::AAFwk::Want &value);
5114cf0368Sopenharmony_ci    size_t Count(const std::monostate &value);
5214cf0368Sopenharmony_ci    size_t Count(const void *value);
5314cf0368Sopenharmony_ci
5414cf0368Sopenharmony_ci    bool Write(TAG tag, const std::string &value);
5514cf0368Sopenharmony_ci    bool Write(TAG tag, const std::vector<uint8_t> &value);
5614cf0368Sopenharmony_ci    bool Write(TAG tag, const OHOS::AAFwk::Want &value);
5714cf0368Sopenharmony_ci    bool Write(TAG tag, const std::monostate &value);
5814cf0368Sopenharmony_ci    bool Write(TAG tag, const void *value);
5914cf0368Sopenharmony_ci
6014cf0368Sopenharmony_ci    bool Read(std::string &value, const TLVHead &head);
6114cf0368Sopenharmony_ci    bool Read(std::vector<uint8_t> &value, const TLVHead &head);
6214cf0368Sopenharmony_ci    bool Read(OHOS::AAFwk::Want &value, const TLVHead &head);
6314cf0368Sopenharmony_ci    bool Read(std::monostate &value, const TLVHead &head);
6414cf0368Sopenharmony_ci    bool Read(void *value, const TLVHead &head);
6514cf0368Sopenharmony_ci
6614cf0368Sopenharmony_ci    template <typename T> size_t CountBasic(const T &value);
6714cf0368Sopenharmony_ci    template <typename T> bool WriteBasic(TAG type, const T &value);
6814cf0368Sopenharmony_ci    template <typename T> bool ReadBasic(T &value, const TLVHead &head);
6914cf0368Sopenharmony_ci
7014cf0368Sopenharmony_ci    size_t CountHead();
7114cf0368Sopenharmony_ci    bool WriteHead(uint16_t tag, uint32_t len);
7214cf0368Sopenharmony_ci    bool WriteBackHead(uint16_t tag, size_t tagCursor, uint32_t len);
7314cf0368Sopenharmony_ci    bool ReadHead(TLVHead &head);
7414cf0368Sopenharmony_ci
7514cf0368Sopenharmony_ci    bool Skip(TLVHead &head);
7614cf0368Sopenharmony_ci    bool HasExpectBuffer(const uint32_t expectLen) const;
7714cf0368Sopenharmony_ci    bool SaveBufferToFile();
7814cf0368Sopenharmony_ci    bool SaveBufferToFileFront(size_t tagCursor, uint32_t len);
7914cf0368Sopenharmony_ci    bool LoadBufferFormFile(size_t size);
8014cf0368Sopenharmony_ci
8114cf0368Sopenharmony_ci
8214cf0368Sopenharmony_ciprivate:
8314cf0368Sopenharmony_ci    void PrepareBufferForFile(size_t size);
8414cf0368Sopenharmony_ci    std::uint8_t *GetStartCursor();
8514cf0368Sopenharmony_ci
8614cf0368Sopenharmony_ci    std::size_t total_ = 0;
8714cf0368Sopenharmony_ci    std::size_t cursor_ = 0;
8814cf0368Sopenharmony_ci    std::vector<std::uint8_t> *buffer_;
8914cf0368Sopenharmony_ci    std::FILE *file_ = nullptr;
9014cf0368Sopenharmony_ci};
9114cf0368Sopenharmony_ci
9214cf0368Sopenharmony_citemplate <typename T> size_t TLVObject::CountBasic(const T &value)
9314cf0368Sopenharmony_ci{
9414cf0368Sopenharmony_ci    static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
9514cf0368Sopenharmony_ci    auto size = sizeof(value) + sizeof(TLVHead);
9614cf0368Sopenharmony_ci    total_ += size;
9714cf0368Sopenharmony_ci    return size;
9814cf0368Sopenharmony_ci}
9914cf0368Sopenharmony_ci
10014cf0368Sopenharmony_citemplate <typename T> bool TLVObject::WriteBasic(TAG type, const T &value)
10114cf0368Sopenharmony_ci{
10214cf0368Sopenharmony_ci    static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
10314cf0368Sopenharmony_ci    if (!HasExpectBuffer(sizeof(TLVHead) + sizeof(value))) {
10414cf0368Sopenharmony_ci        return false;
10514cf0368Sopenharmony_ci    }
10614cf0368Sopenharmony_ci    auto tlvHead = reinterpret_cast<TLVHead *>(GetStartCursor());
10714cf0368Sopenharmony_ci    tlvHead->tag = HostToNet(static_cast<uint16_t>(type));
10814cf0368Sopenharmony_ci    tlvHead->len = HostToNet((uint32_t)sizeof(value));
10914cf0368Sopenharmony_ci    auto valueBuff = HostToNet(value);
11014cf0368Sopenharmony_ci    if (memcpy_s(tlvHead->value, sizeof(value), &valueBuff, sizeof(value)) != EOK) {
11114cf0368Sopenharmony_ci        return false;
11214cf0368Sopenharmony_ci    }
11314cf0368Sopenharmony_ci    cursor_ += sizeof(TLVHead) + sizeof(value);
11414cf0368Sopenharmony_ci    return SaveBufferToFile();
11514cf0368Sopenharmony_ci}
11614cf0368Sopenharmony_ci
11714cf0368Sopenharmony_citemplate <typename T> bool TLVObject::ReadBasic(T &value, const TLVHead &head)
11814cf0368Sopenharmony_ci{
11914cf0368Sopenharmony_ci    static_assert(std::is_fundamental<T>::value, "T must be a fundamental type.");
12014cf0368Sopenharmony_ci    if (head.len == 0 || head.len != sizeof(T)) {
12114cf0368Sopenharmony_ci        return false;
12214cf0368Sopenharmony_ci    }
12314cf0368Sopenharmony_ci    if (!HasExpectBuffer(head.len)) {
12414cf0368Sopenharmony_ci        return false;
12514cf0368Sopenharmony_ci    }
12614cf0368Sopenharmony_ci    if (!LoadBufferFormFile(head.len)) {
12714cf0368Sopenharmony_ci        return false;
12814cf0368Sopenharmony_ci    }
12914cf0368Sopenharmony_ci    auto startCursor = GetStartCursor();
13014cf0368Sopenharmony_ci    auto ret = memcpy_s(&value, sizeof(T), startCursor, sizeof(T));
13114cf0368Sopenharmony_ci    if (ret != EOK) {
13214cf0368Sopenharmony_ci        return false;
13314cf0368Sopenharmony_ci    }
13414cf0368Sopenharmony_ci    value = NetToHost(value);
13514cf0368Sopenharmony_ci    cursor_ += sizeof(T);
13614cf0368Sopenharmony_ci    return true;
13714cf0368Sopenharmony_ci}
13814cf0368Sopenharmony_ci} // namespace UDMF
13914cf0368Sopenharmony_ci} // namespace OHOS
14014cf0368Sopenharmony_ci#endif // UDMF_TLV_OBJECT_H
141