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#define LOG_TAG "TlvObject"
1714cf0368Sopenharmony_ci#include "tlv_object.h"
1814cf0368Sopenharmony_ci#include "logger.h"
1914cf0368Sopenharmony_ci
2014cf0368Sopenharmony_cinamespace OHOS {
2114cf0368Sopenharmony_cinamespace UDMF {
2214cf0368Sopenharmony_ciTLVObject::TLVObject(std::vector<std::uint8_t> &buffer)
2314cf0368Sopenharmony_ci{
2414cf0368Sopenharmony_ci    total_ += buffer.size();
2514cf0368Sopenharmony_ci    buffer_ = &buffer;
2614cf0368Sopenharmony_ci    cursor_ = 0;
2714cf0368Sopenharmony_ci    file_ = nullptr;
2814cf0368Sopenharmony_ci}
2914cf0368Sopenharmony_ci
3014cf0368Sopenharmony_civoid TLVObject::SetFile(std::FILE *file)
3114cf0368Sopenharmony_ci{
3214cf0368Sopenharmony_ci    file_ = file;
3314cf0368Sopenharmony_ci    if (fseek(file_, 0, SEEK_END) != 0) {
3414cf0368Sopenharmony_ci        LOG_ERROR(UDMF_SERVICE, "fseek to end error!");
3514cf0368Sopenharmony_ci    }
3614cf0368Sopenharmony_ci
3714cf0368Sopenharmony_ci    auto total = ftell(file_);
3814cf0368Sopenharmony_ci    if (total < 0) {
3914cf0368Sopenharmony_ci        LOG_ERROR(UDMF_SERVICE, "Values are out of range, total:%{public}ld", total);
4014cf0368Sopenharmony_ci        return;
4114cf0368Sopenharmony_ci    }
4214cf0368Sopenharmony_ci    total_ = static_cast<size_t>(total);
4314cf0368Sopenharmony_ci    ResetCursor();
4414cf0368Sopenharmony_ci}
4514cf0368Sopenharmony_ci
4614cf0368Sopenharmony_civoid TLVObject::UpdateSize()
4714cf0368Sopenharmony_ci{
4814cf0368Sopenharmony_ci    if (file_ != nullptr) {
4914cf0368Sopenharmony_ci        return;
5014cf0368Sopenharmony_ci    }
5114cf0368Sopenharmony_ci    buffer_->resize(total_);
5214cf0368Sopenharmony_ci}
5314cf0368Sopenharmony_ci
5414cf0368Sopenharmony_cistd::vector<std::uint8_t> TLVObject::GetBuffer()
5514cf0368Sopenharmony_ci{
5614cf0368Sopenharmony_ci    return *buffer_;
5714cf0368Sopenharmony_ci}
5814cf0368Sopenharmony_ci
5914cf0368Sopenharmony_cisize_t TLVObject::GetTotal()
6014cf0368Sopenharmony_ci{
6114cf0368Sopenharmony_ci    return total_;
6214cf0368Sopenharmony_ci}
6314cf0368Sopenharmony_ci
6414cf0368Sopenharmony_cisize_t TLVObject::GetCursor()
6514cf0368Sopenharmony_ci{
6614cf0368Sopenharmony_ci    return cursor_;
6714cf0368Sopenharmony_ci}
6814cf0368Sopenharmony_ci
6914cf0368Sopenharmony_cisize_t TLVObject::OffsetHead()
7014cf0368Sopenharmony_ci{
7114cf0368Sopenharmony_ci    if (file_ != nullptr) {
7214cf0368Sopenharmony_ci        if (fseek(file_, sizeof(TLVHead), SEEK_CUR) != 0) {
7314cf0368Sopenharmony_ci            LOG_ERROR(UDMF_SERVICE, "OffsetHead file error!");
7414cf0368Sopenharmony_ci            return 0;
7514cf0368Sopenharmony_ci        }
7614cf0368Sopenharmony_ci    }
7714cf0368Sopenharmony_ci    cursor_ += sizeof(TLVHead);
7814cf0368Sopenharmony_ci    return cursor_;
7914cf0368Sopenharmony_ci}
8014cf0368Sopenharmony_ci
8114cf0368Sopenharmony_civoid TLVObject::ResetCursor()
8214cf0368Sopenharmony_ci{
8314cf0368Sopenharmony_ci    cursor_ = 0;
8414cf0368Sopenharmony_ci    if (file_ != nullptr) {
8514cf0368Sopenharmony_ci        if (fseek(file_, 0, SEEK_SET) != 0) {
8614cf0368Sopenharmony_ci            LOG_ERROR(UDMF_SERVICE, "ResetCursor file error!");
8714cf0368Sopenharmony_ci        }
8814cf0368Sopenharmony_ci    }
8914cf0368Sopenharmony_ci}
9014cf0368Sopenharmony_ci
9114cf0368Sopenharmony_cisize_t TLVObject::Count(const std::string &value)
9214cf0368Sopenharmony_ci{
9314cf0368Sopenharmony_ci    auto size = sizeof(TLVHead) + value.size();
9414cf0368Sopenharmony_ci    total_ += size;
9514cf0368Sopenharmony_ci    return size;
9614cf0368Sopenharmony_ci}
9714cf0368Sopenharmony_ci
9814cf0368Sopenharmony_cisize_t TLVObject::Count(const std::vector<uint8_t> &value)
9914cf0368Sopenharmony_ci{
10014cf0368Sopenharmony_ci    auto size = sizeof(TLVHead) + value.size();
10114cf0368Sopenharmony_ci    total_ += size;
10214cf0368Sopenharmony_ci    return size;
10314cf0368Sopenharmony_ci}
10414cf0368Sopenharmony_ci
10514cf0368Sopenharmony_cisize_t TLVObject::Count(const OHOS::AAFwk::Want &value)
10614cf0368Sopenharmony_ci{
10714cf0368Sopenharmony_ci    Parcel parcel;
10814cf0368Sopenharmony_ci    if (!value.Marshalling(parcel)) {
10914cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error when Count");
11014cf0368Sopenharmony_ci        return 0;
11114cf0368Sopenharmony_ci    }
11214cf0368Sopenharmony_ci    auto size = sizeof(TLVHead) + parcel.GetDataSize();
11314cf0368Sopenharmony_ci    total_ += size;
11414cf0368Sopenharmony_ci    return size;
11514cf0368Sopenharmony_ci}
11614cf0368Sopenharmony_ci
11714cf0368Sopenharmony_cisize_t TLVObject::Count(const std::monostate &value)
11814cf0368Sopenharmony_ci{
11914cf0368Sopenharmony_ci    auto size = sizeof(TLVHead);
12014cf0368Sopenharmony_ci    total_ += size;
12114cf0368Sopenharmony_ci    return size;
12214cf0368Sopenharmony_ci}
12314cf0368Sopenharmony_ci
12414cf0368Sopenharmony_cisize_t TLVObject::Count(const void *value)
12514cf0368Sopenharmony_ci{
12614cf0368Sopenharmony_ci    auto size = sizeof(TLVHead);
12714cf0368Sopenharmony_ci    total_ += size;
12814cf0368Sopenharmony_ci    return size;
12914cf0368Sopenharmony_ci}
13014cf0368Sopenharmony_ci
13114cf0368Sopenharmony_cibool TLVObject::Write(TAG tag, const std::string &value)
13214cf0368Sopenharmony_ci{
13314cf0368Sopenharmony_ci    if (!HasExpectBuffer(sizeof(TLVHead) + value.size())) {
13414cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv write. tag=%{public}hu, value=%{public}s", tag,
13514cf0368Sopenharmony_ci            value.c_str());
13614cf0368Sopenharmony_ci        return false;
13714cf0368Sopenharmony_ci    }
13814cf0368Sopenharmony_ci    auto tlvHead = reinterpret_cast<TLVHead *>(GetStartCursor());
13914cf0368Sopenharmony_ci    tlvHead->tag = HostToNet(static_cast<uint16_t>(tag));
14014cf0368Sopenharmony_ci    tlvHead->len = HostToNet((uint32_t)value.size());
14114cf0368Sopenharmony_ci    if (!value.empty()) {
14214cf0368Sopenharmony_ci        auto err = memcpy_s(tlvHead->value, value.size(), value.c_str(), value.size());
14314cf0368Sopenharmony_ci        if (err != EOK) {
14414cf0368Sopenharmony_ci            LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write. tag=%{public}hu, value=%{public}s", tag,
14514cf0368Sopenharmony_ci                value.c_str());
14614cf0368Sopenharmony_ci            return false;
14714cf0368Sopenharmony_ci        }
14814cf0368Sopenharmony_ci    }
14914cf0368Sopenharmony_ci    cursor_ += sizeof(TLVHead) + value.size();
15014cf0368Sopenharmony_ci    return SaveBufferToFile();
15114cf0368Sopenharmony_ci}
15214cf0368Sopenharmony_ci
15314cf0368Sopenharmony_cibool TLVObject::Read(std::string &value, const TLVHead &head)
15414cf0368Sopenharmony_ci{
15514cf0368Sopenharmony_ci    if (!HasExpectBuffer(head.len)) {
15614cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read string. tag=%{public}hu", head.tag);
15714cf0368Sopenharmony_ci        return false;
15814cf0368Sopenharmony_ci    }
15914cf0368Sopenharmony_ci    if (!LoadBufferFormFile(head.len)) {
16014cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "LoadBufferFormFile error in tlv read string. tag=%{public}hu", head.tag);
16114cf0368Sopenharmony_ci        return false;
16214cf0368Sopenharmony_ci    }
16314cf0368Sopenharmony_ci    auto startCursor = GetStartCursor();
16414cf0368Sopenharmony_ci    value.append(reinterpret_cast<const char *>(startCursor), head.len);
16514cf0368Sopenharmony_ci    cursor_ += head.len;
16614cf0368Sopenharmony_ci    return true;
16714cf0368Sopenharmony_ci}
16814cf0368Sopenharmony_ci
16914cf0368Sopenharmony_cibool TLVObject::Write(TAG tag, const std::vector<uint8_t> &value)
17014cf0368Sopenharmony_ci{
17114cf0368Sopenharmony_ci    if (!HasExpectBuffer(sizeof(TLVHead) + value.size())) {
17214cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv write u8 vector. tag=%{public}hu", tag);
17314cf0368Sopenharmony_ci        return false;
17414cf0368Sopenharmony_ci    }
17514cf0368Sopenharmony_ci    auto tlvHead = reinterpret_cast<TLVHead *>(GetStartCursor());
17614cf0368Sopenharmony_ci    tlvHead->tag = HostToNet(static_cast<uint16_t>(tag));
17714cf0368Sopenharmony_ci    tlvHead->len = HostToNet(static_cast<uint32_t>(value.size()));
17814cf0368Sopenharmony_ci    if (!value.empty()) {
17914cf0368Sopenharmony_ci        auto err = memcpy_s(tlvHead->value, value.size(), value.data(), value.size());
18014cf0368Sopenharmony_ci        if (err != EOK) {
18114cf0368Sopenharmony_ci            LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write u8 vector. tag=%{public}hu", tag);
18214cf0368Sopenharmony_ci            return false;
18314cf0368Sopenharmony_ci        }
18414cf0368Sopenharmony_ci    }
18514cf0368Sopenharmony_ci    cursor_ += sizeof(TLVHead) + value.size();
18614cf0368Sopenharmony_ci    return SaveBufferToFile();
18714cf0368Sopenharmony_ci}
18814cf0368Sopenharmony_ci
18914cf0368Sopenharmony_ci
19014cf0368Sopenharmony_cibool TLVObject::Read(std::vector<uint8_t> &value, const TLVHead &head)
19114cf0368Sopenharmony_ci{
19214cf0368Sopenharmony_ci    if (!HasExpectBuffer(head.len)) {
19314cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read u8 vector. tag=%{public}hu", head.tag);
19414cf0368Sopenharmony_ci        return false;
19514cf0368Sopenharmony_ci    }
19614cf0368Sopenharmony_ci    if (!LoadBufferFormFile(head.len)) {
19714cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "LoadBufferFormFile error in tlv read u8 vector. tag=%{public}hu", head.tag);
19814cf0368Sopenharmony_ci        return false;
19914cf0368Sopenharmony_ci    }
20014cf0368Sopenharmony_ci    auto startCursor = GetStartCursor();
20114cf0368Sopenharmony_ci    std::vector<uint8_t> buff(startCursor, startCursor + head.len);
20214cf0368Sopenharmony_ci    value = std::move(buff);
20314cf0368Sopenharmony_ci    cursor_ += head.len;
20414cf0368Sopenharmony_ci    return true;
20514cf0368Sopenharmony_ci}
20614cf0368Sopenharmony_ci
20714cf0368Sopenharmony_cibool TLVObject::Write(TAG tag, const OHOS::AAFwk::Want &value)
20814cf0368Sopenharmony_ci{
20914cf0368Sopenharmony_ci    Parcel parcel;
21014cf0368Sopenharmony_ci    if (!value.Marshalling(parcel)) {
21114cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Marshalling want error in tlv write. tag=%{public}hu", tag);
21214cf0368Sopenharmony_ci        return false;
21314cf0368Sopenharmony_ci    }
21414cf0368Sopenharmony_ci    auto size = parcel.GetDataSize();
21514cf0368Sopenharmony_ci    auto buffer = parcel.GetData();
21614cf0368Sopenharmony_ci
21714cf0368Sopenharmony_ci    if (!HasExpectBuffer(sizeof(TLVHead) + size)) {
21814cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv write want. tag=%{public}hu", tag);
21914cf0368Sopenharmony_ci        return false;
22014cf0368Sopenharmony_ci    }
22114cf0368Sopenharmony_ci    auto tlvHead = reinterpret_cast<TLVHead *>(GetStartCursor());
22214cf0368Sopenharmony_ci    tlvHead->tag = HostToNet(static_cast<uint16_t>(tag));
22314cf0368Sopenharmony_ci    tlvHead->len = HostToNet(static_cast<uint32_t>(size));
22414cf0368Sopenharmony_ci    if (size != 0) {
22514cf0368Sopenharmony_ci        auto err = memcpy_s(tlvHead->value, size, reinterpret_cast<const void *>(buffer), size);
22614cf0368Sopenharmony_ci        if (err != EOK) {
22714cf0368Sopenharmony_ci            LOG_ERROR(UDMF_FRAMEWORK, "memcpy error in tlv write want. tag=%{public}hu", tag);
22814cf0368Sopenharmony_ci            return false;
22914cf0368Sopenharmony_ci        }
23014cf0368Sopenharmony_ci    }
23114cf0368Sopenharmony_ci    cursor_ += sizeof(TLVHead) + size;
23214cf0368Sopenharmony_ci    return SaveBufferToFile();
23314cf0368Sopenharmony_ci}
23414cf0368Sopenharmony_ci
23514cf0368Sopenharmony_cibool TLVObject::Read(OHOS::AAFwk::Want &value, const TLVHead &head)
23614cf0368Sopenharmony_ci{
23714cf0368Sopenharmony_ci    if (!HasExpectBuffer(head.len)) {
23814cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read want. tag=%{public}hu", head.tag);
23914cf0368Sopenharmony_ci        return false;
24014cf0368Sopenharmony_ci    }
24114cf0368Sopenharmony_ci    if (!LoadBufferFormFile(head.len)) {
24214cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "LoadBufferFormFile error in tlv read want. tag=%{public}hu", head.tag);
24314cf0368Sopenharmony_ci        return false;
24414cf0368Sopenharmony_ci    }
24514cf0368Sopenharmony_ci    auto startCursor = GetStartCursor();
24614cf0368Sopenharmony_ci    std::vector<uint8_t> buff(startCursor, startCursor + head.len);
24714cf0368Sopenharmony_ci
24814cf0368Sopenharmony_ci    auto buffer = (uintptr_t)(buff.data() + cursor_);
24914cf0368Sopenharmony_ci    cursor_ += head.len;
25014cf0368Sopenharmony_ci
25114cf0368Sopenharmony_ci    Parcel parcel;
25214cf0368Sopenharmony_ci    if (!parcel.ParseFrom(buffer, head.len)) {
25314cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "ParseFrom error in tlv read want. tag=%{public}hu", head.tag);
25414cf0368Sopenharmony_ci        return false;
25514cf0368Sopenharmony_ci    }
25614cf0368Sopenharmony_ci    auto want = AAFwk::Want::Unmarshalling(parcel);
25714cf0368Sopenharmony_ci    if (want == nullptr) {
25814cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Unmarshalling want error in tlv read. tag=%{public}hu", head.tag);
25914cf0368Sopenharmony_ci        return false;
26014cf0368Sopenharmony_ci    }
26114cf0368Sopenharmony_ci    value = *want;
26214cf0368Sopenharmony_ci    return true;
26314cf0368Sopenharmony_ci}
26414cf0368Sopenharmony_ci
26514cf0368Sopenharmony_cibool TLVObject::Write(TAG tag, const std::monostate &value)
26614cf0368Sopenharmony_ci{
26714cf0368Sopenharmony_ci    return WriteHead(static_cast<uint16_t>(tag), (uint32_t)0);
26814cf0368Sopenharmony_ci}
26914cf0368Sopenharmony_ci
27014cf0368Sopenharmony_cibool TLVObject::Read(std::monostate &value, const TLVHead &head)
27114cf0368Sopenharmony_ci{
27214cf0368Sopenharmony_ci    return true;
27314cf0368Sopenharmony_ci}
27414cf0368Sopenharmony_ci
27514cf0368Sopenharmony_cibool TLVObject::Write(TAG tag, const void *value)
27614cf0368Sopenharmony_ci{
27714cf0368Sopenharmony_ci    return WriteHead(static_cast<uint16_t>(tag), (uint32_t)0);
27814cf0368Sopenharmony_ci}
27914cf0368Sopenharmony_ci
28014cf0368Sopenharmony_ci
28114cf0368Sopenharmony_cibool TLVObject::Read(void *value, const TLVHead &head)
28214cf0368Sopenharmony_ci{
28314cf0368Sopenharmony_ci    value = nullptr;
28414cf0368Sopenharmony_ci    return true;
28514cf0368Sopenharmony_ci}
28614cf0368Sopenharmony_ci
28714cf0368Sopenharmony_cisize_t TLVObject::CountHead()
28814cf0368Sopenharmony_ci{
28914cf0368Sopenharmony_ci    total_ += sizeof(TLVHead);
29014cf0368Sopenharmony_ci    return sizeof(TLVHead);
29114cf0368Sopenharmony_ci}
29214cf0368Sopenharmony_ci
29314cf0368Sopenharmony_cibool TLVObject::WriteHead(uint16_t tag, uint32_t len)
29414cf0368Sopenharmony_ci{
29514cf0368Sopenharmony_ci    if (!HasExpectBuffer(sizeof(TLVHead))) {
29614cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv write head. tag=%{public}hu", tag);
29714cf0368Sopenharmony_ci        return false;
29814cf0368Sopenharmony_ci    }
29914cf0368Sopenharmony_ci    PrepareBufferForFile(sizeof(TLVHead));
30014cf0368Sopenharmony_ci    auto tlvHead = reinterpret_cast<TLVHead *>(GetStartCursor());
30114cf0368Sopenharmony_ci    tlvHead->tag = HostToNet(tag);
30214cf0368Sopenharmony_ci    tlvHead->len = HostToNet(len);
30314cf0368Sopenharmony_ci    cursor_ += sizeof(TLVHead);
30414cf0368Sopenharmony_ci    return SaveBufferToFile();
30514cf0368Sopenharmony_ci}
30614cf0368Sopenharmony_ci
30714cf0368Sopenharmony_cibool TLVObject::WriteBackHead(uint16_t tag, size_t tagCursor, uint32_t len)
30814cf0368Sopenharmony_ci{
30914cf0368Sopenharmony_ci    auto startCursor = buffer_->data();
31014cf0368Sopenharmony_ci    if (file_ == nullptr) {
31114cf0368Sopenharmony_ci        startCursor += tagCursor;
31214cf0368Sopenharmony_ci    }
31314cf0368Sopenharmony_ci    auto tlvHead = reinterpret_cast<TLVHead *>(startCursor);
31414cf0368Sopenharmony_ci    tlvHead->tag = HostToNet(tag);
31514cf0368Sopenharmony_ci    tlvHead->len = HostToNet(len);
31614cf0368Sopenharmony_ci    return SaveBufferToFileFront(tagCursor, sizeof(TLVHead));
31714cf0368Sopenharmony_ci}
31814cf0368Sopenharmony_ci
31914cf0368Sopenharmony_cibool TLVObject::ReadHead(TLVHead &head)
32014cf0368Sopenharmony_ci{
32114cf0368Sopenharmony_ci    if (!HasExpectBuffer(sizeof(TLVHead))) {
32214cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read head. tag=%{public}hu", head.tag);
32314cf0368Sopenharmony_ci        return false;
32414cf0368Sopenharmony_ci    }
32514cf0368Sopenharmony_ci    if (!LoadBufferFormFile(sizeof(TLVHead))) {
32614cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "LoadBufferFormFile error in tlv read head. tag=%{public}hu", head.tag);
32714cf0368Sopenharmony_ci        return false;
32814cf0368Sopenharmony_ci    }
32914cf0368Sopenharmony_ci    auto startCursor = GetStartCursor();
33014cf0368Sopenharmony_ci    const auto *pHead = reinterpret_cast<const TLVHead *>(startCursor);
33114cf0368Sopenharmony_ci    auto len = NetToHost(pHead->len);
33214cf0368Sopenharmony_ci    if (file_ == nullptr) {
33314cf0368Sopenharmony_ci        if (!HasExpectBuffer(len + sizeof(TLVHead))) {
33414cf0368Sopenharmony_ci            LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv read head and len. tag=%{public}hu", head.tag);
33514cf0368Sopenharmony_ci            return false;
33614cf0368Sopenharmony_ci        }
33714cf0368Sopenharmony_ci    }
33814cf0368Sopenharmony_ci
33914cf0368Sopenharmony_ci    head.tag = NetToHost(pHead->tag);
34014cf0368Sopenharmony_ci    head.len = len;
34114cf0368Sopenharmony_ci    cursor_ += sizeof(TLVHead);
34214cf0368Sopenharmony_ci    return true;
34314cf0368Sopenharmony_ci}
34414cf0368Sopenharmony_ci
34514cf0368Sopenharmony_cibool TLVObject::Skip(TLVHead &head)
34614cf0368Sopenharmony_ci{
34714cf0368Sopenharmony_ci    if (file_ != nullptr) {
34814cf0368Sopenharmony_ci        cursor_ += head.len;
34914cf0368Sopenharmony_ci        return fseek(file_, head.len * sizeof(uint8_t), SEEK_CUR) == 0;
35014cf0368Sopenharmony_ci    }
35114cf0368Sopenharmony_ci    if (total_ < head.len || total_ - head.len < cursor_) {
35214cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "Has no enough buffer in tlv skip. tag=%{public}hu", head.tag);
35314cf0368Sopenharmony_ci        return false;
35414cf0368Sopenharmony_ci    }
35514cf0368Sopenharmony_ci    cursor_ += head.len;
35614cf0368Sopenharmony_ci    return true;
35714cf0368Sopenharmony_ci}
35814cf0368Sopenharmony_ci
35914cf0368Sopenharmony_cibool TLVObject::HasExpectBuffer(const uint32_t expectLen) const
36014cf0368Sopenharmony_ci{
36114cf0368Sopenharmony_ci    if (buffer_ == nullptr) {
36214cf0368Sopenharmony_ci        return false;
36314cf0368Sopenharmony_ci    }
36414cf0368Sopenharmony_ci    if (file_ != nullptr) {
36514cf0368Sopenharmony_ci        buffer_->resize(expectLen);
36614cf0368Sopenharmony_ci        return true;
36714cf0368Sopenharmony_ci    }
36814cf0368Sopenharmony_ci    return buffer_->size() >= cursor_ && buffer_->size() - cursor_ >= expectLen;
36914cf0368Sopenharmony_ci}
37014cf0368Sopenharmony_ci
37114cf0368Sopenharmony_civoid TLVObject::PrepareBufferForFile(size_t size)
37214cf0368Sopenharmony_ci{
37314cf0368Sopenharmony_ci    if (file_ == nullptr) {
37414cf0368Sopenharmony_ci        return;
37514cf0368Sopenharmony_ci    }
37614cf0368Sopenharmony_ci    buffer_->resize(size);
37714cf0368Sopenharmony_ci}
37814cf0368Sopenharmony_ci
37914cf0368Sopenharmony_cistd::uint8_t *TLVObject::GetStartCursor()
38014cf0368Sopenharmony_ci{
38114cf0368Sopenharmony_ci    auto startCursor = buffer_->data();
38214cf0368Sopenharmony_ci    if (file_ == nullptr) {
38314cf0368Sopenharmony_ci        startCursor += cursor_;
38414cf0368Sopenharmony_ci    }
38514cf0368Sopenharmony_ci    return startCursor;
38614cf0368Sopenharmony_ci}
38714cf0368Sopenharmony_ci
38814cf0368Sopenharmony_cibool TLVObject::SaveBufferToFile()
38914cf0368Sopenharmony_ci{
39014cf0368Sopenharmony_ci    if (file_ == nullptr) {
39114cf0368Sopenharmony_ci        return true;
39214cf0368Sopenharmony_ci    }
39314cf0368Sopenharmony_ci    auto count = fwrite(buffer_->data(), sizeof(uint8_t), buffer_->size(), file_);
39414cf0368Sopenharmony_ci    if (count != buffer_->size()) {
39514cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "fwrite error!");
39614cf0368Sopenharmony_ci        return false;
39714cf0368Sopenharmony_ci    }
39814cf0368Sopenharmony_ci    return true;
39914cf0368Sopenharmony_ci}
40014cf0368Sopenharmony_ci
40114cf0368Sopenharmony_cibool TLVObject::SaveBufferToFileFront(size_t tagCursor, uint32_t len)
40214cf0368Sopenharmony_ci{
40314cf0368Sopenharmony_ci    if (file_ == nullptr) {
40414cf0368Sopenharmony_ci        return true;
40514cf0368Sopenharmony_ci    }
40614cf0368Sopenharmony_ci    int32_t leftOffset =
40714cf0368Sopenharmony_ci        -((static_cast<int32_t>(cursor_) - static_cast<int32_t>(tagCursor))) * static_cast<int32_t>(sizeof(uint8_t));
40814cf0368Sopenharmony_ci    if (fseek(file_, leftOffset * sizeof(uint8_t), SEEK_CUR) != 0) {
40914cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "file fseek left error!");
41014cf0368Sopenharmony_ci        return false;
41114cf0368Sopenharmony_ci    }
41214cf0368Sopenharmony_ci    auto count = fwrite(buffer_->data(), sizeof(uint8_t), sizeof(TLVHead), file_);
41314cf0368Sopenharmony_ci    if (count != sizeof(TLVHead)) {
41414cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "file write error!");
41514cf0368Sopenharmony_ci        return false;
41614cf0368Sopenharmony_ci    }
41714cf0368Sopenharmony_ci    int32_t rightOffset =
41814cf0368Sopenharmony_ci        static_cast<int32_t>(cursor_) - static_cast<int32_t>(tagCursor) - static_cast<int32_t>(sizeof(TLVHead));
41914cf0368Sopenharmony_ci    if (fseek(file_, rightOffset * sizeof(uint8_t), SEEK_CUR) != 0) {
42014cf0368Sopenharmony_ci        LOG_ERROR(UDMF_FRAMEWORK, "file fseek right error!");
42114cf0368Sopenharmony_ci        return false;
42214cf0368Sopenharmony_ci    }
42314cf0368Sopenharmony_ci    return true;
42414cf0368Sopenharmony_ci}
42514cf0368Sopenharmony_ci
42614cf0368Sopenharmony_cibool TLVObject::LoadBufferFormFile(size_t size)
42714cf0368Sopenharmony_ci{
42814cf0368Sopenharmony_ci    if (file_ == nullptr) {
42914cf0368Sopenharmony_ci        return true;
43014cf0368Sopenharmony_ci    }
43114cf0368Sopenharmony_ci    auto count = fread(buffer_->data(), sizeof(uint8_t), buffer_->size(), file_);
43214cf0368Sopenharmony_ci    if (count != buffer_->size()) {
43314cf0368Sopenharmony_ci        return false;
43414cf0368Sopenharmony_ci    }
43514cf0368Sopenharmony_ci    return true;
43614cf0368Sopenharmony_ci}
43714cf0368Sopenharmony_ci} // namespace UDMF
43814cf0368Sopenharmony_ci} // namespace OHOS
439