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}