• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
printf(const char * fmt,...)19 String 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
appendf(const char * fmt,...)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 
vappendf(const char * fmt,va_list args)35 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     va_list reuse;
44     va_copy(reuse, args);
45     size_t size = VSNPRINTF(buffer, BUFFER_SIZE, fmt, args);
46     if (BUFFER_SIZE >= size) {
47         this->append(buffer, size);
48     } else {
49         auto newBuffer = std::unique_ptr<char[]>(new char[size + 1]);
50         VSNPRINTF(newBuffer.get(), size + 1, fmt, reuse);
51         this->append(newBuffer.get(), size);
52     }
53 }
54 
55 
startsWith(const char * s) const56 bool String::startsWith(const char* s) const {
57     return !strncmp(c_str(), s, strlen(s));
58 }
59 
endsWith(const char * s) const60 bool 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 
operator +(const char * s) const68 String String::operator+(const char* s) const {
69     String result(*this);
70     result.append(s);
71     return result;
72 }
73 
operator +(const String & s) const74 String String::operator+(const String& s) const {
75     String result(*this);
76     result.append(s);
77     return result;
78 }
79 
operator ==(const String & s) const80 bool String::operator==(const String& s) const {
81     return this->size() == s.size() && !memcmp(c_str(), s.c_str(), this->size());
82 }
83 
operator !=(const String & s) const84 bool String::operator!=(const String& s) const {
85     return !(*this == s);
86 }
87 
operator ==(const char * s) const88 bool String::operator==(const char* s) const {
89     return this->size() == strlen(s) && !memcmp(c_str(), s, this->size());
90 }
91 
operator !=(const char * s) const92 bool String::operator!=(const char* s) const {
93     return !(*this == s);
94 }
95 
operator +(const char * s1,const String & s2)96 String operator+(const char* s1, const String& s2) {
97     String result(s1);
98     result.append(s2);
99     return result;
100 }
101 
operator ==(const char * s1,const String & s2)102 bool operator==(const char* s1, const String& s2) {
103     return s2 == s1;
104 }
105 
operator !=(const char * s1,const String & s2)106 bool operator!=(const char* s1, const String& s2) {
107     return s2 != s1;
108 }
109 
to_string(int32_t value)110 String to_string(int32_t value) {
111     return SkSL::String::printf("%d", value);
112 }
113 
to_string(uint32_t value)114 String to_string(uint32_t value) {
115     return SkSL::String::printf("%u", value);
116 }
117 
to_string(int64_t value)118 String to_string(int64_t value) {
119     std::stringstream buffer;
120     buffer << value;
121     return String(buffer.str().c_str());
122 }
123 
to_string(uint64_t value)124 String to_string(uint64_t value) {
125     std::stringstream buffer;
126     buffer << value;
127     return String(buffer.str().c_str());
128 }
129 
to_string(double value)130 String to_string(double value) {
131 #ifdef SKSL_BUILD_FOR_WIN
132     #define SNPRINTF    _snprintf
133 #else
134     #define SNPRINTF    snprintf
135 #endif
136 #define MAX_DOUBLE_CHARS 25
137     char buffer[MAX_DOUBLE_CHARS];
138     SKSL_DEBUGCODE(int len = )SNPRINTF(buffer, sizeof(buffer), "%.17g", value);
139     ASSERT(len < MAX_DOUBLE_CHARS);
140     String result(buffer);
141     if (!strchr(buffer, '.') && !strchr(buffer, 'e')) {
142         result += ".0";
143     }
144     return result;
145 #undef SNPRINTF
146 #undef MAX_DOUBLE_CHARS
147 }
148 
stoi(String s)149 int stoi(String s) {
150     char* p;
151     SKSL_DEBUGCODE(errno = 0;)
152     long result = strtoul(s.c_str(), &p, 0);
153     ASSERT(*p == 0);
154     ASSERT(!errno);
155     return (int) result;
156 }
157 
stod(String s)158 double stod(String s) {
159     double result;
160     std::string str(s.c_str(), s.size());
161     std::stringstream buffer(str);
162     buffer.imbue(std::locale::classic());
163     buffer >> result;
164     ASSERT(!buffer.fail());
165     return result;
166 }
167 
stol(String s)168 long stol(String s) {
169     char* p;
170     SKSL_DEBUGCODE(errno = 0;)
171     long result = strtoul(s.c_str(), &p, 0);
172     ASSERT(*p == 0);
173     ASSERT(!errno);
174     return result;
175 }
176 
177 } // namespace
178