=== Utilities 

==== mg_skip()

[source,c]
----
const char *mg_skip(const char *s, const char *end_string,
                    const char *delimiters, struct mg_str *v);
----
Fetch substring from input string `s`, `end` into `v`.
Skips initial delimiter characters. Records first non-delimiter character
as the beginning of substring `v`. Then scans the rest of the string
until a delimiter character or end-of-string is found.
`delimiters` is a 0-terminated string containing delimiter characters.
Either one of `delimiters` or `end_string` terminates the search.
Return an `s` pointer, advanced forward where parsing stopped. 

==== mg_ncasecmp()

[source,c]
----
int mg_ncasecmp(const char *s1, const char *s2, size_t len);
----
Cross-platform version of `strncasecmp()`. 

==== mg_casecmp()

[source,c]
----
int mg_casecmp(const char *s1, const char *s2);
----
Cross-platform version of `strcasecmp()`. 

==== mg_vcmp()

[source,c]
----
int mg_vcmp(const struct mg_str *str2, const char *str1);
----
Cross-platform version of `strcmp()` where where first string is
specified by `struct mg_str`. 

==== mg_vcasecmp()

[source,c]
----
int mg_vcasecmp(const struct mg_str *str2, const char *str1);
----
Cross-platform version of `strncasecmp()` where first string is
specified by `struct mg_str`. 

==== mg_base64_decode()

[source,c]
----
int mg_base64_decode(const unsigned char *s, int len, char *dst);
----
Decode base64-encoded string `s`, `len` into the destination `dst`.
Destination has to have enough space to hold decoded buffer.
Decoding stops either when all string has been decoded, or invalid
character appeared.
Destination is '\0'-terminated.
Return number of decoded characters. On success, that should be equal to
`len`. On error (invalid character) the return value is smaller then `len`. 

==== mg_base64_encode()

[source,c]
----
void mg_base64_encode(const unsigned char *src, int src_len, char *dst);
----
Base64-encode chunk of memory `src`, `src_len` into the destination `dst`.
Destination has to have enough space to hold encoded buffer.
Destination is '\0'-terminated. 

==== mg_stat()

[source,c]
----
int mg_stat(const char *path, cs_stat_t *st);
----
Perform a 64-bit `stat()` call against given file.

`path` should be UTF8 encoded.

Return value is the same as for `stat()` syscall. 

==== mg_fopen()

[source,c]
----
FILE *mg_fopen(const char *path, const char *mode);
----
Open the given file and return a file stream.

`path` and `mode` should be UTF8 encoded.

Return value is the same as for the `fopen()` call. 

==== mg_open()

[source,c]
----
int mg_open(const char *path, int flag, int mode);
----
Open the given file and return a file stream.

`path` should be UTF8 encoded.

Return value is the same as for the `open()` syscall. 

==== mg_start_thread()

[source,c]
----
void *mg_start_thread(void *(*thread_func);
----
Start a new detached thread.
Arguments and semantic is the same as pthead's `pthread_create()`.
`thread_func` is a thread function, `thread_func_param` is a parameter
that is passed to the thread function. 

==== mg_conn_addr_to_str()

[source,c]
----
void mg_conn_addr_to_str(struct mg_connection *nc, char *buf, size_t len,
                         int flags);
----
Convert connection's local or remote address into string.

The `flags` parameter is a bit mask that controls the behavior,
see `MG_SOCK_STRINGIFY_*` definitions.

- MG_SOCK_STRINGIFY_IP - print IP address
- MG_SOCK_STRINGIFY_PORT - print port number
- MG_SOCK_STRINGIFY_REMOTE - print remote peer's IP/port, not local address

If both port number and IP address are printed, they are separated by `:`.
If compiled with `-DMG_ENABLE_IPV6`, IPv6 addresses are supported. 

==== mg_sock_to_str()

[source,c]
----
void mg_sock_to_str(sock_t sock, char *buf, size_t len, int flags);
----
Legacy interface. 

==== mg_sock_addr_to_str()

[source,c]
----
void mg_sock_addr_to_str(const union socket_address *sa, char *buf, size_t len,
                         int flags);
----
Convert socket's address into string.

`flags` is MG_SOCK_STRINGIFY_IP and/or MG_SOCK_STRINGIFY_PORT. 

==== mg_hexdump()

[source,c]
----
int mg_hexdump(const void *buf, int len, char *dst, int dst_len);
----
Generates human-readable hexdump of memory chunk.

Takes a memory buffer `buf` of length `len` and creates a hex dump of that
buffer in `dst`. Generated output is a-la hexdump(1).
Return length of generated string, excluding terminating `\0`. If returned
length is bigger than `dst_len`, overflow bytes are discarded. 

==== mg_hexdump_connection()

[source,c]
----
void mg_hexdump_connection(struct mg_connection *nc, const char *path,
                           const void *buf, int num_bytes, int ev);
----
Generates human-readable hexdump of the data sent or received by connection.
`path` is a file name where hexdump should be written. `num_bytes` is
a number of bytes sent/received. `ev` is one of the `MG_*` events sent to
an event handler. This function is supposed to be called from the
event handler. 

==== mg_avprintf()

[source,c]
----
int mg_avprintf(char **buf, size_t size, const char *fmt, va_list ap);
----
Print message to buffer. If buffer is large enough to hold the message,
return buffer. If buffer is to small, allocate large enough buffer on heap,
and return allocated buffer.
This is a supposed use case:

   char buf[5], *p = buf;
   p = mg_avprintf(&p, sizeof(buf), "%s", "hi there");
   use_p_somehow(p);
   if (p != buf) {
     free(p);
   }

The purpose of this is to avoid malloc-ing if generated strings are small. 

==== mg_is_big_endian()

[source,c]
----
int mg_is_big_endian(void);
----
Return true if target platform is big endian. 

==== mg_next_comma_list_entry()

[source,c]
----
const char *mg_next_comma_list_entry(const char *list, struct mg_str *val,
                                     struct mg_str *eq_val);
----
A helper function for traversing a comma separated list of values.
It returns a list pointer shifted to the next value, or NULL if the end
of the list found.
Value is stored in val vector. If value has form "x=y", then eq_val
vector is initialized to point to the "y" part, and val vector length
is adjusted to point only to "x".
If list is just a comma separated list of entries, like "aa,bb,cc" then
`eq_val` will contain zero-length string.

The purpose of this function is to parse comma separated string without
any copying/memory allocation. 

==== mg_match_prefix()

[source,c]
----
int mg_match_prefix(const char *pattern, int pattern_len, const char *str);
----
Match 0-terminated string (mg_match_prefix) or string with given length
mg_match_prefix_n against a glob pattern.
Match is case-insensitive. Return number of bytes matched, or -1 if no match. 

==== mg_mk_str()

[source,c]
----
struct mg_str mg_mk_str(const char *s);
----
A helper function for creating mg_str struct from plain C string.
`NULL` is allowed and becomes `{NULL, 0}`. 

==== MG_MK_STR()

[source,c]
----
#define MG_MK_STR(str_literal);
----
Macro for initializing mg_str. 

