1 | //======================================================================== |
2 | // |
3 | // GooString.h |
4 | // |
5 | // Simple variable-length string type. |
6 | // |
7 | // Copyright 1996-2003 Glyph & Cog, LLC |
8 | // |
9 | //======================================================================== |
10 | |
11 | //======================================================================== |
12 | // |
13 | // Modified under the Poppler project - http://poppler.freedesktop.org |
14 | // |
15 | // All changes made under the Poppler project to this file are licensed |
16 | // under GPL version 2 or later |
17 | // |
18 | // Copyright (C) 2006 Kristian Høgsberg <krh@redhat.com> |
19 | // Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com> |
20 | // Copyright (C) 2008-2010, 2012, 2014, 2017-2022 Albert Astals Cid <aacid@kde.org> |
21 | // Copyright (C) 2012-2014 Fabio D'Urso <fabiodurso@hotmail.it> |
22 | // Copyright (C) 2013 Jason Crain <jason@aquaticape.us> |
23 | // Copyright (C) 2015, 2018 Adam Reichold <adam.reichold@t-online.de> |
24 | // Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com> |
25 | // Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com> |
26 | // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich |
27 | // Copyright (C) 2019 Christophe Fergeau <cfergeau@redhat.com> |
28 | // Copyright (C) 2019 Tomoyuki Kubota <himajin100000@gmail.com> |
29 | // Copyright (C) 2019, 2020, 2022-2024 Oliver Sander <oliver.sander@tu-dresden.de> |
30 | // Copyright (C) 2019 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de> |
31 | // Copyright (C) 2020 Thorsten Behrens <Thorsten.Behrens@CIB.de> |
32 | // Copyright (C) 2022 Even Rouault <even.rouault@spatialys.com> |
33 | // |
34 | // To see a description of the changes please see the Changelog file that |
35 | // came with your tarball or type make ChangeLog if you are building from git |
36 | // |
37 | //======================================================================== |
38 | |
39 | #ifndef GooString_H |
40 | #define GooString_H |
41 | |
42 | #include "poppler_private_export.h" |
43 | |
44 | #include <cstdarg> |
45 | #include <memory> |
46 | #include <string> |
47 | |
48 | #ifdef __clang__ |
49 | # define GOOSTRING_FORMAT __attribute__((__annotate__("gooformat"))) |
50 | #else |
51 | # define GOOSTRING_FORMAT |
52 | #endif |
53 | |
54 | class GooString : private std::string |
55 | { |
56 | public: |
57 | // Create an empty string. |
58 | GooString() = default; |
59 | |
60 | // Destructor. |
61 | ~GooString() = default; |
62 | |
63 | GooString(GooString &&other) = default; |
64 | GooString &operator=(GooString &&other) = default; |
65 | |
66 | GooString(const GooString &other) = delete; |
67 | GooString &operator=(const GooString &other) = delete; |
68 | |
69 | // Create a string from a C string. |
70 | explicit GooString(const char *sA) : std::string(sA ? sA : "" ) { } |
71 | |
72 | // Zero-cost conversion from and to std::string |
73 | explicit GooString(const std::string &str) : std::string(str) { } |
74 | explicit GooString(std::string &&str) : std::string(std::move(str)) { } |
75 | |
76 | const std::string &toStr() const { return *this; } |
77 | std::string &toNonConstStr() { return *this; } |
78 | |
79 | // Create a string from <lengthA> chars at <sA>. This string |
80 | // can contain null characters. |
81 | GooString(const char *sA, size_t lengthA) : std::string(sA ? sA : "" , sA ? lengthA : 0) { } |
82 | |
83 | // Create a string from <lengthA> chars at <idx> in <str>. |
84 | GooString(const GooString *str, int idx, size_t lengthA) : std::string(*str, idx, lengthA) { } |
85 | GooString(const std::string &str, int idx, size_t lengthA) : std::string(str, idx, lengthA) { } |
86 | |
87 | // Set content of a string to <newStr>. |
88 | GooString *Set(const GooString *newStr) |
89 | { |
90 | assign(str: newStr ? static_cast<const std::string &>(*newStr) : std::string {}); |
91 | return this; |
92 | } |
93 | GooString *Set(const char *newStr) |
94 | { |
95 | assign(s: newStr ? newStr : "" ); |
96 | return this; |
97 | } |
98 | GooString *Set(const char *newStr, int newLen) |
99 | { |
100 | assign(s: newStr ? newStr : "" , n: newStr ? newLen : 0); |
101 | return this; |
102 | } |
103 | |
104 | // Copy a string. |
105 | explicit GooString(const GooString *str) : std::string(str ? static_cast<const std::string &>(*str) : std::string {}) { } |
106 | GooString *copy() const { return new GooString(this); } |
107 | |
108 | // Concatenate two strings. |
109 | GooString(const GooString *str1, const GooString *str2) |
110 | { |
111 | reserve(res: str1->size() + str2->size()); |
112 | static_cast<std::string &>(*this).append(str: *str1); |
113 | static_cast<std::string &>(*this).append(str: *str2); |
114 | } |
115 | |
116 | // Create a formatted string. Similar to printf, but without the |
117 | // string overflow issues. Formatting elements consist of: |
118 | // {<arg>:[<width>][.<precision>]<type>} |
119 | // where: |
120 | // - <arg> is the argument number (arg 0 is the first argument |
121 | // following the format string) -- NB: args must be first used in |
122 | // order; they can be reused in any order |
123 | // - <width> is the field width -- negative to reverse the alignment; |
124 | // starting with a leading zero to zero-fill (for integers) |
125 | // - <precision> is the number of digits to the right of the decimal |
126 | // point (for floating point numbers) |
127 | // - <type> is one of: |
128 | // d, x, X, o, b -- int in decimal, lowercase hex, uppercase hex, octal, binary |
129 | // ud, ux, uX, uo, ub -- unsigned int |
130 | // ld, lx, lX, lo, lb, uld, ulx, ulX, ulo, ulb -- long, unsigned long |
131 | // lld, llx, llX, llo, llb, ulld, ullx, ullX, ullo, ullb |
132 | // -- long long, unsigned long long |
133 | // f, g, gs -- floating point (float or double) |
134 | // f -- always prints trailing zeros (eg 1.0 with .2f will print 1.00) |
135 | // g -- omits trailing zeros and, if possible, the dot (eg 1.0 shows up as 1) |
136 | // gs -- is like g, but treats <precision> as number of significant |
137 | // digits to show (eg 0.0123 with .2gs will print 0.012) |
138 | // c -- character (char, short or int) |
139 | // s -- string (char *) |
140 | // t -- GooString * |
141 | // w -- blank space; arg determines width |
142 | // To get literal curly braces, use {{ or }}. |
143 | POPPLER_PRIVATE_EXPORT static std::unique_ptr<GooString> format(const char *fmt, ...) GOOSTRING_FORMAT; |
144 | POPPLER_PRIVATE_EXPORT static std::unique_ptr<GooString> formatv(const char *fmt, va_list argList); |
145 | |
146 | // Get length. |
147 | int getLength() const { return size(); } |
148 | |
149 | // Get C string. |
150 | using std::string::c_str; |
151 | |
152 | // Get <i>th character. |
153 | char getChar(size_t i) const { return (*this)[i]; } |
154 | |
155 | // Change <i>th character. |
156 | void setChar(int i, char c) { (*this)[i] = c; } |
157 | |
158 | // Clear string to zero length. |
159 | using std::string::clear; |
160 | |
161 | // Append a character or string. |
162 | GooString *append(char c) |
163 | { |
164 | push_back(c: c); |
165 | return this; |
166 | } |
167 | GooString *append(const GooString *str) |
168 | { |
169 | static_cast<std::string &>(*this).append(str: *str); |
170 | return this; |
171 | } |
172 | GooString *append(const std::string &str) |
173 | { |
174 | static_cast<std::string &>(*this).append(str: str); |
175 | return this; |
176 | } |
177 | GooString *append(const char *str) |
178 | { |
179 | static_cast<std::string &>(*this).append(s: str); |
180 | return this; |
181 | } |
182 | GooString *append(const char *str, size_t lengthA) |
183 | { |
184 | static_cast<std::string &>(*this).append(s: str, n: lengthA); |
185 | return this; |
186 | } |
187 | |
188 | // Append a formatted string. |
189 | POPPLER_PRIVATE_EXPORT GooString *appendf(const char *fmt, ...) GOOSTRING_FORMAT; |
190 | POPPLER_PRIVATE_EXPORT GooString *appendfv(const char *fmt, va_list argList); |
191 | |
192 | // Insert a character or string. |
193 | GooString *insert(int i, char c) |
194 | { |
195 | static_cast<std::string &>(*this).insert(pos: i, n: 1, c: c); |
196 | return this; |
197 | } |
198 | GooString *insert(int i, const GooString *str) |
199 | { |
200 | static_cast<std::string &>(*this).insert(pos1: i, str: *str); |
201 | return this; |
202 | } |
203 | GooString *insert(int i, const std::string &str) |
204 | { |
205 | static_cast<std::string &>(*this).insert(pos1: i, str: str); |
206 | return this; |
207 | } |
208 | GooString *insert(int i, const char *str) |
209 | { |
210 | static_cast<std::string &>(*this).insert(pos: i, s: str); |
211 | return this; |
212 | } |
213 | GooString *insert(int i, const char *str, int lengthA) |
214 | { |
215 | static_cast<std::string &>(*this).insert(pos: i, s: str, n: lengthA); |
216 | return this; |
217 | } |
218 | |
219 | // Delete a character or range of characters. |
220 | GooString *del(int i, int n = 1) |
221 | { |
222 | erase(pos: i, n: n); |
223 | return this; |
224 | } |
225 | |
226 | // Convert string to all-lower case. |
227 | POPPLER_PRIVATE_EXPORT GooString *lowerCase(); |
228 | POPPLER_PRIVATE_EXPORT static void lowerCase(std::string &s); |
229 | |
230 | // Returns a new string converted to all-lower case. |
231 | POPPLER_PRIVATE_EXPORT static std::string toLowerCase(const std::string &s); |
232 | |
233 | // Compare two strings: -1:< 0:= +1:> |
234 | int cmp(const GooString *str) const { return compare(str: *str); } |
235 | int cmp(const std::string &str) const { return compare(str: str); } |
236 | int cmpN(GooString *str, int n) const { return compare(pos: 0, n: n, str: *str); } |
237 | int cmp(const char *sA) const { return compare(s: sA); } |
238 | int cmpN(const char *sA, int n) const { return compare(pos: 0, n1: n, s: sA); } |
239 | |
240 | // Return true if strings starts with prefix |
241 | using std::string::starts_with; |
242 | |
243 | // Return true if string ends with suffix |
244 | using std::string::ends_with; |
245 | }; |
246 | |
247 | #endif |
248 | |