Coverage Report

Created: 2025-07-12 06:31

/src/tinysparql/subprojects/glib-2.80.3/glib/gstring.c
Line
Count
Source (jump to first uncovered line)
1
/* GLIB - Library of useful routines for C programming
2
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3
 *
4
 * SPDX-License-Identifier: LGPL-2.1-or-later
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
/*
21
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22
 * file for a list of people on the GLib Team.  See the ChangeLog
23
 * files for a list of changes.  These files are distributed with
24
 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25
 */
26
27
/*
28
 * MT safe
29
 */
30
31
#include "config.h"
32
33
#include <stdarg.h>
34
#include <stdlib.h>
35
#include <stdio.h>
36
#include <string.h>
37
#include <ctype.h>
38
39
#include "gstring.h"
40
#include "guriprivate.h"
41
#include "gprintf.h"
42
#include "gutilsprivate.h"
43
44
45
/**
46
 * GString:
47
 * @str: points to the character data. It may move as text is added.
48
 *   The @str field is null-terminated and so
49
 *   can be used as an ordinary C string.
50
 * @len: contains the length of the string, not including the
51
 *   terminating nul byte.
52
 * @allocated_len: the number of bytes that can be stored in the
53
 *   string before it needs to be reallocated. May be larger than @len.
54
 *
55
 * A `GString` is an object that handles the memory management of a C string.
56
 *
57
 * The emphasis of `GString` is on text, typically UTF-8. Crucially, the "str" member
58
 * of a `GString` is guaranteed to have a trailing nul character, and it is therefore
59
 * always safe to call functions such as `strchr()` or `strdup()` on it.
60
 *
61
 * However, a `GString` can also hold arbitrary binary data, because it has a "len" member,
62
 * which includes any possible embedded nul characters in the data. Conceptually then,
63
 * `GString` is like a `GByteArray` with the addition of many convenience methods for
64
 * text, and a guaranteed nul terminator.
65
 */
66
67
static void
68
g_string_expand (GString *string,
69
                 gsize    len)
70
3.70M
{
71
  /* Detect potential overflow */
72
3.70M
  if G_UNLIKELY ((G_MAXSIZE - string->len - 1) < len)
73
3.70M
    g_error ("adding %" G_GSIZE_FORMAT " to string would overflow", len);
74
75
3.70M
  string->allocated_len = g_nearest_pow (string->len + len + 1);
76
  /* If the new size is bigger than G_MAXSIZE / 2, only allocate enough
77
   * memory for this string and don't over-allocate.
78
   */
79
3.70M
  if (string->allocated_len == 0)
80
0
    string->allocated_len = string->len + len + 1;
81
82
3.70M
  string->str = g_realloc (string->str, string->allocated_len);
83
3.70M
}
84
85
static inline void
86
g_string_maybe_expand (GString *string,
87
                       gsize    len)
88
1.91M
{
89
1.91M
  if (G_UNLIKELY (string->len + len >= string->allocated_len))
90
378k
    g_string_expand (string, len);
91
1.91M
}
92
93
/**
94
 * g_string_sized_new: (constructor)
95
 * @dfl_size: the default size of the space allocated to hold the string
96
 *
97
 * Creates a new #GString, with enough space for @dfl_size
98
 * bytes. This is useful if you are going to add a lot of
99
 * text to the string and don't want it to be reallocated
100
 * too often.
101
 *
102
 * Returns: (transfer full): the new #GString
103
 */
104
GString *
105
g_string_sized_new (gsize dfl_size)
106
3.32M
{
107
3.32M
  GString *string = g_slice_new (GString);
108
109
3.32M
  string->allocated_len = 0;
110
3.32M
  string->len   = 0;
111
3.32M
  string->str   = NULL;
112
113
3.32M
  g_string_expand (string, MAX (dfl_size, 64));
114
3.32M
  string->str[0] = 0;
115
116
3.32M
  return string;
117
3.32M
}
118
119
/**
120
 * g_string_new: (constructor)
121
 * @init: (nullable): the initial text to copy into the string, or %NULL to
122
 *   start with an empty string
123
 *
124
 * Creates a new #GString, initialized with the given string.
125
 *
126
 * Returns: (transfer full): the new #GString
127
 */
128
GString *
129
g_string_new (const gchar *init)
130
2.90M
{
131
2.90M
  GString *string;
132
133
2.90M
  if (init == NULL || *init == '\0')
134
2.79M
    string = g_string_sized_new (2);
135
101k
  else
136
101k
    {
137
101k
      gint len;
138
139
101k
      len = strlen (init);
140
101k
      string = g_string_sized_new (len + 2);
141
142
101k
      g_string_append_len (string, init, len);
143
101k
    }
144
145
2.90M
  return string;
146
2.90M
}
147
148
/**
149
 * g_string_new_take: (constructor)
150
 * @init: (nullable) (transfer full): initial text used as the string.
151
 *     Ownership of the string is transferred to the #GString.
152
 *     Passing %NULL creates an empty string.
153
 *
154
 * Creates a new #GString, initialized with the given string.
155
 *
156
 * After this call, @init belongs to the #GString and may no longer be
157
 * modified by the caller. The memory of @data has to be dynamically
158
 * allocated and will eventually be freed with g_free().
159
 *
160
 * Returns: (transfer full): the new #GString
161
 *
162
 * Since: 2.78
163
 */
