• 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 "include/private/SkSLString.h"
9 #include "src/sksl/SkSLUtil.h"
10 #include <algorithm>
11 #include <cinttypes>
12 #include <errno.h>
13 #include <limits.h>
14 #include <locale>
15 #include <sstream>
16 #include <string>
17 
18 namespace SkSL {
19 
printf(const char * fmt,...)20 String String::printf(const char* fmt, ...) {
21     va_list args;
22     va_start(args, fmt);
23     String result;
24     result.vappendf(fmt, args);
25     va_end(args);
26     return result;
27 }
28 
appendf(const char * fmt,...)29 void String::appendf(const char* fmt, ...) {
30     va_list args;
31     va_start(args, fmt);
32     this->vappendf(fmt, args);
33     va_end(args);
34 }
35 
vappendf(const char * fmt,va_list args)36 void String::vappendf(const char* fmt, va_list args) {
37     #define BUFFER_SIZE 256
38     char buffer[BUFFER_SIZE];
39     va_list reuse;
40     va_copy(reuse, args);
41     size_t size = vsnprintf(buffer, BUFFER_SIZE, fmt, args);
42     if (BUFFER_SIZE >= size + 1) {
43         this->append(buffer, size);
44     } else {
45         auto newBuffer = std::unique_ptr<char[]>(new char[size + 1]);
46         vsnprintf(newBuffer.get(), size + 1, fmt, reuse);
47         this->append(newBuffer.get(), size);
48     }
49     va_end(reuse);
50 }
51 
consumeSuffix(const char suffix[])52 bool String::consumeSuffix(const char suffix[]) {
53     size_t suffixLength = strlen(suffix);
54     if (this->length() < suffixLength) {
55         return false;
56     }
57     if (0 != strncmp(this->data() + this->size() - suffixLength, suffix, suffixLength)) {
58         return false;
59     }
60     this->resize(this->length() - suffixLength);
61     return true;
62 }
63 
operator +(const char * s) const64 String String::operator+(const char* s) const {
65     String result(*this);
66     result.append(s);
67     return result;
68 }
69 
operator +(const String & s) const70 String String::operator+(const String& s) const {
71     String result(*this);
72     result.append(s);
73     return result;
74 }
75 
operator +(skstd::string_view s) const76 String String::operator+(skstd::string_view s) const {
77     String result(*this);
78     result.append(s.data(), s.length());
79     return result;
80 }
81 
operator +=(char c)82 String& String::operator+=(char c) {
83     INHERITED::operator+=(c);
84     return *this;
85 }
86 
operator +=(const char * s)87 String& String::operator+=(const char* s) {
88     INHERITED::operator+=(s);
89     return *this;
90 }
91 
operator +=(const String & s)92 String& String::operator+=(const String& s) {
93     INHERITED::operator+=(s);
94     return *this;
95 }
96 
operator +=(skstd::string_view s)97 String& String::operator+=(skstd::string_view s) {
98     this->append(s.data(), s.length());
99     return *this;
100 }
101 
operator +(const char * s1,const String & s2)102 String operator+(const char* s1, const String& s2) {
103     String result(s1);
104     result.append(s2);
105     return result;
106 }
107 
operator +(skstd::string_view left,skstd::string_view right)108 String operator+(skstd::string_view left, skstd::string_view right) {
109     return String(left) + right;
110 }
111 
to_string(int32_t value)112 String to_string(int32_t value) {
113     return SkSL::String(std::to_string(value));
114 }
115 
to_string(uint32_t value)116 String to_string(uint32_t value) {
117     return SkSL::String(std::to_string(value));
118 }
119 
to_string(int64_t value)120 String to_string(int64_t value) {
121     return SkSL::String(std::to_string(value));
122 }
123 
to_string(uint64_t value)124 String to_string(uint64_t value) {
125     return SkSL::String(std::to_string(value));
126 }
127 
to_string(double value)128 String to_string(double value) {
129     std::stringstream buffer;
130     buffer.imbue(std::locale::classic());
131     buffer.precision(17);
132     buffer << value;
133     bool needsDotZero = true;
134     const std::string str = buffer.str();
135     for (int i = str.size() - 1; i >= 0; --i) {
136         char c = str[i];
137         if (c == '.' || c == 'e') {
138             needsDotZero = false;
139             break;
140         }
141     }
142     if (needsDotZero) {
143         buffer << ".0";
144     }
145     return String(buffer.str().c_str());
146 }
147 
stod(const skstd::string_view & s,SKSL_FLOAT * value)148 bool stod(const skstd::string_view& s, SKSL_FLOAT* value) {
149     std::string str(s.data(), s.size());
150     std::stringstream buffer(str);
151     buffer.imbue(std::locale::classic());
152     buffer >> *value;
153     return !buffer.fail();
154 }
155 
stoi(const skstd::string_view & s,SKSL_INT * value)156 bool stoi(const skstd::string_view& s, SKSL_INT* value) {
157     char* p;
158     errno = 0;
159     unsigned long long result = strtoull(s.begin(), &p, /*base=*/0);
160     *value = static_cast<SKSL_INT>(result);
161     return p == s.end() && errno == 0 && result <= 0xFFFFFFFF;
162 }
163 
164 }  // namespace SkSL
165