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