164
GString *
165
g_string_new_take (gchar *init)
166
0
{
167
0
  GString *string;
168
169
0
  if (init == NULL)
170
0
    {
171
0
      return g_string_new (NULL);
172
0
    }
173
174
0
  string = g_slice_new (GString);
175
176
0
  string->str = init;
177
0
  string->len = strlen (string->str);
178
0
  string->allocated_len = string->len + 1;
179
180
0
  return string;
181
0
}
182
183
/**
184
 * g_string_new_len: (constructor)
185
 * @init: initial contents of the string
186
 * @len: length of @init to use
187
 *
188
 * Creates a new #GString with @len bytes of the @init buffer.
189
 * Because a length is provided, @init need not be nul-terminated,
190
 * and can contain embedded nul bytes.
191
 *
192
 * Since this function does not stop at nul bytes, it is the caller's
193
 * responsibility to ensure that @init has at least @len addressable
194
 * bytes.
195
 *
196
 * Returns: (transfer full): a new #GString
197
 */
198
GString *
199
g_string_new_len (const gchar *init,
200
                  gssize       len)
201
0
{
202
0
  GString *string;
203
204
0
  if (len < 0)
205
0
    return g_string_new (init);
206
0
  else
207
0
    {
208
0
      string = g_string_sized_new (len);
209
210
0
      if (init)
211
0
        g_string_append_len (string, init, len);
212
213
0
      return string;
214
0
    }
215
0
}
216
217
/**
218
 * g_string_free:
219
 * @string: (transfer full): a #GString
220
 * @free_segment: if %TRUE, the actual character data is freed as well
221
 *
222
 * Frees the memory allocated for the #GString.
223
 * If @free_segment is %TRUE it also frees the character data.  If
224
 * it's %FALSE, the caller gains ownership of the buffer and must
225
 * free it after use with g_free().
226
 *
227
 * Instead of passing %FALSE to this function, consider using
228
 * g_string_free_and_steal().
229
 *
230
 * Returns: (nullable): the character data of @string
231
 *          (i.e. %NULL if @free_segment is %TRUE)
232
 */
233
gchar *
234
(g_string_free) (GString  *string,
235
                 gboolean  free_segment)
236
3.32M
{
237
3.32M
  gchar *segment;
238
239
3.32M
  g_return_val_if_fail (string != NULL, NULL);
240
241
3.32M
  if (free_segment)
242
674k
    {
243
674k
      g_free (string->str);
244
674k
      segment = NULL;
245
674k
    }
246
2.64M
  else
247
2.64M
    segment = string->str;
248
249
3.32M
  g_slice_free (GString, string);
250
251
3.32M
  return segment;
252
3.32M
}
253
254
/**
255
 * g_string_free_and_steal:
256
 * @string: (transfer full): a #GString
257
 *
258
 * Frees the memory allocated for the #GString.
259
 *
260
 * The caller gains ownership of the buffer and
261
 * must free it after use with g_free().
262
 *
263
 * Returns: (transfer full): the character data of @string
264
 *
265
 * Since: 2.76
266
 */
267
gchar *
268
g_string_free_and_steal (GString *string)
269
2.64M
{
270
2.64M
  return (g_string_free) (string, FALSE);
271
2.64M
}
272
273
/**
274
 * g_string_free_to_bytes:
275
 * @string: (transfer full): a #GString
276
 *
277
 * Transfers ownership of the contents of @string to a newly allocated
278
 * #GBytes.  The #GString structure itself is deallocated, and it is
279
 * therefore invalid to use @string after invoking this function.
280
 *
281
 * Note that while #GString ensures that its buffer always has a
282
 * trailing nul character (not reflected in its "len"), the returned
283
 * #GBytes does not include this extra nul; i.e. it has length exactly
284
 * equal to the "len" member.
285
 *
286
 * Returns: (transfer full): A newly allocated #GBytes containing contents of @string; @string itself is freed
287
 * Since: 2.34
288
 */
289
GBytes*
290
g_string_free_to_bytes (GString *string)
291
0
{
292
0
  gsize len;
293
0
  gchar *buf;
294
295
0
  g_return_val_if_fail (string != NULL, NULL);
296
297
0
  len = string->len;
298
299
0
  buf = g_string_free (string, FALSE);
300
301
0
  return g_bytes_new_take (buf, len);
302
0
}
303
304
/**
305
 * g_string_equal:
306
 * @v: a #GString
307
 * @v2: another #GString
308
 *
309
 * Compares two strings for equality, returning %TRUE if they are equal.
310
 * For use with #GHashTable.
311
 *
312
 * Returns: %TRUE if the strings are the same length and contain the
313
 *     same bytes
314
 */
315
gboolean
316
g_string_equal (const GString *v,
317
                const GString *v2)
318
0
{
319
0
  gchar *p, *q;
320
0
  GString *string1 = (GString *) v;
321
0
  GString *string2 = (GString *) v2;
322
0
  gsize i = string1->len;
323
324
0
  if (i != string2->len)
325
0
    return FALSE;
326
327
0
  p = string1->str;
328
0
  q = string2->str;
329
0
  while (i)
330
0
    {
331
0
      if (*p != *q)
332
0
        return FALSE;
333
0
      p++;
334
0
      q++;
335
0
      i--;
336
0
    }
337
0
  return TRUE;
338
0
}
339
340
/**
341
 * g_string_hash:
342
 * @str: a string to hash
343
 *
344
 * Creates a hash code for @str; for use with #GHashTable.
345
 *
346
 * Returns: hash code for @str
347
 */
