1 | // Copyright (c) 2017 Google Inc. |
2 | // |
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 | #ifndef SOURCE_UTIL_STRING_UTILS_H_ |
16 | #define SOURCE_UTIL_STRING_UTILS_H_ |
17 | |
18 | #include <assert.h> |
19 | #include <sstream> |
20 | #include <string> |
21 | #include <vector> |
22 | |
23 | #include "source/util/string_utils.h" |
24 | |
25 | namespace spvtools { |
26 | namespace utils { |
27 | |
28 | // Converts arithmetic value |val| to its default string representation. |
29 | template <class T> |
30 | std::string ToString(T val) { |
31 | static_assert( |
32 | std::is_arithmetic<T>::value, |
33 | "spvtools::utils::ToString is restricted to only arithmetic values" ); |
34 | std::stringstream os; |
35 | os << val; |
36 | return os.str(); |
37 | } |
38 | |
39 | // Converts cardinal number to ordinal number string. |
40 | std::string CardinalToOrdinal(size_t cardinal); |
41 | |
42 | // Splits the string |flag|, of the form '--pass_name[=pass_args]' into two |
43 | // strings "pass_name" and "pass_args". If |flag| has no arguments, the second |
44 | // string will be empty. |
45 | std::pair<std::string, std::string> SplitFlagArgs(const std::string& flag); |
46 | |
47 | // Encodes a string as a sequence of words, using the SPIR-V encoding. |
48 | inline std::vector<uint32_t> MakeVector(std::string input) { |
49 | std::vector<uint32_t> result; |
50 | uint32_t word = 0; |
51 | size_t num_bytes = input.size(); |
52 | // SPIR-V strings are null-terminated. The byte_index == num_bytes |
53 | // case is used to push the terminating null byte. |
54 | for (size_t byte_index = 0; byte_index <= num_bytes; byte_index++) { |
55 | const auto new_byte = |
56 | (byte_index < num_bytes ? uint8_t(input[byte_index]) : uint8_t(0)); |
57 | word |= (new_byte << (8 * (byte_index % sizeof(uint32_t)))); |
58 | if (3 == (byte_index % sizeof(uint32_t))) { |
59 | result.push_back(word); |
60 | word = 0; |
61 | } |
62 | } |
63 | // Emit a trailing partial word. |
64 | if ((num_bytes + 1) % sizeof(uint32_t)) { |
65 | result.push_back(word); |
66 | } |
67 | return result; |
68 | } |
69 | |
70 | // Decode a string from a sequence of words, using the SPIR-V encoding. |
71 | template <class VectorType> |
72 | inline std::string MakeString(const VectorType& words) { |
73 | std::string result; |
74 | |
75 | for (uint32_t word : words) { |
76 | for (int byte_index = 0; byte_index < 4; byte_index++) { |
77 | uint32_t = (word >> (8 * byte_index)) & 0xFF; |
78 | char c = static_cast<char>(extracted_word); |
79 | if (c == 0) { |
80 | return result; |
81 | } |
82 | result += c; |
83 | } |
84 | } |
85 | assert(false && "Did not find terminating null for the string." ); |
86 | return result; |
87 | } // namespace utils |
88 | |
89 | } // namespace utils |
90 | } // namespace spvtools |
91 | |
92 | #endif // SOURCE_UTIL_STRING_UTILS_H_ |
93 | |