aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils.c
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2019-03-18 18:38:47 +0100
committerHarald Welte <laforge@gnumonks.org>2019-04-10 22:42:32 +0000
commit179f35702ece13f4ab7fd1b331bef664834d8473 (patch)
tree9dad4da8eb773040ea8a2dc096190118f5d2abd6 /src/utils.c
parentd08e9866a5c3da6edda574bbe6d277047d10fded (diff)
Add _c versions of functions that otherwise return static buffers
We have a habit of returning static buffers from some functions, particularly when generating some kind of string values. This is convenient in terms of memory management, but it comes at the expense of not being thread-safe, and not allowing for two calls of the related function within one printf() statement. Let's introduce _c suffix versions of those functions where the caller passes in a talloc context from which the output buffer shall be allocated. Change-Id: I8481c19b68ff67cfa22abb93c405ebcfcb0ab19b
Diffstat (limited to 'src/utils.c')
-rw-r--r--src/utils.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/utils.c b/src/utils.c
index 47963650..b8b4ef56 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -338,6 +338,27 @@ char *osmo_hexdump(const unsigned char *buf, int len)
}
/*! Convert binary sequence to hexadecimal ASCII string
+ * \param[in] ctx talloc context from where to allocate the output string
+ * \param[in] buf pointer to sequence of bytes
+ * \param[in] len length of buf in number of bytes
+ * \returns pointer to zero-terminated string
+ *
+ * This function will print a sequence of bytes as hexadecimal numbers,
+ * adding one space character between each byte (e.g. "1a ef d9")
+ *
+ * The maximum size of the output buffer is 4096 bytes, i.e. the maximum
+ * number of input bytes that can be printed in one call is 1365!
+ */
+char *osmo_hexdump_c(const void *ctx, const unsigned char *buf, int len)
+{
+ char *hexd_buff = talloc_size(ctx, len*3 + 1);
+ if (!hexd_buff)
+ return NULL;
+ osmo_hexdump_buf(hexd_buff, sizeof(hexd_buff), buf, len, " ", true);
+ return hexd_buff;
+}
+
+/*! Convert binary sequence to hexadecimal ASCII string
* \param[in] buf pointer to sequence of bytes
* \param[in] len length of buf in number of bytes
* \returns pointer to zero-terminated string
@@ -354,6 +375,28 @@ char *osmo_hexdump_nospc(const unsigned char *buf, int len)
return hexd_buff;
}
+/*! Convert binary sequence to hexadecimal ASCII string
+ * \param[in] ctx talloc context from where to allocate the output string
+ * \param[in] buf pointer to sequence of bytes
+ * \param[in] len length of buf in number of bytes
+ * \returns pointer to zero-terminated string
+ *
+ * This function will print a sequence of bytes as hexadecimal numbers,
+ * without any space character between each byte (e.g. "1aefd9")
+ *
+ * The maximum size of the output buffer is 4096 bytes, i.e. the maximum
+ * number of input bytes that can be printed in one call is 2048!
+ */
+char *osmo_hexdump_nospc_c(const void *ctx, const unsigned char *buf, int len)
+{
+ char *hexd_buff = talloc_size(ctx, len*2 + 1);
+ if (!hexd_buff)
+ return NULL;
+ osmo_hexdump_buf(hexd_buff, sizeof(hexd_buff), buf, len, "", true);
+ return hexd_buff;
+}
+
+
/* Compat with previous typo to preserve abi */
char *osmo_osmo_hexdump_nospc(const unsigned char *buf, int len)
#if defined(__MACH__) && defined(__APPLE__)
@@ -639,6 +682,19 @@ const char *osmo_escape_str(const char *str, int in_len)
return osmo_escape_str_buf(str, in_len, namebuf, sizeof(namebuf));
}
+/*! Return the string with all non-printable characters escaped, in dynamically-allocated buffer.
+ * \param[in] str A string that may contain any characters.
+ * \param[in] len Pass -1 to print until nul char, or >= 0 to force a length.
+ * \returns dynamically-allocated output buffer, containing an escaped representation
+ */
+char *osmo_escape_str_c(const void *ctx, const char *str, int in_len)
+{
+ char *buf = talloc_size(ctx, in_len+1);
+ if (!buf)
+ return NULL;
+ return osmo_escape_str_buf(str, in_len, buf, in_len+1);
+}
+
/*! Like osmo_escape_str(), but returns double-quotes around a string, or "NULL" for a NULL string.
* This allows passing any char* value and get its C representation as string.
* \param[in] str A string that may contain any characters.
@@ -671,6 +727,20 @@ const char *osmo_quote_str(const char *str, int in_len)
return osmo_quote_str_buf(str, in_len, namebuf, sizeof(namebuf));
}
+/*! Like osmo_quote_str_buf() but returns the result in a dynamically-allocated buffer.
+ * The static buffer is shared with get_value_string() and osmo_escape_str().
+ * \param[in] str A string that may contain any characters.
+ * \param[in] in_len Pass -1 to print until nul char, or >= 0 to force a length.
+ * \returns dynamically-allocated buffer containing a quoted and escaped representation.
+ */
+char *osmo_quote_str_c(const void *ctx, const char *str, int in_len)
+{
+ char *buf = talloc_size(ctx, OSMO_MAX(in_len+2, 32));
+ if (!buf)
+ return NULL;
+ return osmo_quote_str_buf(str, in_len, buf, 32);
+}
+
/*! perform an integer square root operation on unsigned 32bit integer.
* This implementation is taken from "Hacker's Delight" Figure 11-1 "Integer square root, Newton's
* method", which can also be found at http://www.hackersdelight.org/hdcodetxt/isqrt.c.txt */
@@ -754,6 +824,21 @@ const char *osmo_str_tolower(const char *src)
return buf;
}
+/*! Convert a string to lowercase, dynamically allocating the output from given talloc context
+ * See also osmo_str_tolower_buf().
+ * \param[in] ctx talloc context from where to allocate the output string
+ * \param[in] src String to convert to lowercase.
+ * \returns Resulting lowercase string in a dynamically allocated buffer, always nul terminated.
+ */
+char *osmo_str_tolower_c(const void *ctx, const char *src)
+{
+ char *buf = talloc_size(ctx, strlen(src)+1);
+ if (!buf)
+ return NULL;
+ osmo_str_tolower_buf(buf, sizeof(buf), src);
+ return buf;
+}
+
/*! Convert a string to uppercase, while checking buffer size boundaries.
* The result written to \a dest is guaranteed to be nul terminated if \a dest_len > 0.
* If dest == src, the string is converted in-place, if necessary truncated at dest_len - 1 characters
@@ -797,6 +882,21 @@ const char *osmo_str_toupper(const char *src)
return buf;
}
+/*! Convert a string to uppercase, dynamically allocating the output from given talloc context
+ * See also osmo_str_tolower_buf().
+ * \param[in] ctx talloc context from where to allocate the output string
+ * \param[in] src String to convert to uppercase.
+ * \returns Resulting uppercase string in a dynamically allocated buffer, always nul terminated.
+ */
+char *osmo_str_toupper_c(const void *ctx, const char *src)
+{
+ char *buf = talloc_size(ctx, strlen(src)+1);
+ if (!buf)
+ return NULL;
+ osmo_str_toupper_buf(buf, sizeof(buf), src);
+ return buf;
+}
+
/*! Calculate the Luhn checksum (as used for IMEIs).
* \param[in] in Input digits in ASCII string representation.
* \param[in] in_len Count of digits to use for the input (14 for IMEI).