1 /**
2  * Copyright (c) 2021-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 
16 #include <iostream>
17 
18 #include "quick.h"
19 
20 #include "libpandabase/utils/logger.h"
21 #include "libpandabase/utils/pandargs.h"
22 #include "libpandafile/file_writer.h"
23 
PrintHelp(ark::PandArgParser &pa_parser)24 static void PrintHelp(ark::PandArgParser &pa_parser)
25 {
26     std::cerr << "Usage:" << std::endl;
27     std::cerr << "arkquicker [options] INPUT_FILE OUTPUT_FILE" << std::endl << std::endl;
28     std::cerr << "Supported options:" << std::endl << std::endl;
29     std::cerr << pa_parser.GetHelpString() << std::endl;
30 }
31 
ParseArgs(ark::PandArgParser &pa_parser, int argc, const char **argv)32 static bool ParseArgs(ark::PandArgParser &pa_parser, int argc, const char **argv)
33 {
34     if (!pa_parser.Parse(argc, argv)) {
35         PrintHelp(pa_parser);
36         return false;
37     }
38 
39     return true;
40 }
41 
ProcessArgs(ark::PandArgParser &pa_parser, const ark::PandArg<std::string> &input, const ark::PandArg<std::string> &output, const ark::PandArg<bool> &help)42 static bool ProcessArgs(ark::PandArgParser &pa_parser, const ark::PandArg<std::string> &input,
43                         const ark::PandArg<std::string> &output, const ark::PandArg<bool> &help)
44 {
45     if (input.GetValue().empty() || output.GetValue().empty() || help.GetValue()) {
46         PrintHelp(pa_parser);
47         return false;
48     }
49 
50     ark::Logger::InitializeStdLogging(
51         ark::Logger::Level::ERROR,
52         ark::Logger::ComponentMask().set(ark::Logger::Component::QUICKENER).set(ark::Logger::Component::PANDAFILE));
53 
54     return true;
55 }
56 
main(int argc, const char **argv)57 int main(int argc, const char **argv)
58 {
59     ark::PandArg<bool> help("help", false, "Print this message and exit");
60     ark::PandArg<std::string> input("INPUT", "", "Path to the input binary file");
61     ark::PandArg<std::string> output("OUTPUT", "", "Path to the output binary file");
62 
63     ark::PandArgParser pa_parser;
64 
65     pa_parser.Add(&help);
66     pa_parser.PushBackTail(&input);
67     pa_parser.PushBackTail(&output);
68     pa_parser.EnableTail();
69 
70     if (!ParseArgs(pa_parser, argc, argv)) {
71         return 1;
72     }
73 
74     if (!ProcessArgs(pa_parser, input, output, help)) {
75         return 1;
76     }
77 
78     auto input_file = ark::panda_file::File::Open(input.GetValue());
79     if (!input_file) {
80         LOG(ERROR, QUICKENER) << "Cannot open file '" << input.GetValue() << "'";
81         return 1;
82     }
83     ark::panda_file::FileReader reader(std::move(input_file));
84     if (!reader.ReadContainer()) {
85         LOG(ERROR, QUICKENER) << "Cannot read container";
86         return 1;
87     }
88 
89     ark::panda_file::ItemContainer *container = reader.GetContainerPtr();
90 
91     ark::quick::Quickener quickener(container, const_cast<ark::panda_file::File *>(reader.GetFilePtr()),
92                                     reader.GetItems());
93     quickener.QuickContainer();
94 
95     auto writer = ark::panda_file::FileWriter(output.GetValue());
96     if (!writer) {
97         PLOG(ERROR, QUICKENER) << "Cannot create file writer with path '" << output.GetValue() << "'";
98         return 1;
99     }
100 
101     if (!container->Write(&writer, false)) {
102         PLOG(ERROR, QUICKENER) << "Cannot write panda file '" << output.GetValue() << "'";
103         return 1;
104     }
105 
106     return 0;
107 }
108