openat: don’t close (-1)
[gnulib.git] / doc / string-desc.texi
blobab987dec1c3aa3b7c953b5143c93e71d221d861b
1 @node Handling strings with NUL characters
2 @section Handling strings with NUL characters
4 @c Copyright (C) 2023--2024 Free Software Foundation, Inc.
6 @c Permission is granted to copy, distribute and/or modify this document
7 @c under the terms of the GNU Free Documentation License, Version 1.3 or
8 @c any later version published by the Free Software Foundation; with no
9 @c Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.  A
10 @c copy of the license is at <https://www.gnu.org/licenses/fdl-1.3.en.html>.
12 @c Written by Bruno Haible.
14 Strings in C are usually represented by a character sequence with a
15 terminating NUL character.  A @samp{char *}, pointer to the first byte
16 of this character sequence, is what gets passed around as function
17 argument or return value.
19 The major restriction of this string representation is that it cannot
20 handle strings that contain NUL characters: such strings will appear
21 shorter than they were meant to be.  In most application areas, this is
22 not a problem, and the @code{char *} type is well usable.
24 A second problem of this string representation is that
25 taking a substring is not cheap:
26 it either requires a memory allocation
27 or a destructive modification of the string.
28 The former has a runtime cost;
29 the latter complicates the logic of the program.
30 This matters for application areas that analyze text, such as parsers.
32 In areas where strings with embedded NUL characters need to be handled
33 or where taking substrings is a recurrent operation,
34 the common approach is to use a @code{char *ptr} pointer variable
35 together with a @code{size_t nbytes} variable (or an @code{idx_t nbytes}
36 variable, if you want to avoid problems due to integer overflow).  This
37 works fine in code that constructs or manipulates strings with embedded
38 NUL characters.  But when it comes to @emph{storing} them, for example
39 in an array or as key or value of a hash table, one needs a type that
40 combines these two fields.
42 @mindex string-desc
43 @mindex xstring-desc
44 @mindex string-desc-quotearg
45 The Gnulib modules @code{string-desc}, @code{xstring-desc}, and
46 @code{string-desc-quotearg} provide such a type.  We call it a
47 ``string descriptor'' and name it @code{string_desc_t}.
49 The type @code{string_desc_t} is a struct that contains a pointer to the
50 first byte and the number of bytes of the memory region that make up the
51 string.  An additional terminating NUL byte, that may be present in
52 memory, is not included in this byte count.  This type implements the
53 same concept as @code{std::string_view} in C++, or the @code{String}
54 type in Java.
56 A @code{string_desc_t} can be passed to a function as an argument, or
57 can be the return value of a function.  This is type-safe: If, by
58 mistake, a programmer passes a @code{string_desc_t} to a function that
59 expects a @code{char *} argument, or vice versa, or assigns a
60 @code{string_desc_t} value to a variable of type @code{char *}, or
61 vice versa, the compiler will report an error.
63 Functions related to string descriptors are provided:
64 @itemize
65 @item
66 Side-effect-free operations in @code{"string-desc.h"},
67 @item
68 Memory-allocating operations in @code{"string-desc.h"},
69 @item
70 Memory-allocating operations with out-of-memory checking in
71 @code{"xstring-desc.h"},
72 @item
73 Operations with side effects in @code{"string-desc.h"}.
74 @end itemize
76 For outputting a string descriptor, the @code{*printf} family of
77 functions cannot be used directly.  A format string directive such as
78 @code{"%.*s"} would not work:
79 @itemize
80 @item
81 it would stop the output at the first encountered NUL character,
82 @item
83 it would require to cast the number of bytes to @code{int}, and thus
84 would not work for strings longer than @code{INT_MAX} bytes.
85 @end itemize
86 @c @noindent Other format string directives don't work either, because
87 @c the only way to produce a NUL character in @code{*printf}'s output
88 @c is through a dedicated @code{%c} or @code{%lc} directive.
90 Therefore Gnulib offers
91 @itemize
92 @item
93 a function @code{string_desc_fwrite} that outputs a string descriptor to
94 a @code{FILE} stream,
95 @item
96 a function @code{string_desc_write} that outputs a string descriptor to
97 a file descriptor,
98 @item
99 and for those applications where the NUL characters should become
100 visible as @samp{\0}, a family of @code{quotearg} based functions, that
101 allow to specify the escaping rules in detail.
102 @end itemize
104 The functionality is thus split across three modules as follows:
105 @itemize
106 @item
107 The module @code{string-desc}, under LGPL, defines the type and
108 elementary functions.
109 @item
110 The module @code{xstring-desc}, under GPL, defines the memory-allocating
111 functions with out-of-memory checking.
112 @item
113 The module @code{string-desc-quotearg}, under GPL, defines the
114 @code{quotearg} based functions.
115 @end itemize