348
guint
349
g_string_hash (const GString *str)
350
0
{
351
0
  const gchar *p = str->str;
352
0
  gsize n = str->len;
353
0
  guint h = 0;
354
355
  /* 31 bit hash function */
356
0
  while (n--)
357
0
    {
358
0
      h = (h << 5) - h + *p;
359
0
      p++;
360
0
    }
361
362
0
  return h;
363
0
}
364
365
/**
366
 * g_string_assign:
367
 * @string: the destination #GString. Its current contents
368
 *          are destroyed.
369
 * @rval: the string to copy into @string
370
 *
371
 * Copies the bytes from a string into a #GString,
372
 * destroying any previous contents. It is rather like
373
 * the standard strcpy() function, except that you do not
374
 * have to worry about having enough space to copy the string.
375
 *
376
 * Returns: (transfer none): @string
377
 */
378
GString *
379
g_string_assign (GString     *string,
380
                 const gchar *rval)
381
0
{
382
0
  g_return_val_if_fail (string != NULL, NULL);
383
0
  g_return_val_if_fail (rval != NULL, string);
384
385
  /* Make sure assigning to itself doesn't corrupt the string. */
386
0
  if (string->str != rval)
387
0
    {
388
      /* Assigning from substring should be ok, since
389
       * g_string_truncate() does not reallocate.
390
       */
391
0
      g_string_truncate (string, 0);
392
0
      g_string_append (string, rval);
393
0
    }
394
395
0
  return string;
396
0
}
397
398
/**
399
 * g_string_truncate:
400
 * @string: a #GString
401
 * @len: the new size of @string
402
 *
403
 * Cuts off the end of the GString, leaving the first @len bytes.
404
 *
405
 * Returns: (transfer none): @string
406
 */
407
GString *
408
(g_string_truncate) (GString *string,
409
                     gsize    len)
410
0
{
411
0
  g_return_val_if_fail (string != NULL, NULL);
412
413
0
  string->len = MIN (len, string->len);
414
0
  string->str[string->len] = 0;
415
416
0
  return string;
417
0
}
418
419
/**
420
 * g_string_set_size:
421
 * @string: a #GString
422
 * @len: the new length
423
 *
424
 * Sets the length of a #GString. If the length is less than
425
 * the current length, the string will be truncated. If the
426
 * length is greater than the current length, the contents
427
 * of the newly added area are undefined. (However, as
428
 * always, string->str[string->len] will be a nul byte.)
429
 *
430
 * Returns: (transfer none): @string
431
 */
432
GString *
433
g_string_set_size (GString *string,
434
                   gsize    len)
435
0
{
436
0
  g_return_val_if_fail (string != NULL, NULL);
437
438
0
  if (len >= string->allocated_len)
439
0
    g_string_maybe_expand (string, len - string->len);
440
441
0
  string->len = len;
442
0
  string->str[len] = 0;
443
444
0
  return string;
445
0
}
446
447
/**
448
 * g_string_insert_len:
449
 * @string: a #GString
450
 * @pos: position in @string where insertion should
451
 *       happen, or -1 for at the end
452
 * @val: bytes to insert
453
 * @len: number of bytes of @val to insert, or -1 for all of @val
454
 *
455
 * Inserts @len bytes of @val into @string at @pos.
456
 *
457
 * If @len is positive, @val may contain embedded nuls and need
458
 * not be nul-terminated. It is the caller's responsibility to
459
 * ensure that @val has at least @len addressable bytes.
460
 *
461
 * If @len is negative, @val must be nul-terminated and @len
462
 * is considered to request the entire string length.
463
 *
464
 * If @pos is -1, bytes are inserted at the end of the string.
465
 *
466
 * Returns: (transfer none): @string
467
 */
468
GString *
469
g_string_insert_len (GString     *string,
470
                     gssize       pos,
471
                     const gchar *val,
472
                     gssize       len)
