/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /** * @file utils.h * * Compare, copy and printf functions. * * @author Mike Becker * @author Olaf Wintermann */ #ifndef UCX_UTILS_H #define UCX_UTILS_H #include "ucx.h" #include "string.h" #include "allocator.h" #include #include #include #ifdef __cplusplus extern "C" { #endif /** * Default buffer size for ucx_stream_copy() and ucx_stream_ncopy(). */ #define UCX_STREAM_COPY_BUFSIZE 4096 /** * Copies a string. * @param s the string to copy * @param data omitted * @return a pointer to a copy of s1 that can be passed to free(void*) */ void *ucx_strcpy(const void *s, void *data); /** * Copies a memory area. * @param m a pointer to the memory area * @param n a pointer to the size_t containing the size of the memory area * @return a pointer to a copy of the specified memory area that can * be passed to free(void*) */ void *ucx_memcpy(const void *m, void *n); /** * Reads data from a stream and writes it to another stream. * * @param src the source stream * @param dest the destination stream * @param rfnc the read function * @param wfnc the write function * @param buf a pointer to the copy buffer or NULL if a buffer * shall be implicitly created on the heap * @param bufsize the size of the copy buffer - if NULL was * provided for buf, this is the size of the buffer that shall be * implicitly created * @param n the maximum number of bytes that shall be copied * @return the total number of bytes copied */ size_t ucx_stream_bncopy(void *src, void *dest, read_func rfnc, write_func wfnc, char* buf, size_t bufsize, size_t n); /** * Shorthand for an unbounded ucx_stream_bncopy call using a default buffer. * * @param src the source stream * @param dest the destination stream * @param rfnc the read function * @param wfnc the write function * @return total number of bytes copied * * @see #UCX_STREAM_COPY_BUFSIZE */ #define ucx_stream_copy(src,dest,rfnc,wfnc) ucx_stream_bncopy(\ src, dest, (read_func)rfnc, (write_func)wfnc, \ NULL, UCX_STREAM_COPY_BUFSIZE, (size_t)-1) /** * Shorthand for ucx_stream_bncopy using a default copy buffer. * * @param src the source stream * @param dest the destination stream * @param rfnc the read function * @param wfnc the write function * @param n maximum number of bytes that shall be copied * @return total number of bytes copied */ #define ucx_stream_ncopy(src,dest,rfnc,wfnc, n) ucx_stream_bncopy(\ src, dest, (read_func)rfnc, (write_func)wfnc, \ NULL, UCX_STREAM_COPY_BUFSIZE, n) /** * Shorthand for an unbounded ucx_stream_bncopy call using the specified buffer. * * @param src the source stream * @param dest the destination stream * @param rfnc the read function * @param wfnc the write function * @param buf a pointer to the copy buffer or NULL if a buffer * shall be implicitly created on the heap * @param bufsize the size of the copy buffer - if NULL was * provided for buf, this is the size of the buffer that shall be * implicitly created * @return total number of bytes copied */ #define ucx_stream_bcopy(src,dest,rfnc,wfnc, buf, bufsize) ucx_stream_bncopy(\ src, dest, (read_func)rfnc, (write_func)wfnc, \ buf, bufsize, (size_t)-1) /** * Wraps the strcmp function. * @param s1 string one * @param s2 string two * @param data omitted * @return the result of strcmp(s1, s2) */ int ucx_cmp_str(const void *s1, const void *s2, void *data); /** * Wraps the strncmp function. * @param s1 string one * @param s2 string two * @param n a pointer to the size_t containing the third strncmp parameter * @return the result of strncmp(s1, s2, *n) */ int ucx_cmp_strn(const void *s1, const void *s2, void *n); /** * Wraps the sstrcmp function. * @param s1 sstr one * @param s2 sstr two * @param data ignored * @return the result of sstrcmp(s1, s2) */ int ucx_cmp_sstr(const void *s1, const void *s2, void *data); /** * Compares two integers of type int. * @param i1 pointer to integer one * @param i2 pointer to integer two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_int(const void *i1, const void *i2, void *data); /** * Compares two integers of type long int. * @param i1 pointer to long integer one * @param i2 pointer to long integer two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_longint(const void *i1, const void *i2, void *data); /** * Compares two integers of type long long. * @param i1 pointer to long long one * @param i2 pointer to long long two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_longlong(const void *i1, const void *i2, void *data); /** * Compares two integers of type int16_t. * @param i1 pointer to int16_t one * @param i2 pointer to int16_t two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_int16(const void *i1, const void *i2, void *data); /** * Compares two integers of type int32_t. * @param i1 pointer to int32_t one * @param i2 pointer to int32_t two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_int32(const void *i1, const void *i2, void *data); /** * Compares two integers of type int64_t. * @param i1 pointer to int64_t one * @param i2 pointer to int64_t two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_int64(const void *i1, const void *i2, void *data); /** * Compares two integers of type unsigned int. * @param i1 pointer to unsigned integer one * @param i2 pointer to unsigned integer two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_uint(const void *i1, const void *i2, void *data); /** * Compares two integers of type unsigned long int. * @param i1 pointer to unsigned long integer one * @param i2 pointer to unsigned long integer two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_ulongint(const void *i1, const void *i2, void *data); /** * Compares two integers of type unsigned long long. * @param i1 pointer to unsigned long long one * @param i2 pointer to unsigned long long two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_ulonglong(const void *i1, const void *i2, void *data); /** * Compares two integers of type uint16_t. * @param i1 pointer to uint16_t one * @param i2 pointer to uint16_t two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_uint16(const void *i1, const void *i2, void *data); /** * Compares two integers of type uint32_t. * @param i1 pointer to uint32_t one * @param i2 pointer to uint32_t two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_uint32(const void *i1, const void *i2, void *data); /** * Compares two integers of type uint64_t. * @param i1 pointer to uint64_t one * @param i2 pointer to uint64_t two * @param data omitted * @return -1, if *i1 is less than *i2, 0 if both are equal, * 1 if *i1 is greater than *i2 */ int ucx_cmp_uint64(const void *i1, const void *i2, void *data); /** * Distance function for integers of type int. * @param i1 pointer to integer one * @param i2 pointer to integer two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_int(const void *i1, const void *i2, void *data); /** * Distance function for integers of type long int. * @param i1 pointer to long integer one * @param i2 pointer to long integer two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_longint(const void *i1, const void *i2, void *data); /** * Distance function for integers of type long long. * @param i1 pointer to long long one * @param i2 pointer to long long two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_longlong(const void *i1, const void *i2, void *data); /** * Distance function for integers of type int16_t. * @param i1 pointer to int16_t one * @param i2 pointer to int16_t two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_int16(const void *i1, const void *i2, void *data); /** * Distance function for integers of type int32_t. * @param i1 pointer to int32_t one * @param i2 pointer to int32_t two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_int32(const void *i1, const void *i2, void *data); /** * Distance function for integers of type int64_t. * @param i1 pointer to int64_t one * @param i2 pointer to int64_t two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_int64(const void *i1, const void *i2, void *data); /** * Distance function for integers of type unsigned int. * @param i1 pointer to unsigned integer one * @param i2 pointer to unsigned integer two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_uint(const void *i1, const void *i2, void *data); /** * Distance function for integers of type unsigned long int. * @param i1 pointer to unsigned long integer one * @param i2 pointer to unsigned long integer two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_ulongint(const void *i1, const void *i2, void *data); /** * Distance function for integers of type unsigned long long. * @param i1 pointer to unsigned long long one * @param i2 pointer to unsigned long long two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_ulonglong(const void *i1, const void *i2, void *data); /** * Distance function for integers of type uint16_t. * @param i1 pointer to uint16_t one * @param i2 pointer to uint16_t two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_uint16(const void *i1, const void *i2, void *data); /** * Distance function for integers of type uint32_t. * @param i1 pointer to uint32_t one * @param i2 pointer to uint32_t two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_uint32(const void *i1, const void *i2, void *data); /** * Distance function for integers of type uint64_t. * @param i1 pointer to uint64_t one * @param i2 pointer to uint64_t two * @param data omitted * @return i1 minus i2 */ intmax_t ucx_dist_uint64(const void *i1, const void *i2, void *data); /** * Compares two real numbers of type float. * @param f1 pointer to float one * @param f2 pointer to float two * @param data if provided: a pointer to precision (default: 1e-6f) * @return -1, if *f1 is less than *f2, 0 if both are equal, * 1 if *f1 is greater than *f2 */ int ucx_cmp_float(const void *f1, const void *f2, void *data); /** * Compares two real numbers of type double. * @param d1 pointer to double one * @param d2 pointer to double two * @param data if provided: a pointer to precision (default: 1e-14) * @return -1, if *d1 is less than *d2, 0 if both are equal, * 1 if *d1 is greater than *d2 */ int ucx_cmp_double(const void *d1, const void *d2, void *data); /** * Compares two pointers. * @param ptr1 pointer one * @param ptr2 pointer two * @param data omitted * @return -1 if ptr1 is less than ptr2, 0 if both are equal, * 1 if ptr1 is greater than ptr2 */ int ucx_cmp_ptr(const void *ptr1, const void *ptr2, void *data); /** * Compares two memory areas. * @param ptr1 pointer one * @param ptr2 pointer two * @param n a pointer to the size_t containing the third parameter for memcmp * @return the result of memcmp(ptr1, ptr2, *n) */ int ucx_cmp_mem(const void *ptr1, const void *ptr2, void *n); /** * A printf() like function which writes the output to a stream by * using a write_func(). * @param stream the stream the data is written to * @param wfc the write function * @param fmt format string * @param ... additional arguments * @return the total number of bytes written */ int ucx_fprintf(void *stream, write_func wfc, const char *fmt, ...); /** * va_list version of ucx_fprintf(). * @param stream the stream the data is written to * @param wfc the write function * @param fmt format string * @param ap argument list * @return the total number of bytes written * @see ucx_fprintf() */ int ucx_vfprintf(void *stream, write_func wfc, const char *fmt, va_list ap); /** * A printf() like function which allocates space for a sstr_t * the result is written to. * * Attention: The sstr_t data is allocated with the allocators * ucx_allocator_malloc() function. So it is implementation dependent, if * the returned sstr_t.ptr pointer must be passed to the allocators * ucx_allocator_free() function manually. * * Note: The sstr_t.ptr of the return value will always be * NULL-terminated. * * @param allocator the UcxAllocator used for allocating the result sstr_t * @param fmt format string * @param ... additional arguments * @return a sstr_t containing the formatted string */ sstr_t ucx_asprintf(UcxAllocator *allocator, const char *fmt, ...); /** * va_list version of ucx_asprintf(). * * @param allocator the UcxAllocator used for allocating the result sstr_t * @param fmt format string * @param ap argument list * @return a sstr_t containing the formatted string * @see ucx_asprintf() */ sstr_t ucx_vasprintf(UcxAllocator *allocator, const char *fmt, va_list ap); /** Shortcut for ucx_asprintf() with default allocator. */ #define ucx_sprintf(...) \ ucx_asprintf(ucx_default_allocator(), __VA_ARGS__) /** * A printf() like function which writes the output to a * UcxBuffer. * * @param buffer the buffer the data is written to * @param ... format string and additional arguments * @return the total number of bytes written * @see ucx_fprintf() */ #define ucx_bprintf(buffer, ...) ucx_fprintf((UcxBuffer*)buffer, \ (write_func)ucx_buffer_write, __VA_ARGS__) #ifdef __cplusplus } #endif #endif /* UCX_UTILS_H */