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 // For API compatibility with SkString's reset (vs. std:string's clear) 86 void reset(); 87 // For API compatibility with SkString's findLastOf(vs. find_last_of -> size_t) 88 int findLastOf(const char c) const; 89 #endif 90 void vappendf(const char* fmt, va_list va); 91 92 bool startsWith(const char* s) const; 93 bool endsWith(const char* s) const; 94 95 int find(const char* substring, int fromPos = 0) const; 96 int find(const String& substring, int fromPos = 0) const; 97 98 String operator+(const char* s) const; 99 String operator+(const String& s) const; 100 String operator+(StringFragment s) const; 101 String& operator+=(char c); 102 String& operator+=(const char* s); 103 String& operator+=(const String& s); 104 String& operator+=(StringFragment s); 105 bool operator==(const char* s) const; 106 bool operator!=(const char* s) const; 107 bool operator==(const String& s) const; 108 bool operator!=(const String& s) const; 109 friend String operator+(const char* s1, const String& s2); 110 friend bool operator==(const char* s1, const String& s2); 111 friend bool operator!=(const char* s1, const String& s2); 112 113 private: 114 typedef SKSL_STRING_BASE INHERITED; 115 }; 116 117 String operator+(const char* s1, const String& s2); 118 bool operator!=(const char* s1, const String& s2); 119 120 String to_string(double value); 121 122 String to_string(int32_t value); 123 124 String to_string(uint32_t value); 125 126 String to_string(int64_t value); 127 128 String to_string(uint64_t value); 129 130 int stoi(const String& s); 131 132 double stod(const String& s); 133 134 long stol(const String& s); 135 136 } // namespace 137 138 namespace std { 139 template<> struct hash<SkSL::StringFragment> { 140 size_t operator()(const SkSL::StringFragment& s) const { 141 size_t result = 0; 142 for (size_t i = 0; i < s.fLength; ++i) { 143 result = result * 101 + s.fChars[i]; 144 } 145 return result; 146 } 147 }; 148 } // namespace 149 150 #ifdef SKSL_USE_STD_STRING 151 namespace std { 152 template<> struct hash<SkSL::String> { 153 size_t operator()(const SkSL::String& s) const { 154 return hash<std::string>{}(s); 155 } 156 }; 157 } // namespace 158 #else 159 #include "SkOpts.h" 160 namespace std { 161 template<> struct hash<SkSL::String> { 162 size_t operator()(const SkSL::String& s) const { 163 return SkOpts::hash_fn(s.c_str(), s.size(), 0); 164 } 165 }; 166 } // namespace 167 #endif // SKIA_STANDALONE 168 169 #endif 170