1cc290419Sopenharmony_ci/*
2cc290419Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
3cc290419Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4cc290419Sopenharmony_ci * you may not use this file except in compliance with the License.
5cc290419Sopenharmony_ci * You may obtain a copy of the License at
6cc290419Sopenharmony_ci *
7cc290419Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8cc290419Sopenharmony_ci *
9cc290419Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10cc290419Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11cc290419Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12cc290419Sopenharmony_ci * See the License for the specific language governing permissions and
13cc290419Sopenharmony_ci * limitations under the License.
14cc290419Sopenharmony_ci */
15cc290419Sopenharmony_ci#include "header.h"
16cc290419Sopenharmony_ci#include <cstring>
17cc290419Sopenharmony_ci#include <sstream>
18cc290419Sopenharmony_ci#include <string>
19cc290419Sopenharmony_ci#include <iomanip>
20cc290419Sopenharmony_ci
21cc290419Sopenharmony_cinamespace Hdc {
22cc290419Sopenharmony_ciconstexpr uint8_t MAGIC[HEADER_MAGIC_LEN] = {'u', 's', 't', 'a', 'r', 0x20};
23cc290419Sopenharmony_ciconstexpr uint8_t VERSION[HEADER_VERSION_LEN] = {0x20, 0x00};
24cc290419Sopenharmony_ci
25cc290419Sopenharmony_cistd::string DecimalToOctalString(size_t decimalNumber, int length)
26cc290419Sopenharmony_ci{
27cc290419Sopenharmony_ci    std::ostringstream oss;
28cc290419Sopenharmony_ci    oss << std::oct << std::setw(length) << std::setfill('0') << decimalNumber;
29cc290419Sopenharmony_ci    return oss.str();
30cc290419Sopenharmony_ci}
31cc290419Sopenharmony_ci
32cc290419Sopenharmony_ciHeader::Header()
33cc290419Sopenharmony_ci{
34cc290419Sopenharmony_ci    (void)memset_s(this, sizeof(struct Header), 0, sizeof(struct Header));
35cc290419Sopenharmony_ci    (void)memcpy_s(magic, HEADER_MAGIC_LEN, MAGIC, HEADER_MAGIC_LEN);
36cc290419Sopenharmony_ci    (void)memcpy_s(version, HEADER_VERSION_LEN, VERSION, HEADER_VERSION_LEN);
37cc290419Sopenharmony_ci}
38cc290419Sopenharmony_ci
39cc290419Sopenharmony_ciHeader::Header(uint8_t data[512], int dataLen)
40cc290419Sopenharmony_ci{
41cc290419Sopenharmony_ci    if (memcpy_s(this, sizeof(struct Header), data, dataLen) != EOK) {
42cc290419Sopenharmony_ci        string tmp(reinterpret_cast<char*>(data), dataLen);
43cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "memcpy_s failed for %s", tmp.c_str());
44cc290419Sopenharmony_ci    }
45cc290419Sopenharmony_ci}
46cc290419Sopenharmony_ci
47cc290419Sopenharmony_cistd::string Header::Name()
48cc290419Sopenharmony_ci{
49cc290419Sopenharmony_ci    std::string fullName(reinterpret_cast<char*>(prefix));
50cc290419Sopenharmony_ci    fullName.append(reinterpret_cast<char*>(this->name));
51cc290419Sopenharmony_ci    return fullName;
52cc290419Sopenharmony_ci}
53cc290419Sopenharmony_ci
54cc290419Sopenharmony_cibool Header::UpdataName(std::string fileName)
55cc290419Sopenharmony_ci{
56cc290419Sopenharmony_ci    auto len = fileName.length();
57cc290419Sopenharmony_ci    if (len >= HEADER_MAX_FILE_LEN) {
58cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "len too long %u", len);
59cc290419Sopenharmony_ci        return false;
60cc290419Sopenharmony_ci    }
61cc290419Sopenharmony_ci    int rc = 0;
62cc290419Sopenharmony_ci    char *p = nullptr;
63cc290419Sopenharmony_ci    if (len < HEADER_NAME_LEN) {
64cc290419Sopenharmony_ci        p = reinterpret_cast<char*>(this->name);
65cc290419Sopenharmony_ci        rc = snprintf_s(p, HEADER_NAME_LEN, HEADER_NAME_LEN - 1, "%s", fileName.c_str());
66cc290419Sopenharmony_ci        if (rc < 0) {
67cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "snprintf_s name failed rc:%d p_name:%s", rc, fileName.c_str());
68cc290419Sopenharmony_ci        }
69cc290419Sopenharmony_ci    } else {
70cc290419Sopenharmony_ci        auto sprefix = fileName.substr(0, len - (HEADER_NAME_LEN - 1));
71cc290419Sopenharmony_ci        auto sname = fileName.substr(len - (HEADER_NAME_LEN - 1));
72cc290419Sopenharmony_ci        p = reinterpret_cast<char*>(this->name);
73cc290419Sopenharmony_ci        rc = snprintf_s(p, HEADER_NAME_LEN, HEADER_NAME_LEN - 1, "%s", sname.c_str());
74cc290419Sopenharmony_ci        if (rc < 0) {
75cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "snprintf_s name failed rc:%d sname:%s", rc, sname.c_str());
76cc290419Sopenharmony_ci        }
77cc290419Sopenharmony_ci        p = reinterpret_cast<char*>(this->prefix);
78cc290419Sopenharmony_ci        rc = snprintf_s(p, HEADER_NAME_LEN, HEADER_NAME_LEN - 1, "%s", sprefix.c_str());
79cc290419Sopenharmony_ci        if (rc < 0) {
80cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "snprintf_s prefix failed rc:%d sprefix:%s", rc, sprefix.c_str());
81cc290419Sopenharmony_ci        }
82cc290419Sopenharmony_ci    }
83cc290419Sopenharmony_ci    return true;
84cc290419Sopenharmony_ci}
85cc290419Sopenharmony_ci
86cc290419Sopenharmony_ciuint64_t Header::Size()
87cc290419Sopenharmony_ci{
88cc290419Sopenharmony_ci    std::string octalStr(reinterpret_cast<char*>(this->size), (HEADER_SIZE_LEN - 1));
89cc290419Sopenharmony_ci    uint64_t num = 0;
90cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "header size octalStr %s", octalStr.c_str());
91cc290419Sopenharmony_ci    if (!octalStr.empty()) {
92cc290419Sopenharmony_ci        const int octal = 8;
93cc290419Sopenharmony_ci        if (std::find_if(octalStr.begin(), octalStr.end(),
94cc290419Sopenharmony_ci            [](unsigned char c) { return c < '0' || c > '7'; }) == octalStr.end()) {
95cc290419Sopenharmony_ci            num = stoull(octalStr, nullptr, octal);
96cc290419Sopenharmony_ci        } else {
97cc290419Sopenharmony_ci            num = 0;
98cc290419Sopenharmony_ci            WRITE_LOG(LOG_WARN, "header size %s is invaild", octalStr.c_str());
99cc290419Sopenharmony_ci        }
100cc290419Sopenharmony_ci    }
101cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "header size num %llu", num);
102cc290419Sopenharmony_ci    return num;
103cc290419Sopenharmony_ci}
104cc290419Sopenharmony_ci
105cc290419Sopenharmony_civoid Header::UpdataSize(size_t fileLen)
106cc290419Sopenharmony_ci{
107cc290419Sopenharmony_ci    auto sizeStr = DecimalToOctalString(fileLen, HEADER_SIZE_LEN - 1);
108cc290419Sopenharmony_ci    WRITE_LOG(LOG_DEBUG, "UpdataSize sizeStr %s", sizeStr.c_str());
109cc290419Sopenharmony_ci    char *p = reinterpret_cast<char*>(this->size);
110cc290419Sopenharmony_ci    int rc = snprintf_s(p, HEADER_SIZE_LEN, HEADER_SIZE_LEN - 1, "%s", sizeStr.c_str());
111cc290419Sopenharmony_ci    if (rc < 0) {
112cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "snprintf_s size failed rc:%d sizeStr:%s", rc, sizeStr.c_str());
113cc290419Sopenharmony_ci    }
114cc290419Sopenharmony_ci}
115cc290419Sopenharmony_ci
116cc290419Sopenharmony_ciTypeFlage Header::FileType()
117cc290419Sopenharmony_ci{
118cc290419Sopenharmony_ci    if (this->typeflage[0] < TypeFlage::ORDINARYFILE || this->typeflage[0] > TypeFlage::RESERVE) {
119cc290419Sopenharmony_ci        return TypeFlage::INVALID;
120cc290419Sopenharmony_ci    }
121cc290419Sopenharmony_ci
122cc290419Sopenharmony_ci    return TypeFlage(this->typeflage[0]);
123cc290419Sopenharmony_ci}
124cc290419Sopenharmony_ci
125cc290419Sopenharmony_civoid Header::UpdataFileType(TypeFlage fileType)
126cc290419Sopenharmony_ci{
127cc290419Sopenharmony_ci    if (fileType < TypeFlage::ORDINARYFILE || fileType > TypeFlage::RESERVE) {
128cc290419Sopenharmony_ci        this->typeflage[0] = TypeFlage::INVALID;
129cc290419Sopenharmony_ci        return;
130cc290419Sopenharmony_ci    }
131cc290419Sopenharmony_ci    this->typeflage[0] = fileType;
132cc290419Sopenharmony_ci}
133cc290419Sopenharmony_ci
134cc290419Sopenharmony_cibool Header::IsInvalid()
135cc290419Sopenharmony_ci{
136cc290419Sopenharmony_ci    return FileType() == TypeFlage::INVALID;
137cc290419Sopenharmony_ci}
138cc290419Sopenharmony_ci
139cc290419Sopenharmony_civoid Header::UpdataCheckSum()
140cc290419Sopenharmony_ci{
141cc290419Sopenharmony_ci    uint64_t sum = 0;
142cc290419Sopenharmony_ci    uint8_t *tmp = reinterpret_cast<uint8_t*>(this);
143cc290419Sopenharmony_ci    for (size_t i = 0; i < sizeof(struct Header); i++) {
144cc290419Sopenharmony_ci        sum += tmp[i];
145cc290419Sopenharmony_ci    }
146cc290419Sopenharmony_ci    constexpr uint64_t cnt = 256;
147cc290419Sopenharmony_ci    sum += cnt;
148cc290419Sopenharmony_ci
149cc290419Sopenharmony_ci    auto sizeStr = DecimalToOctalString(sum, HEADER_CHKSUM_LEN - 1);
150cc290419Sopenharmony_ci    char *p = reinterpret_cast<char*>(this->chksum);
151cc290419Sopenharmony_ci    int rc = snprintf_s(p, HEADER_CHKSUM_LEN, HEADER_CHKSUM_LEN - 1, "%s", sizeStr.c_str());
152cc290419Sopenharmony_ci    if (rc < 0) {
153cc290419Sopenharmony_ci        WRITE_LOG(LOG_WARN, "snprintf_s chksum failed rc:%d sizeStr:%s", rc, sizeStr.c_str());
154cc290419Sopenharmony_ci    }
155cc290419Sopenharmony_ci}
156cc290419Sopenharmony_ci
157cc290419Sopenharmony_civoid Header::GetBytes(uint8_t data[512], int dataLen)
158cc290419Sopenharmony_ci{
159cc290419Sopenharmony_ci    UpdataCheckSum();
160cc290419Sopenharmony_ci    errno_t ret = memcpy_s(data, dataLen, this, sizeof(struct Header));
161cc290419Sopenharmony_ci    if (ret != EOK) {
162cc290419Sopenharmony_ci        WRITE_LOG(LOG_FATAL, "memcpy_s failed, errno:%d", ret);
163cc290419Sopenharmony_ci    }
164cc290419Sopenharmony_ci}
165cc290419Sopenharmony_ci
166cc290419Sopenharmony_ci}