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
20namespace SkSL {
21
22// Represents a (not necessarily null-terminated) slice of a string.
23struct StringFragment {
24 StringFragment()
25 : fChars("")
26 , fLength(0) {}
27
28 StringFragment(const char* chars)
29 : fChars(chars)
30 , fLength(strlen(chars)) {}
31
32 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
47 operator SkString() const { return SkString(fChars, fLength); }
48#endif
49
50 const char* fChars;
51 size_t fLength;
52};
53
54bool operator==(const char* s1, StringFragment s2);
55
56bool operator!=(const char* s1, StringFragment s2);
57
58class SK_API String : public std::string {
59public:
60 String() = default;
61 String(const String&) = default;
62 String(String&&) = default;
63 String& operator=(const String&) = default;
64 String& operator=(String&&) = default;
65
66 String(const char* s)
67 : INHERITED(s) {}
68
69 String(const char* s, size_t size)
70 : INHERITED(s, size) {}
71
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
107 operator SkString() const { return SkString(c_str()); }
108#endif
109
110private:
111 typedef std::string INHERITED;
112};
113
114String operator+(const char* s1, const String& s2);
115bool operator!=(const char* s1, const String& s2);
116
117String to_string(double value);
118
119String to_string(int32_t value);
120
121String to_string(uint32_t value);
122
123String to_string(int64_t value);
124
125String to_string(uint64_t value);
126
127SKSL_INT stoi(const String& s);
128
129SKSL_FLOAT stod(const String& s);
130
131long stol(const String& s);
132
133} // namespace SkSL
134
135namespace 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