mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-11-12 20:47:06 +00:00
add libks (kitchen sink) as a new lib to collect random cool cross platform BSD licensed C funcs
This commit is contained in:
1 parent
cf480c8b3a
commit
cd6ead9178
21 files changed
+13851
No files matched your search
@@ -0,0 +1,2 @@
|
||||
const char *cc = ".========================================================================================================.\n| ____ _____ ____ _ ____ _ _ _____ |\n| / ___|___ _ __ ___ ___ |_ _|__ / ___| |_ _ ___ / ___|___ _ __ ( ) |___ / |\n| | | / _ \\| '_ ` _ \\ / _ \\ | |/ _ \\ | | | | | | |/ _ \\ | / _ \\| '_ \\ |/| | |_ \\ |\n| | |__| (_) | | | | | | __/ | | (_) | | |___| | |_| | __/ |__| (_) | | | | | |___) | |\n| \\____\\___/|_| |_| |_|\\___| |_|\\___/ \\____|_|\\__,_|\\___|\\____\\___/|_| |_| |_|____/ |\n| |\n| ____ _ _ _ _ ____ _ |\n| / ___| |__ (_) ___ __ _ __ _ ___ | | | / ___| / \\ |\n| | | | '_ \\| |/ __/ _` |/ _` |/ _ \\ | | | \\___ \\ / _ \\ |\n| | |___| | | | | (_| (_| | (_| | (_) | | |_| |___) / ___ \\ |\n| \\____|_| |_|_|\\___\\__,_|\\__, |\\___( ) \\___/|____/_/ \\_\\ |\n| |___/ |/ |\n| _ _ __ _ _ ___ _ _ ____ ___ _ _____ |\n| / \\ _ _ __ _ _ _ ___| |_ / /_ | |_| |__ ( _ )| |_| |__ |___ \\ / _ \\/ |___ / |\n| / _ \\| | | |/ _` | | | / __| __| | '_ \\| __| '_ \\ _____ / _ \\| __| '_ \\ __) | | | | | |_ \\ |\n| / ___ \\ |_| | (_| | |_| \\__ \\ |_ | (_) | |_| | | | |_____| | (_) | |_| | | | / __/| |_| | |___) | |\n| /_/ \\_\\__,_|\\__, |\\__,_|___/\\__| \\___/ \\__|_| |_| \\___/ \\__|_| |_| |_____|\\___/|_|____/ |\n| |___/ |\n| _ |\n| __ ____ ____ __ ___| |_ _ ___ ___ ___ _ __ ___ ___ _ __ ___ |\n| \\ \\ /\\ / /\\ \\ /\\ / /\\ \\ /\\ / / / __| | | | |/ _ \\/ __/ _ \\| '_ \\ / __/ _ \\| '_ ` _ \\ |\n| \\ V V / \\ V V / \\ V V / _ | (__| | |_| | __/ (_| (_) | | | | _ | (_| (_) | | | | | | |\n| \\_/\\_/ \\_/\\_/ \\_/\\_/ (_) \\___|_|\\__,_|\\___|\\___\\___/|_| |_| (_) \\___\\___/|_| |_| |_| |\n| |\n.========================================================================================================.\n";
|
||||
|
||||
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2012, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* 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 OWNER
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _KS_H_
|
||||
#define _KS_H_
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#define ks_copy_string(_x, _y, _z) strncpy(_x, _y, _z - 1)
|
||||
#define ks_set_string(_x, _y) ks_copy_string(_x, _y, sizeof(_x))
|
||||
#define KS_VA_NONE "%s", ""
|
||||
|
||||
|
||||
typedef enum {
|
||||
KS_POLL_READ = (1 << 0),
|
||||
KS_POLL_WRITE = (1 << 1),
|
||||
KS_POLL_ERROR = (1 << 2)
|
||||
} ks_poll_t;
|
||||
|
||||
#ifdef WIN32
|
||||
#define KS_SEQ_FWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
|
||||
#define KS_SEQ_BWHITE FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||
#define KS_SEQ_FRED FOREGROUND_RED | FOREGROUND_INTENSITY
|
||||
#define KS_SEQ_BRED FOREGROUND_RED
|
||||
#define KS_SEQ_FMAGEN FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY
|
||||
#define KS_SEQ_BMAGEN FOREGROUND_BLUE | FOREGROUND_RED
|
||||
#define KS_SEQ_FCYAN FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY
|
||||
#define KS_SEQ_BCYAN FOREGROUND_GREEN | FOREGROUND_BLUE
|
||||
#define KS_SEQ_FGREEN FOREGROUND_GREEN | FOREGROUND_INTENSITY
|
||||
#define KS_SEQ_BGREEN FOREGROUND_GREEN
|
||||
#define KS_SEQ_FYELLOW FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY
|
||||
#define KS_SEQ_BYELLOW FOREGROUND_RED | FOREGROUND_GREEN
|
||||
#define KS_SEQ_DEFAULT_COLOR KS_SEQ_FWHITE
|
||||
#define KS_SEQ_FBLUE FOREGROUND_BLUE | FOREGROUND_INTENSITY
|
||||
#define KS_SEQ_BBLUE FOREGROUND_BLUE
|
||||
#define KS_SEQ_FBLACK 0 | FOREGROUND_INTENSITY
|
||||
#define KS_SEQ_BBLACK 0
|
||||
#else
|
||||
#define KS_SEQ_ESC "\033["
|
||||
/* Ansi Control character suffixes */
|
||||
#define KS_SEQ_HOME_CHAR 'H'
|
||||
#define KS_SEQ_HOME_CHAR_STR "H"
|
||||
#define KS_SEQ_CLEARLINE_CHAR '1'
|
||||
#define KS_SEQ_CLEARLINE_CHAR_STR "1"
|
||||
#define KS_SEQ_CLEARLINEEND_CHAR "K"
|
||||
#define KS_SEQ_CLEARSCR_CHAR0 '2'
|
||||
#define KS_SEQ_CLEARSCR_CHAR1 'J'
|
||||
#define KS_SEQ_CLEARSCR_CHAR "2J"
|
||||
#define KS_SEQ_DEFAULT_COLOR KS_SEQ_ESC KS_SEQ_END_COLOR /* Reset to Default fg/bg color */
|
||||
#define KS_SEQ_AND_COLOR ";" /* To add multiple color definitions */
|
||||
#define KS_SEQ_END_COLOR "m" /* To end color definitions */
|
||||
/* Foreground colors values */
|
||||
#define KS_SEQ_F_BLACK "30"
|
||||
#define KS_SEQ_F_RED "31"
|
||||
#define KS_SEQ_F_GREEN "32"
|
||||
#define KS_SEQ_F_YELLOW "33"
|
||||
#define KS_SEQ_F_BLUE "34"
|
||||
#define KS_SEQ_F_MAGEN "35"
|
||||
#define KS_SEQ_F_CYAN "36"
|
||||
#define KS_SEQ_F_WHITE "37"
|
||||
/* Background colors values */
|
||||
#define KS_SEQ_B_BLACK "40"
|
||||
#define KS_SEQ_B_RED "41"
|
||||
#define KS_SEQ_B_GREEN "42"
|
||||
#define KS_SEQ_B_YELLOW "43"
|
||||
#define KS_SEQ_B_BLUE "44"
|
||||
#define KS_SEQ_B_MAGEN "45"
|
||||
#define KS_SEQ_B_CYAN "46"
|
||||
#define KS_SEQ_B_WHITE "47"
|
||||
/* Preset escape sequences - Change foreground colors only */
|
||||
#define KS_SEQ_FBLACK KS_SEQ_ESC KS_SEQ_F_BLACK KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_FRED KS_SEQ_ESC KS_SEQ_F_RED KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_FGREEN KS_SEQ_ESC KS_SEQ_F_GREEN KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_FYELLOW KS_SEQ_ESC KS_SEQ_F_YELLOW KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_FBLUE KS_SEQ_ESC KS_SEQ_F_BLUE KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_FMAGEN KS_SEQ_ESC KS_SEQ_F_MAGEN KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_FCYAN KS_SEQ_ESC KS_SEQ_F_CYAN KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_FWHITE KS_SEQ_ESC KS_SEQ_F_WHITE KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_BBLACK KS_SEQ_ESC KS_SEQ_B_BLACK KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_BRED KS_SEQ_ESC KS_SEQ_B_RED KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_BGREEN KS_SEQ_ESC KS_SEQ_B_GREEN KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_BYELLOW KS_SEQ_ESC KS_SEQ_B_YELLOW KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_BBLUE KS_SEQ_ESC KS_SEQ_B_BLUE KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_BMAGEN KS_SEQ_ESC KS_SEQ_B_MAGEN KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_BCYAN KS_SEQ_ESC KS_SEQ_B_CYAN KS_SEQ_END_COLOR
|
||||
#define KS_SEQ_BWHITE KS_SEQ_ESC KS_SEQ_B_WHITE KS_SEQ_END_COLOR
|
||||
/* Preset escape sequences */
|
||||
#define KS_SEQ_HOME KS_SEQ_ESC KS_SEQ_HOME_CHAR_STR
|
||||
#define KS_SEQ_CLEARLINE KS_SEQ_ESC KS_SEQ_CLEARLINE_CHAR_STR
|
||||
#define KS_SEQ_CLEARLINEEND KS_SEQ_ESC KS_SEQ_CLEARLINEEND_CHAR
|
||||
#define KS_SEQ_CLEARSCR KS_SEQ_ESC KS_SEQ_CLEARSCR_CHAR KS_SEQ_HOME
|
||||
#endif
|
||||
|
||||
#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
#define _XOPEN_SOURCE 600
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRINGS_H
|
||||
#define HAVE_STRINGS_H 1
|
||||
#endif
|
||||
#ifndef HAVE_SYS_SOCKET_H
|
||||
#define HAVE_SYS_SOCKET_H 1
|
||||
#endif
|
||||
|
||||
#ifndef __WINDOWS__
|
||||
#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifndef __inline__
|
||||
#define __inline__ __inline
|
||||
#endif
|
||||
#if (_MSC_VER >= 1400) /* VC8+ */
|
||||
#ifndef _CRT_SECURE_NO_DEPRECATE
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
#ifndef _CRT_NONSTDC_NO_DEPRECATE
|
||||
#define _CRT_NONSTDC_NO_DEPRECATE
|
||||
#endif
|
||||
#endif
|
||||
#ifndef strcasecmp
|
||||
#define strcasecmp(s1, s2) _stricmp(s1, s2)
|
||||
#endif
|
||||
#ifndef strncasecmp
|
||||
#define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
|
||||
#endif
|
||||
#ifndef snprintf
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#ifndef S_IRUSR
|
||||
#define S_IRUSR _S_IREAD
|
||||
#endif
|
||||
#ifndef S_IWUSR
|
||||
#define S_IWUSR _S_IWRITE
|
||||
#endif
|
||||
#undef HAVE_STRINGS_H
|
||||
#undef HAVE_SYS_SOCKET_H
|
||||
#endif
|
||||
|
||||
#include <time.h>
|
||||
#ifndef WIN32
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/select.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <sys/signal.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
|
||||
#if (_MSC_VER >= 1400) // VC8+
|
||||
#define ks_assert(expr) assert(expr);__analysis_assume( expr )
|
||||
#endif
|
||||
|
||||
#ifndef ks_assert
|
||||
#define ks_assert(_x) assert(_x)
|
||||
#endif
|
||||
|
||||
#define ks_safe_free(_x) if (_x) free(_x); _x = NULL
|
||||
#define ks_strlen_zero(s) (!s || *(s) == '\0')
|
||||
#define ks_strlen_zero_buf(s) (*(s) == '\0')
|
||||
#define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1)
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
typedef SOCKET ks_socket_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int8 int8_t;
|
||||
typedef intptr_t ks_ssize_t;
|
||||
typedef int ks_filehandle_t;
|
||||
#define KS_SOCK_INVALID INVALID_SOCKET
|
||||
#define strerror_r(num, buf, size) strerror_s(buf, size, num)
|
||||
#if defined(KS_DECLARE_STATIC)
|
||||
#define KS_DECLARE(type) type __stdcall
|
||||
#define KS_DECLARE_NONSTD(type) type __cdecl
|
||||
#define KS_DECLARE_DATA
|
||||
#elif defined(KS_EXPORTS)
|
||||
#define KS_DECLARE(type) __declspec(dllexport) type __stdcall
|
||||
#define KS_DECLARE_NONSTD(type) __declspec(dllexport) type __cdecl
|
||||
#define KS_DECLARE_DATA __declspec(dllexport)
|
||||
#else
|
||||
#define KS_DECLARE(type) __declspec(dllimport) type __stdcall
|
||||
#define KS_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
|
||||
#define KS_DECLARE_DATA __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define KS_DECLARE(type) type
|
||||
#define KS_DECLARE_NONSTD(type) type
|
||||
#define KS_DECLARE_DATA
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#define KS_SOCK_INVALID -1
|
||||
typedef int ks_socket_t;
|
||||
typedef ssize_t ks_ssize_t;
|
||||
typedef int ks_filehandle_t;
|
||||
#endif
|
||||
|
||||
#include "math.h"
|
||||
#include "ks_json.h"
|
||||
|
||||
typedef int16_t ks_port_t;
|
||||
typedef size_t ks_size_t;
|
||||
|
||||
typedef enum {
|
||||
KS_SUCCESS,
|
||||
KS_FAIL,
|
||||
KS_BREAK,
|
||||
KS_DISCONNECTED,
|
||||
KS_GENERR
|
||||
} ks_status_t;
|
||||
|
||||
#define BUF_CHUNK 65536 * 50
|
||||
#define BUF_START 65536 * 100
|
||||
|
||||
#include <ks_threadmutex.h>
|
||||
#include <ks_buffer.h>
|
||||
|
||||
#define ks_test_flag(obj, flag) ((obj)->flags & flag)
|
||||
#define ks_set_flag(obj, flag) (obj)->flags |= (flag)
|
||||
#define ks_clear_flag(obj, flag) (obj)->flags &= ~(flag)
|
||||
|
||||
/*! \brief Used internally for truth test */
|
||||
typedef enum {
|
||||
KS_TRUE = 1,
|
||||
KS_FALSE = 0
|
||||
} ks_bool_t;
|
||||
|
||||
#ifndef __FUNCTION__
|
||||
#define __FUNCTION__ (const char *)__func__
|
||||
#endif
|
||||
|
||||
#define KS_PRE __FILE__, __FUNCTION__, __LINE__
|
||||
#define KS_LOG_LEVEL_DEBUG 7
|
||||
#define KS_LOG_LEVEL_INFO 6
|
||||
#define KS_LOG_LEVEL_NOTICE 5
|
||||
#define KS_LOG_LEVEL_WARNING 4
|
||||
#define KS_LOG_LEVEL_ERROR 3
|
||||
#define KS_LOG_LEVEL_CRIT 2
|
||||
#define KS_LOG_LEVEL_ALERT 1
|
||||
#define KS_LOG_LEVEL_EMERG 0
|
||||
|
||||
#define KS_LOG_DEBUG KS_PRE, KS_LOG_LEVEL_DEBUG
|
||||
#define KS_LOG_INFO KS_PRE, KS_LOG_LEVEL_INFO
|
||||
#define KS_LOG_NOTICE KS_PRE, KS_LOG_LEVEL_NOTICE
|
||||
#define KS_LOG_WARNING KS_PRE, KS_LOG_LEVEL_WARNING
|
||||
#define KS_LOG_ERROR KS_PRE, KS_LOG_LEVEL_ERROR
|
||||
#define KS_LOG_CRIT KS_PRE, KS_LOG_LEVEL_CRIT
|
||||
#define KS_LOG_ALERT KS_PRE, KS_LOG_LEVEL_ALERT
|
||||
#define KS_LOG_EMERG KS_PRE, KS_LOG_LEVEL_EMERG
|
||||
typedef void (*ks_logger_t)(const char *file, const char *func, int line, int level, const char *fmt, ...);
|
||||
typedef void (*ks_listen_callback_t)(ks_socket_t server_sock, ks_socket_t client_sock, struct sockaddr_in *addr);
|
||||
|
||||
|
||||
KS_DECLARE(int) ks_vasprintf(char **ret, const char *fmt, va_list ap);
|
||||
|
||||
KS_DECLARE_DATA extern ks_logger_t ks_log;
|
||||
|
||||
/*! Sets the logger for libks. Default is the null_logger */
|
||||
KS_DECLARE(void) ks_global_set_logger(ks_logger_t logger);
|
||||
/*! Sets the default log level for libks */
|
||||
KS_DECLARE(void) ks_global_set_default_logger(int level);
|
||||
|
||||
|
||||
#include "ks_threadmutex.h"
|
||||
#include "ks_config.h"
|
||||
#include "ks_buffer.h"
|
||||
#include "mpool.h"
|
||||
#include "simclist.h"
|
||||
#include "table.h"
|
||||
|
||||
KS_DECLARE(size_t) ks_url_encode(const char *url, char *buf, size_t len);
|
||||
KS_DECLARE(char *)ks_url_decode(char *s);
|
||||
KS_DECLARE(const char *)ks_stristr(const char *instr, const char *str);
|
||||
KS_DECLARE(int) ks_toupper(int c);
|
||||
KS_DECLARE(int) ks_tolower(int c);
|
||||
KS_DECLARE(int) ks_snprintf(char *buffer, size_t count, const char *fmt, ...);
|
||||
|
||||
|
||||
KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags);
|
||||
|
||||
KS_DECLARE(unsigned int) ks_separate_string_string(char *buf, const char *delim, char **array, unsigned int arraylen);
|
||||
|
||||
#define ks_recv(_h) ks_recv_event(_h, 0, NULL)
|
||||
#define ks_recv_timed(_h, _ms) ks_recv_event_timed(_h, _ms, 0, NULL)
|
||||
|
||||
static __inline__ int ks_safe_strcasecmp(const char *s1, const char *s2)
|
||||
{
|
||||
if (!(s1 && s2)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return strcasecmp(s1, s2);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
|
||||
#endif /* defined(_KS_H_) */
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2012, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* 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 OWNER
|
||||
* 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.
|
||||
*/
|
||||
#include "ks.h"
|
||||
#ifndef KS_BUFFER_H
|
||||
#define KS_BUFFER_H
|
||||
/**
|
||||
* @defgroup ks_buffer Buffer Routines
|
||||
* @ingroup buffer
|
||||
* The purpose of this module is to make a plain buffering interface that can be used for read/write buffers
|
||||
* throughout the application.
|
||||
* @{
|
||||
*/
|
||||
struct ks_buffer;
|
||||
typedef struct ks_buffer ks_buffer_t;
|
||||
|
||||
/*! \brief Allocate a new dynamic ks_buffer
|
||||
* \param buffer returned pointer to the new buffer
|
||||
* \param blocksize length to realloc by as data is added
|
||||
* \param start_len ammount of memory to reserve initially
|
||||
* \param max_len length the buffer is allowed to grow to
|
||||
* \return status
|
||||
*/
|
||||
KS_DECLARE(ks_status_t) ks_buffer_create(ks_buffer_t **buffer, ks_size_t blocksize, ks_size_t start_len, ks_size_t max_len);
|
||||
|
||||
/*! \brief Get the length of a ks_buffer_t
|
||||
* \param buffer any buffer of type ks_buffer_t
|
||||
* \return int size of the buffer.
|
||||
*/
|
||||
KS_DECLARE(ks_size_t) ks_buffer_len(ks_buffer_t *buffer);
|
||||
|
||||
/*! \brief Get the freespace of a ks_buffer_t
|
||||
* \param buffer any buffer of type ks_buffer_t
|
||||
* \return int freespace in the buffer.
|
||||
*/
|
||||
KS_DECLARE(ks_size_t) ks_buffer_freespace(ks_buffer_t *buffer);
|
||||
|
||||
/*! \brief Get the in use amount of a ks_buffer_t
|
||||
* \param buffer any buffer of type ks_buffer_t
|
||||
* \return int ammount of buffer curently in use
|
||||
*/
|
||||
KS_DECLARE(ks_size_t) ks_buffer_inuse(ks_buffer_t *buffer);
|
||||
|
||||
/*! \brief Read data from a ks_buffer_t up to the ammount of datalen if it is available. Remove read data from buffer.
|
||||
* \param buffer any buffer of type ks_buffer_t
|
||||
* \param data pointer to the read data to be returned
|
||||
* \param datalen amount of data to be returned
|
||||
* \return int ammount of data actually read
|
||||
*/
|
||||
KS_DECLARE(ks_size_t) ks_buffer_read(ks_buffer_t *buffer, void *data, ks_size_t datalen);
|
||||
|
||||
KS_DECLARE(ks_size_t) ks_buffer_read_packet(ks_buffer_t *buffer, void *data, ks_size_t maxlen);
|
||||
KS_DECLARE(ks_size_t) ks_buffer_packet_count(ks_buffer_t *buffer);
|
||||
|
||||
/*! \brief Read data endlessly from a ks_buffer_t
|
||||
* \param buffer any buffer of type ks_buffer_t
|
||||
* \param data pointer to the read data to be returned
|
||||
* \param datalen amount of data to be returned
|
||||
* \return int ammount of data actually read
|
||||
* \note Once you have read all the data from the buffer it will loop around.
|
||||
*/
|
||||
KS_DECLARE(ks_size_t) ks_buffer_read_loop(ks_buffer_t *buffer, void *data, ks_size_t datalen);
|
||||
|
||||
/*! \brief Assign a number of loops to read
|
||||
* \param buffer any buffer of type ks_buffer_t
|
||||
* \param loops the number of loops (-1 for infinite)
|
||||
*/
|
||||
KS_DECLARE(void) ks_buffer_set_loops(ks_buffer_t *buffer, int32_t loops);
|
||||
|
||||
/*! \brief Write data into a ks_buffer_t up to the length of datalen
|
||||
* \param buffer any buffer of type ks_buffer_t
|
||||
* \param data pointer to the data to be written
|
||||
* \param datalen amount of data to be written
|
||||
* \return int amount of buffer used after the write, or 0 if no space available
|
||||
*/
|
||||
KS_DECLARE(ks_size_t) ks_buffer_write(ks_buffer_t *buffer, const void *data, ks_size_t datalen);
|
||||
|
||||
/*! \brief Remove data from the buffer
|
||||
* \param buffer any buffer of type ks_buffer_t
|
||||
* \param datalen amount of data to be removed
|
||||
* \return int size of buffer, or 0 if unable to toss that much data
|
||||
*/
|
||||
KS_DECLARE(ks_size_t) ks_buffer_toss(ks_buffer_t *buffer, ks_size_t datalen);
|
||||
|
||||
/*! \brief Remove all data from the buffer
|
||||
* \param buffer any buffer of type ks_buffer_t
|
||||
*/
|
||||
KS_DECLARE(void) ks_buffer_zero(ks_buffer_t *buffer);
|
||||
|
||||
/*! \brief Destroy the buffer
|
||||
* \param buffer buffer to destroy
|
||||
* \note only neccessary on dynamic buffers (noop on pooled ones)
|
||||
*/
|
||||
KS_DECLARE(void) ks_buffer_destroy(ks_buffer_t **buffer);
|
||||
|
||||
/*! \brief Seek to offset from the beginning of the buffer
|
||||
* \param buffer buffer to seek
|
||||
* \param datalen offset in bytes
|
||||
* \return new position
|
||||
*/
|
||||
KS_DECLARE(ks_size_t) ks_buffer_seek(ks_buffer_t *buffer, ks_size_t datalen);
|
||||
|
||||
/** @} */
|
||||
|
||||
KS_DECLARE(ks_size_t) ks_buffer_zwrite(ks_buffer_t *buffer, const void *data, ks_size_t datalen);
|
||||
|
||||
#endif
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 2007-2012, Anthony Minessale II
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * 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.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* 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 OWNER
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup config Config File Parser
|
||||
* @ingroup config
|
||||
* This module implements a basic interface and file format parser
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* EXAMPLE
|
||||
*
|
||||
* [category1]
|
||||
* var1 => val1
|
||||
* var2 => val2
|
||||
* \# lines that begin with \# are comments
|
||||
* \#var3 => val3
|
||||
* </pre>
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef KS_CONFIG_H
|
||||
#define KS_CONFIG_H
|
||||
|
||||
#include "ks.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
|
||||
#define KS_URL_SEPARATOR "://"
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#define KS_PATH_SEPARATOR "\\"
|
||||
#ifndef KS_CONFIG_DIR
|
||||
#define KS_CONFIG_DIR "c:\\openks"
|
||||
#endif
|
||||
#define ks_is_file_path(file) (*(file +1) == ':' || *file == '/' || strstr(file, SWITCH_URL_SEPARATOR))
|
||||
#else
|
||||
#define KS_PATH_SEPARATOR "/"
|
||||
#ifndef KS_CONFIG_DIR
|
||||
#define KS_CONFIG_DIR "/etc/openks"
|
||||
#endif
|
||||
#define ks_is_file_path(file) ((*file == '/') || strstr(file, SWITCH_URL_SEPARATOR))
|
||||
#endif
|
||||
|
||||
/*!
|
||||
\brief Evaluate the truthfullness of a string expression
|
||||
\param expr a string expression
|
||||
\return true or false
|
||||
*/
|
||||
#define ks_true(expr)\
|
||||
(expr && ( !strcasecmp(expr, "yes") ||\
|
||||
!strcasecmp(expr, "on") ||\
|
||||
!strcasecmp(expr, "true") ||\
|
||||
!strcasecmp(expr, "enabled") ||\
|
||||
!strcasecmp(expr, "active") ||\
|
||||
!strcasecmp(expr, "allow") ||\
|
||||
atoi(expr))) ? 1 : 0
|
||||
|
||||
/*!
|
||||
\brief Evaluate the falsefullness of a string expression
|
||||
\param expr a string expression
|
||||
\return true or false
|
||||
*/
|
||||
#define ks_false(expr)\
|
||||
(expr && ( !strcasecmp(expr, "no") ||\
|
||||
!strcasecmp(expr, "off") ||\
|
||||
!strcasecmp(expr, "false") ||\
|
||||
!strcasecmp(expr, "disabled") ||\
|
||||
!strcasecmp(expr, "inactive") ||\
|
||||
!strcasecmp(expr, "disallow") ||\
|
||||
!atoi(expr))) ? 1 : 0
|
||||
|
||||
typedef struct ks_config ks_config_t;
|
||||
|
||||
/*! \brief A simple file handle representing an open configuration file **/
|
||||
struct ks_config {
|
||||
/*! FILE stream buffer to the opened file */
|
||||
FILE *file;
|
||||
/*! path to the file */
|
||||
char path[512];
|
||||
/*! current category */
|
||||
char category[256];
|
||||
/*! current section */
|
||||
char section[256];
|
||||
/*! buffer of current line being read */
|
||||
char buf[1024];
|
||||
/*! current line number in file */
|
||||
int lineno;
|
||||
/*! current category number in file */
|
||||
int catno;
|
||||
/*! current section number in file */
|
||||
int sectno;
|
||||
|
||||
int lockto;
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Open a configuration file
|
||||
\param cfg (ks_config_t *) config handle to use
|
||||
\param file_path path to the file
|
||||
\return 1 (true) on success 0 (false) on failure
|
||||
*/
|
||||
KS_DECLARE(int) ks_config_open_file(ks_config_t * cfg, const char *file_path);
|
||||
|
||||
/*!
|
||||
\brief Close a previously opened configuration file
|
||||
\param cfg (ks_config_t *) config handle to use
|
||||
*/
|
||||
KS_DECLARE(void) ks_config_close_file(ks_config_t * cfg);
|
||||
|
||||
/*!
|
||||
\brief Retrieve next name/value pair from configuration file
|
||||
\param cfg (ks_config_t *) config handle to use
|
||||
\param var pointer to aim at the new variable name
|
||||
\param val pointer to aim at the new value
|
||||
*/
|
||||
KS_DECLARE(int) ks_config_next_pair(ks_config_t * cfg, char **var, char **val);
|
||||
|
||||
/*!
|
||||
\brief Retrieve the CAS bits from a configuration string value
|
||||
\param strvalue pointer to the configuration string value (expected to be in format whatever:xxxx)
|
||||
\param outbits pointer to aim at the CAS bits
|
||||
*/
|
||||
KS_DECLARE(int) ks_config_get_cas_bits(char *strvalue, unsigned char *outbits);
|
||||
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif /* defined(KS_CONFIG_H) */
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
Executable
+127
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Copyright (c) 2009 Dave Gamble
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
#include "ks.h"
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_False 0
|
||||
#define cJSON_True 1
|
||||
#define cJSON_NULL 2
|
||||
#define cJSON_Number 3
|
||||
#define cJSON_String 4
|
||||
#define cJSON_Array 5
|
||||
#define cJSON_Object 6
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON {
|
||||
struct cJSON *next,*prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
|
||||
int type; /* The type of the item, as above. */
|
||||
|
||||
char *valuestring; /* The item's string, if type==cJSON_String */
|
||||
int valueint; /* The item's number, if type==cJSON_Number */
|
||||
double valuedouble; /* The item's number, if type==cJSON_Number */
|
||||
|
||||
char *string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks {
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
KS_DECLARE(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
|
||||
KS_DECLARE(cJSON *)cJSON_Parse(const char *value);
|
||||
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
|
||||
KS_DECLARE(char *)cJSON_Print(cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
|
||||
KS_DECLARE(char *)cJSON_PrintUnformatted(cJSON *item);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
KS_DECLARE(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
KS_DECLARE(int) cJSON_GetArraySize(cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
KS_DECLARE(cJSON *)cJSON_GetArrayItem(cJSON *array,int item);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
KS_DECLARE(cJSON *)cJSON_GetObjectItem(cJSON *object,const char *string);
|
||||
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
KS_DECLARE(const char *)cJSON_GetErrorPtr();
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
KS_DECLARE(cJSON *)cJSON_CreateNull();
|
||||
KS_DECLARE(cJSON *)cJSON_CreateTrue();
|
||||
KS_DECLARE(cJSON *)cJSON_CreateFalse();
|
||||
KS_DECLARE(cJSON *)cJSON_CreateBool(int b);
|
||||
KS_DECLARE(cJSON *)cJSON_CreateNumber(double num);
|
||||
KS_DECLARE(cJSON *)cJSON_CreateString(const char *string);
|
||||
KS_DECLARE(cJSON *)cJSON_CreateArray();
|
||||
KS_DECLARE(cJSON *)cJSON_CreateObject();
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
KS_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count);
|
||||
KS_DECLARE(cJSON *)cJSON_CreateFloatArray(float *numbers,int count);
|
||||
KS_DECLARE(cJSON *)cJSON_CreateDoubleArray(double *numbers,int count);
|
||||
KS_DECLARE(cJSON *)cJSON_CreateStringArray(const char **strings,int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
KS_DECLARE(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
KS_DECLARE(void) cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
KS_DECLARE(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
KS_DECLARE(void) cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
KS_DECLARE(cJSON *)cJSON_DetachItemFromArray(cJSON *array,int which);
|
||||
KS_DECLARE(void) cJSON_DeleteItemFromArray(cJSON *array,int which);
|
||||
KS_DECLARE(cJSON *)cJSON_DetachItemFromObject(cJSON *object,const char *string);
|
||||
KS_DECLARE(void) cJSON_DeleteItemFromObject(cJSON *object,const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
KS_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
|
||||
KS_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Cross Platform Thread/Mutex abstraction
|
||||
* Copyright(C) 2007 Michael Jerris
|
||||
*
|
||||
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
* copies of the Software, and permit persons to whom the Software is
|
||||
* furnished to do so.
|
||||
*
|
||||
* This work is provided under this license on an "as is" basis, without warranty of any kind,
|
||||
* either expressed or implied, including, without limitation, warranties that the covered code
|
||||
* is free of defects, merchantable, fit for a particular purpose or non-infringing. The entire
|
||||
* risk as to the quality and performance of the covered code is with you. Should any covered
|
||||
* code prove defective in any respect, you (not the initial developer or any other contributor)
|
||||
* assume the cost of any necessary servicing, repair or correction. This disclaimer of warranty
|
||||
* constitutes an essential part of this license. No use of any covered code is authorized hereunder
|
||||
* except under this disclaimer.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _KS_THREADMUTEX_H
|
||||
#define _KS_THREADMUTEX_H
|
||||
|
||||
#include "ks.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
typedef struct ks_mutex ks_mutex_t;
|
||||
typedef struct ks_thread ks_thread_t;
|
||||
typedef void *(*ks_thread_function_t) (ks_thread_t *, void *);
|
||||
|
||||
KS_DECLARE(ks_status_t) ks_thread_create_detached(ks_thread_function_t func, void *data);
|
||||
ks_status_t ks_thread_create_detached_ex(ks_thread_function_t func, void *data, size_t stack_size);
|
||||
void ks_thread_override_default_stacksize(size_t size);
|
||||
KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex);
|
||||
KS_DECLARE(ks_status_t) ks_mutex_destroy(ks_mutex_t **mutex);
|
||||
KS_DECLARE(ks_status_t) ks_mutex_lock(ks_mutex_t *mutex);
|
||||
KS_DECLARE(ks_status_t) ks_mutex_trylock(ks_mutex_t *mutex);
|
||||
KS_DECLARE(ks_status_t) ks_mutex_unlock(ks_mutex_t *mutex);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* defined(__cplusplus) */
|
||||
|
||||
#endif /* defined(_KS_THREADMUTEX_H) */
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
* mode:c
|
||||
* indent-tabs-mode:t
|
||||
* tab-width:4
|
||||
* c-basic-offset:4
|
||||
* End:
|
||||
* For VIM:
|
||||
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
|
||||
*/
|
||||
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* Memory pool defines.
|
||||
*
|
||||
* Copyright 1996 by Gray Watson.
|
||||
*
|
||||
* This file is part of the mpool package.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for
|
||||
* any purpose and without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies, and that the name of Gray Watson not be used in advertising
|
||||
* or publicity pertaining to distribution of the document or software
|
||||
* without specific, written prior permission.
|
||||
*
|
||||
* Gray Watson makes no representations about the suitability of the
|
||||
* software described herein for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* The author may be reached via http://256.com/gray/
|
||||
*
|
||||
* $Id: mpool.h,v 1.4 2006/05/31 20:26:11 gray Exp $
|
||||
*/
|
||||
|
||||
#ifndef __MPOOL_H__
|
||||
#define __MPOOL_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* mpool flags to mpool_alloc or mpool_set_attr
|
||||
*/
|
||||
|
||||
/*
|
||||
* Choose a best fit algorithm not first fit. This takes more CPU
|
||||
* time but will result in a tighter heap.
|
||||
*/
|
||||
#define MPOOL_FLAG_BEST_FIT (1<<0)
|
||||
|
||||
/*
|
||||
* By default the library adds 2 bytes onto all allocations to insert
|
||||
* a magic number that it can look for to determine how large a freed
|
||||
* memory chunk is. This flag indicates that few if any frees are
|
||||
* going to be performed on the pool and to not waste memory on these
|
||||
* bytes.
|
||||
*/
|
||||
#define MPOOL_FLAG_NO_FREE (1<<1)
|
||||
|
||||
/*
|
||||
* This enables very heavy packing at the possible expense of CPU.
|
||||
* This affects a number of parts of the library.
|
||||
*
|
||||
* By default the 1st page of memory is reserved for the main mpool
|
||||
* structure. This flag will cause the rest of the 1st block to be
|
||||
* available for use as user memory.
|
||||
*
|
||||
* By default the library looks through the memory when freed looking
|
||||
* for a magic value. There is an internal max size that it will look
|
||||
* and then it will give up. This flag forces it to look until it
|
||||
* finds it.
|
||||
*/
|
||||
#define MPOOL_FLAG_HEAVY_PACKING (1<<2)
|
||||
|
||||
/*
|
||||
* Use sbrk not mmap to allocate pages. This is not recommended for
|
||||
* normal use.
|
||||
*/
|
||||
#define MPOOL_FLAG_USE_SBRK (1<<3)
|
||||
|
||||
/*
|
||||
* Mpool error codes
|
||||
*/
|
||||
#define MPOOL_ERROR_NONE 1 /* no error */
|
||||
#define MPOOL_ERROR_ARG_NULL 2 /* function argument is null */
|
||||
#define MPOOL_ERROR_ARG_INVALID 3 /* function argument is invalid */
|
||||
#define MPOOL_ERROR_PNT 4 /* invalid mpool pointer */
|
||||
#define MPOOL_ERROR_POOL_OVER 5 /* mpool structure was overwritten */
|
||||
#define MPOOL_ERROR_PAGE_SIZE 6 /* could not get system page-size */
|
||||
#define MPOOL_ERROR_OPEN_ZERO 7 /* could not open /dev/zero */
|
||||
#define MPOOL_ERROR_NO_MEM 8 /* no memory available */
|
||||
#define MPOOL_ERROR_MMAP 9 /* problems with mmap */
|
||||
#define MPOOL_ERROR_SIZE 10 /* error processing requested size */
|
||||
#define MPOOL_ERROR_TOO_BIG 11 /* allocation exceeded max size */
|
||||
#define MPOOL_ERROR_MEM 12 /* invalid memory address */
|
||||
#define MPOOL_ERROR_MEM_OVER 13 /* memory lower bounds overwritten */
|
||||
#define MPOOL_ERROR_NOT_FOUND 14 /* memory block not found in pool */
|
||||
#define MPOOL_ERROR_IS_FREE 15 /* memory block already free */
|
||||
#define MPOOL_ERROR_BLOCK_STAT 16 /* invalid internal block status */
|
||||
#define MPOOL_ERROR_FREE_ADDR 17 /* invalid internal free address */
|
||||
#define MPOOL_ERROR_SBRK_CONTIG 18 /* sbrk did not return contiguous mem*/
|
||||
#define MPOOL_ERROR_NO_PAGES 19 /* ran out of pages in pool */
|
||||
#define MPOOL_ERROR_ALLOC 20 /* calloc,malloc,free,realloc failed */
|
||||
#define MPOOL_ERROR_PNT_OVER 21 /* pointer structure was overwritten */
|
||||
|
||||
/*
|
||||
* Mpool function IDs for the mpool_log_func callback function.
|
||||
*/
|
||||
#define MPOOL_FUNC_CLOSE 1 /* mpool_close function called */
|
||||
#define MPOOL_FUNC_CLEAR 2 /* mpool_clear function called */
|
||||
#define MPOOL_FUNC_ALLOC 3 /* mpool_alloc function called */
|
||||
#define MPOOL_FUNC_CALLOC 4 /* mpool_calloc function called */
|
||||
#define MPOOL_FUNC_FREE 5 /* mpool_free function called */
|
||||
#define MPOOL_FUNC_RESIZE 6 /* mpool_resize function called */
|
||||
|
||||
/*
|
||||
* void mpool_log_func_t
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Mpool transaction log function.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* ARGUMENT:
|
||||
*
|
||||
* mp_p -> Associated mpool address.
|
||||
*
|
||||
* func_id -> Integer function ID which identifies which mpool
|
||||
* function is being called.
|
||||
*
|
||||
* byte_size -> Optionally specified byte size.
|
||||
*
|
||||
* ele_n -> Optionally specified element number. For mpool_calloc
|
||||
* only.
|
||||
*
|
||||
* new_addr -> Optionally specified new address. For mpool_alloc,
|
||||
* mpool_calloc, and mpool_resize only.
|
||||
*
|
||||
* old_addr -> Optionally specified old address. For mpool_resize and
|
||||
* mpool_free only.
|
||||
*
|
||||
* old_byte_size -> Optionally specified old byte size. For
|
||||
* mpool_resize only.
|
||||
*/
|
||||
typedef void (*mpool_log_func_t)(const void *mp_p,
|
||||
const int func_id,
|
||||
const unsigned long byte_size,
|
||||
const unsigned long ele_n,
|
||||
const void *old_addr, const void *new_addr,
|
||||
const unsigned long old_byte_size);
|
||||
|
||||
#ifdef MPOOL_MAIN
|
||||
|
||||
#include "mpool_loc.h"
|
||||
|
||||
#else
|
||||
|
||||
/* generic mpool type */
|
||||
typedef void mpool_t;
|
||||
|
||||
#endif
|
||||
|
||||
/*<<<<<<<<<< The below prototypes are auto-generated by fillproto */
|
||||
|
||||
/*
|
||||
* mpool_t *mpool_open
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Open/allocate a new memory pool.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - Pool pointer which must be passed to mpool_close to
|
||||
* deallocate.
|
||||
*
|
||||
* Failure - NULL
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* flags -> Flags to set attributes of the memory pool. See the top
|
||||
* of mpool.h.
|
||||
*
|
||||
* page_size -> Set the internal memory page-size. This must be a
|
||||
* multiple of the getpagesize() value. Set to 0 for the default.
|
||||
*
|
||||
* start_addr -> Starting address to try and allocate memory pools.
|
||||
* This is ignored if the MPOOL_FLAG_USE_SBRK is enabled.
|
||||
*
|
||||
* error_p <- Pointer to integer which, if not NULL, will be set with
|
||||
* a mpool error code.
|
||||
*/
|
||||
extern
|
||||
mpool_t *mpool_open(const unsigned int flags, const unsigned int page_size,
|
||||
void *start_addr, int *error_p);
|
||||
|
||||
/*
|
||||
* int mpool_close
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Close/free a memory allocation pool previously opened with
|
||||
* mpool_open.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - MPOOL_ERROR_NONE
|
||||
*
|
||||
* Failure - Mpool error code
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to our memory pool.
|
||||
*/
|
||||
extern
|
||||
int mpool_close(mpool_t *mp_p);
|
||||
|
||||
/*
|
||||
* int mpool_clear
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Wipe an opened memory pool clean so we can start again.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - MPOOL_ERROR_NONE
|
||||
*
|
||||
* Failure - Mpool error code
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to our memory pool.
|
||||
*/
|
||||
extern
|
||||
int mpool_clear(mpool_t *mp_p);
|
||||
|
||||
/*
|
||||
* void *mpool_alloc
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Allocate space for bytes inside of an already open memory pool.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - Pointer to the address to use.
|
||||
*
|
||||
* Failure - NULL
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to the memory pool. If NULL then it will do a
|
||||
* normal malloc.
|
||||
*
|
||||
* byte_size -> Number of bytes to allocate in the pool. Must be >0.
|
||||
*
|
||||
* error_p <- Pointer to integer which, if not NULL, will be set with
|
||||
* a mpool error code.
|
||||
*/
|
||||
extern
|
||||
void *mpool_alloc(mpool_t *mp_p, const unsigned long byte_size,
|
||||
int *error_p);
|
||||
|
||||
/*
|
||||
* void *mpool_calloc
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Allocate space for elements of bytes in the memory pool and zero
|
||||
* the space afterwards.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - Pointer to the address to use.
|
||||
*
|
||||
* Failure - NULL
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to the memory pool. If NULL then it will do a
|
||||
* normal calloc.
|
||||
*
|
||||
* ele_n -> Number of elements to allocate.
|
||||
*
|
||||
* ele_size -> Number of bytes per element being allocated.
|
||||
*
|
||||
* error_p <- Pointer to integer which, if not NULL, will be set with
|
||||
* a mpool error code.
|
||||
*/
|
||||
extern
|
||||
void *mpool_calloc(mpool_t *mp_p, const unsigned long ele_n,
|
||||
const unsigned long ele_size, int *error_p);
|
||||
|
||||
/*
|
||||
* int mpool_free
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Free an address from a memory pool.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - MPOOL_ERROR_NONE
|
||||
*
|
||||
* Failure - Mpool error code
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to the memory pool. If NULL then it will do a
|
||||
* normal free.
|
||||
*
|
||||
* addr <-> Address to free.
|
||||
*
|
||||
* size -> Size of the address being freed.
|
||||
*/
|
||||
extern
|
||||
int mpool_free(mpool_t *mp_p, void *addr, const unsigned long size);
|
||||
|
||||
/*
|
||||
* void *mpool_resize
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Reallocate an address in a mmeory pool to a new size. This is
|
||||
* different from realloc in that it needs the old address' size. If
|
||||
* you don't have it then you need to allocate new space, copy the
|
||||
* data, and free the old pointer yourself.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - Pointer to the address to use.
|
||||
*
|
||||
* Failure - NULL
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to the memory pool. If NULL then it will do a
|
||||
* normal realloc.
|
||||
*
|
||||
* old_addr -> Previously allocated address.
|
||||
*
|
||||
* old_byte_size -> Size of the old address. Must be known, cannot be
|
||||
* 0.
|
||||
*
|
||||
* new_byte_size -> New size of the allocation.
|
||||
*
|
||||
* error_p <- Pointer to integer which, if not NULL, will be set with
|
||||
* a mpool error code.
|
||||
*/
|
||||
extern
|
||||
void *mpool_resize(mpool_t *mp_p, void *old_addr,
|
||||
const unsigned long old_byte_size,
|
||||
const unsigned long new_byte_size,
|
||||
int *error_p);
|
||||
|
||||
/*
|
||||
* int mpool_stats
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Return stats from the memory pool.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - MPOOL_ERROR_NONE
|
||||
*
|
||||
* Failure - Mpool error code
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p -> Pointer to the memory pool.
|
||||
*
|
||||
* page_size_p <- Pointer to an unsigned integer which, if not NULL,
|
||||
* will be set to the page-size of the pool.
|
||||
*
|
||||
* num_alloced_p <- Pointer to an unsigned long which, if not NULL,
|
||||
* will be set to the number of pointers currently allocated in pool.
|
||||
*
|
||||
* user_alloced_p <- Pointer to an unsigned long which, if not NULL,
|
||||
* will be set to the number of user bytes allocated in this pool.
|
||||
*
|
||||
* max_alloced_p <- Pointer to an unsigned long which, if not NULL,
|
||||
* will be set to the maximum number of user bytes that have been
|
||||
* allocated in this pool.
|
||||
*
|
||||
* tot_alloced_p <- Pointer to an unsigned long which, if not NULL,
|
||||
* will be set to the total amount of space (including administrative
|
||||
* overhead) used by the pool.
|
||||
*/
|
||||
extern
|
||||
int mpool_stats(const mpool_t *mp_p, unsigned int *page_size_p,
|
||||
unsigned long *num_alloced_p,
|
||||
unsigned long *user_alloced_p,
|
||||
unsigned long *max_alloced_p,
|
||||
unsigned long *tot_alloced_p);
|
||||
|
||||
/*
|
||||
* int mpool_set_log_func
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Set a logging callback function to be called whenever there was a
|
||||
* memory transaction. See mpool_log_func_t.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - MPOOL_ERROR_NONE
|
||||
*
|
||||
* Failure - Mpool error code
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to the memory pool.
|
||||
*
|
||||
* log_func -> Log function (defined in mpool.h) which will be called
|
||||
* with each mpool transaction.
|
||||
*/
|
||||
extern
|
||||
int mpool_set_log_func(mpool_t *mp_p, mpool_log_func_t log_func);
|
||||
|
||||
/*
|
||||
* int mpool_set_max_pages
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Set the maximum number of pages that the library will use. Once it
|
||||
* hits the limit it will return MPOOL_ERROR_NO_PAGES.
|
||||
*
|
||||
* NOTE: if the MPOOL_FLAG_HEAVY_PACKING is set then this max-pages
|
||||
* value will include the page with the mpool header structure in it.
|
||||
* If the flag is _not_ set then the max-pages will not include this
|
||||
* first page.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - MPOOL_ERROR_NONE
|
||||
*
|
||||
* Failure - Mpool error code
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* mp_p <-> Pointer to the memory pool.
|
||||
*
|
||||
* max_pages -> Maximum number of pages used by the library.
|
||||
*/
|
||||
extern
|
||||
int mpool_set_max_pages(mpool_t *mp_p, const unsigned int max_pages);
|
||||
|
||||
/*
|
||||
* const char *mpool_strerror
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Return the corresponding string for the error number.
|
||||
*
|
||||
* RETURNS:
|
||||
*
|
||||
* Success - String equivalient of the error.
|
||||
*
|
||||
* Failure - String "invalid error code"
|
||||
*
|
||||
* ARGUMENTS:
|
||||
*
|
||||
* error -> Error number that we are converting.
|
||||
*/
|
||||
extern
|
||||
const char *mpool_strerror(const int error);
|
||||
|
||||
/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */
|
||||
|
||||
#endif /* ! __MPOOL_H__ */
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Memory pool local defines.
|
||||
*
|
||||
* Copyright 1996 by Gray Watson.
|
||||
*
|
||||
* This file is part of the mpool package.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for
|
||||
* any purpose and without fee is hereby granted, provided that the
|
||||
* above copyright notice and this permission notice appear in all
|
||||
* copies, and that the name of Gray Watson not be used in advertising
|
||||
* or publicity pertaining to distribution of the document or software
|
||||
* without specific, written prior permission.
|
||||
*
|
||||
* Gray Watson makes no representations about the suitability of the
|
||||
* software described herein for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* The author may be reached via http://256.com/gray/
|
||||
*
|
||||
* $Id: mpool_loc.h,v 1.2 2005/05/20 20:08:54 gray Exp $
|
||||
*/
|
||||
|
||||
#ifndef __MPOOL_LOC_H__
|
||||
#define __MPOOL_LOC_H__
|
||||
|
||||
#define MPOOL_MAGIC 0xABACABA /* magic for struct */
|
||||
#define BLOCK_MAGIC 0xB1B1007 /* magic for blocks */
|
||||
#define FENCE_MAGIC0 (unsigned char)(0xFAU) /* 1st magic mem byte */
|
||||
#define FENCE_MAGIC1 (unsigned char)(0xD3U) /* 2nd magic mem byte */
|
||||
|
||||
#define FENCE_SIZE 2 /* fence space */
|
||||
#define MIN_ALLOCATION (sizeof(mpool_free_t)) /* min alloc */
|
||||
#define MAX_FREE_SEARCH 10240 /* max size to search */
|
||||
#define MAX_FREE_LIST_SEARCH 100 /* max looking for free mem */
|
||||
|
||||
/*
|
||||
* bitflag tools for Variable and a Flag
|
||||
*/
|
||||
#define BIT_FLAG(x) (1 << (x))
|
||||
#define BIT_SET(v,f) (v) |= (f)
|
||||
#define BIT_CLEAR(v,f) (v) &= ~(f)
|
||||
#define BIT_IS_SET(v,f) ((v) & (f))
|
||||
#define BIT_TOGGLE(v,f) (v) ^= (f)
|
||||
|
||||
#define SET_POINTER(pnt, val) \
|
||||
do { \
|
||||
if ((pnt) != NULL) { \
|
||||
(*(pnt)) = (val); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define BLOCK_FLAG_USED BIT_FLAG(0) /* block is used */
|
||||
#define BLOCK_FLAG_FREE BIT_FLAG(1) /* block is free */
|
||||
|
||||
#define DEFAULT_PAGE_MULT 16 /* pagesize = this * getpagesize*/
|
||||
|
||||
/* How many pages SIZE bytes resides in. We add in the block header. */
|
||||
#define PAGES_IN_SIZE(mp_p, size) (((size) + sizeof(mpool_block_t) + \
|
||||
(mp_p)->mp_page_size - 1) / \
|
||||
(mp_p)->mp_page_size)
|
||||
#define SIZE_OF_PAGES(mp_p, page_n) ((page_n) * (mp_p)->mp_page_size)
|
||||
#define MAX_BITS 30 /* we only can allocate 1gb chunks */
|
||||
|
||||
#define MAX_BLOCK_USER_MEMORY(mp_p) ((mp_p)->mp_page_size - \
|
||||
sizeof(mpool_block_t))
|
||||
#define FIRST_ADDR_IN_BLOCK(block_p) (void *)((char *)(block_p) + \
|
||||
sizeof(mpool_block_t))
|
||||
#define MEMORY_IN_BLOCK(block_p) ((char *)(block_p)->mb_bounds_p - \
|
||||
((char *)(block_p) + \
|
||||
sizeof(mpool_block_t)))
|
||||
|
||||
typedef struct {
|
||||
unsigned int mp_magic; /* magic number for struct */
|
||||
unsigned int mp_flags; /* flags for the struct */
|
||||
unsigned long mp_alloc_c; /* number of allocations */
|
||||
unsigned long mp_user_alloc; /* user bytes allocated */
|
||||
unsigned long mp_max_alloc; /* maximum user bytes allocated */
|
||||
unsigned int mp_page_c; /* number of pages allocated */
|
||||
unsigned int mp_max_pages; /* maximum number of pages to use */
|
||||
unsigned int mp_page_size; /* page-size of our system */
|
||||
int mp_fd; /* fd for /dev/zero if mmap-ing */
|
||||
off_t mp_top; /* top of our allocations in fd */
|
||||
mpool_log_func_t mp_log_func; /* log callback function */
|
||||
void *mp_addr; /* current address for mmaping */
|
||||
void *mp_min_p; /* min address in pool for checks */
|
||||
void *mp_bounds_p; /* max address in pool for checks */
|
||||
struct mpool_block_st *mp_first_p; /* first memory block we are using */
|
||||
struct mpool_block_st *mp_last_p; /* last memory block we are using */
|
||||
struct mpool_block_st *mp_free[MAX_BITS + 1]; /* free lists based on size */
|
||||
unsigned int mp_magic2; /* upper magic for overwrite sanity */
|
||||
} mpool_t;
|
||||
|
||||
/* for debuggers to be able to interrogate the generic type in the .h file */
|
||||
typedef mpool_t mpool_ext_t;
|
||||
|
||||
/*
|
||||
* Block header structure. This structure *MUST* be long-word
|
||||
* aligned.
|
||||
*/
|
||||
typedef struct mpool_block_st {
|
||||
unsigned int mb_magic; /* magic number for block header */
|
||||
void *mb_bounds_p; /* block boundary location */
|
||||
struct mpool_block_st *mb_next_p; /* linked list next pointer */
|
||||
unsigned int mb_magic2; /* upper magic for overwrite sanity */
|
||||
} mpool_block_t;
|
||||
|
||||
/*
|
||||
* Free list structure.
|
||||
*/
|
||||
typedef struct {
|
||||
void *mf_next_p; /* pointer to the next free address */
|
||||
unsigned long mf_size; /* size of the free block */
|
||||
} mpool_free_t;
|
||||
|
||||
#endif /* ! __MPOOL_LOC_H__ */
|
||||
Executable
+980
@@ -0,0 +1,980 @@
|
||||
/*
|
||||
* Copyright (c) 2007,2008 Mij <mij@bitchx.it>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* SimCList library. See http://mij.oltrelinux.com/devel/simclist
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SIMCLIST_H
|
||||
#define SIMCLIST_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifndef SIMCLIST_NO_DUMPRESTORE
|
||||
# ifndef _WIN32
|
||||
# include <sys/time.h> /* list_dump_info_t's struct timeval */
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Be friend of both C90 and C99 compilers */
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
/* "inline" and "restrict" are keywords */
|
||||
#else
|
||||
# define inline /* inline */
|
||||
# define restrict /* restrict */
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Type representing list hashes.
|
||||
*
|
||||
* This is a signed integer value.
|
||||
*/
|
||||
typedef int32_t list_hash_t;
|
||||
|
||||
#ifndef SIMCLIST_NO_DUMPRESTORE
|
||||
typedef struct {
|
||||
uint16_t version; /* dump version */
|
||||
struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */
|
||||
uint32_t list_size;
|
||||
uint32_t list_numels;
|
||||
list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */
|
||||
uint32_t dumpsize;
|
||||
int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */
|
||||
} list_dump_info_t;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* a comparator of elements.
|
||||
*
|
||||
* A comparator of elements is a function that:
|
||||
* -# receives two references to elements a and b
|
||||
* -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively
|
||||
*
|
||||
* It is responsability of the function to handle possible NULL values.
|
||||
*/
|
||||
typedef int (*element_comparator)(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* a seeker of elements.
|
||||
*
|
||||
* An element seeker is a function that:
|
||||
* -# receives a reference to an element el
|
||||
* -# receives a reference to some indicator data
|
||||
* -# returns non-0 if the element matches the indicator, 0 otherwise
|
||||
*
|
||||
* It is responsability of the function to handle possible NULL values in any
|
||||
* argument.
|
||||
*/
|
||||
typedef int (*element_seeker)(const void *el, const void *indicator);
|
||||
|
||||
/**
|
||||
* an element lenght meter.
|
||||
*
|
||||
* An element meter is a function that:
|
||||
* -# receives the reference to an element el
|
||||
* -# returns its size in bytes
|
||||
*
|
||||
* It is responsability of the function to handle possible NULL values.
|
||||
*/
|
||||
typedef size_t (*element_meter)(const void *el);
|
||||
|
||||
/**
|
||||
* a function computing the hash of elements.
|
||||
*
|
||||
* An hash computing function is a function that:
|
||||
* -# receives the reference to an element el
|
||||
* -# returns a hash value for el
|
||||
*
|
||||
* It is responsability of the function to handle possible NULL values.
|
||||
*/
|
||||
typedef list_hash_t (*element_hash_computer)(const void *el);
|
||||
|
||||
/**
|
||||
* a function for serializing an element.
|
||||
*
|
||||
* A serializer function is one that gets a reference to an element,
|
||||
* and returns a reference to a buffer that contains its serialization
|
||||
* along with the length of this buffer.
|
||||
* It is responsability of the function to handle possible NULL values,
|
||||
* returning a NULL buffer and a 0 buffer length.
|
||||
*
|
||||
* These functions have 3 goals:
|
||||
* -# "freeze" and "flatten" the memory representation of the element
|
||||
* -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations
|
||||
* -# possibly extract a compressed representation of the element
|
||||
*
|
||||
* @param el reference to the element data
|
||||
* @param serialize_buffer reference to fill with the length of the buffer
|
||||
* @return reference to the buffer with the serialized data
|
||||
*/
|
||||
typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len);
|
||||
|
||||
/**
|
||||
* a function for un-serializing an element.
|
||||
*
|
||||
* An unserializer function accomplishes the inverse operation of the
|
||||
* serializer function. An unserializer function is one that gets a
|
||||
* serialized representation of an element and turns it backe to the original
|
||||
* element. The serialized representation is passed as a reference to a buffer
|
||||
* with its data, and the function allocates and returns the buffer containing
|
||||
* the original element, and it sets the length of this buffer into the
|
||||
* integer passed by reference.
|
||||
*
|
||||
* @param data reference to the buffer with the serialized representation of the element
|
||||
* @param data_len reference to the location where to store the length of the data in the buffer returned
|
||||
* @return reference to a buffer with the original, unserialized representation of the element
|
||||
*/
|
||||
typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len);
|
||||
|
||||
/* [private-use] list entry -- olds actual user datum */
|
||||
struct list_entry_s {
|
||||
void *data;
|
||||
|
||||
/* doubly-linked list service references */
|
||||
struct list_entry_s *next;
|
||||
struct list_entry_s *prev;
|
||||
};
|
||||
|
||||
/* [private-use] list attributes */
|
||||
struct list_attributes_s {
|
||||
/* user-set routine for comparing list elements */
|
||||
element_comparator comparator;
|
||||
/* user-set routing for seeking elements */
|
||||
element_seeker seeker;
|
||||
/* user-set routine for determining the length of an element */
|
||||
element_meter meter;
|
||||
int copy_data;
|
||||
/* user-set routine for computing the hash of an element */
|
||||
element_hash_computer hasher;
|
||||
/* user-set routine for serializing an element */
|
||||
element_serializer serializer;
|
||||
/* user-set routine for unserializing an element */
|
||||
element_unserializer unserializer;
|
||||
};
|
||||
|
||||
/** list object */
|
||||
typedef struct {
|
||||
struct list_entry_s *head_sentinel;
|
||||
struct list_entry_s *tail_sentinel;
|
||||
struct list_entry_s *mid;
|
||||
|
||||
unsigned int numels;
|
||||
|
||||
/* array of spare elements */
|
||||
struct list_entry_s **spareels;
|
||||
unsigned int spareelsnum;
|
||||
|
||||
#ifdef SIMCLIST_WITH_THREADS
|
||||
/* how many threads are currently running */
|
||||
unsigned int threadcount;
|
||||
#endif
|
||||
|
||||
/* service variables for list iteration */
|
||||
int iter_active;
|
||||
unsigned int iter_pos;
|
||||
struct list_entry_s *iter_curentry;
|
||||
|
||||
/* list attributes */
|
||||
struct list_attributes_s attrs;
|
||||
} list_t;
|
||||
|
||||
/**
|
||||
* initialize a list object for use.
|
||||
*
|
||||
* @param l must point to a user-provided memory location
|
||||
* @return 0 for success. -1 for failure
|
||||
*/
|
||||
int list_init(list_t *restrict l);
|
||||
|
||||
/**
|
||||
* completely remove the list from memory.
|
||||
*
|
||||
* This function is the inverse of list_init(). It is meant to be called when
|
||||
* the list is no longer going to be used. Elements and possible memory taken
|
||||
* for internal use are freed.
|
||||
*
|
||||
* @param l list to destroy
|
||||
*/
|
||||
void list_destroy(list_t *restrict l);
|
||||
|
||||
/**
|
||||
* set the comparator function for list elements.
|
||||
*
|
||||
* Comparator functions are used for searching and sorting. If NULL is passed
|
||||
* as reference to the function, the comparator is disabled.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param comparator_fun pointer to the actual comparator function
|
||||
* @return 0 if the attribute was successfully set; -1 otherwise
|
||||
*
|
||||
* @see element_comparator()
|
||||
*/
|
||||
int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun);
|
||||
|
||||
/**
|
||||
* set a seeker function for list elements.
|
||||
*
|
||||
* Seeker functions are used for finding elements. If NULL is passed as reference
|
||||
* to the function, the seeker is disabled.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param seeker_fun pointer to the actual seeker function
|
||||
* @return 0 if the attribute was successfully set; -1 otherwise
|
||||
*
|
||||
* @see element_seeker()
|
||||
*/
|
||||
int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
|
||||
|
||||
/**
|
||||
* require to free element data when list entry is removed (default: don't free).
|
||||
*
|
||||
* [ advanced preference ]
|
||||
*
|
||||
* By default, when an element is removed from the list, it disappears from
|
||||
* the list by its actual data is not free()d. With this option, every
|
||||
* deletion causes element data to be freed.
|
||||
*
|
||||
* It is responsability of this function to correctly handle NULL values, if
|
||||
* NULL elements are inserted into the list.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param metric_fun pointer to the actual metric function
|
||||
* @param copy_data 0: do not free element data (default); non-0: do free
|
||||
* @return 0 if the attribute was successfully set; -1 otherwise
|
||||
*
|
||||
* @see element_meter()
|
||||
* @see list_meter_int8_t()
|
||||
* @see list_meter_int16_t()
|
||||
* @see list_meter_int32_t()
|
||||
* @see list_meter_int64_t()
|
||||
* @see list_meter_uint8_t()
|
||||
* @see list_meter_uint16_t()
|
||||
* @see list_meter_uint32_t()
|
||||
* @see list_meter_uint64_t()
|
||||
* @see list_meter_float()
|
||||
* @see list_meter_double()
|
||||
* @see list_meter_string()
|
||||
*/
|
||||
int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data);
|
||||
|
||||
/**
|
||||
* set the element hash computing function for the list elements.
|
||||
*
|
||||
* [ advanced preference ]
|
||||
*
|
||||
* An hash can be requested depicting the list status at a given time. An hash
|
||||
* only depends on the elements and their order. By default, the hash of an
|
||||
* element is only computed on its reference. With this function, the user can
|
||||
* set a custom function computing the hash of an element. If such function is
|
||||
* provided, the list_hash() function automatically computes the list hash using
|
||||
* the custom function instead of simply referring to element references.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param hash_computer_fun pointer to the actual hash computing function
|
||||
* @return 0 if the attribute was successfully set; -1 otherwise
|
||||
*
|
||||
* @see element_hash_computer()
|
||||
*/
|
||||
int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun);
|
||||
|
||||
/**
|
||||
* set the element serializer function for the list elements.
|
||||
*
|
||||
* [ advanced preference ]
|
||||
*
|
||||
* Serialize functions are used for dumping the list to some persistent
|
||||
* storage. The serializer function is called for each element; it is passed
|
||||
* a reference to the element and a reference to a size_t object. It will
|
||||
* provide (and return) the buffer with the serialization of the element and
|
||||
* fill the size_t object with the length of this serialization data.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param serializer_fun pointer to the actual serializer function
|
||||
* @return 0 if the attribute was successfully set; -1 otherwise
|
||||
*
|
||||
* @see element_serializer()
|
||||
* @see list_dump_filedescriptor()
|
||||
* @see list_restore_filedescriptor()
|
||||
*/
|
||||
int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun);
|
||||
|
||||
/**
|
||||
* set the element unserializer function for the list elements.
|
||||
*
|
||||
* [ advanced preference ]
|
||||
*
|
||||
* Unserialize functions are used for restoring the list from some persistent
|
||||
* storage. The unserializer function is called for each element segment read
|
||||
* from the storage; it is passed the segment and a reference to an integer.
|
||||
* It shall allocate and return a buffer compiled with the resumed memory
|
||||
* representation of the element, and set the integer value to the length of
|
||||
* this buffer.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param unserializer_fun pointer to the actual unserializer function
|
||||
* @return 0 if the attribute was successfully set; -1 otherwise
|
||||
*
|
||||
* @see element_unserializer()
|
||||
* @see list_dump_filedescriptor()
|
||||
* @see list_restore_filedescriptor()
|
||||
*/
|
||||
int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun);
|
||||
|
||||
/**
|
||||
* append data at the end of the list.
|
||||
*
|
||||
* This function is useful for adding elements with a FIFO/queue policy.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param data pointer to user data to append
|
||||
*
|
||||
* @return 1 for success. < 0 for failure
|
||||
*/
|
||||
int list_append(list_t *restrict l, const void *data);
|
||||
|
||||
/**
|
||||
* insert data in the head of the list.
|
||||
*
|
||||
* This function is useful for adding elements with a LIFO/Stack policy.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param data pointer to user data to append
|
||||
*
|
||||
* @return 1 for success. < 0 for failure
|
||||
*/
|
||||
int list_prepend(list_t *restrict l, const void *restrict data);
|
||||
|
||||
/**
|
||||
* extract the element in the top of the list.
|
||||
*
|
||||
* This function is for using a list with a FIFO/queue policy.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return reference to user datum, or NULL on errors
|
||||
*/
|
||||
void *list_fetch(list_t *restrict l);
|
||||
|
||||
/**
|
||||
* retrieve an element at a given position.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param pos [0,size-1] position index of the element wanted
|
||||
* @return reference to user datum, or NULL on errors
|
||||
*/
|
||||
void *list_get_at(const list_t *restrict l, unsigned int pos);
|
||||
|
||||
/**
|
||||
* return the maximum element of the list.
|
||||
*
|
||||
* @warning Requires a comparator function to be set for the list.
|
||||
*
|
||||
* Returns the maximum element with respect to the comparator function output.
|
||||
*
|
||||
* @see list_attributes_comparator()
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return the reference to the element, or NULL
|
||||
*/
|
||||
void *list_get_max(const list_t *restrict l);
|
||||
|
||||
/**
|
||||
* return the minimum element of the list.
|
||||
*
|
||||
* @warning Requires a comparator function to be set for the list.
|
||||
*
|
||||
* Returns the minimum element with respect to the comparator function output.
|
||||
*
|
||||
* @see list_attributes_comparator()
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return the reference to the element, or NULL
|
||||
*/
|
||||
void *list_get_min(const list_t *restrict l);
|
||||
|
||||
/**
|
||||
* retrieve and remove from list an element at a given position.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param pos [0,size-1] position index of the element wanted
|
||||
* @return reference to user datum, or NULL on errors
|
||||
*/
|
||||
void *list_extract_at(list_t *restrict l, unsigned int pos);
|
||||
|
||||
/**
|
||||
* insert an element at a given position.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param data reference to data to be inserted
|
||||
* @param pos [0,size-1] position index to insert the element at
|
||||
* @return positive value on success. Negative on failure
|
||||
*/
|
||||
int list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
|
||||
|
||||
/**
|
||||
* expunge the first found given element from the list.
|
||||
*
|
||||
* Inspects the given list looking for the given element; if the element
|
||||
* is found, it is removed. Only the first occurence is removed.
|
||||
* If a comparator function was not set, elements are compared by reference.
|
||||
* Otherwise, the comparator is used to match the element.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param data reference of the element to search for
|
||||
* @return 0 on success. Negative value on failure
|
||||
*
|
||||
* @see list_attributes_comparator()
|
||||
* @see list_delete_at()
|
||||
*/
|
||||
int list_delete(list_t *restrict l, const void *data);
|
||||
|
||||
/**
|
||||
* expunge an element at a given position from the list.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param pos [0,size-1] position index of the element to be deleted
|
||||
* @return 0 on success. Negative value on failure
|
||||
*/
|
||||
int list_delete_at(list_t *restrict l, unsigned int pos);
|
||||
|
||||
/**
|
||||
* expunge an array of elements from the list, given their position range.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param posstart [0,size-1] position index of the first element to be deleted
|
||||
* @param posend [posstart,size-1] position of the last element to be deleted
|
||||
* @return the number of elements successfully removed on success, <0 on error
|
||||
*/
|
||||
int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
|
||||
|
||||
/**
|
||||
* clear all the elements off of the list.
|
||||
*
|
||||
* The element datums will not be freed.
|
||||
*
|
||||
* @see list_delete_range()
|
||||
* @see list_size()
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return the number of elements removed on success, <0 on error
|
||||
*/
|
||||
int list_clear(list_t *restrict l);
|
||||
|
||||
/**
|
||||
* inspect the number of elements in the list.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return number of elements currently held by the list
|
||||
*/
|
||||
unsigned int list_size(const list_t *restrict l);
|
||||
|
||||
/**
|
||||
* inspect whether the list is empty.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return 0 iff the list is not empty
|
||||
*
|
||||
* @see list_size()
|
||||
*/
|
||||
int list_empty(const list_t *restrict l);
|
||||
|
||||
/**
|
||||
* find the position of an element in a list.
|
||||
*
|
||||
* @warning Requires a comparator function to be set for the list.
|
||||
*
|
||||
* Inspects the given list looking for the given element; if the element
|
||||
* is found, its position into the list is returned.
|
||||
* Elements are inspected comparing references if a comparator has not been
|
||||
* set. Otherwise, the comparator is used to find the element.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param data reference of the element to search for
|
||||
* @return position of element in the list, or <0 if not found
|
||||
*
|
||||
* @see list_attributes_comparator()
|
||||
* @see list_get_at()
|
||||
*/
|
||||
int list_locate(const list_t *restrict l, const void *data);
|
||||
|
||||
/**
|
||||
* returns an element given an indicator.
|
||||
*
|
||||
* @warning Requires a seeker function to be set for the list.
|
||||
*
|
||||
* Inspect the given list looking with the seeker if an element matches
|
||||
* an indicator. If such element is found, the reference to the element
|
||||
* is returned.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param indicator indicator data to pass to the seeker along with elements
|
||||
* @return reference to the element accepted by the seeker, or NULL if none found
|
||||
*/
|
||||
void *list_seek(list_t *restrict l, const void *indicator);
|
||||
|
||||
/**
|
||||
* inspect whether some data is member of the list.
|
||||
*
|
||||
* @warning Requires a comparator function to be set for the list.
|
||||
*
|
||||
* By default, a per-reference comparison is accomplished. That is,
|
||||
* the data is in list if any element of the list points to the same
|
||||
* location of data.
|
||||
* A "semantic" comparison is accomplished, otherwise, if a comparator
|
||||
* function has been set previously, with list_attributes_comparator();
|
||||
* in which case, the given data reference is believed to be in list iff
|
||||
* comparator_fun(elementdata, userdata) == 0 for any element in the list.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param data reference to the data to search
|
||||
* @return 0 iff the list does not contain data as an element
|
||||
*
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_contains(const list_t *restrict l, const void *data);
|
||||
|
||||
/**
|
||||
* concatenate two lists
|
||||
*
|
||||
* Concatenates one list with another, and stores the result into a
|
||||
* user-provided list object, which must be different from both the
|
||||
* lists to concatenate. Attributes from the original lists are not
|
||||
* cloned.
|
||||
* The destination list referred is threated as virgin room: if it
|
||||
* is an existing list containing elements, memory leaks will happen.
|
||||
* It is OK to specify the same list twice as source, for "doubling"
|
||||
* it in the destination.
|
||||
*
|
||||
* @param l1 base list
|
||||
* @param l2 list to append to the base
|
||||
* @param dest reference to the destination list
|
||||
* @return 0 for success, -1 for errors
|
||||
*/
|
||||
int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
|
||||
|
||||
/**
|
||||
* sort list elements.
|
||||
*
|
||||
* @warning Requires a comparator function to be set for the list.
|
||||
*
|
||||
* Sorts the list in ascending or descending order as specified by the versus
|
||||
* flag. The algorithm chooses autonomously what algorithm is best suited for
|
||||
* sorting the list wrt its current status.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param versus positive: order small to big; negative: order big to small
|
||||
* @return 0 iff sorting was successful
|
||||
*
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_sort(list_t *restrict l, int versus);
|
||||
|
||||
/**
|
||||
* start an iteration session.
|
||||
*
|
||||
* This function prepares the list to be iterated.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return 0 if the list cannot be currently iterated. >0 otherwise
|
||||
*
|
||||
* @see list_iterator_stop()
|
||||
*/
|
||||
int list_iterator_start(list_t *restrict l);
|
||||
|
||||
/**
|
||||
* return the next element in the iteration session.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return element datum, or NULL on errors
|
||||
*/
|
||||
void *list_iterator_next(list_t *restrict l);
|
||||
|
||||
/**
|
||||
* inspect whether more elements are available in the iteration session.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return 0 iff no more elements are available.
|
||||
*/
|
||||
int list_iterator_hasnext(const list_t *restrict l);
|
||||
|
||||
/**
|
||||
* end an iteration session.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @return 0 iff the iteration session cannot be stopped
|
||||
*/
|
||||
int list_iterator_stop(list_t *restrict l);
|
||||
|
||||
/**
|
||||
* return the hash of the current status of the list.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param hash where the resulting hash is put
|
||||
*
|
||||
* @return 0 for success; <0 for failure
|
||||
*/
|
||||
int list_hash(const list_t *restrict l, list_hash_t *restrict hash);
|
||||
|
||||
#ifndef SIMCLIST_NO_DUMPRESTORE
|
||||
/**
|
||||
* get meta informations on a list dump on filedescriptor.
|
||||
*
|
||||
* [ advanced function ]
|
||||
*
|
||||
* Extracts the meta information from a SimCList dump located in a file
|
||||
* descriptor. The file descriptor must be open and positioned at the
|
||||
* beginning of the SimCList dump block.
|
||||
*
|
||||
* @param fd file descriptor to get metadata from
|
||||
* @param info reference to a dump metainformation structure to fill
|
||||
* @return 0 for success; <0 for failure
|
||||
*
|
||||
* @see list_dump_filedescriptor()
|
||||
*/
|
||||
int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
|
||||
|
||||
/**
|
||||
* get meta informations on a list dump on file.
|
||||
*
|
||||
* [ advanced function ]
|
||||
*
|
||||
* Extracts the meta information from a SimCList dump located in a file.
|
||||
*
|
||||
* @param filename filename of the file to fetch from
|
||||
* @param info reference to a dump metainformation structure to fill
|
||||
* @return 0 for success; <0 for failure
|
||||
*
|
||||
* @see list_dump_filedescriptor()
|
||||
*/
|
||||
int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info);
|
||||
|
||||
/**
|
||||
* dump the list into an open, writable file descriptor.
|
||||
*
|
||||
* This function "dumps" the list to a persistent storage so it can be
|
||||
* preserved across process terminations.
|
||||
* When called, the file descriptor must be open for writing and positioned
|
||||
* where the serialized data must begin. It writes its serialization of the
|
||||
* list in a form which is portable across different architectures. Dump can
|
||||
* be safely performed on stream-only (non seekable) descriptors. The file
|
||||
* descriptor is not closed at the end of the operations.
|
||||
*
|
||||
* To use dump functions, either of these conditions must be satisfied:
|
||||
* -# a metric function has been specified with list_attributes_copy()
|
||||
* -# a serializer function has been specified with list_attributes_serializer()
|
||||
*
|
||||
* If a metric function has been specified, each element of the list is dumped
|
||||
* as-is from memory, copying it from its pointer for its length down to the
|
||||
* file descriptor. This might have impacts on portability of the dump to
|
||||
* different architectures.
|
||||
*
|
||||
* If a serializer function has been specified, its result for each element is
|
||||
* dumped to the file descriptor.
|
||||
*
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param fd file descriptor to write to
|
||||
* @param len location to store the resulting length of the dump (bytes), or NULL
|
||||
*
|
||||
* @return 0 if successful; -1 otherwise
|
||||
*
|
||||
* @see element_serializer()
|
||||
* @see list_attributes_copy()
|
||||
* @see list_attributes_serializer()
|
||||
*/
|
||||
int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len);
|
||||
|
||||
/**
|
||||
* dump the list to a file name.
|
||||
*
|
||||
* This function creates a filename and dumps the current content of the list
|
||||
* to it. If the file exists it is overwritten. The number of bytes written to
|
||||
* the file can be returned in a specified argument.
|
||||
*
|
||||
* @param l list to operate
|
||||
* @param filename filename to write to
|
||||
* @param len location to store the resulting length of the dump (bytes), or NULL
|
||||
*
|
||||
* @return 0 if successful; -1 otherwise
|
||||
*
|
||||
* @see list_attributes_copy()
|
||||
* @see element_serializer()
|
||||
* @see list_attributes_serializer()
|
||||
* @see list_dump_filedescriptor()
|
||||
* @see list_restore_file()
|
||||
*
|
||||
* This function stores a representation of the list
|
||||
*/
|
||||
int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len);
|
||||
|
||||
/**
|
||||
* restore the list from an open, readable file descriptor to memory.
|
||||
*
|
||||
* This function is the "inverse" of list_dump_filedescriptor(). It restores
|
||||
* the list content from a (open, read-ready) file descriptor to memory. An
|
||||
* unserializer might be needed to restore elements from the persistent
|
||||
* representation back into memory-consistent format. List attributes can not
|
||||
* be restored and must be set manually.
|
||||
*
|
||||
* @see list_dump_filedescriptor()
|
||||
* @see list_attributes_serializer()
|
||||
* @see list_attributes_unserializer()
|
||||
*
|
||||
* @param l list to restore to
|
||||
* @param fd file descriptor to read from.
|
||||
* @param len location to store the length of the dump read (bytes), or NULL
|
||||
* @return 0 if successful; -1 otherwise
|
||||
*/
|
||||
int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len);
|
||||
|
||||
/**
|
||||
* restore the list from a file name.
|
||||
*
|
||||
* This function restores the content of a list from a file into memory. It is
|
||||
* the inverse of list_dump_file().
|
||||
*
|
||||
* @see element_unserializer()
|
||||
* @see list_attributes_unserializer()
|
||||
* @see list_dump_file()
|
||||
* @see list_restore_filedescriptor()
|
||||
*
|
||||
* @param l list to restore to
|
||||
* @param filename filename to read data from
|
||||
* @param len location to store the length of the dump read (bytes), or NULL
|
||||
* @return 0 if successful; -1 otherwise
|
||||
*/
|
||||
int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len);
|
||||
#endif
|
||||
|
||||
/* ready-made comparators, meters and hash computers */
|
||||
/* comparator functions */
|
||||
/**
|
||||
* ready-made comparator for int8_t elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_int8_t(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for int16_t elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_int16_t(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for int32_t elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_int32_t(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for int64_t elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_int64_t(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for uint8_t elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_uint8_t(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for uint16_t elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_uint16_t(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for uint32_t elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_uint32_t(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for uint64_t elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_uint64_t(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for float elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_float(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for double elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_double(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* ready-made comparator for string elements.
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_comparator_string(const void *a, const void *b);
|
||||
|
||||
/* metric functions */
|
||||
/**
|
||||
* ready-made metric function for int8_t elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_int8_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for int16_t elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_int16_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for int32_t elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_int32_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for int64_t elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_int64_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for uint8_t elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_uint8_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for uint16_t elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_uint16_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for uint32_t elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_uint32_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for uint64_t elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_uint64_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for float elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_float(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for double elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_double(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made metric function for string elements.
|
||||
* @see list_attributes_copy()
|
||||
*/
|
||||
size_t list_meter_string(const void *el);
|
||||
|
||||
/* hash functions */
|
||||
/**
|
||||
* ready-made hash function for int8_t elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_int8_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for int16_t elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_int16_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for int32_t elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_int32_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for int64_t elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_int64_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for uint8_t elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_uint8_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for uint16_t elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_uint16_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for uint32_t elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_uint32_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for uint64_t elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_uint64_t(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for float elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_float(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for double elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_double(const void *el);
|
||||
|
||||
/**
|
||||
* ready-made hash function for string elements.
|
||||
* @see list_attributes_hash_computer()
|
||||
*/
|
||||
list_hash_t list_hashcomputer_string(const void *el);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* local defines for the table module
|
||||
*
|
||||
* Copyright 2000 by Gray Watson.
|
||||
*
|
||||
* This file is part of the table package.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose and without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies,
|
||||
* and that the name of Gray Watson not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software
|
||||
* without specific, written prior permission.
|
||||
*
|
||||
* Gray Watson makes no representations about the suitability of the
|
||||
* software described herein for any purpose. It is provided "as is"
|
||||
* without express or implied warranty.
|
||||
*
|
||||
* The author may be reached via http://256.com/gray/
|
||||
*
|
||||
* $Id: table_loc.h,v 1.11 2000/03/09 03:30:42 gray Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TABLE_LOC_H__
|
||||
#define __TABLE_LOC_H__
|
||||
|
||||
#ifndef unix
|
||||
#define NO_MMAP
|
||||
#endif
|
||||
|
||||
#ifndef BITSPERBYTE
|
||||
#define BITSPERBYTE 8
|
||||
#endif
|
||||
#ifndef BITS
|
||||
#define BITS(type) (BITSPERBYTE * (int)sizeof(type))
|
||||
#endif
|
||||
|
||||
#define TABLE_MAGIC 0xBADF00D /* very magic magicness */
|
||||
#define LINEAR_MAGIC 0xAD00D00 /* magic value for linear struct */
|
||||
#define DEFAULT_SIZE 1024 /* default table size */
|
||||
#define MAX_ALIGNMENT 128 /* max alignment value */
|
||||
|
||||
/*
|
||||
* Maximum number of splits. This should mean that these routines can
|
||||
* handle at least 2^128 different values (that's _quite_ a few). And
|
||||
* then you can always increase the value.
|
||||
*/
|
||||
#define MAX_QSORT_SPLITS 128
|
||||
|
||||
/*
|
||||
* Maximum number of entries that must be in list for it to be
|
||||
* partitioned. If there are fewer elements then just do our
|
||||
* insertion sort.
|
||||
*/
|
||||
#define MAX_QSORT_MANY 8
|
||||
|
||||
/*
|
||||
* Macros.
|
||||
*/
|
||||
|
||||
/* returns 1 when we should grow or shrink the table */
|
||||
#define SHOULD_TABLE_GROW(tab) ((tab)->ta_entry_n > (tab)->ta_bucket_n * 2)
|
||||
#define SHOULD_TABLE_SHRINK(tab) ((tab)->ta_entry_n < (tab)->ta_bucket_n / 2)
|
||||
|
||||
/*
|
||||
* void HASH_MIX
|
||||
*
|
||||
* DESCRIPTION:
|
||||
*
|
||||
* Mix 3 32-bit values reversibly. For every delta with one or two
|
||||
* bits set, and the deltas of all three high bits or all three low
|
||||
* bits, whether the original value of a,b,c is almost all zero or is
|
||||
* uniformly distributed.
|
||||
*
|
||||
* If HASH_MIX() is run forward or backward, at least 32 bits in a,b,c
|
||||
* have at least 1/4 probability of changing. If mix() is run
|
||||
* forward, every bit of c will change between 1/3 and 2/3 of the
|
||||
* time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
|
||||
*
|
||||
* HASH_MIX() takes 36 machine instructions, but only 18 cycles on a
|
||||
* superscalar machine (like a Pentium or a Sparc). No faster mixer
|
||||
* seems to work, that's the result of my brute-force search. There
|
||||
* were about 2^68 hashes to choose from. I only tested about a
|
||||
* billion of those.
|
||||
*/
|
||||
#define HASH_MIX(a, b, c) \
|
||||
do { \
|
||||
a -= b; a -= c; a ^= (c >> 13); \
|
||||
b -= c; b -= a; b ^= (a << 8); \
|
||||
c -= a; c -= b; c ^= (b >> 13); \
|
||||
a -= b; a -= c; a ^= (c >> 12); \
|
||||
b -= c; b -= a; b ^= (a << 16); \
|
||||
c -= a; c -= b; c ^= (b >> 5); \
|
||||
a -= b; a -= c; a ^= (c >> 3); \
|
||||
b -= c; b -= a; b ^= (a << 10); \
|
||||
c -= a; c -= b; c ^= (b >> 15); \
|
||||
} while(0)
|
||||
|
||||
#define SET_POINTER(pnt, val) \
|
||||
do { \
|
||||
if ((pnt) != NULL) { \
|
||||
(*(pnt)) = (val); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* The following macros take care of the mmap case. When we are
|
||||
* mmaping a table from a disk file, all of the pointers in the table
|
||||
* structures are replaced with offsets into the file. The following
|
||||
* macro, for each pointer, adds the starting address of the mmaped
|
||||
* section onto each pointer/offset turning it back into a legitimate
|
||||
* pointer.
|
||||
*/
|
||||
#ifdef NO_MMAP
|
||||
|
||||
#define TABLE_POINTER(table, type, pnt) (pnt)
|
||||
|
||||
#else
|
||||
|
||||
#define TABLE_POINTER(tab_p, type, pnt) \
|
||||
((tab_p)->ta_mmap == NULL || (pnt) == NULL ? (pnt) : \
|
||||
(type)((char *)((tab_p)->ta_mmap) + (long)(pnt)))
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Macros to get at the key and the data pointers
|
||||
*/
|
||||
#define ENTRY_KEY_BUF(entry_p) ((entry_p)->te_key_buf)
|
||||
#define ENTRY_DATA_BUF(tab_p, entry_p) \
|
||||
(ENTRY_KEY_BUF(entry_p) + (entry_p)->te_key_size)
|
||||
|
||||
/*
|
||||
* Table structures...
|
||||
*/
|
||||
|
||||
/*
|
||||
* HACK: this should be equiv as the table_entry_t without the key_buf
|
||||
* char. We use this with the ENTRY_SIZE() macro above which solves
|
||||
* the problem with the lack of the [0] GNU hack. We use the
|
||||
* table_entry_t structure to better map the memory and make things
|
||||
* faster.
|
||||
*/
|
||||
typedef struct table_shell_st {
|
||||
unsigned int te_key_size; /* size of data */
|
||||
unsigned int te_data_size; /* size of data */
|
||||
struct table_shell_st *te_next_p; /* pointer to next in the list */
|
||||
/* NOTE: this does not have the te_key_buf field here */
|
||||
} table_shell_t;
|
||||
|
||||
/*
|
||||
* Elements in the bucket linked-lists. The key[1] is the start of
|
||||
* the key with the rest of the key and all of the data information
|
||||
* packed in memory directly after the end of this structure.
|
||||
*
|
||||
* NOTE: if this structure is changed, the table_shell_t must be
|
||||
* changed to match.
|
||||
*/
|
||||
typedef struct table_entry_st {
|
||||
unsigned int te_key_size; /* size of data */
|
||||
unsigned int te_data_size; /* size of data */
|
||||
struct table_entry_st *te_next_p; /* pointer to next in the list */
|
||||
unsigned char te_key_buf[1]; /* 1st byte of key buf */
|
||||
} table_entry_t;
|
||||
|
||||
/* external structure for debuggers be able to see void */
|
||||
typedef table_entry_t table_entry_ext_t;
|
||||
|
||||
/* main table structure */
|
||||
typedef struct table_st {
|
||||
unsigned int ta_magic; /* magic number */
|
||||
unsigned int ta_flags; /* table's flags defined in table.h */
|
||||
unsigned int ta_bucket_n; /* num of buckets, should be 2^X */
|
||||
unsigned int ta_entry_n; /* num of entries in all buckets */
|
||||
unsigned int ta_data_align; /* data alignment value */
|
||||
table_entry_t **ta_buckets; /* array of linked lists */
|
||||
table_linear_t ta_linear; /* linear tracking */
|
||||
struct table_st *ta_mmap; /* mmaped table */
|
||||
unsigned long ta_file_size; /* size of on-disk space */
|
||||
|
||||
void *ta_mem_pool; /* pointer to some memory pool */
|
||||
table_mem_alloc_t ta_alloc_func; /* memory allocation function */
|
||||
table_mem_resize_t ta_resize_func; /* memory resize function */
|
||||
table_mem_free_t ta_free_func; /* memory free function */
|
||||
} table_t;
|
||||
|
||||
/* external table structure for debuggers */
|
||||
typedef table_t table_ext_t;
|
||||
|
||||
/* local comparison functions */
|
||||
typedef int (*compare_t)(const void *element1_p, const void *element2_p,
|
||||
table_compare_t user_compare,
|
||||
const table_t *table_p, int *err_bp);
|
||||
|
||||
/*
|
||||
* to map error to string
|
||||
*/
|
||||
typedef struct {
|
||||
int es_error; /* error number */
|
||||
char *es_string; /* assocaited string */
|
||||
} error_str_t;
|
||||
|
||||
static error_str_t errors[] = {
|
||||
{ TABLE_ERROR_NONE, "no error" },
|
||||
{ TABLE_ERROR_PNT, "invalid table pointer" },
|
||||
{ TABLE_ERROR_ARG_NULL, "buffer argument is null" },
|
||||
{ TABLE_ERROR_SIZE, "incorrect size argument" },
|
||||
{ TABLE_ERROR_OVERWRITE, "key exists and no overwrite" },
|
||||
{ TABLE_ERROR_NOT_FOUND, "key does not exist" },
|
||||
{ TABLE_ERROR_ALLOC, "error allocating memory" },
|
||||
{ TABLE_ERROR_LINEAR, "linear access not in progress" },
|
||||
{ TABLE_ERROR_OPEN, "could not open file" },
|
||||
{ TABLE_ERROR_SEEK, "could not seek to position in file" },
|
||||
{ TABLE_ERROR_READ, "could not read from file" },
|
||||
{ TABLE_ERROR_WRITE, "could not write to file" },
|
||||
{ TABLE_ERROR_MMAP_NONE, "no mmap support compiled in library" },
|
||||
{ TABLE_ERROR_MMAP, "could not mmap the file" },
|
||||
{ TABLE_ERROR_MMAP_OP, "operation not valid on mmap files" },
|
||||
{ TABLE_ERROR_EMPTY, "table is empty" },
|
||||
{ TABLE_ERROR_NOT_EMPTY, "table contains data" },
|
||||
{ TABLE_ERROR_ALIGNMENT, "invalid alignment value" },
|
||||
{ TABLE_ERROR_COMPARE, "problems with internal comparison" },
|
||||
{ TABLE_ERROR_FREE, "memory free error" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#define INVALID_ERROR "invalid error code"
|
||||
|
||||
#endif /* ! __TABLE_LOC_H__ */
|
||||
Reference in new issue
Block a user