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