1 // Copyright 2018 Google LLC
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 // https://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 ASTC_CODEC_BASE_STRING_UTILS_H_
16 #define ASTC_CODEC_BASE_STRING_UTILS_H_
17
18 #include <limits>
19 #include <string>
20
21 namespace astc_codec {
22 namespace base {
23
24 // Iterates over a string's parts using |splitBy| as a delimiter.
25 // |splitBy| must be a nonempty string well, or it's a no-op.
26 // Otherwise, |func| is called on each of the splits, excluding the
27 // characters that are part of |splitBy|. If two |splitBy|'s occur in a row,
28 // |func| will be called on a StringView("") in between. See
29 // StringUtils_unittest.cpp for the full story.
30 template<class Func>
Split(const std::string & str,const std::string & splitBy,Func func)31 void Split(const std::string& str, const std::string& splitBy, Func func) {
32 if (splitBy.empty()) {
33 return;
34 }
35
36 size_t splitSize = splitBy.size();
37 size_t begin = 0;
38 size_t end = str.find(splitBy);
39
40 while (true) {
41 func(str.substr(begin, end - begin));
42 if (end == std::string::npos) {
43 return;
44 }
45
46 begin = end + splitSize;
47 end = str.find(splitBy, begin);
48 }
49 }
50
ParseInt32(const char * str,int32_t deflt)51 static int32_t ParseInt32(const char* str, int32_t deflt) {
52 using std::numeric_limits;
53
54 char* error = nullptr;
55 int64_t value = strtol(str, &error, 0);
56 // Limit long values to int32 min/max. Needed for lp64; no-op on 32 bits.
57 if (value > std::numeric_limits<int32_t>::max()) {
58 value = std::numeric_limits<int32_t>::max();
59 } else if (value < std::numeric_limits<int32_t>::min()) {
60 value = std::numeric_limits<int32_t>::min();
61 }
62 return (error == str) ? deflt : static_cast<int32_t>(value);
63 }
64
65 } // namespace base
66 } // namespace astc_codec
67
68 #endif // ASTC_CODEC_BASE_STRING_UTILS_H_
69