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
54class GooString : private std::string
55{
56public:
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

source code of poppler/goo/GooString.h