473
20.0k
{
474
20.0k
  gsize len_unsigned, pos_unsigned;
475
476
20.0k
  g_return_val_if_fail (string != NULL, NULL);
477
20.0k
  g_return_val_if_fail (len == 0 || val != NULL, string);
478
479
20.0k
  if (len == 0)
480
0
    return string;
481
482
20.0k
  if (len < 0)
483
0
    len = strlen (val);
484
20.0k
  len_unsigned = len;
485
486
20.0k
  if (pos < 0)
487
20.0k
    pos_unsigned = string->len;
488
0
  else
489
0
    {
490
0
      pos_unsigned = pos;
491
0
      g_return_val_if_fail (pos_unsigned <= string->len, string);
492
0
    }
493
494
  /* Check whether val represents a substring of string.
495
   * This test probably violates chapter and verse of the C standards,
496
   * since ">=" and "<=" are only valid when val really is a substring.
497
   * In practice, it will work on modern archs.
498
   */
499
20.0k
  if (G_UNLIKELY (val >= string->str && val <= string->str + string->len))
500
0
    {
501
0
      gsize offset = val - string->str;
502
0
      gsize precount = 0;
503
504
0
      g_string_maybe_expand (string, len_unsigned);
505
0
      val = string->str + offset;
506
      /* At this point, val is valid again.  */
507
508
      /* Open up space where we are going to insert.  */
509
0
      if (pos_unsigned < string->len)
510
0
        memmove (string->str + pos_unsigned + len_unsigned,
511
0
                 string->str + pos_unsigned, string->len - pos_unsigned);
512
513
      /* Move the source part before the gap, if any.  */
514
0
      if (offset < pos_unsigned)
515
0
        {
516
0
          precount = MIN (len_unsigned, pos_unsigned - offset);
517
0
          memcpy (string->str + pos_unsigned, val, precount);
518
0
        }
519
520
      /* Move the source part after the gap, if any.  */
521
0
      if (len_unsigned > precount)
522
0
        memcpy (string->str + pos_unsigned + precount,
523
0
                val + /* Already moved: */ precount +
524
0
                      /* Space opened up: */ len_unsigned,
525
0
                len_unsigned - precount);
526
0
    }
527
20.0k
  else
528
20.0k
    {
529
20.0k
      g_string_maybe_expand (string, len_unsigned);
530
531
      /* If we aren't appending at the end, move a hunk
532
       * of the old string to the end, opening up space
533
       */
534
20.0k
      if (pos_unsigned < string->len)
535
0
        memmove (string->str + pos_unsigned + len_unsigned,
536
0
                 string->str + pos_unsigned, string->len - pos_unsigned);
537
538
      /* insert the new string */
539
20.0k
      if (len_unsigned == 1)
540
398
        string->str[pos_unsigned] = *val;
541
19.6k
      else
542
19.6k
        memcpy (string->str + pos_unsigned, val, len_unsigned);
543
20.0k
    }
544
545
20.0k
  string->len += len_unsigned;
546
547
20.0k
  string->str[string->len] = 0;
548
549
20.0k
  return string;
550
20.0k
}
551
552
/**
553
 * g_string_append_uri_escaped:
554
 * @string: a #GString
555
 * @unescaped: a string
556
 * @reserved_chars_allowed: a string of reserved characters allowed
557
 *     to be used, or %NULL
558
 * @allow_utf8: set %TRUE if the escaped string may include UTF8 characters
559
 *
560
 * Appends @unescaped to @string, escaping any characters that
561
 * are reserved in URIs using URI-style escape sequences.
562
 *
563
 * Returns: (transfer none): @string
564
 *
565
 * Since: 2.16
566
 */
567
GString *
568
g_string_append_uri_escaped (GString     *string,
569
                             const gchar *unescaped,
570
                             const gchar *reserved_chars_allowed,
571
                             gboolean     allow_utf8)
572
393k
{
573
393k
  _uri_encoder (string, (const guchar *) unescaped, strlen (unescaped),
574
393k
                reserved_chars_allowed, allow_utf8);
575
393k
  return string;
576
393k
}
577
578
/**
579
 * g_string_append:
580
 * @string: a #GString
581
 * @val: the string to append onto the end of @string
582
 *
583
 * Adds a string onto the end of a #GString, expanding
584
 * it if necessary.
585
 *
586
 * Returns: (transfer none): @string
587
 */
588
GString *
589
(g_string_append) (GString     *string,
590
                   const gchar *val)
591
0
{
592
0
  return g_string_insert_len (string, -1, val, -1);
593
0
}
594
595
/**
596
 * g_string_append_len:
597
 * @string: a #GString
598
 * @val: bytes to append
599
 * @len: number of bytes of @val to use, or -1 for all of @val
600
 *
601
 * Appends @len bytes of @val to @string.
602
 *
603
 * If @len is positive, @val may contain embedded nuls and need
604
 * not be nul-terminated. It is the caller's responsibility to
605
 * ensure that @val has at least @len addressable bytes.
606
 *
607
 * If @len is negative, @val must be nul-terminated and @len
608
 * is considered to request the entire string length. This
609
 * makes g_string_append_len() equivalent to g_string_append().
610
 *
611
 * Returns: (transfer none): @string
612
 */
613
GString *
614
(g_string_append_len) (GString     *string,
615
                       const gchar *val,
616
                       gssize       len)
617
0
{
618
0
  return g_string_insert_len (string, -1, val, len);
619
0
}
620
621
/**
622
 * g_string_append_c:
623
 * @string: a #GString
624
 * @c: the byte to append onto the end of @string
625
 *
626
 * Adds a byte onto the end of a #GString, expanding
627
 * it if necessary.
628
 *
629
 * Returns: (transfer none): @string
630
 */
631
GString *
632
(g_string_append_c) (GString *string,
633
                     gchar    c)
634
0
{
635
0
  g_return_val_if_fail (string != NULL, NULL);
636
637
0
  return g_string_insert_c (string, -1, c);
638
0
}
639
640
/**
641
 * g_string_append_unichar:
642
 * @string: a #GString
643
 * @wc: a Unicode character
644
 *
645
 * Converts a Unicode character into UTF-8, and appends it
646
 * to the string.
647
 *
648
 * Returns: (transfer none): @string
649
 */
650
GString *
651
g_string_append_unichar (GString  *string,
652
                         gunichar  wc)
653
172k
{
654
172k
  g_return_val_if_fail (string != NULL, NULL);
655
656
172k
  return g_string_insert_unichar (string, -1, wc);
657
172k
}
658
659
/**
660
 * g_string_prepend:
661
 * @string: a #GString
662
 * @val: the string to prepend on the start of @string
663
 *
664
 * Adds a string on to the start of a #GString,
665
 * expanding it if necessary.
666
 *
667
 * Returns: (transfer none): @string
668
 */
