Line data Source code
1 : //
2 : // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 : // Use of this source code is governed by a BSD-style license that can be
4 : // found in the LICENSE file.
5 : //
6 : // string_utils:
7 : // String helper functions.
8 : //
9 :
10 : #include "string_utils.h"
11 :
12 : #include <algorithm>
13 : #include <stdlib.h>
14 : #include <string.h>
15 : #include <fstream>
16 : #include <sstream>
17 :
18 : #include "common/platform.h"
19 :
20 : namespace angle
21 : {
22 :
23 : const char kWhitespaceASCII[] = " \f\n\r\t\v";
24 :
25 0 : std::vector<std::string> SplitString(const std::string &input,
26 : const std::string &delimiters,
27 : WhitespaceHandling whitespace,
28 : SplitResult resultType)
29 : {
30 0 : std::vector<std::string> result;
31 0 : if (input.empty())
32 : {
33 0 : return result;
34 : }
35 :
36 0 : std::string::size_type start = 0;
37 0 : while (start != std::string::npos)
38 : {
39 0 : auto end = input.find_first_of(delimiters, start);
40 :
41 0 : std::string piece;
42 0 : if (end == std::string::npos)
43 : {
44 0 : piece = input.substr(start);
45 0 : start = std::string::npos;
46 : }
47 : else
48 : {
49 0 : piece = input.substr(start, end - start);
50 0 : start = end + 1;
51 : }
52 :
53 0 : if (whitespace == TRIM_WHITESPACE)
54 : {
55 0 : piece = TrimString(piece, kWhitespaceASCII);
56 : }
57 :
58 0 : if (resultType == SPLIT_WANT_ALL || !piece.empty())
59 : {
60 0 : result.push_back(piece);
61 : }
62 : }
63 :
64 0 : return result;
65 : }
66 :
67 0 : void SplitStringAlongWhitespace(const std::string &input,
68 : std::vector<std::string> *tokensOut)
69 : {
70 :
71 0 : std::istringstream stream(input);
72 0 : std::string line;
73 :
74 0 : while (std::getline(stream, line))
75 : {
76 0 : size_t prev = 0, pos;
77 0 : while ((pos = line.find_first_of(kWhitespaceASCII, prev)) != std::string::npos)
78 : {
79 0 : if (pos > prev)
80 0 : tokensOut->push_back(line.substr(prev, pos - prev));
81 0 : prev = pos + 1;
82 : }
83 0 : if (prev < line.length())
84 0 : tokensOut->push_back(line.substr(prev, std::string::npos));
85 : }
86 0 : }
87 :
88 0 : std::string TrimString(const std::string &input, const std::string &trimChars)
89 : {
90 0 : auto begin = input.find_first_not_of(trimChars);
91 0 : if (begin == std::string::npos)
92 : {
93 0 : return "";
94 : }
95 :
96 0 : std::string::size_type end = input.find_last_not_of(trimChars);
97 0 : if (end == std::string::npos)
98 : {
99 0 : return input.substr(begin);
100 : }
101 :
102 0 : return input.substr(begin, end - begin + 1);
103 : }
104 :
105 0 : bool HexStringToUInt(const std::string &input, unsigned int *uintOut)
106 : {
107 0 : unsigned int offset = 0;
108 :
109 0 : if (input.size() >= 2 && input[0] == '0' && input[1] == 'x')
110 : {
111 0 : offset = 2u;
112 : }
113 :
114 : // Simple validity check
115 0 : if (input.find_first_not_of("0123456789ABCDEFabcdef", offset) != std::string::npos)
116 : {
117 0 : return false;
118 : }
119 :
120 0 : std::stringstream inStream(input);
121 0 : inStream >> std::hex >> *uintOut;
122 0 : return !inStream.fail();
123 : }
124 :
125 0 : bool ReadFileToString(const std::string &path, std::string *stringOut)
126 : {
127 0 : std::ifstream inFile(path.c_str());
128 0 : if (inFile.fail())
129 : {
130 0 : return false;
131 : }
132 :
133 0 : inFile.seekg(0, std::ios::end);
134 0 : stringOut->reserve(static_cast<std::string::size_type>(inFile.tellg()));
135 0 : inFile.seekg(0, std::ios::beg);
136 :
137 0 : stringOut->assign(std::istreambuf_iterator<char>(inFile), std::istreambuf_iterator<char>());
138 0 : return !inFile.fail();
139 : }
140 :
141 0 : Optional<std::vector<wchar_t>> WidenString(size_t length, const char *cString)
142 : {
143 0 : std::vector<wchar_t> wcstring(length + 1);
144 : #if !defined(ANGLE_PLATFORM_WINDOWS)
145 0 : size_t written = mbstowcs(wcstring.data(), cString, length + 1);
146 0 : if (written == 0)
147 : {
148 0 : return Optional<std::vector<wchar_t>>::Invalid();
149 : }
150 : #else
151 : size_t convertedChars = 0;
152 : errno_t err = mbstowcs_s(&convertedChars, wcstring.data(), length + 1, cString, _TRUNCATE);
153 : if (err != 0)
154 : {
155 : return Optional<std::vector<wchar_t>>::Invalid();
156 : }
157 : #endif
158 0 : return Optional<std::vector<wchar_t>>(wcstring);
159 : }
160 :
161 0 : bool BeginsWith(const std::string &str, const char *prefix)
162 : {
163 0 : return strncmp(str.c_str(), prefix, strlen(prefix)) == 0;
164 : }
165 :
166 0 : bool BeginsWith(const char *str, const char *prefix)
167 : {
168 0 : return strncmp(str, prefix, strlen(prefix)) == 0;
169 : }
170 :
171 0 : bool EndsWith(const std::string &str, const char *suffix)
172 : {
173 0 : const auto len = strlen(suffix);
174 0 : if (len > str.size())
175 0 : return false;
176 :
177 0 : const char *end = str.c_str() + str.size() - len;
178 :
179 0 : return memcmp(end, suffix, len) == 0;
180 : }
181 :
182 : } // namespace angle
|