1/** 2 * Copyright (c) 2021-2022 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 LIBPANDAFILE_FILE_FORMAT_VERSION_H 17#define LIBPANDAFILE_FILE_FORMAT_VERSION_H 18 19#include <array> 20#include <string> 21#include <sstream> 22#include <iomanip> 23#include <set> 24 25#include "file.h" 26#include "utils/const_value.h" 27 28namespace panda::panda_file { 29constexpr uint8_t API_12 = 12; 30const std::string SUB_API_VERSION_1 = "beta1"; 31const std::string SUB_API_VERSION_2 = "beta2"; 32const std::string DEFAULT_SUB_API_VERSION = SUB_API_VERSION_1; 33 34constexpr std::array<uint8_t, File::VERSION_SIZE> version {<%= Panda::version.split('.').join(', ') %>}; 35constexpr std::array<uint8_t, File::VERSION_SIZE> minVersion {<%= Panda::min_version.split('.').join(', ') %>}; 36const std::set<std::array<uint8_t, File::VERSION_SIZE>> incompatibleVersion { 37% Panda::incompatible_version.each do |api_version| 38 {<%= api_version.split('.').join(', ') %>}, 39% end 40}; 41 42std::string GetVersion(const std::array<uint8_t, File::VERSION_SIZE> &version); 43 44inline void PrintBytecodeVersion() 45{ 46 std::stringstream ss; 47 48 ss << "Bytecode version " << GetVersion(version) << '\n'; 49 ss << "Minimum supported bytecode version " << GetVersion(minVersion) << '\n'; 50 51 std::cout << ss.str() << std::endl; 52} 53 54const std::map<uint8_t, std::array<uint8_t, File::VERSION_SIZE>> api_version_map { 55% current_version_raw = Panda::version.split('.') 56% current_api = current_version_raw[0] 57% current_version = current_version_raw.join(', ') 58 {0, {<%= current_version %>}}, 59% Panda::api_version_map.each do |api_version| 60 {<%= api_version[0] %>, {<%= api_version[1].split('.').join(', ') %>}}, 61% end 62 {<%= current_api %>, {<%= current_version %>}} 63}; 64 65inline void PrintSupportedApi() { 66 static constexpr size_t WIDTH = 20; // set output width 67 std::cout << "Supported apis and corresponding file versions:" << std::endl; 68 std::cout << std::setw(WIDTH) << "api" << std::setw(WIDTH) << "file version" << std::endl; 69 for (const auto &[legal_api, file_version] : api_version_map) { 70 if (legal_api == 0) { 71 continue; 72 } else { 73 std::cout << std::setw(WIDTH) << static_cast<uint32_t>(legal_api); 74 } 75 std::cout << std::setw(WIDTH) << GetVersion(file_version) << std::endl; 76 } 77} 78 79inline std::optional<const std::array<uint8_t, File::VERSION_SIZE>> GetVersionByApi(uint8_t api, std::string subApi) 80{ 81 if (api == API_12 && (subApi == SUB_API_VERSION_1 || subApi == SUB_API_VERSION_2)) { 82 return std::array<uint8_t, File::VERSION_SIZE> {12, 0, 2, 0}; 83 } 84 85 const auto iter = api_version_map.find(api); 86 if (iter == api_version_map.end()) { 87 // if there is no corresponding api version, the default branch is current version. 88 return version; 89 } 90 return iter->second; 91} 92 93} // namespace panda::panda_file 94 95#endif 96