669
GString *
670
g_string_prepend (GString     *string,
671
                  const gchar *val)
672
0
{
673
0
  return g_string_insert_len (string, 0, val, -1);
674
0
}
675
676
/**
677
 * g_string_prepend_len:
678
 * @string: a #GString
679
 * @val: bytes to prepend
680
 * @len: number of bytes in @val to prepend, or -1 for all of @val
681
 *
682
 * Prepends @len bytes of @val to @string.
683
 *
684
 * If @len is positive, @val may contain embedded nuls and need
685
 * not be nul-terminated. It is the caller's responsibility to
686
 * ensure that @val has at least @len addressable bytes.
687
 *
688
 * If @len is negative, @val must be nul-terminated and @len
689
 * is considered to request the entire string length. This
690
 * makes g_string_prepend_len() equivalent to g_string_prepend().
691
 *
692
 * Returns: (transfer none): @string
693
 */
694
GString *
695
g_string_prepend_len (GString     *string,
696
                      const gchar *val,
697
                      gssize       len)
698
0
{
699
0
  return g_string_insert_len (string, 0, val, len);
700
0
}
701
702
/**
703
 * g_string_prepend_c:
704
 * @string: a #GString
705
 * @c: the byte to prepend on the start of the #GString
706
 *
707
 * Adds a byte onto the start of a #GString,
708
 * expanding it if necessary.
709
 *
710
 * Returns: (transfer none): @string
711
 */
712
GString *
713
g_string_prepend_c (GString *string,
714
                    gchar    c)
715
0
{
716
0
  g_return_val_if_fail (string != NULL, NULL);
717
718
0
  return g_string_insert_c (string, 0, c);
719
0
}
720
721
/**
722
 * g_string_prepend_unichar:
723
 * @string: a #GString
724
 * @wc: a Unicode character
725
 *
726
 * Converts a Unicode character into UTF-8, and prepends it
727
 * to the string.
728
 *
729
 * Returns: (transfer none): @string
730
 */
731
GString *
732
g_string_prepend_unichar (GString  *string,
733
                          gunichar  wc)
734
0
{
735
0
  g_return_val_if_fail (string != NULL, NULL);
736
737
0
  return g_string_insert_unichar (string, 0, wc);
738
0
}
739
740
/**
741
 * g_string_insert:
742
 * @string: a #GString
743
 * @pos: the position to insert the copy of the string
744
 * @val: the string to insert
745
 *
746
 * Inserts a copy of a string into a #GString,
747
 * expanding it if necessary.
748
 *
749
 * Returns: (transfer none): @string
750
 */
751
GString *
752
g_string_insert (GString     *string,
753
                 gssize       pos,
754
                 const gchar *val)
755
0
{
756
0
  return g_string_insert_len (string, pos, val, -1);
757
0
}
758
759
/**
760
 * g_string_insert_c:
761
 * @string: a #GString
762
 * @pos: the position to insert the byte
763
 * @c: the byte to insert
764
 *
765
 * Inserts a byte into a #GString, expanding it if necessary.
766
 *
767
 * Returns: (transfer none): @string
768
 */
769
GString *
770
g_string_insert_c (GString *string,
771
                   gssize   pos,
772
                   gchar    c)
773
172k
{
774
172k
  gsize pos_unsigned;
775
776
172k
  g_return_val_if_fail (string != NULL, NULL);
777
778
172k
  g_string_maybe_expand (string, 1);
779
780
172k
  if (pos < 0)
781
172k
    pos = string->len;
782
0
  else
783
172k
    g_return_val_if_fail ((gsize) pos <= string->len, string);
784
172k
  pos_unsigned = pos;
785
786
  /* If not just an append, move the old stuff */
787
172k
  if (pos_unsigned < string->len)
788
0
    memmove (string->str + pos_unsigned + 1,
789
0
             string->str + pos_unsigned, string->len - pos_unsigned);
790
791
172k
  string->str[pos_unsigned] = c;
792
793
172k
  string->len += 1;
794
795
172k
  string->str[string->len] = 0;
796
797
172k
  return string;
798
172k
}
799
800
/**
801
 * g_string_insert_unichar:
802
 * @string: a #GString
803
 * @pos: the position at which to insert character, or -1
804
 *     to append at the end of the string
805
 * @wc: a Unicode character
806
 *
807
 * Converts a Unicode character into UTF-8, and insert it
808
 * into the string at the given position.
809
 *
810
 * Returns: (transfer none): @string
811
 */
812
GString *
813
g_string_insert_unichar (GString  *string,
814
                         gssize    pos,
815
                         gunichar  wc)
