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 "include/private/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 class String; 23 24 // Represents a (not necessarily null-terminated) slice of a string. 25 struct StringFragment { StringFragmentStringFragment26 StringFragment() 27 : fChars("") 28 , fLength(0) {} 29 StringFragmentStringFragment30 StringFragment(const char* chars) 31 : fChars(chars) 32 , fLength(strlen(chars)) {} 33 StringFragmentStringFragment34 StringFragment(const char* chars, size_t length) 35 : fChars(chars) 36 , fLength(length) {} 37 beginStringFragment38 const char* begin() const { return fChars; } endStringFragment39 const char* end() const { return fChars + fLength; } 40 dataStringFragment41 const char* data() const { return fChars; } sizeStringFragment42 size_t size() const { return fLength; } lengthStringFragment43 size_t length() const { return fLength; } 44 char operator[](size_t idx) const { return fChars[idx]; } 45 46 bool startsWith(const char prefix[]) const; 47 bool endsWith(const char suffix[]) const; 48 49 bool operator==(const char* s) const; 50 bool operator!=(const char* s) const; 51 bool operator==(StringFragment s) const; 52 bool operator!=(StringFragment s) const; 53 bool operator<(StringFragment s) const; 54 String operator+(const char* s) const; 55 String operator+(const StringFragment& s) const; 56 String operator+(const String& s) const; 57 58 #ifndef SKSL_STANDALONE SkStringStringFragment59 operator SkString() const { return SkString(fChars, fLength); } 60 #endif 61 62 const char* fChars; 63 size_t fLength; 64 }; 65 66 bool operator==(const char* s1, StringFragment s2); 67 68 bool operator!=(const char* s1, StringFragment s2); 69 70 class SK_API String : public std::string { 71 public: 72 using std::string::string; 73 String(std::string s)74 explicit String(std::string s) : INHERITED(std::move(s)) {} String(StringFragment s)75 String(StringFragment s) : INHERITED(s.fChars, s.fLength) {} 76 77 static String printf(const char* fmt, ...) SK_PRINTF_LIKE(1, 2); 78 void appendf(const char* fmt, ...) SK_PRINTF_LIKE(2, 3); 79 void vappendf(const char* fmt, va_list va); 80 startsWith(const char prefix[])81 bool startsWith(const char prefix[]) const { 82 return StringFragment(data(), size()).startsWith(prefix); 83 } endsWith(const char suffix[])84 bool endsWith(const char suffix[]) const { 85 return StringFragment(data(), size()).endsWith(suffix); 86 } 87 88 bool consumeSuffix(const char suffix[]); 89 90 String operator+(const char* s) const; 91 String operator+(const String& s) const; 92 String operator+(StringFragment s) const; 93 String& operator+=(char c); 94 String& operator+=(const char* s); 95 String& operator+=(const String& s); 96 String& operator+=(StringFragment s); 97 bool operator==(const char* s) const; 98 bool operator!=(const char* s) const; 99 bool operator==(const String& s) const; 100 bool operator!=(const String& s) const; 101 friend String operator+(const char* s1, const String& s2); 102 friend bool operator==(const char* s1, const String& s2); 103 friend bool operator!=(const char* s1, const String& s2); 104 105 private: 106 using INHERITED = std::string; 107 }; 108 109 String operator+(const char* s1, const String& s2); 110 bool operator!=(const char* s1, const String& s2); 111 112 String to_string(double value); 113 String to_string(int32_t value); 114 String to_string(uint32_t value); 115 String to_string(int64_t value); 116 String to_string(uint64_t value); 117 118 bool stod(const StringFragment& s, SKSL_FLOAT* value); 119 bool stoi(const StringFragment& s, SKSL_INT* value); 120 121 } // namespace SkSL 122 123 namespace std { 124 template<> struct hash<SkSL::StringFragment> { 125 size_t operator()(const SkSL::StringFragment& s) const { 126 size_t result = 0; 127 for (size_t i = 0; i < s.fLength; ++i) { 128 result = result * 101 + (size_t) s.fChars[i]; 129 } 130 return result; 131 } 132 }; 133 134 template<> struct hash<SkSL::String> { 135 size_t operator()(const SkSL::String& s) const { 136 return hash<std::string>{}(s); 137 } 138 }; 139 } // namespace std 140 141 #endif 142