/src/poppler/goo/GooString.h
Line | Count | Source |
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, 2024, 2025 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 | | // Copyright (C) 2025 g10 Code GmbH, Author: Sune Stolborg Vuorela <sune@vuorela.dk> |
34 | | // |
35 | | // To see a description of the changes please see the Changelog file that |
36 | | // came with your tarball or type make ChangeLog if you are building from git |
37 | | // |
38 | | //======================================================================== |
39 | | |
40 | | #ifndef GooString_H |
41 | | #define GooString_H |
42 | | |
43 | | #include "poppler_private_export.h" |
44 | | |
45 | | #include <cstdarg> |
46 | | #include <memory> |
47 | | #include <string> |
48 | | |
49 | | #ifdef __clang__ |
50 | | # define GOOSTRING_FORMAT __attribute__((__annotate__("gooformat"))) |
51 | | #else |
52 | | # define GOOSTRING_FORMAT |
53 | | #endif |
54 | | |
55 | | class GooString : private std::string |
56 | | { |
57 | | public: |
58 | | // Create an empty string. |
59 | 3.21G | GooString() = default; |
60 | | |
61 | | // Destructor. |
62 | | ~GooString() = default; |
63 | | |
64 | 203k | GooString(GooString &&other) = default; |
65 | 228 | GooString &operator=(GooString &&other) = default; |
66 | | |
67 | | GooString(const GooString &other) = delete; |
68 | | GooString &operator=(const GooString &other) = delete; |
69 | | |
70 | | // Create a string from a C string. |
71 | 1.34M | explicit GooString(const char *sA) : std::string(sA ? sA : "") { } |
72 | | |
73 | | // disallow explicit creation from nullptr |
74 | | // (c++23 also disallows it for std::string) |
75 | | // note, this only prevents GooString(nullptr), |
76 | | // not const char*s = nullptr; GooString(s). |
77 | | explicit GooString(std::nullptr_t) = delete; |
78 | | |
79 | | // Zero-cost conversion from and to std::string |
80 | 83.8M | explicit GooString(const std::string &str) : std::string(str) { } |
81 | 3.51M | explicit GooString(std::string &&str) : std::string(std::move(str)) { } |
82 | | |
83 | 2.61G | const std::string &toStr() const { return *this; } |
84 | 483k | std::string &toNonConstStr() { return *this; } |
85 | | |
86 | | // Create a string from <lengthA> chars at <sA>. This string |
87 | | // can contain null characters. |
88 | 186k | GooString(const char *sA, size_t lengthA) : std::string(sA ? sA : "", sA ? lengthA : 0) { } |
89 | | |
90 | | // Create a string from <lengthA> chars at <idx> in <str>. |
91 | 864k | GooString(const GooString *str, int idx, size_t lengthA) : std::string(*str, idx, lengthA) { } |
92 | 0 | GooString(const std::string &str, int idx, size_t lengthA) : std::string(str, idx, lengthA) { } |
93 | | |
94 | | // Set content of a string to <newStr>. |
95 | | GooString *Set(const GooString *newStr) |
96 | 0 | { |
97 | 0 | assign(newStr ? static_cast<const std::string &>(*newStr) : std::string {}); |
98 | 0 | return this; |
99 | 0 | } |
100 | | GooString *Set(const char *newStr) |
101 | 137k | { |
102 | 137k | assign(newStr ? newStr : ""); |
103 | 137k | return this; |
104 | 137k | } |
105 | | GooString *Set(const char *newStr, int newLen) |
106 | 0 | { |
107 | 0 | assign(newStr ? newStr : "", newStr ? newLen : 0); |
108 | 0 | return this; |
109 | 0 | } |
110 | | |
111 | | // Copy a string. |
112 | 29.5M | std::unique_ptr<GooString> copy() const { return std::make_unique<GooString>(this->toStr()); } |
113 | | |
114 | | // Create a formatted string. Similar to printf, but without the |
115 | | // string overflow issues. Formatting elements consist of: |
116 | | // {<arg>:[<width>][.<precision>]<type>} |
117 | | // where: |
118 | | // - <arg> is the argument number (arg 0 is the first argument |
119 | | // following the format string) -- NB: args must be first used in |
120 | | // order; they can be reused in any order |
121 | | // - <width> is the field width -- negative to reverse the alignment; |
122 | | // starting with a leading zero to zero-fill (for integers) |
123 | | // - <precision> is the number of digits to the right of the decimal |
124 | | // point (for floating point numbers) |
125 | | // - <type> is one of: |
126 | | // d, x, X, o, b -- int in decimal, lowercase hex, uppercase hex, octal, binary |
127 | | // ud, ux, uX, uo, ub -- unsigned int |
128 | | // ld, lx, lX, lo, lb, uld, ulx, ulX, ulo, ulb -- long, unsigned long |
129 | | // lld, llx, llX, llo, llb, ulld, ullx, ullX, ullo, ullb |
130 | | // -- long long, unsigned long long |
131 | | // f, g, gs -- floating point (float or double) |
132 | | // f -- always prints trailing zeros (eg 1.0 with .2f will print 1.00) |
133 | | // g -- omits trailing zeros and, if possible, the dot (eg 1.0 shows up as 1) |
134 | | // gs -- is like g, but treats <precision> as number of significant |
135 | | // digits to show (eg 0.0123 with .2gs will print 0.012) |
136 | | // c -- character (char, short or int) |
137 | | // s -- string (char *) |
138 | | // t -- GooString * |
139 | | // w -- blank space; arg determines width |
140 | | // To get literal curly braces, use {{ or }}. |
141 | | POPPLER_PRIVATE_EXPORT static std::string format(const char *fmt, ...) GOOSTRING_FORMAT; |
142 | | POPPLER_PRIVATE_EXPORT static std::string formatv(const char *fmt, va_list argList); |
143 | | |
144 | | POPPLER_PRIVATE_EXPORT static std::string formatLongLong(long long x, int width); |
145 | | |
146 | | // Get length. |
147 | | using std::string::empty; |
148 | | using std::string::size; |
149 | | |
150 | | // Get C string. |
151 | | using std::string::c_str; |
152 | | |
153 | | // Get <i>th character. |
154 | 129M | char getChar(size_t i) const { return (*this)[i]; } |
155 | | |
156 | | // Change <i>th character. |
157 | 70.0M | void setChar(size_t i, char c) { (*this)[i] = c; } |
158 | | |
159 | | // Clear string to zero length. |
160 | | using std::string::clear; |
161 | | |
162 | | // Append a character or string. |
163 | 22.3G | void append(char c) { push_back(c); } |
164 | | GooString *append(const GooString *str) |
165 | 1.09M | { |
166 | 1.09M | static_cast<std::string &>(*this).append(*str); |
167 | 1.09M | return this; |
168 | 1.09M | } |
169 | | GooString *append(const std::string &str) |
170 | 130k | { |
171 | 130k | static_cast<std::string &>(*this).append(str); |
172 | 130k | return this; |
173 | 130k | } |
174 | | GooString *append(const char *str) |
175 | 1.32M | { |
176 | 1.32M | static_cast<std::string &>(*this).append(str); |
177 | 1.32M | return this; |
178 | 1.32M | } |
179 | | GooString *append(const char *str, size_t lengthA) |
180 | 3.72G | { |
181 | 3.72G | static_cast<std::string &>(*this).append(str, lengthA); |
182 | 3.72G | return this; |
183 | 3.72G | } |
184 | | |
185 | | // Append a formatted string. |
186 | | POPPLER_PRIVATE_EXPORT GooString *appendf(const char *fmt, ...) GOOSTRING_FORMAT; |
187 | | POPPLER_PRIVATE_EXPORT GooString *appendfv(const char *fmt, va_list argList); |
188 | | |
189 | | // Insert a character or string. |
190 | | GooString *insert(int i, int count, char c) |
191 | 0 | { |
192 | 0 | static_cast<std::string &>(*this).insert(i, count, c); |
193 | 0 | return this; |
194 | 0 | } |
195 | | GooString *insert(int i, const GooString *str) |
196 | 223 | { |
197 | 223 | static_cast<std::string &>(*this).insert(i, *str); |
198 | 223 | return this; |
199 | 223 | } |
200 | | GooString *insert(int i, const std::string &str) |
201 | 0 | { |
202 | 0 | static_cast<std::string &>(*this).insert(i, str); |
203 | 0 | return this; |
204 | 0 | } |
205 | | GooString *insert(int i, const char *str) |
206 | 0 | { |
207 | 0 | static_cast<std::string &>(*this).insert(i, str); |
208 | 0 | return this; |
209 | 0 | } |
210 | | GooString *insert(int i, const char *str, int lengthA) |
211 | 0 | { |
212 | 0 | static_cast<std::string &>(*this).insert(i, str, lengthA); |
213 | 0 | return this; |
214 | 0 | } |
215 | | |
216 | | // Delete a character or range of characters. |
217 | | using std::string::erase; |
218 | | |
219 | | // Convert string to all-lower case. |
220 | | POPPLER_PRIVATE_EXPORT GooString *lowerCase(); |
221 | | POPPLER_PRIVATE_EXPORT static void lowerCase(std::string &s); |
222 | | |
223 | | // Returns a new string converted to all-lower case. |
224 | | POPPLER_PRIVATE_EXPORT static std::string toLowerCase(const std::string &s); |
225 | | |
226 | | // Compare two strings: -1:< 0:= +1:> |
227 | 26.7M | int cmp(const GooString *str) const { return compare(*str); } |
228 | 108k | int cmp(const std::string &str) const { return compare(str); } |
229 | 9.01M | int cmp(const char *sA) const { return compare(sA); } |
230 | | |
231 | | // Return true if strings starts with prefix |
232 | | using std::string::starts_with; |
233 | | |
234 | | // Return true if string ends with suffix |
235 | | using std::string::ends_with; |
236 | | }; |
237 | | |
238 | | #endif |