Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/Data/Text/Parsers.cpp
3187 views
1
#include <algorithm>
2
#include <cstdarg>
3
#include <climits>
4
#include <cstdio>
5
#include <string>
6
7
#include "Common/Data/Text/Parsers.h"
8
#include "Common/Data/Text/I18n.h"
9
#include "Common/StringUtils.h"
10
11
// Not strictly a parser...
12
void NiceSizeFormat(uint64_t size, char *out, size_t bufSize) {
13
int s = 0;
14
int frac = 0;
15
while (size >= 1024) {
16
s++;
17
frac = (int)size & 1023;
18
size /= 1024;
19
}
20
float f = (float)size + ((float)frac / 1024.0f);
21
if (s == 0)
22
snprintf(out, bufSize, "%d B", (int)size);
23
else {
24
static const char* const sizes[] = { "B","KB","MB","GB","TB","PB","EB" };
25
snprintf(out, bufSize, "%3.2f %s", f, sizes[s]);
26
}
27
}
28
29
std::string NiceSizeFormat(uint64_t size) {
30
char buffer[16];
31
NiceSizeFormat(size, buffer, sizeof(buffer));
32
return std::string(buffer);
33
}
34
35
std::string NiceTimeFormat(int seconds) {
36
auto di = GetI18NCategory(I18NCat::DIALOG);
37
if (seconds < 60) {
38
return StringFromFormat(di->T_cstr("%d seconds"), seconds);
39
} else if (seconds < 60 * 60) {
40
int minutes = seconds / 60;
41
return StringFromFormat(di->T_cstr("%d minutes"), minutes);
42
} else {
43
int hours = seconds / 3600;
44
return StringFromFormat(di->T_cstr("%d hours"), hours);
45
}
46
}
47
48
bool Version::ParseVersionString(std::string str) {
49
if (str.empty())
50
return false;
51
if (str[0] == 'v')
52
str = str.substr(1);
53
if (3 != sscanf(str.c_str(), "%i.%i.%i", &major, &minor, &sub)) {
54
sub = 0;
55
if (2 != sscanf(str.c_str(), "%i.%i", &major, &minor))
56
return false;
57
}
58
return true;
59
}
60
61
std::string Version::ToString() const {
62
char temp[128];
63
snprintf(temp, sizeof(temp), "%i.%i.%i", major, minor, sub);
64
return std::string(temp);
65
}
66
67
int Version::ToInteger() const {
68
// This allows for ~2000 major versions, ~100 minor versions, and ~10000 sub versions.
69
return major * 1000000 + minor * 10000 + sub;
70
}
71
72
bool ParseMacAddress(const std::string &str, uint8_t macAddr[6]) {
73
unsigned int mac[6];
74
if (6 != sscanf(str.c_str(), "%02x:%02x:%02x:%02x:%02x:%02x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5])) {
75
return false;
76
}
77
for (int i = 0; i < 6; i++) {
78
macAddr[i] = mac[i];
79
}
80
return true;
81
}
82
83
static bool TryParseUnsigned32(const std::string &str, uint32_t *const output) {
84
char *endptr = NULL;
85
86
// Holy crap this is ugly.
87
88
// Reset errno to a value other than ERANGE
89
errno = 0;
90
91
unsigned long value = strtoul(str.c_str(), &endptr, 0);
92
93
if (!endptr || *endptr)
94
return false;
95
96
if (errno == ERANGE)
97
return false;
98
99
if (ULONG_MAX > UINT_MAX) {
100
#ifdef _MSC_VER
101
#pragma warning (disable:4309)
102
#endif
103
// Note: The typecasts avoid GCC warnings when long is 32 bits wide.
104
if (value >= static_cast<unsigned long>(0x100000000ull)
105
&& value <= static_cast<unsigned long>(0xFFFFFFFF00000000ull))
106
return false;
107
}
108
109
*output = static_cast<uint32_t>(value);
110
return true;
111
}
112
113
bool TryParse(const std::string &str, uint32_t *const output) {
114
if (str[0] != '#') {
115
return TryParseUnsigned32(str, output);
116
} else {
117
// Parse it as "#RGBA" and convert to a ABGR interger
118
std::string s = ReplaceAll(str, "#", "0x");
119
if (TryParseUnsigned32(s, output)) {
120
int a = (*output >> 24) & 0xff;
121
int b = (*output >> 16) & 0xff;
122
int g = (*output >> 8) & 0xff;
123
int r = *output & 0xff;
124
*output = (r << 24) | (g << 16) | (b << 8) | a;
125
return true;
126
} else {
127
return false;
128
}
129
}
130
}
131
132
bool TryParse(const std::string &str, uint64_t *const output) {
133
char *endptr = NULL;
134
135
// Holy crap this is ugly.
136
137
// Reset errno to a value other than ERANGE
138
errno = 0;
139
140
uint64_t value = strtoull(str.c_str(), &endptr, 0);
141
142
if (!endptr || *endptr)
143
return false;
144
145
if (errno == ERANGE)
146
return false;
147
148
*output = value;
149
return true;
150
}
151
152
bool TryParse(const std::string &str, bool *const output) {
153
if ("1" == str || !strcasecmp("true", str.c_str()))
154
*output = true;
155
else if ("0" == str || !strcasecmp("false", str.c_str()))
156
*output = false;
157
else
158
return false;
159
160
return true;
161
}
162
163
StringWriter &StringWriter::F(const char *format, ...) {
164
const size_t remainder = bufSize_ - (p_ - start_);
165
if (remainder < 3) {
166
return *this;
167
}
168
va_list args;
169
va_start(args, format);
170
int wouldHaveBeenWritten = vsnprintf(p_, remainder, format, args);
171
p_ += std::min((int)remainder, wouldHaveBeenWritten);
172
va_end(args);
173
return *this;
174
}
175
176