816
172k
{
817
172k
  gint charlen, first, i;
818
172k
  gchar *dest;
819
820
172k
  g_return_val_if_fail (string != NULL, NULL);
821
822
  /* Code copied from g_unichar_to_utf() */
823
172k
  if (wc < 0x80)
824
42.2k
    {
825
42.2k
      first = 0;
826
42.2k
      charlen = 1;
827
42.2k
    }
828
129k
  else if (wc < 0x800)
829
25.1k
    {
830
25.1k
      first = 0xc0;
831
25.1k
      charlen = 2;
832
25.1k
    }
833
104k
  else if (wc < 0x10000)
834
28.4k
    {
835
28.4k
      first = 0xe0;
836
28.4k
      charlen = 3;
837
28.4k
    }
838
76.2k
   else if (wc < 0x200000)
839
840
    {
840
840
      first = 0xf0;
841
840
      charlen = 4;
842
840
    }
843
75.4k
  else if (wc < 0x4000000)
844
1.59k
    {
845
1.59k
      first = 0xf8;
846
1.59k
      charlen = 5;
847
1.59k
    }
848
73.8k
  else
849
73.8k
    {
850
73.8k
      first = 0xfc;
851
73.8k
      charlen = 6;
852
73.8k
    }
853
  /* End of copied code */
854
855
172k
  g_string_maybe_expand (string, charlen);
856
857
172k
  if (pos < 0)
858
172k
    pos = string->len;
859
0
  else
860
172k
    g_return_val_if_fail ((gsize) pos <= string->len, string);
861
862
  /* If not just an append, move the old stuff */
863
172k
  if ((gsize) pos < string->len)
864
0
    memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
865
866
172k
  dest = string->str + pos;
867
  /* Code copied from g_unichar_to_utf() */
868
632k
  for (i = charlen - 1; i > 0; --i)
869
460k
    {
870
460k
      dest[i] = (wc & 0x3f) | 0x80;
871
460k
      wc >>= 6;
872
460k
    }
873
172k
  dest[0] = wc | first;
874
  /* End of copied code */
875
876
172k
  string->len += charlen;
877
878
172k
  string->str[string->len] = 0;
879
880
172k
  return string;
881
172k
}
882
883
/**
884
 * g_string_overwrite:
885
 * @string: a #GString
886
 * @pos: the position at which to start overwriting
887
 * @val: the string that will overwrite the @string starting at @pos
888
 *
889
 * Overwrites part of a string, lengthening it if necessary.
890
 *
891
 * Returns: (transfer none): @string
892
 *
893
 * Since: 2.14
894
 */
895
GString *
896
g_string_overwrite (GString     *string,
897
                    gsize        pos,
898
                    const gchar *val)
899
0
{
900
0
  g_return_val_if_fail (val != NULL, string);
901
0
  return g_string_overwrite_len (string, pos, val, strlen (val));
902
0
}
903
904
/**
905
 * g_string_overwrite_len:
906
 * @string: a #GString
907
 * @pos: the position at which to start overwriting
908
 * @val: the string that will overwrite the @string starting at @pos
909
 * @len: the number of bytes to write from @val
910
 *
911
 * Overwrites part of a string, lengthening it if necessary.
912
 * This function will work with embedded nuls.
913
 *
914
 * Returns: (transfer none): @string
915
 *
916
 * Since: 2.14
917
 */
918
GString *
919
g_string_overwrite_len (GString     *string,
920
                        gsize        pos,
921
                        const gchar *val,
922
                        gssize       len)
923
0
{
924
0
  gsize end;
925
926
0
  g_return_val_if_fail (string != NULL, NULL);
927
928
0
  if (!len)
929
0
    return string;
930
931
0
  g_return_val_if_fail (val != NULL, string);
932
0
  g_return_val_if_fail (pos <= string->len, string);
933
934
0
  if (len < 0)
935
0
    len = strlen (val);
936
937
0
  end = pos + len;
938
939
0
  if (end > string->len)
940
0
    g_string_maybe_expand (string, end - string->len);
941
942
0
  memcpy (string->str + pos, val, len);
943
944
0
  if (end > string->len)
945
0
    {
946
0
      string->str[end] = '\0';
947
0
      string->len = end;
948
0
    }
949
950
0
  return string;
951
0
}
952
953
/**
954
 * g_string_erase:
955
 * @string: a #GString
956
 * @pos: the position of the content to remove
957
 * @len: the number of bytes to remove, or -1 to remove all
958
 *       following bytes
959
 *
960
 * Removes @len bytes from a #GString, starting at position @pos.
961
 * The rest of the #GString is shifted down to fill the gap.
962
 *
963
 * Returns: (transfer none): @string
964
 */
965
GString *
966
g_string_erase (GString *string,
967
                gssize   pos,
968
                gssize   len)
969
0
{
970
0
  gsize len_unsigned, pos_unsigned;
971
972
0
  g_return_val_if_fail (string != NULL, NULL);
973
0
  g_return_val_if_fail (pos >= 0, string);
974
0
  pos_unsigned = pos;
975
976
0
  g_return_val_if_fail (pos_unsigned <= string->len, string);
977
978
0
  if (len < 0)
979
0
    len_unsigned = string->len - pos_unsigned;
980
0
  else
981
0
    {
982
0
      len_unsigned = len;
983
0
      g_return_val_if_fail (pos_unsigned + len_unsigned <= string->len, string);
984
985
0
      if (pos_unsigned + len_unsigned < string->len)
986
0
        memmove (string->str + pos_unsigned,
987
0
                 string->str + pos_unsigned + len_unsigned,
988
0
                 string->len - (pos_unsigned + len_unsigned));
989
0
    }
990
991
0
  string->len -= len_unsigned;
992
993
0
  string->str[string->len] = 0;
994
995
0
  return string;
996
0
}
997
998
/**
999
 * g_string_replace:
1000
 * @string: a #GString
1001
 * @find: the string to find in @string
1002
 * @replace: the string to insert in place of @find
1003
 * @limit: the maximum instances of @find to replace with @replace, or `0` for
1004
 * no limit
1005
 *
1006
 * Replaces the string @find with the string @replace in a #GString up to
1007
 * @limit times. If the number of instances of @find in the #GString is
1008
 * less than @limit, all instances are replaced. If @limit is `0`,
1009
 * all instances of @find are replaced.
1010
 *
1011
 * If @find is the empty string, since versions 2.69.1 and 2.68.4 the
1012
 * replacement will be inserted no more than once per possible position
1013
 * (beginning of string, end of string and between characters). This did
1014
 * not work correctly in earlier versions.
1015
 *
1016
 * Returns: the number of find and replace operations performed.
1017
 *
1018
 * Since: 2.68
1019
 */
