LMMS
Loading...
Searching...
No Matches
wdlstring.h
Go to the documentation of this file.
1/*
2 WDL - wdlstring.h
3 Copyright (C) 2005 and later, Cockos Incorporated
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20
21*/
22
23/*
24
25 This file provides a simple class for variable-length string manipulation.
26 It provides only the simplest features, and does not do anything confusing like
27 operator overloading. It uses a WDL_HeapBuf for internal storage.
28
29 Actually: there are WDL_String and WDL_FastString -- the latter's Get() returns const char, and tracks
30 the length of the string, which is often faster. Because of this, you are not permitted to directly modify
31 the buffer returned by Get().
32
33
34*/
35
36#ifndef _WDL_STRING_H_
37#define _WDL_STRING_H_
38
39#include "heapbuf.h"
40#include <stdio.h>
41#include <stdarg.h>
42
43#ifndef WDL_STRING_IMPL_ONLY
45{
46 public:
47 #ifdef WDL_STRING_INTF_ONLY
48 void Set(const char *str, int maxlen=0);
49 void Set(const WDL_String *str, int maxlen=0);
50 void Append(const char *str, int maxlen=0);
51 void Append(const WDL_String *str, int maxlen=0);
52 void DeleteSub(int position, int len);
53 void Insert(const char *str, int position, int maxlen=0);
54 void Insert(const WDL_String *str, int position, int maxlen=0);
55 #ifdef WDL_STRING_FASTSUB_DEFINED
56 bool SetLen(int length, bool resizeDown=false, char fillchar=' '); // returns true on success
57 #else
58 bool SetLen(int length, bool resizeDown=false); // returns true on success
59 #endif
60 void Ellipsize(int minlen, int maxlen);
61 const char *get_filepart() const; // returns whole string if no dir chars
62 const char *get_fileext() const; // returns ".ext" or end of string "" if no extension
63 bool remove_fileext(); // returns true if extension was removed
64 char remove_filepart(bool keepTrailingSlash=false); // returns dir character used, or zero if string emptied
65 int remove_trailing_dirchars(); // returns trailing dirchar count removed, will not convert "/" into ""
66
67 void SetAppendFormattedArgs(bool append, int maxlen, const char* fmt, va_list arglist);
68 void WDL_VARARG_WARN(printf,3,4) SetFormatted(int maxlen, const char *fmt, ...);
69 void WDL_VARARG_WARN(printf,3,4) AppendFormatted(int maxlen, const char *fmt, ...);
70 #endif
71
72 const char *Get() const { return m_hb.GetSize()?(char*)m_hb.Get():""; }
73
74 #ifdef WDL_STRING_FASTSUB_DEFINED
75 int GetLength() const { int a = m_hb.GetSize(); return a>0?a-1:0; }
76
77 // for binary-safe manipulations
78 void SetRaw(const char *str, int len) { __doSet(0,str,len,0); }
79 void AppendRaw(const char *str, int len) { __doSet(GetLength(),str,len,0); }
80 void InsertRaw(const char *str, int position, int ilen)
81 {
82 const int srclen = GetLength();
83 if (position<0) position=0;
84 else if (position>srclen) position=srclen;
85 if (ilen>0) __doSet(position,str,ilen,srclen-position);
86 }
87
88 #else
89 char *Get()
90 {
91 if (m_hb.GetSize()) return (char *)m_hb.Get();
92 static char c; c=0; return &c; // don't return "", in case it gets written to.
93 }
94 int GetLength() const { return m_hb.GetSize()?(int)strlen((const char*)m_hb.Get()):0; }
95 #endif
96
97 explicit WDL_String(int hbgran) : m_hb(hbgran WDL_HEAPBUF_TRACEPARM("WDL_String(4)")) { }
98 explicit WDL_String(const char *initial=NULL, int initial_len=0) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String"))
99 {
100 if (initial) Set(initial,initial_len);
101 }
102 WDL_String(const WDL_String &s) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String(2)")) { Set(&s); }
103 WDL_String(const WDL_String *s) : m_hb(128 WDL_HEAPBUF_TRACEPARM("WDL_String(3)")) { if (s && s != this) Set(s); }
105#endif // ! WDL_STRING_IMPL_ONLY
106
107#ifndef WDL_STRING_INTF_ONLY
108 #ifdef WDL_STRING_IMPL_ONLY
109 #define WDL_STRING_FUNCPREFIX WDL_String::
110 #define WDL_STRING_DEFPARM(x)
111 #else
112 #define WDL_STRING_FUNCPREFIX
113 #define WDL_STRING_DEFPARM(x) =(x)
114 #endif
115
116 void WDL_STRING_FUNCPREFIX Set(const char *str, int maxlen WDL_STRING_DEFPARM(0))
117 {
118 int s=0;
119 if (str)
120 {
121 if (maxlen>0) while (s < maxlen && str[s]) s++;
122 else s=(int)strlen(str);
123 }
124 __doSet(0,str,s,0);
125 }
126
128 {
129 #ifdef WDL_STRING_FASTSUB_DEFINED
130 int s = str ? str->GetLength() : 0;
131 if (maxlen>0 && maxlen<s) s=maxlen;
132
133 __doSet(0,str?str->Get():NULL,s,0);
134 #else
135 Set(str?str->Get():NULL, maxlen); // might be faster: "partial" strlen
136 #endif
137 }
138
139 void WDL_STRING_FUNCPREFIX Append(const char *str, int maxlen WDL_STRING_DEFPARM(0))
140 {
141 int s=0;
142 if (str)
143 {
144 if (maxlen>0) while (s < maxlen && str[s]) s++;
145 else s=(int)strlen(str);
146 }
147
148 __doSet(GetLength(),str,s,0);
149 }
150
152 {
153 #ifdef WDL_STRING_FASTSUB_DEFINED
154 int s = str ? str->GetLength() : 0;
155 if (maxlen>0 && maxlen<s) s=maxlen;
156
157 __doSet(GetLength(),str?str->Get():NULL,s,0);
158 #else
159 Append(str?str->Get():NULL, maxlen); // might be faster: "partial" strlen
160 #endif
161 }
162
163 void WDL_STRING_FUNCPREFIX DeleteSub(int position, int len)
164 {
165 int l=m_hb.GetSize()-1;
166 char *p=(char *)m_hb.Get();
167 if (l<0 || !*p || position < 0 || position >= l) return;
168 if (position+len > l) len=l-position;
169 if (len>0)
170 {
171 memmove(p+position,p+position+len,l-position-len+1);
172 m_hb.Resize(l+1-len,false);
173 }
174 }
175
176 void WDL_STRING_FUNCPREFIX Insert(const char *str, int position, int maxlen WDL_STRING_DEFPARM(0))
177 {
178 int ilen=0;
179 if (str)
180 {
181 if (maxlen>0) while (ilen < maxlen && str[ilen]) ilen++;
182 else ilen=(int)strlen(str);
183 }
184
185 const int srclen = GetLength();
186 if (position<0) position=0;
187 else if (position>srclen) position=srclen;
188 if (ilen>0) __doSet(position,str,ilen,srclen-position);
189 }
190
191 void WDL_STRING_FUNCPREFIX Insert(const WDL_String *str, int position, int maxlen WDL_STRING_DEFPARM(0))
192 {
193 #ifdef WDL_STRING_FASTSUB_DEFINED
194 int ilen = str ? str->GetLength() : 0;
195 if (maxlen>0 && maxlen<ilen) ilen=maxlen;
196
197 const int srclen = m_hb.GetSize()>0 ? m_hb.GetSize()-1 : 0;
198 if (position<0) position=0;
199 else if (position>srclen) position=srclen;
200 if (ilen>0) __doSet(position,str->Get(),ilen,srclen-position);
201 #else
202 Insert(str?str->Get():NULL, position, maxlen); // might be faster: "partial" strlen
203 #endif
204 }
205
206 bool WDL_STRING_FUNCPREFIX SetLen(int length, bool resizeDown WDL_STRING_DEFPARM(false)
208 , char fillchar WDL_STRING_DEFPARM(' ')
209 #endif
210 )
211 {
212 #ifdef WDL_STRING_FASTSUB_DEFINED
213 int osz = m_hb.GetSize()-1;
214 if (osz<0)osz=0;
215 #endif
216 if (length < 0) length=0;
217 char *b=(char*)m_hb.ResizeOK(length+1,resizeDown);
218 if (b)
219 {
220 #ifdef WDL_STRING_FASTSUB_DEFINED
221 const int fill = length-osz;
222 if (fill > 0) memset(b+osz,fillchar,fill);
223 #endif
224 b[length]=0;
225 return true;
226 }
227 return false;
228 }
229
230 void WDL_STRING_FUNCPREFIX SetAppendFormattedArgs(bool append, int maxlen, const char* fmt, va_list arglist)
231 {
232 int offs = append ? GetLength() : 0;
233 char *b= (char*) m_hb.ResizeOK(offs+maxlen+1,false);
234
235 if (!b) return;
236
237 b+=offs;
238
239 #ifdef _WIN32
240 int written = _vsnprintf(b, maxlen+1, fmt, arglist);
241 if (written < 0 || written>=maxlen) b[written=b[0]?maxlen:0]=0;
242 #else
243 int written = vsnprintf(b, maxlen+1, fmt, arglist);
244 if (written > maxlen) written=maxlen;
245 #endif
246
247 m_hb.Resize(offs + written + 1,false);
248 }
249
250 void WDL_VARARG_WARN(printf,3,4) WDL_STRING_FUNCPREFIX SetFormatted(int maxlen, const char *fmt, ...)
251 {
252 va_list arglist;
253 va_start(arglist, fmt);
254 SetAppendFormattedArgs(false,maxlen,fmt,arglist);
255 va_end(arglist);
256 }
257
258 void WDL_VARARG_WARN(printf,3,4) WDL_STRING_FUNCPREFIX AppendFormatted(int maxlen, const char *fmt, ...)
259 {
260 va_list arglist;
261 va_start(arglist, fmt);
262 SetAppendFormattedArgs(true,maxlen,fmt,arglist);
263 va_end(arglist);
264 }
265
266 void WDL_STRING_FUNCPREFIX Ellipsize(int minlen, int maxlen)
267 {
268 if (maxlen >= 4 && m_hb.GetSize() && GetLength() > maxlen)
269 {
270 if (minlen<0) minlen=0;
271 char *b = (char *)m_hb.Get();
272 int i;
273 for (i = maxlen-4; i >= minlen; --i)
274 {
275 if (b[i] == ' ')
276 {
277 memcpy(b+i, "...",4);
278 m_hb.Resize(i+4,false);
279 break;
280 }
281 }
283 {
284 memcpy(b+maxlen-4, "...",4);
285 m_hb.Resize(maxlen,false);
286 }
287 }
288 }
289 const char * WDL_STRING_FUNCPREFIX get_filepart() const // returns whole string if no dir chars
290 {
291 const char *s = Get();
292 const char *p = s + GetLength() - 1;
293 while (p >= s && !WDL_IS_DIRCHAR(*p)) --p;
294 return p + 1;
295 }
296 const char * WDL_STRING_FUNCPREFIX get_fileext() const // returns ".ext" or end of string "" if no extension
297 {
298 const char *s = Get();
299 const char *endp = s + GetLength();
300 const char *p = endp - 1;
301 while (p >= s && !WDL_IS_DIRCHAR(*p))
302 {
303 if (*p == '.') return p;
304 --p;
305 }
306 return endp;
307 }
308 bool WDL_STRING_FUNCPREFIX remove_fileext() // returns true if extension was removed
309 {
310 const char *str = Get();
311 int pos = GetLength() - 1;
312 while (pos >= 0)
313 {
314 char c = str[pos];
315 if (WDL_IS_DIRCHAR(c)) break;
316 if (c == '.')
317 {
318 SetLen(pos);
319 return true;
320 }
321 --pos;
322 }
323 return false;
324 }
325
326 char WDL_STRING_FUNCPREFIX remove_filepart(bool keepTrailingSlash WDL_STRING_DEFPARM(false)) // returns directory character used, or 0 if string emptied
327 {
328 char rv=0;
329 const char *str = Get();
330 int pos = GetLength() - 1;
331 while (pos > 0)
332 {
333 char c = str[pos];
334 if (WDL_IS_DIRCHAR(c))
335 {
336 rv=c;
337 if (keepTrailingSlash) ++pos;
338 break;
339 }
340 --pos;
341 }
342 SetLen(pos);
343 return rv;
344 }
345
346 int WDL_STRING_FUNCPREFIX remove_trailing_dirchars() // returns trailing dirchar count removed
347 {
348 int cnt = 0;
349 const char *str = Get();
350 const int l = GetLength()-1;
351 while (cnt < l)
352 {
353 char c = str[l - cnt];
354 if (!WDL_IS_DIRCHAR(c)) break;
355 ++cnt;
356 }
357 if (cnt > 0) SetLen(l + 1 - cnt);
358 return cnt;
359 }
360#ifndef WDL_STRING_IMPL_ONLY
361 private:
362#endif
363 void WDL_STRING_FUNCPREFIX __doSet(int offs, const char *str, int len, int trailkeep)
364 {
365 // if non-empty, or (empty and allocated and Set() rather than append/insert), then allow update, otherwise do nothing
366 if (len==0 && !trailkeep && !offs)
367 {
368 #ifdef WDL_STRING_FREE_ON_CLEAR
369 m_hb.Resize(0,true);
370 #else
371 char *p = (char *)m_hb.Resize(1,false);
372 if (p) *p=0;
373 #endif
374 }
375 else if (len>0 && offs >= 0)
376 {
377 const int oldsz = m_hb.GetSize();
378 const int newsz=offs+len+trailkeep+1;
379 const int growamt = newsz-oldsz;
380 if (growamt > 0)
381 {
382 const char *oldb = (const char *)m_hb.Get();
383 const char *newb = (const char *)m_hb.Resize(newsz,false); // resize up if necessary
384
385 // in case str overlaps with input, keep it valid
386 if (str && newb != oldb && str >= oldb && str < oldb+oldsz) str = newb + (str - oldb);
387 }
388
389 if (m_hb.GetSize() >= newsz)
390 {
391 char *newbuf = (char *)m_hb.Get();
392 if (trailkeep>0) memmove(newbuf+offs+len,newbuf+offs,trailkeep);
393 if (str) memmove(newbuf+offs,str,len);
394 newbuf[newsz-1]=0;
395
396 // resize down if necessary
397 if (growamt < 0) m_hb.Resize(newsz,false);
398 }
399 }
400 }
401
402 #undef WDL_STRING_FUNCPREFIX
403 #undef WDL_STRING_DEFPARM
404#endif // ! WDL_STRING_INTF_ONLY
405
406#ifndef WDL_STRING_IMPL_ONLY
407
408 private:
409 #ifdef WDL_STRING_INTF_ONLY
410 void __doSet(int offs, const char *str, int len, int trailkeep);
411 #endif
412
414};
415#endif
416
417#ifndef WDL_STRING_FASTSUB_DEFINED
418#undef _WDL_STRING_H_
419#define WDL_STRING_FASTSUB_DEFINED
420#define WDL_String WDL_FastString
421#include "wdlstring.h"
422#undef WDL_STRING_FASTSUB_DEFINED
423#undef WDL_String
424#endif
425
426#endif
427
#define NULL
Definition CarlaBridgeFormat.cpp:30
uint8_t a
Definition Spc_Cpu.h:141
Definition heapbuf.h:48
int GetSize() const
Definition heapbuf.h:57
const char * Get() const
Definition wdlstring.h:72
bool WDL_STRING_FUNCPREFIX remove_fileext()
Definition wdlstring.h:308
WDL_HeapBuf m_hb
Definition wdlstring.h:413
void WDL_STRING_FUNCPREFIX Set(const char *str, int maxlen WDL_STRING_DEFPARM(0))
Definition wdlstring.h:116
int WDL_STRING_FUNCPREFIX remove_trailing_dirchars()
Definition wdlstring.h:346
void WDL_STRING_FUNCPREFIX SetAppendFormattedArgs(bool append, int maxlen, const char *fmt, va_list arglist)
Definition wdlstring.h:230
void WDL_STRING_FUNCPREFIX Append(const WDL_String *str, int maxlen WDL_STRING_DEFPARM(0))
Definition wdlstring.h:151
void WDL_STRING_FUNCPREFIX Set(const WDL_String *str, int maxlen WDL_STRING_DEFPARM(0))
Definition wdlstring.h:127
SetAppendFormattedArgs(true, maxlen, fmt, arglist)
void WDL_STRING_FUNCPREFIX Insert(const WDL_String *str, int position, int maxlen WDL_STRING_DEFPARM(0))
Definition wdlstring.h:191
WDL_String(int hbgran)
Definition wdlstring.h:97
const char *WDL_STRING_FUNCPREFIX get_filepart() const
Definition wdlstring.h:289
void const char * fmt
Definition wdlstring.h:250
WDL_String(const WDL_String *s)
Definition wdlstring.h:103
void WDL_STRING_FUNCPREFIX Ellipsize(int minlen, int maxlen)
Definition wdlstring.h:266
char WDL_STRING_FUNCPREFIX remove_filepart(bool keepTrailingSlash WDL_STRING_DEFPARM(false))
Definition wdlstring.h:326
SetAppendFormattedArgs(false, maxlen, fmt, arglist)
const char *WDL_STRING_FUNCPREFIX get_fileext() const
Definition wdlstring.h:296
WDL_String(const char *initial=NULL, int initial_len=0)
Definition wdlstring.h:98
WDL_String(const WDL_String &s)
Definition wdlstring.h:102
bool WDL_STRING_FUNCPREFIX SetLen(int length, bool resizeDown WDL_STRING_DEFPARM(false))
Definition wdlstring.h:206
~WDL_String()
Definition wdlstring.h:104
char * Get()
Definition wdlstring.h:89
int GetLength() const
Definition wdlstring.h:94
void const char va_start(arglist, fmt)
void WDL_STRING_FUNCPREFIX Insert(const char *str, int position, int maxlen WDL_STRING_DEFPARM(0))
Definition wdlstring.h:176
void WDL_VARARG_WARN(printf, 3, 4) WDL_STRING_FUNCPREFIX AppendFormatted(int maxlen
void WDL_STRING_FUNCPREFIX Append(const char *str, int maxlen WDL_STRING_DEFPARM(0))
Definition wdlstring.h:139
va_end(arglist)
void WDL_STRING_FUNCPREFIX DeleteSub(int position, int len)
Definition wdlstring.h:163
void WDL_STRING_FUNCPREFIX __doSet(int offs, const char *str, int len, int trailkeep)
Definition wdlstring.h:363
int * l
Definition inflate.c:1579
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
#define WDL_HEAPBUF_TRACEPARM(x)
Definition heapbuf.h:42
QPoint position(const QDropEvent *de)
position is a backwards-compatible adapter for QDropEvent::position and pos functions.
Definition DeprecationHelper.h:47
png_uint_32 length
Definition png.c:2247
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
memcpy(hh, h, RAND_HEAD_LEN)
b
Definition crypt.c:628
typedef int(UZ_EXP MsgFn)()
#define WDL_STRING_DEFPARM(x)
Definition wdlstring.h:113
#define WDL_STRING_FASTSUB_DEFINED
Definition wdlstring.h:419
#define WDL_STRING_FUNCPREFIX
Definition wdlstring.h:112
#define WDL_VARARG_WARN(x, n, s)
Definition wdltypes.h:86
#define WDL_IS_DIRCHAR(x)
Definition wdltypes.h:129
#define const
Definition zconf.h:137