1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *  * Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in
12  *    the documentation and/or other materials provided with the
13  *    distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 #pragma once
29 
30 #include <regex>
31 #include <string>
32 #include <unordered_map>
33 #include <unordered_set>
34 #include <vector>
35 
36 namespace fastboot {
37 namespace extension {
38 
39 enum Expect { OKAY = 0, FAIL, DATA };
40 
41 static const std::unordered_map<std::string, Expect> CMD_EXPECTS = {
42         {"okay", OKAY},
43         {"fail", FAIL},
44         {"data", DATA},
45 };
46 
47 static const std::unordered_map<Expect, std::string> EXPECTS_STR = {
48         {OKAY, "okay"},
49         {FAIL, "fail"},
50         {DATA, "data"},
51 };
52 
53 struct Configuration {
54     struct GetVar {
55         std::string regex_str;
56         std::regex regex;
57         int line_num;
58 
59         // So gtest can print me
60         friend ::std::ostream& operator<<(::std::ostream& os, const GetVar& self) {
61             return os << "<regex='" << self.regex_str << "' line_num=" << self.line_num << ">";
62         }
63     };
64     struct PartitionInfo {
65         enum TestConfig { NO = 0, NO_WRITES, YES };
66         bool hashable;
67         bool slots;   // Does it have slots
68         bool parsed;  // Does the bootloader do parsing on the img?
69         TestConfig test;
70 
71         // So gtest can print me
72         friend ::std::ostream& operator<<(::std::ostream& os, const PartitionInfo& pinfo) {
73             return os << "<hashable=" << pinfo.hashable << " slots=" << pinfo.slots
74                       << " parsed=" << pinfo.parsed << ">";
75         }
76     };
77 
78     struct PackedInfoTest {
79         Expect expect;  // Does it have slots
80         std::string packed_img;
81         std::string unpacked_dir;
82 
83         // So gtest can print me
84         friend ::std::ostream& operator<<(::std::ostream& os, const PackedInfoTest& pinfo) {
85             return os << "<"
86                       << "expect=" << EXPECTS_STR.at(pinfo.expect)
87                       << " packed_img=" << pinfo.packed_img
88                       << " unpacked_dir=" << pinfo.unpacked_dir << ">";
89         }
90     };
91 
92     struct PackedInfo {
93         bool slots;  // Does it have slots
94         std::unordered_set<std::string> children;
95         std::vector<PackedInfoTest> tests;
96     };
97 
98     struct CommandTest {
99         std::string name;
100         int line_num;
101         std::string arg;
102         Expect expect;
103         std::string regex_str;
104         std::regex regex;
105         std::string input;
106         std::string output;
107         std::string validator;
108 
109         // So gtest can print me
110         friend ::std::ostream& operator<<(::std::ostream& os, const CommandTest& self) {
111             return os << "test: " << self.name << " (line: " << self.line_num << ")";
112         }
113     };
114 
115     struct OemCommand {
116         bool restricted;  // Does device need to be unlocked?
117         std::vector<CommandTest> tests;
118     };
119 
120     std::unordered_map<std::string, GetVar> getvars;
121     std::unordered_map<std::string, PartitionInfo> partitions;
122     std::unordered_map<std::string, PackedInfo> packed;
123     std::unordered_map<std::string, OemCommand> oem;
124 
125     std::string checksum;
126     std::string checksum_parser;
127 };
128 
129 bool ParseXml(const std::string& file, Configuration* config);
130 
131 }  // namespace extension
132 }  // namespace fastboot
133