blob: 9b2c1780f86ea3c0d38ab2232cd9bf45b6861d20 [file] [log] [blame]
Ethan Nicholas0df1b042017-03-31 13:56:23 -04001/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "SkSLString.h"
9
10#include "SkSLUtil.h"
Ethan Nicholas0df1b042017-03-31 13:56:23 -040011#include <errno.h>
Ethan Nicholas0df1b042017-03-31 13:56:23 -040012#include <limits.h>
13#include <locale>
14#include <sstream>
15#include <string>
16
17namespace SkSL {
18
19String String::printf(const char* fmt, ...) {
20 va_list args;
21 va_start(args, fmt);
22 String result;
23 result.vappendf(fmt, args);
24 return result;
25}
26
27#ifdef SKSL_STANDALONE
28void String::appendf(const char* fmt, ...) {
29 va_list args;
30 va_start(args, fmt);
31 this->vappendf(fmt, args);
32}
33#endif
34
35void String::vappendf(const char* fmt, va_list args) {
36#ifdef SKSL_BUILD_FOR_WIN
37 #define VSNPRINTF _vsnprintf
38#else
39 #define VSNPRINTF vsnprintf
40#endif
41 #define BUFFER_SIZE 256
42 char buffer[BUFFER_SIZE];
43 size_t size = VSNPRINTF(buffer, BUFFER_SIZE, fmt, args);
44 if (BUFFER_SIZE >= size) {
45 this->append(buffer, size);
46 } else {
47 auto newBuffer = std::unique_ptr<char[]>(new char[size]);
48 VSNPRINTF(newBuffer.get(), size, fmt, args);
49 this->append(newBuffer.get(), size);
50 }
51 va_end(args);
52}
53
54
55bool String::startsWith(const char* s) const {
Ethan Nicholas985febf2017-05-19 14:03:45 -040056 return !strncmp(c_str(), s, strlen(s));
Ethan Nicholas0df1b042017-03-31 13:56:23 -040057}
58
59bool String::endsWith(const char* s) const {
60 size_t len = strlen(s);
61 if (size() < len) {
62 return false;
63 }
Ethan Nicholas985febf2017-05-19 14:03:45 -040064 return !strncmp(c_str() + size() - len, s, len);
Ethan Nicholas0df1b042017-03-31 13:56:23 -040065}
66
67String String::operator+(const char* s) const {
68 String result(*this);
69 result.append(s);
70 return result;
71}
72
73String String::operator+(const String& s) const {
74 String result(*this);
75 result.append(s);
76 return result;
77}
78
79bool String::operator==(const String& s) const {
80 return this->size() == s.size() && !memcmp(c_str(), s.c_str(), this->size());
81}
82
83bool String::operator!=(const String& s) const {
84 return !(*this == s);
85}
86
87bool String::operator==(const char* s) const {
88 return this->size() == strlen(s) && !memcmp(c_str(), s, this->size());
89}
90
91bool String::operator!=(const char* s) const {
92 return !(*this == s);
93}
94
95String operator+(const char* s1, const String& s2) {
96 String result(s1);
97 result.append(s2);
98 return result;
99}
100
101bool operator==(const char* s1, const String& s2) {
102 return s2 == s1;
103}
104
105bool operator!=(const char* s1, const String& s2) {
106 return s2 != s1;
107}
108
109String to_string(int32_t value) {
110 return SkSL::String::printf("%d", value);
111}
112
113String to_string(uint32_t value) {
114 return SkSL::String::printf("%u", value);
115}
116
117String to_string(int64_t value) {
Ethan Nicholasc8c17602017-03-31 18:53:05 -0400118 std::stringstream buffer;
119 buffer << value;
120 return String(buffer.str().c_str());
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400121}
122
123String to_string(uint64_t value) {
Ethan Nicholasc8c17602017-03-31 18:53:05 -0400124 std::stringstream buffer;
125 buffer << value;
126 return String(buffer.str().c_str());
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400127}
128
129String to_string(double value) {
130#ifdef SKSL_BUILD_FOR_WIN
131 #define SNPRINTF _snprintf
132#else
133 #define SNPRINTF snprintf
134#endif
135#define MAX_DOUBLE_CHARS 25
136 char buffer[MAX_DOUBLE_CHARS];
137 SKSL_DEBUGCODE(int len = )SNPRINTF(buffer, sizeof(buffer), "%.17g", value);
138 ASSERT(len < MAX_DOUBLE_CHARS);
139 String result(buffer);
140 if (!strchr(buffer, '.') && !strchr(buffer, 'e')) {
141 result += ".0";
142 }
143 return result;
144#undef SNPRINTF
145#undef MAX_DOUBLE_CHARS
146}
147
148int stoi(String s) {
149 char* p;
150 SKSL_DEBUGCODE(errno = 0;)
151 long result = strtoul(s.c_str(), &p, 0);
152 ASSERT(*p == 0);
153 ASSERT(!errno);
154 return (int) result;
155}
156
157double stod(String s) {
158 double result;
159 std::string str(s.c_str(), s.size());
160 std::stringstream buffer(str);
161 buffer.imbue(std::locale::classic());
162 buffer >> result;
163 ASSERT(!buffer.fail());
164 return result;
165}
166
167long stol(String s) {
168 char* p;
169 SKSL_DEBUGCODE(errno = 0;)
170 long result = strtoul(s.c_str(), &p, 0);
171 ASSERT(*p == 0);
172 ASSERT(!errno);
173 return result;
174}
175
176} // namespace