blob: e98062efd0cf4bd849173dfb9cb5fcb9d71243ec [file] [log] [blame]
Ethan Nicholasf3333c82017-03-31 09:33:41 -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"
11#include <cinttypes>
12#include <errno.h>
13#include <limits.h>
14#include <locale>
15#include <sstream>
16#include <string>
17
18namespace SkSL {
19
20String String::printf(const char* fmt, ...) {
21 va_list args;
22 va_start(args, fmt);
23 String result;
24 result.vappendf(fmt, args);
25 return result;
26}
27
28#ifdef SKSL_STANDALONE
29void String::appendf(const char* fmt, ...) {
30 va_list args;
31 va_start(args, fmt);
32 this->vappendf(fmt, args);
33}
34#endif
35
36void String::vappendf(const char* fmt, va_list args) {
37#ifdef SKSL_BUILD_FOR_WIN
38 #define VSNPRINTF _vsnprintf
39#else
40 #define VSNPRINTF vsnprintf
41#endif
42 #define BUFFER_SIZE 256
43 char buffer[BUFFER_SIZE];
44 size_t size = VSNPRINTF(buffer, BUFFER_SIZE, fmt, args);
45 if (BUFFER_SIZE >= size) {
46 this->append(buffer, size);
47 } else {
48 auto newBuffer = std::unique_ptr<char[]>(new char[size]);
49 VSNPRINTF(newBuffer.get(), size, fmt, args);
50 this->append(newBuffer.get(), size);
51 }
52 va_end(args);
53}
54
55
56bool String::startsWith(const char* s) const {
57 return strncmp(c_str(), s, strlen(s));
58}
59
60bool String::endsWith(const char* s) const {
61 size_t len = strlen(s);
62 if (size() < len) {
63 return false;
64 }
65 return strncmp(c_str() + size() - len, s, len);
66}
67
68String String::operator+(const char* s) const {
69 String result(*this);
70 result.append(s);
71 return result;
72}
73
74String String::operator+(const String& s) const {
75 String result(*this);
76 result.append(s);
77 return result;
78}
79
80bool String::operator==(const String& s) const {
81 return this->size() == s.size() && !memcmp(c_str(), s.c_str(), this->size());
82}
83
84bool String::operator!=(const String& s) const {
85 return !(*this == s);
86}
87
88bool String::operator==(const char* s) const {
89 return this->size() == strlen(s) && !memcmp(c_str(), s, this->size());
90}
91
92bool String::operator!=(const char* s) const {
93 return !(*this == s);
94}
95
96String operator+(const char* s1, const String& s2) {
97 String result(s1);
98 result.append(s2);
99 return result;
100}
101
102bool operator==(const char* s1, const String& s2) {
103 return s2 == s1;
104}
105
106bool operator!=(const char* s1, const String& s2) {
107 return s2 != s1;
108}
109
110String to_string(int32_t value) {
111 return SkSL::String::printf("%d", value);
112}
113
114String to_string(uint32_t value) {
115 return SkSL::String::printf("%u", value);
116}
117
118String to_string(int64_t value) {
119 return SkSL::String::printf("%" PRId64, value);
120}
121
122String to_string(uint64_t value) {
123 return SkSL::String::printf("%" PRIu64, value);
124}
125
126String to_string(double value) {
127#ifdef SKSL_BUILD_FOR_WIN
128 #define SNPRINTF _snprintf
129#else
130 #define SNPRINTF snprintf
131#endif
132#define MAX_DOUBLE_CHARS 25
133 char buffer[MAX_DOUBLE_CHARS];
134 SKSL_DEBUGCODE(int len = )SNPRINTF(buffer, sizeof(buffer), "%.17g", value);
135 ASSERT(len < MAX_DOUBLE_CHARS);
136 String result(buffer);
137 if (!strchr(buffer, '.') && !strchr(buffer, 'e')) {
138 result += ".0";
139 }
140 return result;
141#undef SNPRINTF
142#undef MAX_DOUBLE_CHARS
143}
144
145int stoi(String s) {
146 char* p;
147 SKSL_DEBUGCODE(errno = 0;)
148 long result = strtol(s.c_str(), &p, 0);
149 ASSERT(*p == 0);
150 ASSERT(!errno && INT_MAX >= result && INT_MIN <= result);
151 return (int) result;
152}
153
154double stod(String s) {
155 double result;
156 std::string str(s.c_str(), s.size());
157 std::stringstream buffer(str);
158 buffer.imbue(std::locale::classic());
159 buffer >> result;
160 ASSERT(!buffer.fail());
161 return result;
162}
163
164long stol(String s) {
165 char* p;
166 SKSL_DEBUGCODE(errno = 0;)
167 long result = strtol(s.c_str(), &p, 0);
168 ASSERT(*p == 0);
169 ASSERT(!errno);
170 return result;
171}
172
173} // namespace