• 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 <cmath>
13 #include <errno.h>
14 #include <limits.h>
15 #include <locale>
16 #include <sstream>
17 #include <string>
18 
to_string(float value)19 std::string skstd::to_string(float value) {
20     return skstd::to_string((double)value);
21 }
22 
to_string(double value)23 std::string skstd::to_string(double value) {
24     std::stringstream buffer;
25     buffer.imbue(std::locale::classic());
26     buffer.precision(17);
27     buffer << value;
28     bool needsDotZero = true;
29     const std::string str = buffer.str();
30     for (int i = str.size() - 1; i >= 0; --i) {
31         char c = str[i];
32         if (c == '.' || c == 'e') {
33             needsDotZero = false;
34             break;
35         }
36     }
37     if (needsDotZero) {
38         buffer << ".0";
39     }
40     return buffer.str();
41 }
42 
stod(std::string_view s,SKSL_FLOAT * value)43 bool SkSL::stod(std::string_view s, SKSL_FLOAT* value) {
44     std::string str(s.data(), s.size());
45     std::stringstream buffer(str);
46     buffer.imbue(std::locale::classic());
47     buffer >> *value;
48     return !buffer.fail() && std::isfinite(*value);
49 }
50 
stoi(std::string_view s,SKSL_INT * value)51 bool SkSL::stoi(std::string_view s, SKSL_INT* value) {
52     if (s.empty()) {
53         return false;
54     }
55     char suffix = s.back();
56     if (suffix == 'u' || suffix == 'U') {
57         s.remove_suffix(1);
58     }
59     std::string str(s);  // s is not null-terminated
60     const char* strEnd = str.data() + str.length();
61     char* p;
62     errno = 0;
63     unsigned long long result = strtoull(str.data(), &p, /*base=*/0);
64     *value = static_cast<SKSL_INT>(result);
65     return p == strEnd && errno == 0 && result <= 0xFFFFFFFF;
66 }
67 
printf(const char * fmt,...)68 std::string SkSL::String::printf(const char* fmt, ...) {
69     va_list args;
70     va_start(args, fmt);
71     std::string result;
72     vappendf(&result, fmt, args);
73     va_end(args);
74     return result;
75 }
76 
appendf(std::string * str,const char * fmt,...)77 void SkSL::String::appendf(std::string *str, const char* fmt, ...) {
78     va_list args;
79     va_start(args, fmt);
80     vappendf(str, fmt, args);
81     va_end(args);
82 }
83 
vappendf(std::string * str,const char * fmt,va_list args)84 void SkSL::String::vappendf(std::string *str, const char* fmt, va_list args) {
85     #define BUFFER_SIZE 256
86     char buffer[BUFFER_SIZE];
87     va_list reuse;
88     va_copy(reuse, args);
89     size_t size = vsnprintf(buffer, BUFFER_SIZE, fmt, args);
90     if (BUFFER_SIZE >= size + 1) {
91         str->append(buffer, size);
92     } else {
93         auto newBuffer = std::unique_ptr<char[]>(new char[size + 1]);
94         vsnprintf(newBuffer.get(), size + 1, fmt, reuse);
95         str->append(newBuffer.get(), size);
96     }
97     va_end(reuse);
98 }
99