1020
guint
1021
g_string_replace (GString     *string,
1022
                  const gchar *find,
1023
                  const gchar *replace,
1024
                  guint        limit)
1025
0
{
1026
0
  gsize f_len, r_len, pos;
1027
0
  gchar *cur, *next;
1028
0
  guint n = 0;
1029
1030
0
  g_return_val_if_fail (string != NULL, 0);
1031
0
  g_return_val_if_fail (find != NULL, 0);
1032
0
  g_return_val_if_fail (replace != NULL, 0);
1033
1034
0
  f_len = strlen (find);
1035
0
  r_len = strlen (replace);
1036
0
  cur = string->str;
1037
1038
0
  while ((next = strstr (cur, find)) != NULL)
1039
0
    {
1040
0
      pos = next - string->str;
1041
0
      g_string_erase (string, pos, f_len);
1042
0
      g_string_insert (string, pos, replace);
1043
0
      cur = string->str + pos + r_len;
1044
0
      n++;
1045
      /* Only match the empty string once at any given position, to
1046
       * avoid infinite loops */
1047
0
      if (f_len == 0)
1048
0
        {
1049
0
          if (cur[0] == '\0')
1050
0
            break;
1051
0
          else
1052
0
            cur++;
1053
0
        }
1054
0
      if (n == limit)
1055
0
        break;
1056
0
    }
1057
1058
0
  return n;
1059
0
}
1060
1061
/**
1062
 * g_string_ascii_down:
1063
 * @string: a GString
1064
 *
1065
 * Converts all uppercase ASCII letters to lowercase ASCII letters.
1066
 *
1067
 * Returns: (transfer none): passed-in @string pointer, with all the
1068
 *     uppercase characters converted to lowercase in place,
1069
 *     with semantics that exactly match g_ascii_tolower().
1070
 */
1071
GString *
1072
g_string_ascii_down (GString *string)
1073
0
{
1074
0
  gchar *s;
1075
0
  gint n;
1076
1077
0
  g_return_val_if_fail (string != NULL, NULL);
1078
1079
0
  n = string->len;
1080
0
  s = string->str;
1081
1082
0
  while (n)
1083
0
    {
1084
0
      *s = g_ascii_tolower (*s);
1085
0
      s++;
1086
0
      n--;
1087
0
    }
1088
1089
0
  return string;
1090
0
}
1091
1092
/**
1093
 * g_string_ascii_up:
1094
 * @string: a GString
1095
 *
1096
 * Converts all lowercase ASCII letters to uppercase ASCII letters.
1097
 *
1098
 * Returns: (transfer none): passed-in @string pointer, with all the
1099
 *     lowercase characters converted to uppercase in place,
1100
 *     with semantics that exactly match g_ascii_toupper().
1101
 */
1102
GString *
1103
g_string_ascii_up (GString *string)
1104
0
{
1105
0
  gchar *s;
1106
0
  gint n;
1107
1108
0
  g_return_val_if_fail (string != NULL, NULL);
1109
1110
0
  n = string->len;
1111
0
  s = string->str;
1112
1113
0
  while (n)
1114
0
    {
1115
0
      *s = g_ascii_toupper (*s);
1116
0
      s++;
1117
0
      n--;
1118
0
    }
1119
1120
0
  return string;
1121
0
}
1122
1123
/**
1124
 * g_string_down:
1125
 * @string: a #GString
1126
 *
1127
 * Converts a #GString to lowercase.
1128
 *
1129
 * Returns: (transfer none): the #GString
1130
 *
1131
 * Deprecated:2.2: This function uses the locale-specific
1132
 *     tolower() function, which is almost never the right thing.
1133
 *     Use g_string_ascii_down() or g_utf8_strdown() instead.
1134
 */
1135
GString *
1136
g_string_down (GString *string)
1137
0
{
1138
0
  guchar *s;
1139
0
  glong n;
1140
1141
0
  g_return_val_if_fail (string != NULL, NULL);
1142
1143
0
  n = string->len;
1144
0
  s = (guchar *) string->str;
1145
1146
0
  while (n)
1147
0
    {
1148
0
      if (isupper (*s))
1149
0
        *s = tolower (*s);
1150
0
      s++;
1151
0
      n--;
1152
0
    }
1153
1154
0
  return string;
1155
0
}
1156
1157
/**
1158
 * g_string_up:
1159
 * @string: a #GString
1160
 *
1161
 * Converts a #GString to uppercase.
1162
 *
1163
 * Returns: (transfer none): @string
1164
 *
1165
 * Deprecated:2.2: This function uses the locale-specific
1166
 *     toupper() function, which is almost never the right thing.
1167
 *     Use g_string_ascii_up() or g_utf8_strup() instead.
1168
 */
