1 /* 2 * Copyright (c) 2023 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 16 #ifndef ECMASCRIPT_BASE_FILE_HEADER_H 17 #define ECMASCRIPT_BASE_FILE_HEADER_H 18 19 #include "ecmascript/base/string_helper.h" 20 #include "ecmascript/log_wrapper.h" 21 #include <array> 22 #include <stddef.h> 23 #include <stdint.h> 24 25 namespace panda::ecmascript::base { 26 class FileHeader { 27 protected: 28 static constexpr size_t MAGIC_SIZE = 8; 29 static constexpr size_t VERSION_SIZE = 4; 30 static constexpr std::array<uint8_t, MAGIC_SIZE> MAGIC = {'P', 'A', 'N', 'D', 'A', '\0', '\0', '\0'}; 31 FileHeader(const std::array<uint8_t,VERSION_SIZE> & lastVersion)32 FileHeader(const std::array<uint8_t, VERSION_SIZE> &lastVersion) : magic_(MAGIC), version_(lastVersion) {} 33 VerifyInner(const char * fileDesc,const std::array<uint8_t,VERSION_SIZE> & lastVersion)34 bool VerifyInner(const char* fileDesc, const std::array<uint8_t, VERSION_SIZE> &lastVersion) const 35 { 36 if (magic_ != MAGIC) { 37 LOG_HOST_TOOL_ERROR << "Magic mismatch, please make sure " << fileDesc << 38 " and the source code are matched"; 39 LOG_ECMA(ERROR) << "magic error, expected magic is " << ConvToStr(MAGIC) 40 << ", but got " << ConvToStr(magic_); 41 return false; 42 } 43 if (version_ > lastVersion) { 44 LOG_HOST_TOOL_ERROR << fileDesc << " version error, expected version should be less or equal than " 45 << ConvToStr(lastVersion) << ", but got " << GetVersionInner(); 46 return false; 47 } 48 LOG_ECMA(DEBUG) << "Magic:" << ConvToStr(magic_) << ", version:" << GetVersionInner(); 49 return true; 50 } 51 GetVersionInner()52 std::string GetVersionInner() const 53 { 54 return ConvToStr(version_); 55 } 56 SetVersionInner(std::string version)57 bool SetVersionInner(std::string version) 58 { 59 std::vector<std::string> versionNumber = StringHelper::SplitString(version, "."); 60 if (versionNumber.size() != VERSION_SIZE) { 61 LOG_ECMA(ERROR) << "version: " << version << " format error"; 62 return false; 63 } 64 for (uint32_t i = 0; i < VERSION_SIZE; i++) { 65 uint32_t result; 66 if (!StringHelper::StrToUInt32(versionNumber[i].c_str(), &result)) { 67 LOG_ECMA(ERROR) << "version: " << version << " format error"; 68 return false; 69 } 70 version_[i] = static_cast<uint8_t>(result); 71 } 72 return true; 73 } 74 75 private: 76 template <size_t size> ConvToStr(std::array<uint8_t,size> array)77 std::string ConvToStr(std::array<uint8_t, size> array) const 78 { 79 std::string ret = ""; 80 for (size_t i = 0; i < size; ++i) { 81 if (i) { 82 ret += "."; 83 } 84 ret += std::to_string(array[i]); 85 } 86 return ret; 87 } 88 89 std::array<uint8_t, MAGIC_SIZE> magic_; 90 std::array<uint8_t, VERSION_SIZE> version_; 91 }; 92 93 } // namespace panda::ecmascript::base 94 #endif // ECMASCRIPT_BASE_FILE_HEADER_H 95