/* * Copyright (C) 2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "header.h" #include #include #include #include namespace Hdc { constexpr uint8_t MAGIC[HEADER_MAGIC_LEN] = {'u', 's', 't', 'a', 'r', 0x20}; constexpr uint8_t VERSION[HEADER_VERSION_LEN] = {0x20, 0x00}; std::string DecimalToOctalString(size_t decimalNumber, int length) { std::ostringstream oss; oss << std::oct << std::setw(length) << std::setfill('0') << decimalNumber; return oss.str(); } Header::Header() { (void)memset_s(this, sizeof(struct Header), 0, sizeof(struct Header)); (void)memcpy_s(magic, HEADER_MAGIC_LEN, MAGIC, HEADER_MAGIC_LEN); (void)memcpy_s(version, HEADER_VERSION_LEN, VERSION, HEADER_VERSION_LEN); } Header::Header(uint8_t data[512], int dataLen) { if (memcpy_s(this, sizeof(struct Header), data, dataLen) != EOK) { string tmp(reinterpret_cast(data), dataLen); WRITE_LOG(LOG_WARN, "memcpy_s failed for %s", tmp.c_str()); } } std::string Header::Name() { std::string fullName(reinterpret_cast(prefix)); fullName.append(reinterpret_cast(this->name)); return fullName; } bool Header::UpdataName(std::string fileName) { auto len = fileName.length(); if (len >= HEADER_MAX_FILE_LEN) { WRITE_LOG(LOG_WARN, "len too long %u", len); return false; } int rc = 0; char *p = nullptr; if (len < HEADER_NAME_LEN) { p = reinterpret_cast(this->name); rc = snprintf_s(p, HEADER_NAME_LEN, HEADER_NAME_LEN - 1, "%s", fileName.c_str()); if (rc < 0) { WRITE_LOG(LOG_WARN, "snprintf_s name failed rc:%d p_name:%s", rc, fileName.c_str()); } } else { auto sprefix = fileName.substr(0, len - (HEADER_NAME_LEN - 1)); auto sname = fileName.substr(len - (HEADER_NAME_LEN - 1)); p = reinterpret_cast(this->name); rc = snprintf_s(p, HEADER_NAME_LEN, HEADER_NAME_LEN - 1, "%s", sname.c_str()); if (rc < 0) { WRITE_LOG(LOG_WARN, "snprintf_s name failed rc:%d sname:%s", rc, sname.c_str()); } p = reinterpret_cast(this->prefix); rc = snprintf_s(p, HEADER_NAME_LEN, HEADER_NAME_LEN - 1, "%s", sprefix.c_str()); if (rc < 0) { WRITE_LOG(LOG_WARN, "snprintf_s prefix failed rc:%d sprefix:%s", rc, sprefix.c_str()); } } return true; } uint64_t Header::Size() { std::string octalStr(reinterpret_cast(this->size), (HEADER_SIZE_LEN - 1)); uint64_t num = 0; WRITE_LOG(LOG_DEBUG, "header size octalStr %s", octalStr.c_str()); if (!octalStr.empty()) { const int octal = 8; if (std::find_if(octalStr.begin(), octalStr.end(), [](unsigned char c) { return c < '0' || c > '7'; }) == octalStr.end()) { num = stoull(octalStr, nullptr, octal); } else { num = 0; WRITE_LOG(LOG_WARN, "header size %s is invaild", octalStr.c_str()); } } WRITE_LOG(LOG_DEBUG, "header size num %llu", num); return num; } void Header::UpdataSize(size_t fileLen) { auto sizeStr = DecimalToOctalString(fileLen, HEADER_SIZE_LEN - 1); WRITE_LOG(LOG_DEBUG, "UpdataSize sizeStr %s", sizeStr.c_str()); char *p = reinterpret_cast(this->size); int rc = snprintf_s(p, HEADER_SIZE_LEN, HEADER_SIZE_LEN - 1, "%s", sizeStr.c_str()); if (rc < 0) { WRITE_LOG(LOG_FATAL, "snprintf_s size failed rc:%d sizeStr:%s", rc, sizeStr.c_str()); } } TypeFlage Header::FileType() { if (this->typeflage[0] < TypeFlage::ORDINARYFILE || this->typeflage[0] > TypeFlage::RESERVE) { return TypeFlage::INVALID; } return TypeFlage(this->typeflage[0]); } void Header::UpdataFileType(TypeFlage fileType) { if (fileType < TypeFlage::ORDINARYFILE || fileType > TypeFlage::RESERVE) { this->typeflage[0] = TypeFlage::INVALID; return; } this->typeflage[0] = fileType; } bool Header::IsInvalid() { return FileType() == TypeFlage::INVALID; } void Header::UpdataCheckSum() { uint64_t sum = 0; uint8_t *tmp = reinterpret_cast(this); for (size_t i = 0; i < sizeof(struct Header); i++) { sum += tmp[i]; } constexpr uint64_t cnt = 256; sum += cnt; auto sizeStr = DecimalToOctalString(sum, HEADER_CHKSUM_LEN - 1); char *p = reinterpret_cast(this->chksum); int rc = snprintf_s(p, HEADER_CHKSUM_LEN, HEADER_CHKSUM_LEN - 1, "%s", sizeStr.c_str()); if (rc < 0) { WRITE_LOG(LOG_WARN, "snprintf_s chksum failed rc:%d sizeStr:%s", rc, sizeStr.c_str()); } } void Header::GetBytes(uint8_t data[512], int dataLen) { UpdataCheckSum(); errno_t ret = memcpy_s(data, dataLen, this, sizeof(struct Header)); if (ret != EOK) { WRITE_LOG(LOG_FATAL, "memcpy_s failed, errno:%d", ret); } } }