1169
GString *
1170
g_string_up (GString *string)
1171
0
{
1172
0
  guchar *s;
1173
0
  glong n;
1174
1175
0
  g_return_val_if_fail (string != NULL, NULL);
1176
1177
0
  n = string->len;
1178
0
  s = (guchar *) string->str;
1179
1180
0
  while (n)
1181
0
    {
1182
0
      if (islower (*s))
1183
0
        *s = toupper (*s);
1184
0
      s++;
1185
0
      n--;
1186
0
    }
1187
1188
0
  return string;
1189
0
}
1190
1191
/**
1192
 * g_string_append_vprintf:
1193
 * @string: a #GString
1194
 * @format: (not nullable): the string format. See the printf() documentation
1195
 * @args: the list of arguments to insert in the output
1196
 *
1197
 * Appends a formatted string onto the end of a #GString.
1198
 * This function is similar to g_string_append_printf()
1199
 * except that the arguments to the format string are passed
1200
 * as a va_list.
1201
 *
1202
 * Since: 2.14
1203
 */
1204
void
1205
g_string_append_vprintf (GString     *string,
1206
                         const gchar *format,
1207
                         va_list      args)
1208
1.55M
{
1209
1.55M
  gchar *buf;
1210
1.55M
  gint len;
1211
1212
1.55M
  g_return_if_fail (string != NULL);
1213
1.55M
  g_return_if_fail (format != NULL);
1214
1215
1.55M
  len = g_vasprintf (&buf, format, args);
1216
1217
1.55M
  if (len >= 0)
1218
1.55M
    {
1219
1.55M
      g_string_maybe_expand (string, len);
1220
1.55M
      memcpy (string->str + string->len, buf, len + 1);
1221
1.55M
      string->len += len;
1222
1.55M
      g_free (buf);
1223
1.55M
    }
1224
0
  else
1225
0
    {
1226
0
      g_critical ("Failed to append to string: invalid format/args passed to g_vasprintf()");
1227
0
    }
1228
1.55M
}
1229
1230
/**
1231
 * g_string_vprintf:
1232
 * @string: a #GString
1233
 * @format: (not nullable): the string format. See the printf() documentation
1234
 * @args: the parameters to insert into the format string
1235
 *
1236
 * Writes a formatted string into a #GString.
1237
 * This function is similar to g_string_printf() except that
1238
 * the arguments to the format string are passed as a va_list.
1239
 *
1240
 * Since: 2.14
1241
 */
1242
void
1243
g_string_vprintf (GString     *string,
1244
                  const gchar *format,
1245
                  va_list      args)
1246
0
{
1247
0
  g_string_truncate (string, 0);
1248
0
  g_string_append_vprintf (string, format, args);
1249
0
}
1250
1251
/**
1252
 * g_string_sprintf:
1253
 * @string: a #GString
1254
 * @format: the string format. See the sprintf() documentation
1255
 * @...: the parameters to insert into the format string
1256
 *
1257
 * Writes a formatted string into a #GString.
1258
 * This is similar to the standard sprintf() function,
1259
 * except that the #GString buffer automatically expands
1260
 * to contain the results. The previous contents of the
1261
 * #GString are destroyed.
1262
 *
1263
 * Deprecated: This function has been renamed to g_string_printf().
1264
 */
1265
1266
/**
1267
 * g_string_printf:
1268
 * @string: a #GString
1269
 * @format: the string format. See the printf() documentation
1270
 * @...: the parameters to insert into the format string
1271
 *
1272
 * Writes a formatted string into a #GString.
1273
 * This is similar to the standard sprintf() function,
1274
 * except that the #GString buffer automatically expands
1275
 * to contain the results. The previous contents of the
1276
 * #GString are destroyed.
1277
 */
1278
void
1279
g_string_printf (GString     *string,
1280
                 const gchar *format,
1281
                 ...)
1282
0
{
1283
0
  va_list args;
1284
1285
0
  g_string_truncate (string, 0);
1286
1287
0
  va_start (args, format);
1288
0
  g_string_append_vprintf (string, format, args);
1289
0
  va_end (args);
1290
0
}
1291
1292
/**
1293
 * g_string_sprintfa:
1294
 * @string: a #GString
1295
 * @format: the string format. See the sprintf() documentation
1296
 * @...: the parameters to insert into the format string
1297
 *
1298
 * Appends a formatted string onto the end of a #GString.
1299
 * This function is similar to g_string_sprintf() except that
1300
 * the text is appended to the #GString.
1301
 *
1302
 * Deprecated: This function has been renamed to g_string_append_printf()
1303
 */
1304
1305
/**
1306
 * g_string_append_printf:
1307
 * @string: a #GString
1308
 * @format: the string format. See the printf() documentation
1309
 * @...: the parameters to insert into the format string
1310
 *
1311
 * Appends a formatted string onto the end of a #GString.
1312
 * This function is similar to g_string_printf() except
1313
 * that the text is appended to the #GString.
1314
 */
1315
void
1316
g_string_append_printf (GString     *string,
1317
                        const gchar *format,
1318
                        ...)
1319
1.55M
{
1320
1.55M
  va_list args;
1321
1322
1.55M
  va_start (args, format);
1323
1.55M
  g_string_append_vprintf (string, format, args);
1324
1.55M
  va_end (args);
1325
1.55M
}