1 /*
2 * Copyright (c) 2019, The Linux Foundation. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *    * Redistributions of source code must retain the above copyright
8 *      notice, this list of conditions and the following disclaimer.
9 *    * Redistributions in binary form must reproduce the above
10 *      copyright notice, this list of conditions and the following
11 *      disclaimer in the documentation and/or other materials provided
12 *      with the distribution.
13 *    * Neither the name of The Linux Foundation nor the names of its
14 *      contributors may be used to endorse or promote products derived
15 *      from this software without specific prior written permission.
16 
17 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29 
30 #include <drm/drm_fourcc.h>
31 #include <drm_utils.h>
32 #include <regex>
33 #include <sstream>
34 #include <sstream>
35 #include <string>
36 #include <string>
37 #include <utility>
38 #include <vector>
39 
40 using std::string;
41 using std::stringstream;
42 using std::regex;
43 using std::pair;
44 using std::vector;
45 
46 namespace sde_drm {
47 
ParseFormats(const string & line,vector<pair<uint32_t,uint64_t>> * formats)48 void ParseFormats(const string &line, vector<pair<uint32_t, uint64_t>> *formats) {
49   // Match fourcc strings like RA24 or those with modifier like RA24/5/1. The
50   // digit after first / is vendor code, the digit after second / is modifier
51   // code.
52   regex exp_base("[[:alnum:]]{4}(/[[:digit:]]/([[:digit:]]){1,3})?");
53   regex exp_modifier("[[:alnum:]]{4}(/[[:digit:]]/([[:digit:]]){1,3})");
54   string tmp_line = line;
55   std::smatch str_match;  // Resultant match
56   while (std::regex_search(tmp_line, str_match, exp_base)) { //clang_sa_ignore[core.CallAndMessage]
57     string matched_sub_str = str_match.str();
58     string final_format_str = {};
59     uint64_t modifier = 0;
60 
61     if (std::regex_match(matched_sub_str, exp_modifier)) { //clang_sa_ignore[core.CallAndMessage]
62       // Here we try to parse formats with vendor code and modifier like
63       // RA24/5/1
64 
65       // Extract base format string
66       final_format_str = matched_sub_str.substr(0, matched_sub_str.find("/"));
67 
68       // Match vendor code
69       string vendor_sub_str = matched_sub_str.substr(matched_sub_str.find("/") + 1);
70       uint64_t vendor_code = std::stoi(vendor_sub_str);
71 
72       // Match modifier
73       uint64_t fmt_modifier = std::stoi(vendor_sub_str.substr(vendor_sub_str.find("/") + 1));
74       if (vendor_code == DRM_FORMAT_MOD_VENDOR_QCOM) {
75         // Macro from drm_fourcc.h to form modifier
76         modifier = fourcc_mod_code(QCOM, fmt_modifier);
77       }
78 
79     } else {
80       final_format_str = matched_sub_str.c_str();
81     }
82 
83     // fourcc_code is a macro from drm_fourcc.h to form the format from 4 characters (thus fourcc)
84     formats->push_back(std::make_pair(fourcc_code(final_format_str.at(0), final_format_str.at(1),
85                                                   final_format_str.at(2), final_format_str.at(3)),
86                                       modifier));
87     tmp_line = str_match.suffix();
88   }
89 }
90 
Tokenize(const std::string & str,std::vector<std::string> * tokens,char delim)91 void Tokenize(const std::string &str, std::vector<std::string> *tokens, char delim) {
92   size_t pos = 0;
93   std::string str_temp(str);
94 
95   while ((pos = str_temp.find(delim)) != std::string::npos && delim != ' ') {
96     str_temp.replace(pos, 1, 1, ' ');
97   }
98 
99   std::stringstream ss(str_temp);
100   while (ss >> str_temp) {
101     tokens->push_back(str_temp);
102   }
103 }
104 
105 }  // namespace sde_drm
106