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}