/Users/deen/code/yugabyte-db/src/yb/util/string_util.cc
Line | Count | Source |
1 | | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
2 | | // This source code is licensed under the BSD-style license found in the |
3 | | // LICENSE file in the root directory of this source tree. An additional grant |
4 | | // of patent rights can be found in the PATENTS file in the same directory. |
5 | | // |
6 | | // The following only applies to changes made to this file as part of YugaByte development. |
7 | | // |
8 | | // Portions Copyright (c) YugaByte, Inc. |
9 | | // |
10 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
11 | | // in compliance with the License. You may obtain a copy of the License at |
12 | | // |
13 | | // http://www.apache.org/licenses/LICENSE-2.0 |
14 | | // |
15 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
16 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
17 | | // or implied. See the License for the specific language governing permissions and limitations |
18 | | // under the License. |
19 | | // |
20 | | #include "yb/util/string_util.h" |
21 | | |
22 | | #include <regex> |
23 | | |
24 | | #include <boost/algorithm/string/predicate.hpp> |
25 | | #include <boost/algorithm/string/classification.hpp> |
26 | | #include <boost/algorithm/string/split.hpp> |
27 | | |
28 | | #include <boost/preprocessor/cat.hpp> |
29 | | |
30 | | #include <glog/logging.h> |
31 | | |
32 | | using std::vector; |
33 | | using std::regex; |
34 | | using std::regex_match; |
35 | | using std::string; |
36 | | using std::stringstream; |
37 | | using boost::algorithm::iequals; |
38 | | |
39 | | namespace yb { |
40 | | |
41 | 311 | bool IsBigInteger(const Slice& s) { |
42 | 311 | static const regex int_regex("[+-]?[0-9]+"); |
43 | 311 | return regex_match(s.cdata(), int_regex); |
44 | 311 | } |
45 | | |
46 | 92 | bool IsDecimal(const Slice& s) { |
47 | | // Regexes are based (but do not match exactly) the definition of Decimal::FromString |
48 | 92 | static const string optional_exp_suffix = "([eE][+-]?[0-9]+)?"; |
49 | 92 | static const regex decimal_regex_1("[+-]?[0-9]*\\.[0-9]+" + optional_exp_suffix); |
50 | 92 | static const regex decimal_regex_2("[+-]?[0-9]+\\.?" + optional_exp_suffix); |
51 | 92 | return IsBigInteger(s) |
52 | 83 | || regex_match(s.cdata(), decimal_regex_1) |
53 | 53 | || regex_match(s.cdata(), decimal_regex_2); |
54 | 92 | } |
55 | | |
56 | 9 | bool IsBoolean(const Slice& s) { |
57 | 9 | return iequals(s.cdata(), "true") || iequals(s.cdata(), "false"); |
58 | 9 | } |
59 | | |
60 | 9.19k | vector<string> StringSplit(const string& arg, char delim) { |
61 | 9.19k | vector<string> splits; |
62 | 9.19k | stringstream ss(arg); |
63 | 9.19k | string item; |
64 | 11.7k | while (getline(ss, item, delim)) { |
65 | 2.50k | splits.push_back(std::move(item)); |
66 | 2.50k | } |
67 | 9.19k | return splits; |
68 | 9.19k | } |
69 | | |
70 | 6 | bool StringStartsWithOrEquals(const string& s, const char* start, size_t start_len) { |
71 | 6 | return s.rfind(start, 0) == 0; |
72 | 6 | } |
73 | | |
74 | 49 | bool StringEndsWith(const string& s, const char* end, size_t end_len, string* left) { |
75 | | // For our purpose, s should always have at least one character before the string we are looking |
76 | | // for. |
77 | 49 | if (s.length() <= end_len) { |
78 | 4 | return false; |
79 | 4 | } |
80 | 45 | if (s.find(end, s.length() - end_len) != string::npos) { |
81 | 24 | if (left != nullptr) { |
82 | 24 | *left = s.substr(0, s.length() - end_len); |
83 | 24 | } |
84 | 24 | return true; |
85 | 24 | } |
86 | 21 | return false; |
87 | 21 | } |
88 | | |
89 | 3 | void AppendWithSeparator(const string& to_append, string* dest, const char* separator) { |
90 | 3 | CHECK_NOTNULL(dest); |
91 | 3 | if (!dest->empty()) { |
92 | 2 | *dest += separator; |
93 | 2 | } |
94 | 3 | *dest += to_append; |
95 | 3 | } |
96 | | |
97 | 3 | void AppendWithSeparator(const char* to_append, string* dest, const char* separator) { |
98 | 3 | CHECK_NOTNULL(dest); |
99 | 3 | if (!dest->empty()) { |
100 | 2 | *dest += separator; |
101 | 2 | } |
102 | 3 | *dest += to_append; |
103 | 3 | } |
104 | | |
105 | | std::vector<std::string> SplitAndFlatten( |
106 | | const std::vector<std::string>& input, |
107 | 2 | const char* separators) { |
108 | 2 | std::vector<std::string> result_vec; |
109 | 5 | for (const auto& dir : input) { |
110 | 5 | std::vector<std::string> temp; |
111 | 5 | boost::split(temp, dir, boost::is_any_of(separators)); |
112 | 5 | result_vec.insert(result_vec.end(), temp.begin(), temp.end()); |
113 | 5 | } |
114 | 2 | return result_vec; |
115 | 2 | } |
116 | | |
117 | | } // namespace yb |