/src/rnp/src/common/str-utils.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2017 [Ribose Inc](https://www.ribose.com). |
3 | | * All rights reserved. |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without modification, |
6 | | * are permitted provided that the following conditions are met: |
7 | | * |
8 | | * 1. Redistributions of source code must retain the above copyright notice, |
9 | | * this list of conditions and the following disclaimer. |
10 | | * |
11 | | * 2. Redistributions in binary form must reproduce the above copyright notice, |
12 | | * this list of conditions and the following disclaimer in the documentation |
13 | | * and/or other materials provided with the distribution. |
14 | | * |
15 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
16 | | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
17 | | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
18 | | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE |
19 | | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
20 | | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
21 | | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
22 | | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
23 | | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
24 | | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | | */ |
26 | | /** String utilities |
27 | | * @file |
28 | | */ |
29 | | |
30 | | #include <cstddef> |
31 | | #include <cstring> |
32 | | #include <cctype> |
33 | | #include <stdexcept> |
34 | | #include "str-utils.h" |
35 | | #ifdef _WIN32 |
36 | | #include <locale> |
37 | | #include <codecvt> |
38 | | #endif |
39 | | |
40 | | using std::size_t; |
41 | | using std::strlen; |
42 | | |
43 | | namespace rnp { |
44 | | char * |
45 | | strip_eol(char *s) |
46 | 0 | { |
47 | 0 | size_t len = strlen(s); |
48 | |
|
49 | 0 | while ((len > 0) && ((s[len - 1] == '\n') || (s[len - 1] == '\r'))) { |
50 | 0 | s[--len] = '\0'; |
51 | 0 | } |
52 | |
|
53 | 0 | return s; |
54 | 0 | } |
55 | | |
56 | | bool |
57 | | strip_eol(std::string &s) |
58 | 0 | { |
59 | 0 | size_t len = s.size(); |
60 | 0 | while (len && ((s[len - 1] == '\n') || (s[len - 1] == '\r'))) { |
61 | 0 | len--; |
62 | 0 | } |
63 | 0 | if (len == s.size()) { |
64 | 0 | return false; |
65 | 0 | } |
66 | 0 | s.resize(len); |
67 | 0 | return true; |
68 | 0 | } |
69 | | |
70 | | bool |
71 | | is_blank_line(const char *line, size_t len) |
72 | 274k | { |
73 | 291k | for (size_t i = 0; i < len && line[i]; i++) { |
74 | 291k | if (line[i] != ' ' && line[i] != '\t' && line[i] != '\r') { |
75 | 274k | return false; |
76 | 274k | } |
77 | 291k | } |
78 | 26 | return true; |
79 | 274k | } |
80 | | |
81 | | bool |
82 | | str_case_eq(const char *s1, const char *s2) |
83 | 302k | { |
84 | 592k | while (*s1 && *s2) { |
85 | 556k | if (std::tolower(*s1) != std::tolower(*s2)) { |
86 | 266k | return false; |
87 | 266k | } |
88 | 289k | s1++; |
89 | 289k | s2++; |
90 | 289k | } |
91 | 36.2k | return !*s1 && !*s2; |
92 | 302k | } |
93 | | |
94 | | bool |
95 | | str_case_eq(const std::string &s1, const std::string &s2) |
96 | 0 | { |
97 | 0 | if (s1.size() != s2.size()) { |
98 | 0 | return false; |
99 | 0 | } |
100 | 0 | return str_case_eq(s1.c_str(), s2.c_str()); |
101 | 0 | } |
102 | | |
103 | | static size_t |
104 | | hex_prefix_len(const std::string &str) |
105 | 540k | { |
106 | 540k | if ((str.length() >= 2) && (str[0] == '0') && ((str[1] == 'x') || (str[1] == 'X'))) { |
107 | 540k | return 2; |
108 | 540k | } |
109 | 0 | return 0; |
110 | 540k | } |
111 | | |
112 | | bool |
113 | | is_hex(const std::string &s) |
114 | 540k | { |
115 | 39.3M | for (size_t i = hex_prefix_len(s); i < s.length(); i++) { |
116 | 38.8M | auto &ch = s[i]; |
117 | 38.8M | if ((ch >= '0') && (ch <= '9')) { |
118 | 20.3M | continue; |
119 | 20.3M | } |
120 | 18.4M | if ((ch >= 'a') && (ch <= 'f')) { |
121 | 17.8M | continue; |
122 | 17.8M | } |
123 | 581k | if ((ch >= 'A') && (ch <= 'F')) { |
124 | 581k | continue; |
125 | 581k | } |
126 | 0 | if ((ch == ' ') || (ch == '\t')) { |
127 | 0 | continue; |
128 | 0 | } |
129 | 0 | return false; |
130 | 0 | } |
131 | 540k | return true; |
132 | 540k | } |
133 | | |
134 | | std::string |
135 | | strip_hex(const std::string &s) |
136 | 0 | { |
137 | 0 | std::string res = ""; |
138 | 0 | for (size_t idx = hex_prefix_len(s); idx < s.length(); idx++) { |
139 | 0 | auto ch = s[idx]; |
140 | 0 | if ((ch == ' ') || (ch == '\t')) { |
141 | 0 | continue; |
142 | 0 | } |
143 | 0 | res.push_back(ch); |
144 | 0 | } |
145 | 0 | return res; |
146 | 0 | } |
147 | | |
148 | | char * |
149 | | lowercase(char *s) |
150 | 0 | { |
151 | 0 | if (!s) { |
152 | 0 | return s; |
153 | 0 | } |
154 | 0 | for (char *ptr = s; *ptr; ++ptr) { |
155 | 0 | *ptr = tolower(*ptr); |
156 | 0 | } |
157 | 0 | return s; |
158 | 0 | } |
159 | | |
160 | | bool |
161 | | str_to_int(const std::string &s, int &val) |
162 | 0 | { |
163 | 0 | for (const char &ch : s) { |
164 | 0 | if ((ch < '0') || (ch > '9')) { |
165 | 0 | return false; |
166 | 0 | } |
167 | 0 | } |
168 | 0 | try { |
169 | 0 | val = std::stoi(s); |
170 | 0 | } catch (std::out_of_range const &ex) { |
171 | 0 | return false; |
172 | 0 | } |
173 | 0 | return true; |
174 | 0 | } |
175 | | |
176 | | bool |
177 | | is_slash(char c) |
178 | 0 | { |
179 | 0 | return (c == '/') || (c == '\\'); |
180 | 0 | } |
181 | | |
182 | | } // namespace rnp |
183 | | |
184 | | #ifdef _WIN32 |
185 | | std::wstring |
186 | | wstr_from_utf8(const char *s) |
187 | | { |
188 | | std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> utf8conv; |
189 | | return utf8conv.from_bytes(s); |
190 | | } |
191 | | |
192 | | std::wstring |
193 | | wstr_from_utf8(const char *first, const char *last) |
194 | | { |
195 | | std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> utf8conv; |
196 | | return utf8conv.from_bytes(first, last); |
197 | | } |
198 | | |
199 | | std::wstring |
200 | | wstr_from_utf8(const std::string &s) |
201 | | { |
202 | | return wstr_from_utf8(s.c_str()); |
203 | | } |
204 | | |
205 | | std::string |
206 | | wstr_to_utf8(const wchar_t *ws) |
207 | | { |
208 | | std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> utf8conv; |
209 | | return utf8conv.to_bytes(ws); |
210 | | } |
211 | | |
212 | | std::string |
213 | | wstr_to_utf8(const std::wstring &ws) |
214 | | { |
215 | | return wstr_to_utf8(ws.c_str()); |
216 | | } |
217 | | #endif |