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 44bool IsVersionLessOrEqual(const std::array<uint8_t, File::VERSION_SIZE> &currrent_version, 45 const std::array<uint8_t, File::VERSION_SIZE> &target_version); 46 47inline void PrintBytecodeVersion() 48{ 49 std::stringstream ss; 50 51 ss << "Bytecode version " << GetVersion(version) << '\n'; 52 ss << "Minimum supported bytecode version " << GetVersion(minVersion) << '\n'; 53 54 std::cout << ss.str() << std::endl; 55} 56 57const std::map<uint8_t, std::array<uint8_t, File::VERSION_SIZE>> api_version_map { 58% current_version_raw = Panda::version.split('.') 59% current_api = current_version_raw[0] 60% current_version = current_version_raw.join(', ') 61 {0, {<%= current_version %>}}, 62% Panda::api_version_map.each do |api_version| 63 {<%= api_version[0] %>, {<%= api_version[1].split('.').join(', ') %>}}, 64% end 65 {<%= current_api %>, {<%= current_version %>}} 66}; 67 68inline void PrintSupportedApi() { 69 static constexpr size_t WIDTH = 20; // set output width 70 std::cout << "Supported apis and corresponding file versions:" << std::endl; 71 std::cout << std::setw(WIDTH) << "api" << std::setw(WIDTH) << "file version" << std::endl; 72 for (const auto &[legal_api, file_version] : api_version_map) { 73 if (legal_api == 0) { 74 continue; 75 } else { 76 std::cout << std::setw(WIDTH) << static_cast<uint32_t>(legal_api); 77 } 78 std::cout << std::setw(WIDTH) << GetVersion(file_version) << std::endl; 79 } 80} 81 82inline std::optional<const std::array<uint8_t, File::VERSION_SIZE>> GetVersionByApi(uint8_t api, std::string subApi) 83{ 84 if (api == API_12 && (subApi == SUB_API_VERSION_1 || subApi == SUB_API_VERSION_2)) { 85 return std::array<uint8_t, File::VERSION_SIZE> {12, 0, 2, 0}; 86 } 87 88 const auto iter = api_version_map.find(api); 89 if (iter == api_version_map.end()) { 90 // if there is no corresponding api version, the default branch is current version. 91 return version; 92 } 93 return iter->second; 94} 95 96} // namespace panda::panda_file 97 98#endif 99