Haio 0.2.X
Homebrew Asset IO/CDN
Loading...
Searching...
No Matches
string.cpp
Go to the documentation of this file.
1#include <haio_string.hpp>
2
3#include <charconv>
4#include <stdexcept>
5#include <vector>
6
7namespace {
8
9std::vector<std::string_view> split(std::string_view value, char sep) {
10 std::vector<std::string_view> parts;
11 while (true) {
12 const auto pos = value.find(sep);
13 parts.push_back(value.substr(0, pos));
14 if (pos == std::string_view::npos) break;
15 value.remove_prefix(pos + 1);
16 }
17 return parts;
18}
19
20bool parseInt(std::string_view value, int& out) {
21 if (value.empty()) return false;
22 if (value.front() == '+') value.remove_prefix(1);
23
24 const auto* begin = value.data();
25 const auto* end = value.data() + value.size();
26 const auto [ptr, ec] = std::from_chars(begin, end, out);
27 return ec == std::errc{} && ptr == end;
28}
29
30}
31
32namespace Haio::String {
33
34int getInt(std::string_view value) {
35 int out = 0;
36 if (!parseInt(value, out)) throw std::runtime_error("invalid integer: " + std::string(value));
37 return out;
38}
39
40bool tryGetSize(std::string_view value, Size& out) {
41 const auto sep = value.find_first_of("xX");
42 if (sep == std::string_view::npos) return false;
43
44 int width = 0;
45 int height = 0;
46 if (!parseInt(value.substr(0, sep), width) || !parseInt(value.substr(sep + 1), height)) return false;
47 if (width <= 0 || height <= 0) return false;
48 out = {width, height};
49 return true;
50}
51
52int getPercent(std::string_view value) {
53 auto number = value;
54 if (number.ends_with("%")) {
55 number.remove_suffix(1);
56 } else if (number.ends_with("pct") || number.ends_with("PCT")) {
57 number.remove_suffix(3);
58 } else {
59 return 0;
60 }
61
62 int share = 0;
63 if (!parseInt(number, share) || share <= 0) return 0;
64 return share;
65}
66
67Size getSize(std::string_view value) {
68 Size out;
69 if (!tryGetSize(value, out)) throw std::runtime_error("invalid size: " + std::string(value));
70 return out;
71}
72
73bool tryGetRect(std::string_view value, Rect& out) {
74 const auto parts = split(value, ',');
75 if (parts.size() != 4) return false;
76
77 Rect rect;
78 if (!parseInt(parts[0], rect.x)) return false;
79 if (!parseInt(parts[1], rect.y)) return false;
80 if (!parseInt(parts[2], rect.width)) return false;
81 if (!parseInt(parts[3], rect.height)) return false;
82 if (rect.width <= 0 || rect.height <= 0) return false;
83
84 out = rect;
85 return true;
86}
87
88Rect getRect(std::string_view value) {
89 Rect out;
90 if (!tryGetRect(value, out)) throw std::runtime_error("invalid rect: " + std::string(value));
91 return out;
92}
93
94bool tryGetCropGeometry(std::string_view value, Rect& out) {
95 const auto sep = value.find_first_of("xX");
96 if (sep == std::string_view::npos) return false;
97
98 int width = 0;
99 int height = 0;
100 if (!parseInt(value.substr(0, sep), width)) return false;
101 if (width <= 0) return false;
102
103 auto rest = value.substr(sep + 1);
104 const auto offset = rest.find_first_of("+-");
105 if (!parseInt(rest.substr(0, offset), height)) return false;
106 if (height <= 0) return false;
107
108 Rect rect{.width = width, .height = height};
109 if (offset == std::string_view::npos) {
110 out = rect;
111 return true;
112 }
113
114 rest.remove_prefix(offset);
115 const auto second = rest.substr(1).find_first_of("+-");
116 if (second == std::string_view::npos) return false;
117
118 const auto x = rest.substr(0, second + 1);
119 const auto y = rest.substr(second + 1);
120 if (!parseInt(x, rect.x) || !parseInt(y, rect.y)) return false;
121
122 out = rect;
123 return true;
124}
125
126}
bool tryGetRect(std::string_view value, Rect &out)
Definition string.cpp:73
Size getSize(std::string_view value)
Definition string.cpp:67
bool tryGetSize(std::string_view value, Size &out)
Definition string.cpp:40
int getPercent(std::string_view value)
Definition string.cpp:52
int getInt(std::string_view value)
Definition string.cpp:34
Rect getRect(std::string_view value)
Definition string.cpp:88
bool tryGetCropGeometry(std::string_view value, Rect &out)
Definition string.cpp:94