Coverage Report

Created: 2025-07-01 07:09

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