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