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 "src/sksl/SkSLDefines.h" 12 #include <cstring> 13 #include <stdarg.h> 14 #include <string> 15 16 #ifndef SKSL_STANDALONE 17 #include "include/core/SkString.h" 18 #endif 19 20 namespace SkSL { 21 22 // Represents a (not necessarily null-terminated) slice of a string. 23 struct StringFragment { StringFragmentStringFragment24 StringFragment() 25 : fChars("") 26 , fLength(0) {} 27 StringFragmentStringFragment28 StringFragment(const char* chars) 29 : fChars(chars) 30 , fLength(strlen(chars)) {} 31 StringFragmentStringFragment32 StringFragment(const char* chars, size_t length) 33 : fChars(chars) 34 , fLength(length) {} 35 36 char operator[](size_t idx) const { 37 return fChars[idx]; 38 } 39 40 bool operator==(const char* s) const; 41 bool operator!=(const char* s) const; 42 bool operator==(StringFragment s) const; 43 bool operator!=(StringFragment s) const; 44 bool operator<(StringFragment s) const; 45 46 #ifndef SKSL_STANDALONE SkStringStringFragment47 operator SkString() const { return SkString(fChars, fLength); } 48 #endif 49 50 const char* fChars; 51 size_t fLength; 52 }; 53 54 bool operator==(const char* s1, StringFragment s2); 55 56 bool operator!=(const char* s1, StringFragment s2); 57 58 class SK_API String : public std::string { 59 public: 60 String() = default; 61 String(const String&) = default; 62 String(String&&) = default; 63 String& operator=(const String&) = default; 64 String& operator=(String&&) = default; 65 String(const char * s)66 String(const char* s) 67 : INHERITED(s) {} 68 String(const char * s,size_t size)69 String(const char* s, size_t size) 70 : INHERITED(s, size) {} 71 String(StringFragment s)72 String(StringFragment s) 73 : INHERITED(s.fChars, s.fLength) {} 74 75 static String printf(const char* fmt, ...); 76 77 void appendf(const char* fmt, ...); 78 // For API compatibility with SkString's reset (vs. std:string's clear) 79 void reset(); 80 // For API compatibility with SkString's findLastOf(vs. find_last_of -> size_t) 81 int findLastOf(const char c) const; 82 83 void vappendf(const char* fmt, va_list va); 84 85 bool startsWith(const char* s) const; 86 bool endsWith(const char* s) const; 87 88 int find(const char* substring, int fromPos = 0) const; 89 int find(const String& substring, int fromPos = 0) 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 #ifndef SKSL_STANDALONE SkString()107 operator SkString() const { return SkString(c_str()); } 108 #endif 109 110 private: 111 typedef std::string INHERITED; 112 }; 113 114 String operator+(const char* s1, const String& s2); 115 bool operator!=(const char* s1, const String& s2); 116 117 String to_string(double value); 118 119 String to_string(int32_t value); 120 121 String to_string(uint32_t value); 122 123 String to_string(int64_t value); 124 125 String to_string(uint64_t value); 126 127 SKSL_INT stoi(const String& s); 128 129 SKSL_FLOAT stod(const String& s); 130 131 long stol(const String& s); 132 133 } // namespace SkSL 134 135 namespace std { 136 template<> struct hash<SkSL::StringFragment> { 137 size_t operator()(const SkSL::StringFragment& s) const { 138 size_t result = 0; 139 for (size_t i = 0; i < s.fLength; ++i) { 140 result = result * 101 + s.fChars[i]; 141 } 142 return result; 143 } 144 }; 145 146 template<> struct hash<SkSL::String> { 147 size_t operator()(const SkSL::String& s) const { 148 return hash<std::string>{}(s); 149 } 150 }; 151 } // namespace std 152 153 #endif 154