update libks

This commit is contained in:
Mike Jerris committed 2016-11-23 13:23:33 -06:00
1 parent 238e228942
commit 9fd0b6bd2f
128 files changed
+41586 -2145

No files matched your search

+68 -54
View File
@@ -34,44 +34,54 @@
#ifndef _KS_H_
#define _KS_H_
#include <stdarg.h>
#ifdef __cplusplus
#define KS_BEGIN_EXTERN_C extern "C" {
#define KS_END_EXTERN_C }
#else
#define KS_BEGIN_EXTERN_C
#define KS_END_EXTERN_C
#endif
#include <ks_platform.h>
#include <ks_types.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))
#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)
#include "math.h"
#include "ks_json.h"
KS_BEGIN_EXTERN_C
#define BUF_CHUNK 65536 * 50
#define BUF_START 65536 * 100
#include <ks_threadmutex.h>
#include <ks_buffer.h>
/*!
\brief Test for NULL or zero length string
\param s the string to test
\return true value if the string is NULL or zero length
*/
_Check_return_ static __inline int _zstr(_In_opt_z_ const char *s)
{
return !s || *s == '\0';
}
#ifdef _PREFAST_
#define zstr(x) (_zstr(x) ? 1 : __analysis_assume(x),0)
#else
#define zstr(x) _zstr(x)
#endif
#define ks_strlen_zero(x) zstr(x)
#define ks_strlen_zero_buf(x) zstr_buf(x)
#define zstr_buf(s) (*(s) == '\0')
#define ks_set_string(_x, _y) ks_copy_string(_x, _y, sizeof(_x))
#define ks_safe_free(_x) if (_x) free(_x); _x = NULL
#define end_of(_s) *(*_s == '\0' ? _s : _s + strlen(_s) - 1)
#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)
#define ks_recv(_h) ks_recv_event(_h, 0, NULL)
#define ks_recv_timed(_h, _ms) ks_recv_event_timed(_h, _ms, 0, NULL)
KS_DECLARE(ks_status_t) ks_init(void);
KS_DECLARE(ks_status_t) ks_shutdown(void);
KS_DECLARE(ks_pool_t *) ks_global_pool(void);
KS_DECLARE(ks_status_t) ks_global_set_cleanup(ks_pool_cleanup_fn_t fn, void *arg);
KS_DECLARE(int) ks_vasprintf(char **ret, const char *fmt, va_list ap);
KS_DECLARE_DATA extern ks_logger_t ks_log;
@@ -81,42 +91,46 @@ 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(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(char *) ks_copy_string(char *from_str, const char *to_str, ks_size_t from_str_len);
KS_DECLARE(int) ks_snprintf(char *buffer, size_t count, const char *fmt, ...);
KS_DECLARE(unsigned int) ks_separate_string(char *buf, const char *delim, char **array, unsigned int arraylen);
KS_DECLARE(int) ks_cpu_count(void);
static __inline__ int ks_safe_strcasecmp(const char *s1, const char *s2) {
if (!(s1 && s2)) {
return 1;
}
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);
}
return strcasecmp(s1, s2);
}
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
KS_DECLARE(void) ks_random_string(char *buf, uint16_t len, char *set);
#include "ks_pool.h"
#include "ks_printf.h"
#include "ks_json.h"
#include "ks_threadmutex.h"
#include "ks_hash.h"
#include "ks_config.h"
#include "ks_q.h"
#include "ks_buffer.h"
#include "ks_time.h"
#include "ks_socket.h"
#include "ks_dso.h"
#include "ks_dht.h"
#include "ks_utp.h"
#include "simclist.h"
#include "ks_ssl.h"
#include "kws.h"
#include "ks_bencode.h"
#include "ks_rng.h"
KS_END_EXTERN_C
#endif /* defined(_KS_H_) */
+730
View File
@@ -0,0 +1,730 @@
/*
* libbencodetools
*
* Written by Heikki Orsila <heikki.orsila@iki.fi> and
* Janne Kulmala <janne.t.kulmala@tut.fi> in 2011.
*/
#ifndef TYPEVALIDATOR_BENCODE_H
#define TYPEVALIDATOR_BENCODE_H
#include <stdlib.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Used to verify format strings in compile time */
#ifdef __GNUC__
#define BEN_CHECK_FORMAT(...) __attribute__ ((format( __VA_ARGS__ )))
#else
#define BEN_CHECK_FORMAT(args)
#endif
enum {
BENCODE_BOOL = 1,
BENCODE_DICT,
BENCODE_INT,
BENCODE_LIST,
BENCODE_STR,
BENCODE_USER,
};
enum {
BEN_OK = 0, /* No errors. Set to zero. Non-zero implies an error. */
BEN_INVALID, /* Invalid data was given to decoder */
BEN_INSUFFICIENT, /* Insufficient amount of data for decoding */
BEN_NO_MEMORY, /* Memory allocation failed */
BEN_MISMATCH, /* A given structure did not match unpack format */
};
struct bencode {
char type;
};
struct bencode_bool {
char type;
char b;
};
struct bencode_dict_node {
long long hash;
struct bencode *key;
struct bencode *value;
size_t next;
};
struct bencode_dict {
char type;
char shared; /* non-zero means that the internal data is shared with
other instances and should not be freed */
size_t n;
size_t alloc;
size_t *buckets;
struct bencode_dict_node *nodes;
};
struct bencode_int {
char type;
long long ll;
};
struct bencode_list {
char type;
char shared; /* non-zero means that the internal data is shared with
other instances and should not be freed */
size_t n;
size_t alloc;
struct bencode **values;
};
struct bencode_str {
char type;
size_t len;
char *s;
};
struct ben_decode_ctx;
struct ben_encode_ctx;
struct bencode_type {
size_t size;
struct bencode *(*decode) (struct ben_decode_ctx *ctx);
int (*encode) (struct ben_encode_ctx *ctx, const struct bencode *b);
size_t (*get_size) (const struct bencode *b);
void (*free) (struct bencode *b);
int (*cmp) (const struct bencode *a, const struct bencode *b);
};
struct bencode_user {
char type;
struct bencode_type *info;
};
struct bencode_error {
int error; /* 0 if no errors */
int line; /* Error line: 0 is the first line */
size_t off; /* Error offset in bytes from the start */
};
/* Allocate an instance of a user-defined type */
void *ben_alloc_user(struct bencode_type *type);
/*
* Try to set capacity of a list or a dict to 'n' objects.
* The function does nothing if 'n' is less than or equal to the number of
* objects in 'b'. That is, nothing happens if n <= ben_{dict|list}_len(b).
*
* This function is used only for advice. The implementation need not obey it.
*
* The function returns 0 if the new capacity is used, otherwise -1.
*
* Note: This can be used to make construction of lists and dicts
* more efficient when the number of inserted items is known in advance.
*/
int ben_allocate(struct bencode *b, size_t n);
/*
* Returns an identical but a separate copy of structure b. Returns NULL if
* there is no memory to make a copy. The copy is made recursively.
*/
struct bencode *ben_clone(const struct bencode *b);
/*
* Returns a weak reference copy of structure b. Only a minimum amount of
* data is copied because the returned structure references to the same
* internal data as the original structure. As a result, the original
* structure must remain valid until the copy is destroyed.
*
* This function is used for optimization for special cases.
*/
struct bencode *ben_shared_clone(const struct bencode *b);
/*
* ben_cmp() is similar to strcmp(). It compares integers, strings and lists
* similar to Python. User-defined types can be also compared.
* Note: an integer is always less than a string.
*
* ben_cmp(a, b) returns a negative value if "a < b", 0 if "a == b",
* or a positive value if "a > b".
*
* Algorithm for comparing dictionaries is:
* If 'a' and 'b' have different number of keys or keys have different values,
* a non-zero value is returned. Otherwise, they have the exact same keys
* and comparison is done in ben_cmp() order of keys. The value for each key
* is compared, and the first inequal value (ben_cmp() != 0) defines the
* return value of the comparison.
*
* Note: recursive dictionaries in depth have the same issues.
*/
int ben_cmp(const struct bencode *a, const struct bencode *b);
/* Same as ben_cmp(), but the second argument is a C string */
int ben_cmp_with_str(const struct bencode *a, const char *s);
/*
* Comparison function suitable for qsort(). Uses ben_cmp(), so this can be
* used to order both integer and string arrays.
*/
int ben_cmp_qsort(const void *a, const void *b);
/*
* Decode 'data' with 'len' bytes of data. Returns NULL on error.
* The encoded data must be exactly 'len' bytes (not less), otherwise NULL
* is returned. ben_decode2() function supports partial decoding ('len' is
* larger than actual decoded message) and gives more accurate error reports.
*/
struct bencode *ben_decode(const void *data, size_t len);
/*
* Same as ben_decode(), but allows one to set start offset for decoding with
* 'off' and reports errors more accurately.
*
* '*off' must point to decoding start offset inside 'data'.
* If decoding is successful, '*off' is updated to point to the next byte
* after the decoded message.
*
* If 'error != NULL', it is updated according to the success and error of
* the decoding. BEN_OK is success, BEN_INVALID means invalid data.
* BEN_INSUFFICIENT means data is invalid but could be valid if more data
* was given for decoding. BEN_NO_MEMORY means decoding ran out of memory.
*/
struct bencode *ben_decode2(const void *data, size_t len, size_t *off, int *error);
/*
* Same as ben_decode2(), but allows one to define user types.
*/
struct bencode *ben_decode3(const void *data, size_t len, size_t *off, int *error, struct bencode_type *types[128]);
/*
* Same as ben_decode(), but decodes data encoded with ben_print(). This is
* whitespace tolerant, so intended Python syntax can also be read.
* The decoder skips comments that begin with a '#' character.
* The comment starts from '#' character and ends at the end of the same line.
*
* For example, this can be used to read in config files written as a Python
* dictionary.
*
* ben_decode_printed2() fills information about the error in
* struct bencode_error.
* error->error is 0 on success, otherwise it is an error code
* (see ben_decode2()).
* error->line is the line number where error occured.
* error->off is the byte offset of error (approximation).
*/
struct bencode *ben_decode_printed(const void *data, size_t len);
struct bencode *ben_decode_printed2(const void *data, size_t len, size_t *off, struct bencode_error *error);
/* Get the serialization size of bencode structure 'b' */
size_t ben_encoded_size(const struct bencode *b);
/* encode 'b'. Return encoded data with a pointer, and length in '*len' */
void *ben_encode(size_t *len, const struct bencode *b);
/*
* encode 'b' into 'data' buffer with at most 'maxlen' bytes.
* Returns the size of encoded data.
*/
size_t ben_encode2(char *data, size_t maxlen, const struct bencode *b);
/*
* You must use ben_free() for all allocated bencode structures after use.
* If b == NULL, ben_free does nothing.
*
* ben_free() frees all the objects contained within the bencoded structure.
* It recursively iterates over lists and dictionaries and frees objects.
*/
void ben_free(struct bencode *b);
long long ben_str_hash(const struct bencode *b);
long long ben_int_hash(const struct bencode *b);
long long ben_hash(const struct bencode *b);
/* Create a string from binary data with len bytes */
struct bencode *ben_blob(const void *data, size_t len);
/* Create a boolean from integer */
struct bencode *ben_bool(int b);
/* Create an empty dictionary */
struct bencode *ben_dict(void);
/*
* Try to locate 'key' in dictionary. Returns the associated value, if found.
* Returns NULL if the key does not exist.
*/
struct bencode *ben_dict_get(const struct bencode *d, const struct bencode *key);
struct bencode *ben_dict_get_by_str(const struct bencode *d, const char *key);
struct bencode *ben_dict_get_by_int(const struct bencode *d, long long key);
struct bencode_keyvalue {
struct bencode *key;
struct bencode *value;
};
/*
* Returns an array of key-value pairs in key order as defined by ben_cmp().
* Array elements are struct bencode_keyvalue members. Returns NULL if
* the array can not be allocated or the bencode object is not a dictionary.
* The returned array must be freed by using free(). The length of the
* array can be determined with ben_dict_len(d).
*
* Warning: key and value pointers in the array are pointers to exact same
* objects in the dictionary. Therefore, the dictionary and its key-values
* must exist while the same keys and values are accessed from the array.
*/
struct bencode_keyvalue *ben_dict_ordered_items(const struct bencode *d);
/*
* Try to locate 'key' in dictionary. Returns the associated value, if found.
* The value must be later freed with ben_free(). Returns NULL if the key
* does not exist.
*/
struct bencode *ben_dict_pop(struct bencode *d, const struct bencode *key);
struct bencode *ben_dict_pop_by_str(struct bencode *d, const char *key);
struct bencode *ben_dict_pop_by_int(struct bencode *d, long long key);
/*
* Set 'key' in dictionary to be 'value'. An old value exists for the key
* is freed if it exists. 'key' and 'value' are owned by the dictionary
* after a successful call (one may not call ben_free() for 'key' or
* 'value'). One may free 'key' and 'value' if the call is unsuccessful.
*
* Returns 0 on success, -1 on failure (no memory).
*/
int ben_dict_set(struct bencode *d, struct bencode *key, struct bencode *value);
/* Same as ben_dict_set(), but the key is a C string */
int ben_dict_set_by_str(struct bencode *d, const char *key, struct bencode *value);
/* Same as ben_dict_set(), but the key and value are C strings */
int ben_dict_set_str_by_str(struct bencode *d, const char *key, const char *value);
struct bencode *ben_int(long long ll);
/* Create an empty list */
struct bencode *ben_list(void);
/*
* Append 'b' to 'list'. Returns 0 on success, -1 on failure (no memory).
* One may not call ben_free(b) after a successful call, because the list owns
* the object 'b'.
*/
int ben_list_append(struct bencode *list, struct bencode *b);
int ben_list_append_str(struct bencode *list, const char *s);
int ben_list_append_int(struct bencode *list, long long ll);
/* Remove and return value at position 'pos' in list */
struct bencode *ben_list_pop(struct bencode *list, size_t pos);
/*
* Returns a Python formatted C string representation of 'b' on success,
* NULL on failure. The returned string should be freed with free().
*
* Note: The string is terminated with '\0'. All instances of '\0' bytes in
* the bencoded data are escaped so that there is only one '\0' byte
* in the generated string at the end.
*/
char *ben_print(const struct bencode *b);
/* Create a string from C string (note bencode string may contain '\0'. */
struct bencode *ben_str(const char *s);
/* Return a human readable explanation of error returned with ben_decode2() */
const char *ben_strerror(int error);
/*
* Unpack a Bencoded structure similar to scanf(). Takes a format string and
* a list of pointers as variable arguments. The given b structure is checked
* against the format and values are unpacked using the given specifiers.
* A specifier begins with a percent (%) that follows a string of specifier
* characters documented below.
* The syntax is similar to Python format for recursive data structures, and
* consists of tokens {, }, [, ] with any number of spaces between them.
* The keys of a dictionary are given as literal strings or integers and
* matched against the keys of the Bencoded structure.
*
* Unpack modifiers:
* l The integer is of type long or unsigned long, and the type of the
* argument is expected to be long * or unsigned long *.
* ll The integer is a long long or an unsigned long long, and the
* argument is long long * or unsigned long long *.
* L Same as ll.
* q Same as ll.
*
* Unpack specifiers:
* %ps The Bencode value must be a string and a pointer to a string
* (char **) is expected to be given as arguments. Note, returns a
* reference to the internal string buffer. The returned memory should
* not be freed and it has the same life time as the Bencode string.
*
* %pb Takes any structure and writes a pointer given as an argument.
* The argument is expected to be "struct bencode **". Note, returns a
* reference to the value inside the structure passed to ben_unpack().
* The returned memory should not be freed and it has the same life
* time as the original structure.
*
* %d The bencode value is expected to be a (signed) integer. The
* preceeding conversion modifiers define the type of the given
* pointer.
* %u The bencode value is expected to be an unsigned integer. The
* preceeding conversion modifiers define the type of the given
* pointer.
*/
int ben_unpack(const struct bencode *b, const char *fmt, ...)
BEN_CHECK_FORMAT(scanf, 2, 3);
int ben_unpack2(const struct bencode *b, size_t *off, struct bencode_error *error, const char *fmt, ...)
BEN_CHECK_FORMAT(scanf, 4, 5);
/*
* Pack a Bencoded structure similar to printf(). Takes a format string and
* a list of values as variable arguments.
* Works similarly to ben_decode_printed(), but allows the string to values
* specifiers which are replaced with values given as arguments.
* A specifier begins with a percent (%) that follows a string of specifier
* characters documented below.
*
* Value modifiers:
* l The integer is of type long or unsigned long.
* ll The integer is a long long or an unsigned long long.
* L Same as ll.
* q Same as ll.
*
* Value specifiers:
* %s A string pointer (char *) expected to be given as argument. A new
* Bencode string is constructed from the given string.
*
* %pb A Bencode structure (struct bencode *) is expected to be given as
* argument. Note, takes ownership of the structure, even when an
* error is returned.
*
* %d Constructs a new integer from the given (signed) integer. The
* preceeding conversion modifiers define the type of the value.
*
* %u Constructs a new integer from the given unsigned integer. The
* preceeding conversion modifiers define the type of the value.
*/
struct bencode *ben_pack(const char *fmt, ...)
BEN_CHECK_FORMAT(printf, 1, 2);
/* ben_is_bool() returns 1 iff b is a boolean, 0 otherwise */
static inline int ben_is_bool(const struct bencode *b)
{
return b->type == BENCODE_BOOL;
}
static inline int ben_is_dict(const struct bencode *b)
{
return b->type == BENCODE_DICT;
}
static inline int ben_is_int(const struct bencode *b)
{
return b->type == BENCODE_INT;
}
static inline int ben_is_list(const struct bencode *b)
{
return b->type == BENCODE_LIST;
}
static inline int ben_is_str(const struct bencode *b)
{
return b->type == BENCODE_STR;
}
static inline int ben_is_user(const struct bencode *b)
{
return b->type == BENCODE_USER;
}
/*
* ben_bool_const_cast(b) returns "(const struct bencode_bool *) b" if the
* underlying object is a boolean, NULL otherwise.
*/
static inline const struct bencode_bool *ben_bool_const_cast(const struct bencode *b)
{
return b->type == BENCODE_BOOL ? ((const struct bencode_bool *) b) : NULL;
}
/*
* ben_bool_cast(b) returns "(struct bencode_bool *) b" if the
* underlying object is a boolean, NULL otherwise.
*/
static inline struct bencode_bool *ben_bool_cast(struct bencode *b)
{
return b->type == BENCODE_BOOL ? ((struct bencode_bool *) b) : NULL;
}
static inline const struct bencode_dict *ben_dict_const_cast(const struct bencode *b)
{
return b->type == BENCODE_DICT ? ((const struct bencode_dict *) b) : NULL;
}
static inline struct bencode_dict *ben_dict_cast(struct bencode *b)
{
return b->type == BENCODE_DICT ? ((struct bencode_dict *) b) : NULL;
}
static inline const struct bencode_int *ben_int_const_cast(const struct bencode *i)
{
return i->type == BENCODE_INT ? ((const struct bencode_int *) i) : NULL;
}
static inline struct bencode_int *ben_int_cast(struct bencode *i)
{
return i->type == BENCODE_INT ? ((struct bencode_int *) i) : NULL;
}
static inline const struct bencode_list *ben_list_const_cast(const struct bencode *list)
{
return list->type == BENCODE_LIST ? ((const struct bencode_list *) list) : NULL;
}
static inline struct bencode_list *ben_list_cast(struct bencode *list)
{
return list->type == BENCODE_LIST ? ((struct bencode_list *) list) : NULL;
}
static inline const struct bencode_str *ben_str_const_cast(const struct bencode *str)
{
return str->type == BENCODE_STR ? ((const struct bencode_str *) str) : NULL;
}
static inline struct bencode_str *ben_str_cast(struct bencode *str)
{
return str->type == BENCODE_STR ? ((struct bencode_str *) str) : NULL;
}
static inline const struct bencode_user *ben_user_const_cast(const struct bencode *user)
{
return user->type == BENCODE_USER ? ((const struct bencode_user *) user) : NULL;
}
static inline struct bencode_user *ben_user_cast(struct bencode *user)
{
return user->type == BENCODE_USER ? ((struct bencode_user *) user) : NULL;
}
static inline int ben_is_user_type(const struct bencode *b, struct bencode_type *type)
{
return b->type == BENCODE_USER ? ((const struct bencode_user *) b)->info == type : 0;
}
static inline const void *ben_user_type_const_cast(const struct bencode *b, struct bencode_type *type)
{
return (b->type == BENCODE_USER && ((const struct bencode_user *) b)->info == type) ? b : NULL;
}
static inline void *ben_user_type_cast(struct bencode *b, struct bencode_type *type)
{
return (b->type == BENCODE_USER && ((const struct bencode_user *) b)->info == type) ? b : NULL;
}
/* Return the number of keys in a dictionary 'b' */
static inline size_t ben_dict_len(const struct bencode *b)
{
return ben_dict_const_cast(b)->n;
}
/* Return the number of items in a list 'b' */
static inline size_t ben_list_len(const struct bencode *b)
{
return ben_list_const_cast(b)->n;
}
/* ben_list_get(list, i) returns object at position i in list */
static inline struct bencode *ben_list_get(const struct bencode *list, size_t i)
{
const struct bencode_list *l = ben_list_const_cast(list);
if (i >= l->n) {
fprintf(stderr, "bencode: List index out of bounds\n");
abort();
}
return l->values[i];
}
/*
* ben_list_set(list, i, b) sets object b to list at position i.
* The old value at position i is freed.
* The program aborts if position i is out of bounds.
*/
void ben_list_set(struct bencode *list, size_t i, struct bencode *b);
/* Return the number of bytes in a string 'b' */
static inline size_t ben_str_len(const struct bencode *b)
{
return ben_str_const_cast(b)->len;
}
/* Return boolean value (0 or 1) of 'b' */
static inline int ben_bool_val(const struct bencode *b)
{
return ben_bool_const_cast(b)->b ? 1 : 0;
}
/* Return integer value of 'b' */
static inline long long ben_int_val(const struct bencode *b)
{
return ben_int_const_cast(b)->ll;
}
/*
* Note: the string is always zero terminated. Also, the string may
* contain more than one zero.
* bencode strings are not compatible with C strings.
*/
static inline const char *ben_str_val(const struct bencode *b)
{
return ben_str_const_cast(b)->s;
}
/*
* ben_list_for_each() is an iterator macro for bencoded lists.
*
* Note, it is not allowed to change the list while iterating except by
* using ben_list_pop_current().
*
* pos is a size_t.
*
* Example:
*
* size_t pos;
* struct bencode *list = xxx;
* struct bencode *value;
* ben_list_for_each(value, pos, list) {
* inspect(value);
* }
*/
#define ben_list_for_each(value, pos, l) \
for ((pos) = (size_t) 0; \
(pos) < (ben_list_const_cast(l))->n && \
((value) = ((const struct bencode_list *) (l))->values[(pos)]) != NULL ; \
(pos)++)
/*
* ben_list_pop_current() returns and removes the current item at 'pos'
* while iterating the list with ben_list_for_each().
* It can be used more than once per walk, but only once per item.
* Example below:
*
* Filter out all items from list whose string value does not begin with "foo".
*
* ben_list_for_each(value, pos, list) {
* if (strncmp(ben_str_val(value), "foo", 3) != 0)
* ben_free(ben_list_pop_current(&pos, list));
* }
*/
static inline struct bencode *ben_list_pop_current(struct bencode *list,
size_t *pos)
{
struct bencode *value = ben_list_pop(list, *pos);
(*pos)--;
return value;
}
/*
* ben_dict_for_each() is an iterator macro for bencoded dictionaries.
*
* Note, it is not allowed to change the dictionary while iterating except
* by using ben_dict_pop_current().
*
* struct bencode *dict = ben_dict();
* size_t pos;
* struct bencode *key;
* struct bencode *value;
* ben_dict_set_str_by_str(dict, "foo", "bar");
*
* ben_dict_for_each(key, value, pos, dict) {
* use(key, value);
* }
*
* pos is a size_t.
*/
#define ben_dict_for_each(bkey, bvalue, pos, d) \
for ((pos) = 0; \
(pos) < (ben_dict_const_cast(d))->n && \
((bkey) = ((const struct bencode_dict *) (d))->nodes[(pos)].key) != NULL && \
((bvalue) = ((const struct bencode_dict *) (d))->nodes[(pos)].value) != NULL; \
(pos)++)
/*
* ben_dict_pop_current() deletes the current item at 'pos' while iterating
* the dictionary with ben_dict_for_each(). It can be used more than once
* per walk, but only once per item. Example below:
*
* Filter out all items from dictionary whose key does not begin with "foo".
*
* ben_dict_for_each(key, value, pos, dict) {
* if (strncmp(ben_str_val(key), "foo", 3) != 0)
* ben_free(ben_dict_pop_current(dict, &pos));
* }
*/
struct bencode *ben_dict_pop_current(struct bencode *dict, size_t *pos);
/* Report an error while decoding. Returns NULL. */
void *ben_insufficient_ptr(struct ben_decode_ctx *ctx);
void *ben_invalid_ptr(struct ben_decode_ctx *ctx);
void *ben_oom_ptr(struct ben_decode_ctx *ctx);
/*
* Decode from the current position of 'ctx'.
*
* This function is used to implement decoders for user-defined types.
*/
struct bencode *ben_ctx_decode(struct ben_decode_ctx *ctx);
/*
* Test whether the input of 'ctx' has at least n bytes left.
* Returns 0 when there is enough bytes left and -1 when there isn't.
*
* This function is used to implement decoders for user-defined types.
*/
int ben_need_bytes(const struct ben_decode_ctx *ctx, size_t n);
/*
* Returns the character in current position of 'ctx'.
*
* This function is used to implement decoders for user-defined types.
*/
char ben_current_char(const struct ben_decode_ctx *ctx);
/*
* Get the next n bytes from input.
* Returns pointer to the data or NULL when there aren't enough bytes left.
*
* This function is used to implement decoders for user-defined types.
*/
const char *ben_current_buf(const struct ben_decode_ctx *ctx, size_t n);
/*
* Increments current position by n.
*
* This function is used to implement decoders for user-defined types.
*/
void ben_skip(struct ben_decode_ctx *ctx, size_t n);
/*
* Encode to the output of 'ctx'. The size of the encoded data can be obtained
* with ben_encoded_size().
*
* This function is used to implement encoders for user-defined types.
*/
int ben_ctx_encode(struct ben_encode_ctx *ctx, const struct bencode *b);
/*
* Append one character to output of 'ctx'. The amount of bytes written to the
* output must be the same as returned by get_size().
*
* This function is used to implement encoders for user-defined types.
*/
int ben_put_char(struct ben_encode_ctx *ctx, char c);
/*
* Append data to output of 'ctx'. The amount of bytes written to the output
* must be the same as returned by get_size().
*
* This function is used to implement encoders for user-defined types.
*/
int ben_put_buffer(struct ben_encode_ctx *ctx, const void *buf, size_t len);
#ifdef __cplusplus
}
#endif
#endif
+8 -2
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2012, Anthony Minessale II
* Copyright (c) 2010-2015, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -30,9 +30,14 @@
* 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
#include "ks.h"
KS_BEGIN_EXTERN_C
/**
* @defgroup ks_buffer Buffer Routines
* @ingroup buffer
@@ -133,6 +138,7 @@ 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);
KS_END_EXTERN_C
#endif
/* For Emacs:
* Local Variables:
+28 -36
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* Copyright (c) 2007-2015, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -52,16 +52,12 @@
#ifndef KS_CONFIG_H
#define KS_CONFIG_H
KS_BEGIN_EXTERN_C
#include "ks.h"
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
#define KS_URL_SEPARATOR "://"
#ifdef WIN32
#define KS_PATH_SEPARATOR "\\"
#ifndef KS_CONFIG_DIR
@@ -107,26 +103,26 @@ 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;
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;
};
int lockto;
};
/*!
\brief Open a configuration file
@@ -134,13 +130,13 @@ struct ks_config {
\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);
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);
KS_DECLARE(void) ks_config_close_file(ks_config_t *cfg);
/*!
\brief Retrieve next name/value pair from configuration file
@@ -148,24 +144,20 @@ KS_DECLARE(void) ks_config_close_file(ks_config_t * cfg);
\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);
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);
KS_DECLARE(int) ks_config_get_cas_bits(char *strvalue, unsigned char *outbits);
/** @} */
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
#endif /* defined(KS_CONFIG_H) */
KS_END_EXTERN_C
#endif /* defined(KS_CONFIG_H) */
/* For Emacs:
* Local Variables:
* mode:c
+109
View File
@@ -0,0 +1,109 @@
/*
Copyright (c) 2009-2011 by Juliusz Chroboczek
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.
*/
#ifndef _KS_DHT_H
#define _KS_DHT_H
#include "ks.h"
#include "ks_bencode.h"
KS_BEGIN_EXTERN_C
typedef enum {
KS_DHT_EVENT_NONE = 0,
KS_DHT_EVENT_VALUES = 1,
KS_DHT_EVENT_VALUES6 = 2,
KS_DHT_EVENT_SEARCH_DONE = 3,
KS_DHT_EVENT_SEARCH_DONE6 = 4
} ks_dht_event_t;
typedef enum {
DHT_PARAM_AUTOROUTE = 1
} ks_dht_param_t;
typedef enum {
KS_DHT_AF_INET4 = (1 << 0),
KS_DHT_AF_INET6 = (1 << 1)
} ks_dht_af_flag_t;
typedef void (*dht_callback_t)(void *closure, ks_dht_event_t event, const unsigned char *info_hash, const void *data, size_t data_len);
typedef struct dht_handle_s dht_handle_t;
KS_DECLARE(int) dht_periodic(dht_handle_t *h, const void *buf, size_t buflen, ks_sockaddr_t *from);
KS_DECLARE(ks_status_t) ks_dht_init(dht_handle_t **handle, ks_dht_af_flag_t af_flags, const unsigned char *id, unsigned int port);
KS_DECLARE(void) ks_dht_set_param(dht_handle_t *h, ks_dht_param_t param, ks_bool_t val);
KS_DECLARE(ks_status_t) ks_dht_add_ip(dht_handle_t *h, char *ip, int port);
KS_DECLARE(void) ks_dht_start(dht_handle_t *h);
KS_DECLARE(int) dht_insert_node(dht_handle_t *h, const unsigned char *id, ks_sockaddr_t *sa);
KS_DECLARE(int) dht_ping_node(dht_handle_t *h, ks_sockaddr_t *sa);
KS_DECLARE(int) dht_search(dht_handle_t *h, const unsigned char *id, int port, int af, dht_callback_t callback, void *closure);
KS_DECLARE(int) dht_nodes(dht_handle_t *h, int af, int *good_return, int *dubious_return, int *cached_return, int *incoming_return);
KS_DECLARE(ks_status_t) ks_dht_one_loop(dht_handle_t *h, int timeout);
KS_DECLARE(ks_status_t) ks_dht_get_bind_addrs(dht_handle_t *h, const ks_sockaddr_t ***addrs, ks_size_t *addrlen);
KS_DECLARE(void) ks_dht_set_callback(dht_handle_t *h, dht_callback_t callback, void *closure);
KS_DECLARE(void) ks_dht_set_port(dht_handle_t *h, unsigned int port);
KS_DECLARE(void) dht_dump_tables(dht_handle_t *h, FILE *f);
KS_DECLARE(int) dht_get_nodes(dht_handle_t *h, struct sockaddr_in *sin, int *num, struct sockaddr_in6 *sin6, int *num6);
KS_DECLARE(int) dht_uninit(dht_handle_t **h);
KS_DECLARE(void) ks_dht_set_v(dht_handle_t *h, const unsigned char *v);
KS_DECLARE(int) ks_dht_calculate_mutable_storage_target(unsigned char *pk, unsigned char *salt, int salt_length, unsigned char *target, int target_length);
KS_DECLARE(int) ks_dht_generate_mutable_storage_args(struct bencode *data, int64_t sequence, int cas,
unsigned char *id, int id_len, /* querying nodes id */
const unsigned char *sk, const unsigned char *pk,
unsigned char *salt, unsigned long long salt_length,
unsigned char *token, unsigned long long token_length,
unsigned char *signature, unsigned long long *signature_length,
struct bencode **arguments);
/* This must be provided by the user. */
KS_DECLARE(int) dht_blacklisted(const ks_sockaddr_t *sa);
KS_DECLARE(void) dht_hash(void *hash_return, int hash_size, const void *v1, int len1, const void *v2, int len2, const void *v3, int len3);
KS_DECLARE(int) dht_random_bytes(void *buf, size_t size);
KS_DECLARE(int) ks_dht_send_message_mutable(dht_handle_t *h, unsigned char *sk, unsigned char *pk, char **node_id,
char *message_id, int sequence, char *message, ks_time_t life);
KS_DECLARE(int) ks_dht_send_message_mutable_cjson(dht_handle_t *h, unsigned char *sk, unsigned char *pk, char **node_id,
char *message_id, int sequence, cJSON *message, ks_time_t life);
typedef void (ks_dht_store_entry_json_cb)(struct dht_handle_s *h, const cJSON *msg, void *obj);
KS_DECLARE(void) ks_dht_store_entry_json_cb_set(struct dht_handle_s *h, ks_dht_store_entry_json_cb *store_json_cb, void *arg);
KS_DECLARE(int) ks_dht_api_find_node(dht_handle_t *h, char *node_id_hex, char *target_hex, ks_bool_t ipv6);
KS_END_EXTERN_C
#endif /* _KS_DHT_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 noet:
*/
+49
View File
@@ -0,0 +1,49 @@
/*
* Cross Platform dso/dll load abstraction
* Copyright(C) 2008 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.
*
*/
#include "ks.h"
#ifndef _KS_DSO_H
#define _KS_DSO_H
KS_BEGIN_EXTERN_C
typedef void (*ks_func_ptr_t) (void);
typedef void * ks_dso_lib_t;
KS_DECLARE(ks_status_t) ks_dso_destroy(ks_dso_lib_t *lib);
KS_DECLARE(ks_dso_lib_t) ks_dso_open(const char *path, char **err);
KS_DECLARE(void *) ks_dso_func_sym(ks_dso_lib_t lib, const char *sym, char **err);
KS_DECLARE(char *) ks_build_dso_path(const char *name, char *path, ks_size_t len);
KS_END_EXTERN_C
#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 noet:
*/
+372
View File
@@ -0,0 +1,372 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* ks_hash.h -- Ks_Hash
*
*/
/* ks_hash.h Copyright (C) 2002 Christopher Clark <firstname.lastname@cl.cam.ac.uk> */
#ifndef __KS_HASH_CWC22_H__
#define __KS_HASH_CWC22_H__
#ifdef _MSC_VER
#ifndef __inline__
#define __inline__ __inline
#endif
#endif
#include "ks.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct ks_hash ks_hash_t;
typedef struct ks_hash_iterator ks_hash_iterator_t;
typedef enum {
KS_UNLOCKED,
KS_READLOCKED
} ks_locked_t;
/* Example of use:
*
* ks_hash_t *h;
* struct some_key *k;
* struct some_value *v;
*
* static unsigned int hash_from_key_fn( void *k );
* static int keys_equal_fn ( void *key1, void *key2 );
*
* h = ks_hash_create(16, hash_from_key_fn, keys_equal_fn);
* k = (struct some_key *) malloc(sizeof(struct some_key));
* v = (struct some_value *) malloc(sizeof(struct some_value));
*
* (initialise k and v to suitable values)
*
* if (! ks_hash_insert(h,k,v) )
* { exit(-1); }
*
* if (NULL == (found = ks_hash_search(h,k) ))
* { printf("not found!"); }
*
* if (NULL == (found = ks_hash_remove(h,k) ))
* { printf("Not found\n"); }
*
*/
/* Macros may be used to define type-safe(r) ks_hash access functions, with
* methods specialized to take known key and value types as parameters.
*
* Example:
*
* Insert this at the start of your file:
*
* DEFINE_KS_HASH_INSERT(insert_some, struct some_key, struct some_value);
* DEFINE_KS_HASH_SEARCH(search_some, struct some_key, struct some_value);
* DEFINE_KS_HASH_REMOVE(remove_some, struct some_key, struct some_value);
*
* This defines the functions 'insert_some', 'search_some' and 'remove_some'.
* These operate just like ks_hash_insert etc., with the same parameters,
* but their function signatures have 'struct some_key *' rather than
* 'void *', and hence can generate compile time errors if your program is
* supplying incorrect data as a key (and similarly for value).
*
* Note that the hash and key equality functions passed to ks_hash_create
* still take 'void *' parameters instead of 'some key *'. This shouldn't be
* a difficult issue as they're only defined and passed once, and the other
* functions will ensure that only valid keys are supplied to them.
*
* The cost for this checking is increased code size and runtime overhead
* - if performance is important, it may be worth switching back to the
* unsafe methods once your program has been debugged with the safe methods.
* This just requires switching to some simple alternative defines - eg:
* #define insert_some ks_hash_insert
*
*/
typedef enum {
KS_HASH_FLAG_NONE = 0,
KS_HASH_FLAG_DEFAULT = (1 << 0),
KS_HASH_FLAG_FREE_KEY = (1 << 1),
KS_HASH_FLAG_FREE_VALUE = (1 << 2),
KS_HASH_FLAG_RWLOCK = (1 << 3),
KS_HASH_FLAG_DUP_CHECK = (1 << 4)
} ks_hash_flag_t;
#define KS_HASH_FREE_BOTH KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE
typedef enum {
KS_HASH_MODE_DEFAULT = 0,
KS_HASH_MODE_CASE_SENSITIVE,
KS_HASH_MODE_CASE_INSENSITIVE,
KS_HASH_MODE_INT,
KS_HASH_MODE_INT64,
KS_HASH_MODE_PTR
} ks_hash_mode_t;
/*****************************************************************************
* ks_hash_create
* @name ks_hash_create
* @param minsize minimum initial size of ks_hash
* @param hashfunction function for hashing keys
* @param key_eq_fn function for determining key equality
* @return newly created ks_hash or NULL on failure
*/
KS_DECLARE(ks_status_t)
ks_hash_create_ex(ks_hash_t **hp, unsigned int minsize,
unsigned int (*hashfunction) (void*),
int (*key_eq_fn) (void*,void*), ks_hash_mode_t mode, ks_hash_flag_t flags, ks_hash_destructor_t destructor, ks_pool_t *pool);
/*****************************************************************************
* ks_hash_insert
* @name ks_hash_insert
* @param h the ks_hash to insert into
* @param k the key - ks_hash claims ownership and will free on removal
* @param v the value - does not claim ownership
* @return non-zero for successful insertion
*
* This function will cause the table to expand if the insertion would take
* the ratio of entries to table size over the maximum load factor.
*
* This function does not check for repeated insertions with a duplicate key.
* The value returned when using a duplicate key is undefined -- when
* the ks_hash changes size, the order of retrieval of duplicate key
* entries is reversed.
* If in doubt, remove before insert.
*/
KS_DECLARE(int) ks_hash_insert_ex(ks_hash_t *h, void *k, void *v, ks_hash_flag_t flags, ks_hash_destructor_t destructor);
#define ks_hash_insert(_h, _k, _v) ks_hash_insert_ex(_h, _k, _v, 0, NULL)
#define DEFINE_KS_HASH_INSERT(fnname, keytype, valuetype) \
int fnname (ks_hash_t *h, keytype *k, valuetype *v) \
{ \
return ks_hash_insert(h,k,v); \
}
KS_DECLARE(void) ks_hash_set_flags(ks_hash_t *h, ks_hash_flag_t flags);
KS_DECLARE(void) ks_hash_set_destructor(ks_hash_t *h, ks_hash_destructor_t destructor);
/*****************************************************************************
* ks_hash_search
* @name ks_hash_search
* @param h the ks_hash to search
* @param k the key to search for - does not claim ownership
* @return the value associated with the key, or NULL if none found
*/
KS_DECLARE(void *)
ks_hash_search(ks_hash_t *h, void *k, ks_locked_t locked);
#define DEFINE_KS_HASH_SEARCH(fnname, keytype, valuetype) \
valuetype * fnname (ks_hash_t *h, keytype *k) \
{ \
return (valuetype *) (ks_hash_search(h,k)); \
}
/*****************************************************************************
* ks_hash_remove
* @name ks_hash_remove
* @param h the ks_hash to remove the item from
* @param k the key to search for - does not claim ownership
* @return the value associated with the key, or NULL if none found
*/
KS_DECLARE(void *) /* returns value */
ks_hash_remove(ks_hash_t *h, void *k);
#define DEFINE_KS_HASH_REMOVE(fnname, keytype, valuetype) \
valuetype * fnname (ks_hash_t *h, keytype *k) \
{ \
return (valuetype *) (ks_hash_remove(h,k)); \
}
/*****************************************************************************
* ks_hash_count
* @name ks_hash_count
* @param h the ks_hash
* @return the number of items stored in the ks_hash
*/
KS_DECLARE(unsigned int)
ks_hash_count(ks_hash_t *h);
/*****************************************************************************
* ks_hash_destroy
* @name ks_hash_destroy
* @param h the ks_hash
* @param free_values whether to call 'free' on the remaining values
*/
KS_DECLARE(void)
ks_hash_destroy(ks_hash_t **h);
KS_DECLARE(ks_hash_iterator_t*) ks_hash_first(ks_hash_t *h, ks_locked_t locked);
KS_DECLARE(void) ks_hash_last(ks_hash_iterator_t **iP);
KS_DECLARE(ks_hash_iterator_t*) ks_hash_next(ks_hash_iterator_t **iP);
KS_DECLARE(void) ks_hash_this(ks_hash_iterator_t *i, const void **key, ks_ssize_t *klen, void **val);
KS_DECLARE(void) ks_hash_this_val(ks_hash_iterator_t *i, void *val);
KS_DECLARE(ks_status_t) ks_hash_create(ks_hash_t **hp, ks_hash_mode_t mode, ks_hash_flag_t flags, ks_pool_t *pool);
KS_DECLARE(void) ks_hash_write_lock(ks_hash_t *h);
KS_DECLARE(void) ks_hash_write_unlock(ks_hash_t *h);
KS_DECLARE(ks_status_t) ks_hash_read_lock(ks_hash_t *h);
KS_DECLARE(ks_status_t) ks_hash_read_unlock(ks_hash_t *h);
static __inline uint32_t ks_hash_default_int64(void *ky)
{
int64_t key = *((int64_t *)ky);
key = (~key) + (key << 18);
key = key ^ (key >> 31);
key = key * 21;
key = key ^ (key >> 11);
key = key + (key << 6);
key = key ^ (key >> 22);
return (uint32_t) key;
}
static __inline int ks_hash_equalkeys_int64(void *k1, void *k2)
{
return *(uint64_t *)k1 == *(uint64_t *)k2;
}
static __inline uint32_t ks_hash_default_int(void *ky) {
uint32_t x = *((uint32_t *)ky);
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x) * 0x45d9f3b;
x = ((x >> 16) ^ x);
return x;
}
static __inline int ks_hash_equalkeys_int(void *k1, void *k2)
{
return *(uint32_t *)k1 == *(uint32_t *)k2;
}
#if 0
}
#endif
static __inline uint32_t ks_hash_default_ptr(void *ky)
{
#ifdef KS_64BIT
return ks_hash_default_int64(ky);
#endif
return ks_hash_default_int(ky);
}
static __inline int ks_hash_equalkeys_ptr(void *k1, void *k2)
{
#ifdef KS_64BIT
return ks_hash_equalkeys_int64(k1, k2);
#endif
return ks_hash_equalkeys_int(k1, k2);
}
static __inline int ks_hash_equalkeys(void *k1, void *k2)
{
return strcmp((char *) k1, (char *) k2) ? 0 : 1;
}
static __inline int ks_hash_equalkeys_ci(void *k1, void *k2)
{
return strcasecmp((char *) k1, (char *) k2) ? 0 : 1;
}
static __inline uint32_t ks_hash_default(void *ky)
{
unsigned char *str = (unsigned char *) ky;
uint32_t hash = 0;
int c;
while ((c = *str)) {
str++;
hash = c + (hash << 6) + (hash << 16) - hash;
}
return hash;
}
static __inline uint32_t ks_hash_default_ci(void *ky)
{
unsigned char *str = (unsigned char *) ky;
uint32_t hash = 0;
int c;
while ((c = ks_tolower(*str))) {
str++;
hash = c + (hash << 6) + (hash << 16) - hash;
}
return hash;
}
#ifdef __cplusplus
} /* extern C */
#endif
#endif /* __KS_HASH_CWC22_H__ */
/*
* Copyright (c) 2002, Christopher Clark
* 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.
*/
/* 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 noet:
*/
Executable → Regular
+64 -7
View File
@@ -76,20 +76,21 @@ 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);
KS_DECLARE(cJSON *)cJSON_GetObjectItem(const cJSON *object,const char *string);
KS_DECLARE(const char *)cJSON_GetObjectCstr(const 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();
KS_DECLARE(const char *)cJSON_GetErrorPtr(void);
/* 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_CreateNull(void);
KS_DECLARE(cJSON *)cJSON_CreateTrue(void);
KS_DECLARE(cJSON *)cJSON_CreateFalse(void);
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();
KS_DECLARE(cJSON *)cJSON_CreateArray(void);
KS_DECLARE(cJSON *)cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
KS_DECLARE(cJSON *)cJSON_CreateIntArray(int *numbers,int count);
@@ -114,12 +115,68 @@ KS_DECLARE(void) cJSON_DeleteItemFromObject(cJSON *object,const char *string);
KS_DECLARE(void) cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
KS_DECLARE(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
/* Duplicate a cJSON item */
KS_DECLARE(cJSON *) cJSON_Duplicate(cJSON *item,int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. */
#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))
KS_DECLARE(cJSON *) cJSON_CreateStringPrintf(const char *fmt, ...);
static inline cJSON *json_add_child_obj(cJSON *json, const char *name, cJSON *obj)
{
cJSON *new_json = NULL;
ks_assert(json);
if (obj) {
new_json = obj;
} else {
new_json = cJSON_CreateObject();
}
ks_assert(new_json);
cJSON_AddItemToObject(json, name, new_json);
return new_json;
}
static inline cJSON *json_add_child_array(cJSON *json, const char *name)
{
cJSON *new_json = NULL;
ks_assert(json);
new_json = cJSON_CreateArray();
ks_assert(new_json);
cJSON_AddItemToObject(json, name, new_json);
return new_json;
}
static inline cJSON *json_add_child_string(cJSON *json, const char *name, const char *val)
{
cJSON *new_json = NULL;
ks_assert(json);
new_json = cJSON_CreateString(val);
ks_assert(new_json);
cJSON_AddItemToObject(json, name, new_json);
return new_json;
}
#ifdef __cplusplus
}
#endif
+162 -68
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* Copyright (c) 2007-2015, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,33 +34,94 @@
#ifndef _KS_PLATFORM_H_
#define _KS_PLATFORM_H_
#include <stdarg.h>
KS_BEGIN_EXTERN_C
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
#if !defined(_XOPEN_SOURCE) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(__APPLE__)
#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
#if defined(__linux__) && !defined(_DEFAULT_SOURCE)
#define _DEFAULT_SOURCE 1
#endif
#ifndef __WINDOWS__
#if defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
#define __WINDOWS__
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#if UINTPTR_MAX == 0xffffffffffffffff
#define KS_64BIT 1
#endif
#include <stdarg.h>
#include <time.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include <sys/types.h>
#ifdef __WINDOWS__
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#else
#include <sys/time.h>
#include <sys/select.h>
#include <netinet/tcp.h>
#include <sys/signal.h>
#include <unistd.h>
#include <strings.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#endif
#ifdef _MSC_VER
#pragma comment(lib, "Ws2_32.lib")
#include <io.h>
/*#include <winsock2.h>
#include <ws2tcpip.h>
#include <Synchapi.h>
*/
#ifndef open
#define open _open
#endif
#ifndef close
#define close _close
#endif
#ifndef read
#define read _read
#endif
#ifndef write
#define write _write
#endif
#ifndef __inline__
#define __inline__ __inline
#endif
#ifndef strdup
#define strdup _strdup
#endif
#if (_MSC_VER >= 1400) /* VC8+ */
#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
@@ -69,67 +130,62 @@ extern "C" {
#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
#if (_MSC_VER < 1900) /* VC 2015 */
#ifndef snprintf
#define snprintf _snprintf
#endif
#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 /* _MSC_VER */
#if (_MSC_VER >= 1400) // VC8+
#define ks_assert(expr) assert(expr);__analysis_assume( expr )
#endif
#include <time.h>
#ifndef WIN32
#include <sys/time.h>
#ifndef ks_assert
#define ks_assert(_x) assert(_x)
#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 __WINDOWS__
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;
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#include <assert.h>
#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)
#else
#define KS_SOCK_INVALID -1
typedef int ks_socket_t;
typedef ssize_t ks_ssize_t;
typedef int ks_filehandle_t;
#endif
#ifdef __WINDOWS__
#if defined(KS_DECLARE_STATIC)
#define KS_DECLARE(type) type __stdcall
#define KS_DECLARE_NONSTD(type) type __cdecl
@@ -143,30 +199,68 @@ typedef int ks_filehandle_t;
#define KS_DECLARE_NONSTD(type) __declspec(dllimport) type __cdecl
#define KS_DECLARE_DATA __declspec(dllimport)
#endif
#else // !WIN32
#else // !WIN32
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(KS_API_VISIBILITY)
#define KS_DECLARE(type) __attribute__((visibility("default"))) type
#define KS_DECLARE_NONSTD(type) __attribute__((visibility("default"))) type
#define KS_DECLARE_DATA __attribute__((visibility("default")))
#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
#endif
/* malloc or DIE macros */
#ifdef NDEBUG
#define ks_malloc(ptr, len) (void)( (!!(ptr = malloc(len))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr )
#define ks_zmalloc(ptr, len) (void)( (!!(ptr = calloc(1, (len)))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
#if (_MSC_VER >= 1500) // VC9+
#define ks_strdup(ptr, s) (void)( (!!(ptr = _strdup(s))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
#else
#define ks_strdup(ptr, s) (void)( (!!(ptr = strdup(s))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
#endif
#else
#if (_MSC_VER >= 1500) // VC9+
#define ks_malloc(ptr, len) (void)(assert(((ptr) = malloc((len)))),ptr);__analysis_assume( ptr )
#define ks_zmalloc(ptr, len) (void)(assert((ptr = calloc(1, (len)))),ptr);__analysis_assume( ptr )
#define ks_strdup(ptr, s) (void)(assert(((ptr) = _strdup(s))),ptr);__analysis_assume( ptr )
#else
#define ks_malloc(ptr, len) (void)(assert(((ptr) = malloc((len)))),ptr)
#define ks_zmalloc(ptr, len) (void)(assert((ptr = calloc(1, (len)))),ptr)
#define ks_strdup(ptr, s) (void)(assert(((ptr) = strdup((s)))),ptr)
#endif
#endif
#ifndef __ATTR_SAL
/* used for msvc code analysis */
/* http://msdn2.microsoft.com/en-us/library/ms235402.aspx */
#define _In_
#define _In_z_
#define _In_opt_z_
#define _In_opt_
#define _Printf_format_string_
#define _Ret_opt_z_
#define _Ret_z_
#define _Out_opt_
#define _Out_
#define _Check_return_
#define _Inout_
#define _Inout_opt_
#define _In_bytecount_(x)
#define _Out_opt_bytecapcount_(x)
#define _Out_bytecapcount_(x)
#define _Ret_
#define _Post_z_
#define _Out_cap_(x)
#define _Out_z_cap_(x)
#define _Out_ptrdiff_cap_(x)
#define _Out_opt_ptrdiff_cap_(x)
#define _Post_count_(x)
#endif
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
#endif /* defined(_KS_PLATFORM_H_) */
KS_END_EXTERN_C
#endif /* defined(_KS_PLATFORM_H_) */
/* For Emacs:
* Local Variables:
* mode:c
+478
View File
@@ -0,0 +1,478 @@
/*
* Memory pool defines.
*
* Copyright 1996 by Gray Watson.
*
* This file is part of the ks_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: ks_mpool.h,v 1.4 2006/05/31 20:26:11 gray Exp $
*/
#ifndef __KS_POOL_H__
#define __KS_POOL_H__
#include "ks.h"
KS_BEGIN_EXTERN_C
/*
* ks_pool flags to ks_pool_alloc or ks_pool_set_attr
*/
typedef enum {
KS_POOL_FLAG_DEFAULT = 0,
KS_POOL_FLAG_BEST_FIT = (1 << 0),
/*
* Choose a best fit algorithm not first fit. This takes more CPU
* time but will result in a tighter heap.
*/
KS_POOL_FLAG_HEAVY_PACKING = (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 ks_pool
* 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.
*/
} ks_pool_flag_t;
/*
* Ks_Pool function IDs for the ks_pool_log_func callback function.
*/
#define KS_POOL_FUNC_CLOSE 1 /* ks_pool_close function called */
#define KS_POOL_FUNC_CLEAR 2 /* ks_pool_clear function called */
#define KS_POOL_FUNC_ALLOC 3 /* ks_pool_alloc function called */
#define KS_POOL_FUNC_CALLOC 4 /* ks_pool_calloc function called */
#define KS_POOL_FUNC_FREE 5 /* ks_pool_free function called */
#define KS_POOL_FUNC_RESIZE 6 /* ks_pool_resize function called */
/*
* void ks_pool_log_func_t
*
* DESCRIPTION:
*
* Ks_Pool transaction log function.
*
* RETURNS:
*
* None.
*
* ARGUMENT:
*
* mp_p -> Associated ks_pool address.
*
* func_id -> Integer function ID which identifies which ks_pool
* function is being called.
*
* byte_size -> Optionally specified byte size.
*
* ele_n -> Optionally specified element number. For ks_pool_calloc
* only.
*
* new_addr -> Optionally specified new address. For ks_pool_alloc,
* ks_pool_calloc, and ks_pool_resize only.
*
* old_addr -> Optionally specified old address. For ks_pool_resize and
* ks_pool_free only.
*
* old_byte_size -> Optionally specified old byte size. For
* ks_pool_resize only.
*/
typedef void (*ks_pool_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);
/*
* ks_pool_t *ks_pool_open
*
* DESCRIPTION:
*
* Open/allocate a new memory pool.
*
* RETURNS:
*
* Success - KS_STATUS_SUCCESS
*
* Failure - ks_status_t error code
*
* ARGUMENTS:
*
* poolP <- pointer to new pool that will be set on success
*
*/
KS_DECLARE(ks_status_t) ks_pool_open(ks_pool_t **poolP);
/*
* ks_status_t ks_pool_close
*
* DESCRIPTION:
*
* Close/free a memory allocation pool previously opened with
* ks_pool_open.
*
* RETURNS:
*
* Success - KS_STATUS_SUCCESS
*
* Failure - ks_status_t error code
*
* ARGUMENTS:
*
* mp_pp <-> Pointer to pointer of our memory pool.
*/
KS_DECLARE(ks_status_t) ks_pool_close(ks_pool_t **mp_pP);
/*
* int ks_pool_clear
*
* DESCRIPTION:
*
* Wipe an opened memory pool clean so we can start again.
*
* RETURNS:
*
* Success - KS_STATUS_SUCCESS
*
* Failure - ks_status_t error code
*
* ARGUMENTS:
*
* mp_p <-> Pointer to our memory pool.
*/
KS_DECLARE(ks_status_t) ks_pool_clear(ks_pool_t *mp_p);
/*
* void *ks_pool_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.
*
*/
KS_DECLARE(void *) ks_pool_alloc(ks_pool_t *mp_p, const unsigned long byte_size);
/*
* void *ks_pool_alloc_ex
*
* 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 ks_pool error code.
*/
KS_DECLARE(void *) ks_pool_alloc_ex(ks_pool_t *mp_p, const unsigned long byte_size, ks_status_t *error_p);
/*
* void *ks_pool_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.
*
*/
KS_DECLARE(void *) ks_pool_calloc(ks_pool_t *mp_p, const unsigned long ele_n, const unsigned long ele_size);
/*
* void *ks_pool_calloc_ex
*
* 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 ks_pool error code.
*/
KS_DECLARE(void *) ks_pool_calloc_ex(ks_pool_t *mp_p, const unsigned long ele_n, const unsigned long ele_size, ks_status_t *error_p);
/*
* int ks_pool_free
*
* DESCRIPTION:
*
* Free an address from a memory pool.
*
* RETURNS:
*
* Success - KS_STATUS_SUCCESS
*
* Failure - ks_status_t error code
*
* ARGUMENTS:
*
* mp_p <-> Pointer to the memory pool. If NULL then it will do a
* normal free.
*
* addr <-> Address to free.
*
*/
KS_DECLARE(ks_status_t) ks_pool_free(ks_pool_t *mp_p, void *addr);
/*
* void *ks_pool_resize
*
* DESCRIPTION:
*
* Reallocate an address in a mmeory pool to a new size.
*
* 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.
*
* new_byte_size -> New size of the allocation.
*
*/
KS_DECLARE(void *) ks_pool_resize(ks_pool_t *mp_p, void *old_addr, const unsigned long new_byte_size);
/*
* void *ks_pool_resize_ex
*
* DESCRIPTION:
*
* Reallocate an address in a mmeory pool to a new size.
*
* 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.
*
* new_byte_size -> New size of the allocation.
*
* error_p <- Pointer to integer which, if not NULL, will be set with
* a ks_pool error code.
*/
KS_DECLARE(void *) ks_pool_resize_ex(ks_pool_t *mp_p, void *old_addr, const unsigned long new_byte_size, ks_status_t *error_p);
/*
* int ks_pool_stats
*
* DESCRIPTION:
*
* Return stats from the memory pool.
*
* RETURNS:
*
* Success - KS_STATUS_SUCCESS
*
* Failure - ks_status_t 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.
*/
KS_DECLARE(ks_status_t) ks_pool_stats(const ks_pool_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 ks_pool_set_log_func
*
* DESCRIPTION:
*
* Set a logging callback function to be called whenever there was a
* memory transaction. See ks_pool_log_func_t.
*
* RETURNS:
*
* Success - KS_STATUS_SUCCESS
*
* Failure - ks_status_t error code
*
* ARGUMENTS:
*
* mp_p <-> Pointer to the memory pool.
*
* log_func -> Log function (defined in ks_pool.h) which will be called
* with each ks_pool transaction.
*/
KS_DECLARE(ks_status_t) ks_pool_set_log_func(ks_pool_t *mp_p, ks_pool_log_func_t log_func);
/*
* int ks_pool_set_max_pages
*
* DESCRIPTION:
*
* Set the maximum number of pages that the library will use. Once it
* hits the limit it will return KS_STATUS_NO_PAGES.
*
* NOTE: if the KS_POOL_FLAG_HEAVY_PACKING is set then this max-pages
* value will include the page with the ks_pool header structure in it.
* If the flag is _not_ set then the max-pages will not include this
* first page.
*
* RETURNS:
*
* Success - KS_STATUS_SUCCESS
*
* Failure - ks_status_t error code
*
* ARGUMENTS:
*
* mp_p <-> Pointer to the memory pool.
*
* max_pages -> Maximum number of pages used by the library.
*/
KS_DECLARE(ks_status_t) ks_pool_set_max_pages(ks_pool_t *mp_p, const unsigned int max_pages);
/*
* const char *ks_pool_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.
*/
KS_DECLARE(const char *) ks_pool_strerror(const ks_status_t error);
KS_DECLARE(ks_status_t) ks_pool_set_cleanup(ks_pool_t *mp_p, void *ptr, void *arg, int type, ks_pool_cleanup_fn_t fn);
#define ks_pool_safe_free(_p, _a) ks_pool_free(_p, _a); (_a) = NULL
/*<<<<<<<<<< This is end of the auto-generated output from fillproto. */
KS_DECLARE(char *) ks_pstrdup(ks_pool_t *pool, const char *str);
KS_DECLARE(char *) ks_pstrndup(ks_pool_t *pool, const char *str, size_t len);
KS_DECLARE(char *) ks_pstrmemdup(ks_pool_t *pool, const char *str, size_t len);
KS_DECLARE(void *) ks_pmemdup(ks_pool_t *pool, const void *buf, size_t len);
KS_DECLARE(char *) ks_pstrcat(ks_pool_t *pool, ...);
KS_END_EXTERN_C
#endif /* ! __KS_POOL_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 noet:
*/
+81
View File
@@ -0,0 +1,81 @@
/*
** 2001 September 22
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
*/
#ifndef KS_PRINTF_H
#define KS_PRINTF_H
#include "ks.h"
KS_BEGIN_EXTERN_C
/**
* This routine is a variant of the "sprintf()" from the
* standard C library. The resulting string is written into memory
* obtained from malloc() so that there is never a possiblity of buffer
* overflow. This routine also implement some additional formatting
* options that are useful for constructing SQL statements.
*
* The strings returned by this routine should be freed by calling
* free().
*
* All of the usual printf formatting options apply. In addition, there
* is a "%q" option. %q works like %s in that it substitutes a null-terminated
* string from the argument list. But %q also doubles every '\'' character.
* %q is designed for use inside a string literal. By doubling each '\''
* character it escapes that character and allows it to be inserted into
* the string.
*
* For example, so some string variable contains text as follows:
*
* char *zText = "It's a happy day!";
*
* We can use this text in an SQL statement as follows:
*
* char *z = ks_mprintf("INSERT INTO TABLES('%q')", zText);
* ks_core_db_exec(db, z, callback1, 0, 0);
* free(z);
*
* Because the %q format string is used, the '\'' character in zText
* is escaped and the SQL generated is as follows:
*
* INSERT INTO table1 VALUES('It''s a happy day!')
*
* This is correct. Had we used %s instead of %q, the generated SQL
* would have looked like this:
*
* INSERT INTO table1 VALUES('It's a happy day!');
*
* This second example is an SQL syntax error. As a general rule you
* should always use %q instead of %s when inserting text into a string
* literal.
*/
KS_DECLARE(char *) ks_mprintf(const char *zFormat, ...);
KS_DECLARE(char *) ks_vmprintf(const char *zFormat, va_list ap);
KS_DECLARE(char *) ks_snprintfv(char *zBuf, int n, const char *zFormat, ...);
KS_DECLARE(char *) ks_vsnprintf(char *zbuf, int n, const char *zFormat, va_list ap);
KS_DECLARE(char *) ks_vpprintf(ks_pool_t *pool, const char *zFormat, va_list ap);
KS_DECLARE(char *) ks_pprintf(ks_pool_t *pool, const char *zFormat, ...);
KS_END_EXTERN_C
#endif /* KS_PRINTF_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 noet:
*/
+68
View File
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2007-2015, 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_Q_H_
#define _KS_Q_H_
#include "ks.h"
KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) ks_q_pop_timeout(ks_q_t *q, void **ptr, uint32_t timeout);
KS_DECLARE(ks_status_t) ks_q_wake(ks_q_t *q);
KS_DECLARE(ks_status_t) ks_q_flush(ks_q_t *q);
KS_DECLARE(ks_status_t) ks_q_set_flush_fn(ks_q_t *q, ks_flush_fn_t fn, void *flush_data);
KS_DECLARE(ks_status_t) ks_q_wait(ks_q_t *q);
KS_DECLARE(ks_size_t) ks_q_term(ks_q_t *q);
KS_DECLARE(ks_size_t) ks_q_size(ks_q_t *q);
KS_DECLARE(ks_status_t) ks_q_destroy(ks_q_t **qP);
KS_DECLARE(ks_status_t) ks_q_create(ks_q_t **qP, ks_pool_t *pool, ks_size_t maxlen);
KS_DECLARE(ks_status_t) ks_q_push(ks_q_t *q, void *ptr);
KS_DECLARE(ks_status_t) ks_q_trypush(ks_q_t *q, void *ptr);
KS_DECLARE(ks_status_t) ks_q_pop(ks_q_t *q, void **ptr);
KS_DECLARE(ks_status_t) ks_q_trypop(ks_q_t *q, void **ptr);
KS_END_EXTERN_C
#endif /* defined(_KS_Q_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 noet:
*/
+56
View File
@@ -0,0 +1,56 @@
/*
* Cross Platform random/uuid abstraction
* Copyright(C) 2015 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.
*
*/
#include "ks.h"
#ifndef _KS_RNG_H
#define _KS_RNG_H
KS_BEGIN_EXTERN_C
#ifdef WIN32
#include <Rpc.h>
typedef UUID uuid_t;
#else
#include <uuid/uuid.h>
#endif
KS_DECLARE(uuid_t *) ks_uuid(uuid_t *uuid);
KS_DECLARE(char *) ks_uuid_str(ks_pool_t *pool, uuid_t *uuid);
KS_DECLARE(ks_status_t) ks_rng_init(void);
KS_DECLARE(ks_status_t) ks_rng_shutdown(void);
KS_DECLARE(size_t) ks_rng_get_data(uint8_t* buffer, size_t length);
KS_DECLARE(size_t) ks_rng_add_entropy(const uint8_t *buffer, size_t length);
KS_DECLARE(size_t) ks_rng_seed_data(uint8_t *seed, size_t length);
KS_END_EXTERN_C
#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 noet:
*/
+129
View File
@@ -0,0 +1,129 @@
/*
* Copyright (c) 2007-2014, 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_SOCKET_H_
#define _KS_SOCKET_H_
#include "ks.h"
#ifndef WIN32
#include <poll.h>
#endif
KS_BEGIN_EXTERN_C
#define KS_SO_NONBLOCK 2999
#ifdef WIN32
static __inline int ks_errno(void)
{
return WSAGetLastError();
}
static __inline int ks_errno_is_blocking(int errcode)
{
return errcode == WSAEWOULDBLOCK || errcode == WSAEINPROGRESS || errcode == 35 || errcode == 730035;
}
static __inline int ks_errno_is_interupt(int errcode)
{
return 0;
}
#else
static inline int ks_errno(void)
{
return errno;
}
static inline int ks_errno_is_blocking(int errcode)
{
return errcode == EAGAIN || errcode == EWOULDBLOCK || errcode == EINPROGRESS || errcode == EINTR || errcode == ETIMEDOUT || errcode == 35 || errcode == 730035;
}
static inline int ks_errno_is_interupt(int errcode)
{
return errcode == EINTR;
}
#endif
static __inline int ks_socket_valid(ks_socket_t s) {
return s != KS_SOCK_INVALID;
}
#define KS_SA_INIT {AF_INET};
KS_DECLARE(ks_status_t) ks_socket_send(ks_socket_t sock, void *data, ks_size_t *datalen);
KS_DECLARE(ks_status_t) ks_socket_recv(ks_socket_t sock, void *data, ks_size_t *datalen);
KS_DECLARE(ks_status_t) ks_socket_sendto(ks_socket_t sock, void *data, ks_size_t *datalen, ks_sockaddr_t *addr);
KS_DECLARE(ks_status_t) ks_socket_recvfrom(ks_socket_t sock, void *data, ks_size_t *datalen, ks_sockaddr_t *addr);
typedef struct pollfd *ks_ppollfd_t;
KS_DECLARE(int) ks_poll(ks_ppollfd_t fds, uint32_t nfds, int timeout);
KS_DECLARE(ks_status_t) ks_socket_option(ks_socket_t socket, int option_name, ks_bool_t enabled);
KS_DECLARE(ks_status_t) ks_socket_sndbuf(ks_socket_t socket, int bufsize);
KS_DECLARE(ks_status_t) ks_socket_rcvbuf(ks_socket_t socket, int bufsize);
KS_DECLARE(int) ks_wait_sock(ks_socket_t sock, uint32_t ms, ks_poll_t flags);
KS_DECLARE(ks_socket_t) ks_socket_connect(int type, int protocol, ks_sockaddr_t *addr);
KS_DECLARE(ks_status_t) ks_addr_bind(ks_socket_t server_sock, ks_sockaddr_t *addr);
KS_DECLARE(const char *) ks_addr_get_host(ks_sockaddr_t *addr);
KS_DECLARE(ks_port_t) ks_addr_get_port(ks_sockaddr_t *addr);
KS_DECLARE(int) ks_addr_cmp(const ks_sockaddr_t *sa1, const ks_sockaddr_t *sa2);
KS_DECLARE(ks_status_t) ks_addr_copy(ks_sockaddr_t *addr, const ks_sockaddr_t *src_addr);
KS_DECLARE(ks_status_t) ks_addr_set(ks_sockaddr_t *addr, const char *host, ks_port_t port, int family);
KS_DECLARE(ks_status_t) ks_addr_set_raw(ks_sockaddr_t *addr, void *data, ks_port_t port, int family);
KS_DECLARE(ks_status_t) ks_addr_raw_data(const ks_sockaddr_t *addr, void **data, ks_size_t *datalen);
KS_DECLARE(ks_status_t) ks_listen(const char *host, ks_port_t port, int family, int backlog, ks_listen_callback_t callback, void *user_data);
KS_DECLARE(ks_status_t) ks_socket_shutdown(ks_socket_t sock, int how);
KS_DECLARE(ks_status_t) ks_socket_close(ks_socket_t *sock);
KS_DECLARE(ks_status_t) ks_ip_route(char *buf, int len, const char *route_ip);
KS_DECLARE(ks_status_t) ks_find_local_ip(char *buf, int len, int *mask, int family, const char *route_ip);
KS_DECLARE(ks_status_t) ks_listen_sock(ks_socket_t server_sock, ks_sockaddr_t *addr, int backlog, ks_listen_callback_t callback, void *user_data);
KS_END_EXTERN_C
#endif /* defined(_KS_SOCKET_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 noet:
*/
+28
View File
@@ -0,0 +1,28 @@
#ifndef _KS_SSL_H
#define _KS_SSL_H
#include "ks.h"
#include <openssl/ssl.h>
#include <openssl/engine.h>
KS_BEGIN_EXTERN_C
KS_DECLARE(void) ks_ssl_init_ssl_locks(void);
KS_DECLARE(void) ks_ssl_destroy_ssl_locks(void);
KS_DECLARE(int) ks_gen_cert(const char *dir, const char *file);
KS_END_EXTERN_C
#endif /* defined(_KS_SSL_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 noet:
*/
+106 -22
View File
@@ -1,6 +1,6 @@
/*
/*
* Cross Platform Thread/Mutex abstraction
* Copyright(C) 2007 Michael Jerris
* Copyright(C) 2015 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
@@ -13,38 +13,122 @@
* 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.
* except under this disclaimer.
*
*/
#ifndef _KS_THREADMUTEX_H
#define _KS_THREADMUTEX_H
#include "ks.h"
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
KS_BEGIN_EXTERN_C
typedef struct ks_mutex ks_mutex_t;
typedef struct ks_thread ks_thread_t;
typedef void *(*ks_thread_function_t) (ks_thread_t *, void *);
#ifdef WIN32
#include <process.h>
#define KS_THREAD_CALLING_CONVENTION __stdcall
#else
#include <pthread.h>
#define KS_THREAD_CALLING_CONVENTION
#endif
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);
#define KS_THREAD_DEFAULT_STACK 240 * 1024
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
typedef struct ks_thread ks_thread_t;
typedef void *(*ks_thread_function_t) (ks_thread_t *, void *);
#endif /* defined(_KS_THREADMUTEX_H) */
typedef
#ifdef WIN32
void *
#else
pthread_t
#endif
ks_thread_os_handle_t;
struct ks_thread {
ks_pool_t *pool;
#ifdef WIN32
void *handle;
#else
pthread_t handle;
pthread_attr_t attribute;
#endif
void *private_data;
ks_thread_function_t function;
size_t stack_size;
uint32_t flags;
uint8_t running;
uint8_t priority;
void *return_data;
};
typedef enum {
KS_PRI_LOW = 1,
KS_PRI_NORMAL = 10,
KS_PRI_IMPORTANT = 50,
KS_PRI_REALTIME = 99,
} ks_thread_priority_t;
typedef enum {
KS_THREAD_FLAG_DEFAULT = 0,
KS_THREAD_FLAG_DETATCHED = (1 << 0)
} ks_thread_flags_t;
KS_DECLARE(int) ks_thread_set_priority(int nice_val);
KS_DECLARE(ks_thread_os_handle_t) ks_thread_self(void);
KS_DECLARE(ks_thread_os_handle_t) ks_thread_os_handle(ks_thread_t *thread);
KS_DECLARE(ks_status_t) ks_thread_create_ex(ks_thread_t **thread, ks_thread_function_t func, void *data,
uint32_t flags, size_t stack_size, ks_thread_priority_t priority, ks_pool_t *pool);
KS_DECLARE(ks_status_t) ks_thread_join(ks_thread_t *thread);
KS_DECLARE(uint8_t) ks_thread_priority(ks_thread_t *thread);
#define ks_thread_create(thread, func, data, pool) \
ks_thread_create_ex(thread, func, data, KS_THREAD_FLAG_DEFAULT, KS_THREAD_DEFAULT_STACK, KS_PRI_NORMAL, pool)
typedef enum {
KS_MUTEX_FLAG_DEFAULT = 0,
KS_MUTEX_FLAG_NON_RECURSIVE = (1 << 0)
} ks_mutex_flags_t;
typedef struct ks_mutex ks_mutex_t;
KS_DECLARE(ks_status_t) ks_mutex_create(ks_mutex_t **mutex, unsigned int flags, ks_pool_t *pool);
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);
KS_DECLARE(ks_status_t) ks_mutex_destroy(ks_mutex_t **mutex);
typedef struct ks_cond ks_cond_t;
KS_DECLARE(ks_status_t) ks_cond_create(ks_cond_t **cond, ks_pool_t *pool);
KS_DECLARE(ks_status_t) ks_cond_create_ex(ks_cond_t **cond, ks_pool_t *pool, ks_mutex_t *mutex);
KS_DECLARE(ks_status_t) ks_cond_lock(ks_cond_t *cond);
KS_DECLARE(ks_status_t) ks_cond_trylock(ks_cond_t *cond);
KS_DECLARE(ks_status_t) ks_cond_unlock(ks_cond_t *cond);
KS_DECLARE(ks_status_t) ks_cond_signal(ks_cond_t *cond);
KS_DECLARE(ks_status_t) ks_cond_broadcast(ks_cond_t *cond);
KS_DECLARE(ks_status_t) ks_cond_try_signal(ks_cond_t *cond);
KS_DECLARE(ks_status_t) ks_cond_try_broadcast(ks_cond_t *cond);
KS_DECLARE(ks_status_t) ks_cond_wait(ks_cond_t *cond);
KS_DECLARE(ks_status_t) ks_cond_timedwait(ks_cond_t *cond, ks_time_t ms);
KS_DECLARE(ks_status_t) ks_cond_destroy(ks_cond_t **cond);
KS_DECLARE(ks_mutex_t *) ks_cond_get_mutex(ks_cond_t *cond);
typedef struct ks_rwl ks_rwl_t;
KS_DECLARE(ks_status_t) ks_rwl_create(ks_rwl_t **rwlock, ks_pool_t *pool);
KS_DECLARE(ks_status_t) ks_rwl_read_lock(ks_rwl_t *rwlock);
KS_DECLARE(ks_status_t) ks_rwl_write_lock(ks_rwl_t *rwlock);
KS_DECLARE(ks_status_t) ks_rwl_try_read_lock(ks_rwl_t *rwlock);
KS_DECLARE(ks_status_t) ks_rwl_try_write_lock(ks_rwl_t *rwlock);
KS_DECLARE(ks_status_t) ks_rwl_read_unlock(ks_rwl_t *rwlock);
KS_DECLARE(ks_status_t) ks_rwl_write_unlock(ks_rwl_t *rwlock);
KS_DECLARE(ks_status_t) ks_rwl_destroy(ks_rwl_t **rwlock);
KS_END_EXTERN_C
#endif /* defined(_KS_THREADMUTEX_H) */
/* For Emacs:
* Local Variables:
+64
View File
@@ -0,0 +1,64 @@
/*
* Copyright (c) 2007-2015, 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_TIME_H_
#define _KS_TIME_H_
#include "ks.h"
KS_BEGIN_EXTERN_C
#define KS_USEC_PER_SEC 1000000
#define ks_time_sec(time) ((time) / KS_USEC_PER_SEC)
#define ks_time_usec(time) ((time) % KS_USEC_PER_SEC)
#define ks_time_nsec(time) (((time) % KS_USEC_PER_SEC) * 1000)
#define ks_sleep_ms(_t) ks_sleep(_t * 1000)
KS_DECLARE(ks_time_t) ks_time_now(void);
KS_DECLARE(ks_time_t) ks_time_now_sec(void);
KS_DECLARE(void) ks_sleep(ks_time_t microsec);
KS_END_EXTERN_C
#endif /* defined(_KS_TIME_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 noet:
*/
+142 -104
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2007-2014, Anthony Minessale II
* Copyright (c) 2007-2015, Anthony Minessale II
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -34,113 +34,119 @@
#ifndef _KS_TYPES_H_
#define _KS_TYPES_H_
#include <stdarg.h>
#include "ks.h"
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
KS_BEGIN_EXTERN_C
#include <ks_platform.h>
#define KS_STR2ENUM_P(_FUNC1, _FUNC2, _TYPE) KS_DECLARE(_TYPE) _FUNC1 (const char *name); KS_DECLARE(const char *) _FUNC2 (_TYPE type);
#define KS_STR2ENUM(_FUNC1, _FUNC2, _TYPE, _STRINGS, _MAX) \
KS_DECLARE(_TYPE) _FUNC1 (const char *name) \
{ \
int i; \
_TYPE t = _MAX ; \
\
for (i = 0; i < _MAX ; i++) { \
if (!strcasecmp(name, _STRINGS[i])) { \
t = (_TYPE) i; \
break; \
} \
} \
\
return t; \
} \
KS_DECLARE(const char *) _FUNC2 (_TYPE type) \
{ \
if (type > _MAX) { \
type = _MAX; \
} \
return _STRINGS[(int)type]; \
} \
#define KS_ENUM_NAMES(_NAME, _STRINGS) static const char * _NAME [] = { _STRINGS , NULL };
#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;
typedef enum {
KS_POLL_READ = (1 << 0),
KS_POLL_WRITE = (1 << 1),
KS_POLL_ERROR = (1 << 2)
} ks_poll_t;
typedef uint16_t ks_port_t;
typedef size_t ks_size_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
typedef enum {
KS_STATUS_SUCCESS,
KS_STATUS_FAIL,
KS_STATUS_BREAK,
KS_STATUS_DISCONNECTED,
KS_STATUS_GENERR,
KS_STATUS_INACTIVE,
KS_STATUS_TIMEOUT,
/* Memory pool errors */
KS_STATUS_ARG_NULL, /* function argument is null */
KS_STATUS_ARG_INVALID, /* function argument is invalid */
KS_STATUS_PNT, /* invalid ks_pool pointer */
KS_STATUS_POOL_OVER, /* ks_pool structure was overwritten */
KS_STATUS_PAGE_SIZE, /* could not get system page-size */
KS_STATUS_OPEN_ZERO, /* could not open /dev/zero */
KS_STATUS_NO_MEM, /* no memory available */
KS_STATUS_MMAP, /* problems with mmap */
KS_STATUS_SIZE, /* error processing requested size */
KS_STATUS_TOO_BIG, /* allocation exceeded max size */
KS_STATUS_MEM, /* invalid memory address */
KS_STATUS_MEM_OVER, /* memory lower bounds overwritten */
KS_STATUS_NOT_FOUND, /* memory block not found in pool */
KS_STATUS_IS_FREE, /* memory block already free */
KS_STATUS_BLOCK_STAT, /* invalid internal block status */
KS_STATUS_FREE_ADDR, /* invalid internal free address */
KS_STATUS_NO_PAGES, /* ran out of pages in pool */
KS_STATUS_ALLOC, /* calloc,malloc,free,realloc failed */
KS_STATUS_PNT_OVER, /* pointer structure was overwritten */
KS_STATUS_INVALID_POINTER, /* address is not valid */
/* Always insert new entries above this line*/
KS_STATUS_COUNT
} ks_status_t;
typedef int16_t ks_port_t;
typedef size_t ks_size_t;
#define STATUS_STRINGS\
"SUCCESS",\
"FAIL",\
"BREAK",\
"DISCONNECTED",\
"GENERR",\
"INACTIVE",\
"TIMEOUT",\
"ARG_NULL",\
"ARG_INVALID",\
"PNT",\
"POOL_OVER",\
"PAGE_SIZE",\
"OPEN_ZERO",\
"NO_MEM",\
"MMAP",\
"SIZE",\
"TOO_BIG",\
"MEM",\
"MEM_OVER",\
"NOT_FOUN",\
"IS_FREE",\
"BLOCK_STAT",\
"FREE_ADDR",\
"NO_PAGES",\
"ALLOC",\
"PNT_OVER",\
"INVALID_POINTER",\
/* insert new entries before this */\
"COUNT"
typedef enum {
KS_SUCCESS,
KS_FAIL,
KS_BREAK,
KS_DISCONNECTED,
KS_GENERR
} ks_status_t;
KS_STR2ENUM_P(ks_str2ks_status, ks_status2str, ks_status_t)
/*! \brief Used internally for truth test */
typedef enum {
KS_TRUE = 1,
KS_FALSE = 0
} ks_bool_t;
typedef enum {
KS_TRUE = 1,
KS_FALSE = 0
} ks_bool_t;
#ifndef __FUNCTION__
#define __FUNCTION__ (const char *)__func__
@@ -164,16 +170,49 @@ typedef enum {
#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);
struct ks_pool_s;
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
typedef struct ks_pool_s ks_pool_t;
typedef void (*ks_hash_destructor_t)(void *ptr);
typedef enum {
KS_MPCL_ANNOUNCE,
KS_MPCL_TEARDOWN,
KS_MPCL_DESTROY
} ks_pool_cleanup_action_t;
#endif /* defined(_KS_TYPES_H_) */
typedef enum {
KS_MPCL_FREE,
KS_MPCL_GLOBAL_FREE,
} ks_pool_cleanup_type_t;
typedef union {
struct sockaddr_in v4;
struct sockaddr_in6 v6;
} ks_sockaddr_in_t;
typedef struct {
int family;
ks_sockaddr_in_t v;
ks_port_t port;
char host[48];
} ks_sockaddr_t;
typedef void (*ks_pool_cleanup_fn_t) (ks_pool_t *mpool, void *ptr, void *arg, int type, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t ctype);
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, ks_sockaddr_t *addr, void *user_data);
typedef int64_t ks_time_t;
struct ks_q_s;
typedef struct ks_q_s ks_q_t;
typedef void (*ks_flush_fn_t)(ks_q_t *q, void *ptr, void *flush_data);
KS_END_EXTERN_C
#endif /* defined(_KS_TYPES_H_) */
/* For Emacs:
* Local Variables:
@@ -185,4 +224,3 @@ typedef void (*ks_listen_callback_t)(ks_socket_t server_sock, ks_socket_t client
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
*/
+192
View File
@@ -0,0 +1,192 @@
/*
* Copyright (c) 2007-2015, 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_UTP_H_
#define _KS_UTP_H_
#include "ks.h"
KS_BEGIN_EXTERN_C
typedef struct utp_socket utp_socket_t;
typedef struct utp_context utp_context_t;
enum {
UTP_UDP_DONTFRAG = 2, // Used to be a #define as UDP_IP_DONTFRAG
};
enum {
/* socket has reveived syn-ack (notification only for outgoing connection completion) this implies writability */
UTP_STATE_CONNECT = 1,
/* socket is able to send more data */
UTP_STATE_WRITABLE = 2,
/* connection closed */
UTP_STATE_EOF = 3,
/* socket is being destroyed, meaning all data has been sent if possible. it is not valid to refer to the socket after this state change occurs */
UTP_STATE_DESTROYING = 4,
};
/* Errors codes that can be passed to UTP_ON_ERROR callback */
enum {
UTP_ECONNREFUSED = 0,
UTP_ECONNRESET,
UTP_ETIMEDOUT,
};
enum {
/* callback names */
UTP_ON_FIREWALL = 0,
UTP_ON_ACCEPT,
UTP_ON_CONNECT,
UTP_ON_ERROR,
UTP_ON_READ,
UTP_ON_OVERHEAD_STATISTICS,
UTP_ON_STATE_CHANGE,
UTP_GET_READ_BUFFER_SIZE,
UTP_ON_DELAY_SAMPLE,
UTP_GET_UDP_MTU,
UTP_GET_UDP_OVERHEAD,
UTP_GET_MILLISECONDS,
UTP_GET_MICROSECONDS,
UTP_GET_RANDOM,
UTP_LOG,
UTP_SENDTO,
/* context and socket options that may be set/queried */
UTP_LOG_NORMAL,
UTP_LOG_MTU,
UTP_LOG_DEBUG,
UTP_SNDBUF,
UTP_RCVBUF,
UTP_TARGET_DELAY,
/* must be last */
UTP_ARRAY_SIZE,
};
typedef struct {
utp_context_t *context;
utp_socket_t *socket;
size_t len;
uint32_t flags;
int callback_type;
const uint8_t *buf;
union {
const struct sockaddr *address;
int send;
int sample_ms;
int error_code;
int state;
} d1;
union {
socklen_t address_len;
int type;
} d2;
} utp_callback_arguments;
typedef uint64_t utp_callback_t (utp_callback_arguments *);
/* Returned by utp_get_context_stats() */
typedef struct {
uint32_t _nraw_recv[5]; // total packets recieved less than 300/600/1200/MTU bytes fpr all connections (context-wide)
uint32_t _nraw_send[5]; // total packets sent less than 300/600/1200/MTU bytes for all connections (context-wide)
} utp_context_stats;
// Returned by utp_get_stats()
typedef struct {
uint64_t nbytes_recv; // total bytes received
uint64_t nbytes_xmit; // total bytes transmitted
uint32_t rexmit; // retransmit counter
uint32_t fastrexmit; // fast retransmit counter
uint32_t nxmit; // transmit counter
uint32_t nrecv; // receive counter (total)
uint32_t nduprecv; // duplicate receive counter
uint32_t mtu_guess; // Best guess at MTU
} utp_socket_stats;
#define UTP_IOV_MAX 1024
/* For utp_writev, to writes data from multiple buffers */
struct utp_iovec {
void *iov_base;
size_t iov_len;
};
// Public Functions
utp_context_t* utp_init (int version);
void utp_destroy (utp_context_t *ctx);
void utp_set_callback (utp_context_t *ctx, int callback_name, utp_callback_t *proc);
void* utp_context_set_userdata (utp_context_t *ctx, void *userdata);
void* utp_context_get_userdata (utp_context_t *ctx);
int utp_context_set_option (utp_context_t *ctx, int opt, int val);
int utp_context_get_option (utp_context_t *ctx, int opt);
int utp_process_udp (utp_context_t *ctx, const uint8_t *buf, size_t len, const struct sockaddr *to, socklen_t tolen);
int utp_process_icmp_error (utp_context_t *ctx, const uint8_t *buffer, size_t len, const struct sockaddr *to, socklen_t tolen);
int utp_process_icmp_fragmentation (utp_context_t *ctx, const uint8_t *buffer, size_t len, const struct sockaddr *to, socklen_t tolen, uint16_t next_hop_mtu);
void utp_check_timeouts (utp_context_t *ctx);
void utp_issue_deferred_acks (utp_context_t *ctx);
utp_context_stats* utp_get_context_stats (utp_context_t *ctx);
utp_socket_t* utp_create_socket (utp_context_t *ctx);
void* utp_set_userdata (utp_socket_t *s, void *userdata);
void* utp_get_userdata (utp_socket_t *s);
int utp_setsockopt (utp_socket_t *s, int opt, int val);
int utp_getsockopt (utp_socket_t *s, int opt);
int utp_connect (utp_socket_t *s, const struct sockaddr *to, socklen_t tolen);
ssize_t utp_write (utp_socket_t *s, void *buf, size_t count);
ssize_t utp_writev (utp_socket_t *s, struct utp_iovec *iovec, size_t num_iovecs);
int utp_getpeername (utp_socket_t *s, struct sockaddr *addr, socklen_t *addrlen);
void utp_read_drained (utp_socket_t *s);
int utp_get_delays (utp_socket_t *s, uint32_t *ours, uint32_t *theirs, uint32_t *age);
utp_socket_stats* utp_get_stats (utp_socket_t *s);
utp_context_t* utp_get_context (utp_socket_t *s);
void utp_close (utp_socket_t *s);
KS_END_EXTERN_C
#endif /* defined(_KS_UTP_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 noet:
*/
+106
View File
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2007-2014, 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 _KWS_H
#define _KWS_H
#define WEBSOCKET_GUID "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
#define B64BUFFLEN 1024
#include "ks.h"
KS_BEGIN_EXTERN_C
typedef enum {
WS_NONE = 0,
WS_NORMAL = 1000,
WS_PROTO_ERR = 1002,
WS_DATA_TOO_BIG = 1009
} kws_cause_t;
typedef enum {
WSOC_CONTINUATION = 0x0,
WSOC_TEXT = 0x1,
WSOC_BINARY = 0x2,
WSOC_CLOSE = 0x8,
WSOC_PING = 0x9,
WSOC_PONG = 0xA
} kws_opcode_t;
typedef enum {
KWS_CLIENT,
KWS_SERVER
} kws_type_t;
typedef enum {
KWS_CLOSE_SOCK,
KWS_BLOCK,
KWS_STAY_OPEN
} kws_flag_t;
struct kws_s;
typedef struct kws_s kws_t;
KS_DECLARE(ks_ssize_t) kws_read_frame(kws_t *kws, kws_opcode_t *oc, uint8_t **data);
KS_DECLARE(ks_ssize_t) kws_write_frame(kws_t *kws, kws_opcode_t oc, void *data, ks_size_t bytes);
KS_DECLARE(ks_ssize_t) kws_raw_read(kws_t *kws, void *data, ks_size_t bytes, int block);
KS_DECLARE(ks_ssize_t) kws_raw_write(kws_t *kws, void *data, ks_size_t bytes);
KS_DECLARE(ks_status_t) kws_init(kws_t **kwsP, ks_socket_t sock, SSL_CTX *ssl_ctx, const char *client_data, kws_flag_t flags, ks_pool_t *pool);
KS_DECLARE(ks_ssize_t) kws_close(kws_t *kws, int16_t reason);
KS_DECLARE(void) kws_destroy(kws_t **kwsP);
KS_DECLARE(ks_status_t) kws_get_buffer(kws_t *kws, char **bufP, ks_size_t *buflen);
#if 0
static inline uint64_t get_unaligned_uint64(const void *p)
{
const struct { uint64_t d; } __attribute__((packed)) *pp = p;
return pp->d;
}
#endif
KS_END_EXTERN_C
#endif /* defined(_KWS_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 noet:
*/
+34 -36
View File
@@ -32,20 +32,20 @@ extern "C" {
#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
#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 */
/* "inline" and "restrict" are keywords */
#else
# define inline /* inline */
# define restrict /* restrict */
#define inline /* inline */
#define restrict /* restrict */
#endif
@@ -58,13 +58,13 @@ extern "C" {
#ifndef SIMCLIST_NO_DUMPRESTORE
typedef struct {
uint16_t version; /* dump version */
struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */
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 */
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 */
int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */
} list_dump_info_t;
#endif
@@ -77,7 +77,7 @@ extern "C" {
*
* It is responsability of the function to handle possible NULL values.
*/
typedef int (*element_comparator)(const void *a, const void *b);
typedef int (*element_comparator) (const void *a, const void *b);
/**
* a seeker of elements.
@@ -90,7 +90,7 @@ extern "C" {
* It is responsability of the function to handle possible NULL values in any
* argument.
*/
typedef int (*element_seeker)(const void *el, const void *indicator);
typedef int (*element_seeker) (const void *el, const void *indicator);
/**
* an element lenght meter.
@@ -101,7 +101,7 @@ extern "C" {
*
* It is responsability of the function to handle possible NULL values.
*/
typedef size_t (*element_meter)(const void *el);
typedef size_t (*element_meter) (const void *el);
/**
* a function computing the hash of elements.
@@ -112,7 +112,7 @@ extern "C" {
*
* It is responsability of the function to handle possible NULL values.
*/
typedef list_hash_t (*element_hash_computer)(const void *el);
typedef list_hash_t (*element_hash_computer) (const void *el);
/**
* a function for serializing an element.
@@ -132,7 +132,7 @@ extern "C" {
* @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);
typedef void *(*element_serializer) (const void *restrict el, uint32_t *restrict serializ_len);
/**
* a function for un-serializing an element.
@@ -149,7 +149,7 @@ extern "C" {
* @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);
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 {
@@ -776,49 +776,49 @@ extern "C" {
* ready-made comparator for int8_t elements.
* @see list_attributes_comparator()
*/
int list_comparator_int8_t(const void *a, const void *b);
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);
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);
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);
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);
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);
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);
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);
int list_comparator_uint64_t (const void *a, const void *b);
/**
* ready-made comparator for float elements.
@@ -843,49 +843,49 @@ extern "C" {
* ready-made metric function for int8_t elements.
* @see list_attributes_copy()
*/
size_t list_meter_int8_t(const void *el);
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);
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);
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);
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);
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);
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);
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);
size_t list_meter_uint64_t (const void *el);
/**
* ready-made metric function for float elements.
@@ -975,9 +975,7 @@ extern "C" {
#ifdef __cplusplus
}
#endif
#endif
/* For Emacs:
* Local Variables:
* mode:c