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 #ifndef SKSL_STRING 9 #define SKSL_STRING 10 11 #include <cstring> 12 13 #define SKSL_USE_STD_STRING 14 15 #include <stdarg.h> 16 17 #ifdef SKSL_USE_STD_STRING 18 #define SKSL_STRING_BASE std::string 19 #include <string> 20 #else 21 #define SKSL_STRING_BASE SkString 22 #include "SkString.h" 23 #endif 24 25 namespace SkSL { 26 27 // Represents a (not necessarily null-terminated) slice of a string. 28 struct StringFragment { StringFragmentStringFragment29 StringFragment() 30 : fChars("") 31 , fLength(0) {} 32 StringFragmentStringFragment33 StringFragment(const char* chars) 34 : fChars(chars) 35 , fLength(strlen(chars)) {} 36 StringFragmentStringFragment37 StringFragment(const char* chars, size_t length) 38 : fChars(chars) 39 , fLength(length) {} 40 41 char operator[](size_t idx) const { 42 return fChars[idx]; 43 } 44 45 bool operator==(const char* s) const; 46 bool operator!=(const char* s) const; 47 bool operator==(StringFragment s) const; 48 bool operator!=(StringFragment s) const; 49 bool operator<(StringFragment s) const; 50 51 const char* fChars; 52 size_t fLength; 53 }; 54 55 bool operator==(const char* s1, StringFragment s2); 56 57 bool operator!=(const char* s1, StringFragment s2); 58 59 class String : public SKSL_STRING_BASE { 60 public: 61 String() = default; 62 String(const String&) = default; 63 String(String&&) = default; 64 String& operator=(const String&) = default; 65 String& operator=(String&&) = default; 66 67 #ifndef SKSL_USE_STD_STRING String(const SkString & s)68 String(const SkString& s) 69 : INHERITED(s) {} 70 #endif 71 String(const char * s)72 String(const char* s) 73 : INHERITED(s) {} 74 String(const char * s,size_t size)75 String(const char* s, size_t size) 76 : INHERITED(s, size) {} 77 String(StringFragment s)78 String(StringFragment s) 79 : INHERITED(s.fChars, s.fLength) {} 80 81 static String printf(const char* fmt, ...); 82 83 #ifdef SKSL_USE_STD_STRING 84 void appendf(const char* fmt, ...); 85 #endif 86 void vappendf(const char* fmt, va_list va); 87 88 bool startsWith(const char* s) const; 89 bool endsWith(const char* s) const; 90 91 String operator+(const char* s) const; 92 String operator+(const String& s) const; 93 String operator+(StringFragment s) const; 94 String& operator+=(char c); 95 String& operator+=(const char* s); 96 String& operator+=(const String& s); 97 String& operator+=(StringFragment s); 98 bool operator==(const char* s) const; 99 bool operator!=(const char* s) const; 100 bool operator==(const String& s) const; 101 bool operator!=(const String& s) const; 102 friend String operator+(const char* s1, const String& s2); 103 friend bool operator==(const char* s1, const String& s2); 104 friend bool operator!=(const char* s1, const String& s2); 105 106 private: 107 typedef SKSL_STRING_BASE INHERITED; 108 }; 109 110 String operator+(const char* s1, const String& s2); 111 bool operator!=(const char* s1, const String& s2); 112 113 String to_string(double value); 114 115 String to_string(int32_t value); 116 117 String to_string(uint32_t value); 118 119 String to_string(int64_t value); 120 121 String to_string(uint64_t value); 122 123 int stoi(const String& s); 124 125 double stod(const String& s); 126 127 long stol(const String& s); 128 129 } // namespace 130 131 namespace std { 132 template<> struct hash<SkSL::StringFragment> { 133 size_t operator()(const SkSL::StringFragment& s) const { 134 size_t result = 0; 135 for (size_t i = 0; i < s.fLength; ++i) { 136 result = result * 101 + s.fChars[i]; 137 } 138 return result; 139 } 140 }; 141 } // namespace 142 143 #ifdef SKSL_USE_STD_STRING 144 namespace std { 145 template<> struct hash<SkSL::String> { 146 size_t operator()(const SkSL::String& s) const { 147 return hash<std::string>{}(s); 148 } 149 }; 150 } // namespace 151 #else 152 #include "SkOpts.h" 153 namespace std { 154 template<> struct hash<SkSL::String> { 155 size_t operator()(const SkSL::String& s) const { 156 return SkOpts::hash_fn(s.c_str(), s.size(), 0); 157 } 158 }; 159 } // namespace 160 #endif // SKIA_STANDALONE 161 162 #endif 163