Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2012 Tim Ruehsen |
3 | | * Copyright (c) 2015-2024 Free Software Foundation, Inc. |
4 | | * |
5 | | * This file is part of libwget. |
6 | | * |
7 | | * Libwget is free software: you can redistribute it and/or modify |
8 | | * it under the terms of the GNU Lesser General Public License as published by |
9 | | * the Free Software Foundation, either version 3 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * Libwget is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU Lesser General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU Lesser General Public License |
18 | | * along with libwget. If not, see <https://www.gnu.org/licenses/>. |
19 | | * |
20 | | * |
21 | | * Memory allocation routines |
22 | | * |
23 | | * Changelog |
24 | | * 25.06.2012 Tim Ruehsen created |
25 | | * |
26 | | */ |
27 | | |
28 | | #include <config.h> |
29 | | |
30 | | #include <string.h> |
31 | | |
32 | | #include <wget.h> |
33 | | #include "private.h" |
34 | | |
35 | | /** |
36 | | * \file |
37 | | * \brief Memory functions |
38 | | * \defgroup libwget-mem Memory functions |
39 | | * @{ |
40 | | * |
41 | | * This is a collections of short memory function not available in standard libraries. |
42 | | */ |
43 | | |
44 | | /** |
45 | | * \param[in] m Memory to clone |
46 | | * \param[in] n Length of memory |
47 | | * \return Cloned memory |
48 | | * |
49 | | * Clone's the memory region \p m with length \p n. |
50 | | * Returns NULL if \p m is NULL. |
51 | | * |
52 | | * You should free() the returned pointer when not needed any more. |
53 | | */ |
54 | | void *wget_memdup(const void *m, size_t n) |
55 | 201 | { |
56 | 201 | if (!m) return NULL; |
57 | | |
58 | 201 | void *d = wget_malloc(n); |
59 | 201 | if (!d) |
60 | 0 | return NULL; |
61 | | |
62 | 201 | return memcpy(d, m, n); |
63 | 201 | } |
64 | | |
65 | | /** |
66 | | * \param[in] s String to clone |
67 | | * \return Cloned string |
68 | | * |
69 | | * Clone's the string \p s like strdup() does. |
70 | | * Returns NULL if \p s is NULL. |
71 | | * |
72 | | * You should free() the returned string when not needed any more. |
73 | | */ |
74 | | char *wget_strdup(const char *s) |
75 | 201 | { |
76 | 201 | return s ? wget_memdup(s, strlen(s) + 1) : NULL; |
77 | 201 | } |
78 | | |
79 | | /** |
80 | | * \param[in] m Memory to convert into string |
81 | | * \param[in] n Length of memory |
82 | | * \return Created string |
83 | | * |
84 | | * Convert the given memory region \p m with length \p n into a C string. |
85 | | * Returns NULL if \p m is NULL. |
86 | | * |
87 | | * You should free() the returned string when not needed any more. |
88 | | */ |
89 | | char *wget_strmemdup(const void *m, size_t n) |
90 | 0 | { |
91 | 0 | if (!m) |
92 | 0 | return NULL; |
93 | | |
94 | 0 | void *d = wget_malloc(n + 1); |
95 | 0 | if (!d) |
96 | 0 | return NULL; |
97 | | |
98 | 0 | char *ret = memcpy(d, m, n); |
99 | 0 | ret[n] = 0; |
100 | |
|
101 | 0 | return ret; |
102 | 0 | } |
103 | | |
104 | | /** |
105 | | * \param[out] s Buffer to hold the C string output |
106 | | * \param[in] ssize Size of the output buffer |
107 | | * \param[in] m Memory to read from |
108 | | * \param[in] n Length of memory |
109 | | * \return Number of bytes copied, not counting the trailing 0 byte |
110 | | * |
111 | | * Convert the given memory region \p m with length \p n into a C string at \p s. |
112 | | * A max. of \p ssize - 1 is copied into \p s. |
113 | | */ |
114 | | size_t wget_strmemcpy(char *s, size_t ssize, const void *m, size_t n) |
115 | 0 | { |
116 | 0 | if (!s || !ssize) |
117 | 0 | return 0; |
118 | | |
119 | 0 | if (likely(n > 0)) { |
120 | 0 | if (n >= ssize) |
121 | 0 | n = ssize - 1; // truncate |
122 | |
|
123 | 0 | if (m) |
124 | 0 | memmove(s, m, n); |
125 | 0 | else |
126 | 0 | n = 0; |
127 | 0 | } |
128 | 0 | s[n] = 0; |
129 | |
|
130 | 0 | return n; |
131 | 0 | } |
132 | | |
133 | | /** |
134 | | * \param[out] s Buffer to hold the C string output |
135 | | * \param[in] ssize Size of the output buffer |
136 | | * \param[in] m Memory to read from |
137 | | * \param[in] n Length of memory |
138 | | * \return Pointer to destination (either \p s or a freshly allocated buffer) |
139 | | * |
140 | | * Convert the given memory region \p m with length \p n into a C string at \p s or at freshly allocated memory, |
141 | | * if the space in \p s was not sufficient. |
142 | | * |
143 | | * If \p s was too small to hold \p n + 1 bytes, the result must be free'd after use, e.g. |
144 | | * if (res != s) wget_free(res); |
145 | | */ |
146 | | void *wget_strmemcpy_a(char *s, size_t ssize, const void *m, size_t n) |
147 | 0 | { |
148 | 0 | if (n >= ssize) { |
149 | 0 | if (!(s = wget_malloc(n + 1))) |
150 | 0 | return NULL; |
151 | 0 | } |
152 | | |
153 | 0 | memmove(s, m, n); |
154 | 0 | s[n] = 0; |
155 | 0 | return s; |
156 | 0 | } |
157 | | |
158 | | /**@}*/ |