text: /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
  /* If you are missing that file, acquire a complete release at teeworlds.com.                */
  
  /*
  	Title: OS Abstraction
  */
  
  #ifndef BASE_SYSTEM_H
  #define BASE_SYSTEM_H
  
  #include "detect.h"
  
  #include <time.h>
  
  #ifdef __cplusplus
  extern "C" {
  #endif
  
  /* Group: Debug */
  /*
  	Function: dbg_assert
  		Breaks into the debugger based on a test.
  
  	Parameters:
  		test - Result of the test.
  		msg - Message that should be printed if the test fails.
  
  	Remarks:
  		Does nothing in release version of the library.
  
  	See Also:
  		<dbg_break>
  */
  void dbg_assert(int test, const char *msg);
  #define dbg_assert(test,msg) dbg_assert_imp(__FILE__, __LINE__, test, msg)
  void dbg_assert_imp(const char *filename, int line, int test, const char *msg);
  
  
  #ifdef __clang_analyzer__
  #include <assert.h>
  #undef dbg_assert
  #define dbg_assert(test,msg) assert(test)
  #endif
  
  /*
  	Function: dbg_break
  		Breaks into the debugger.
  
  	Remarks:
  		Does nothing in release version of the library.
  
  	See Also:
  		<dbg_assert>
  */
  void dbg_break();
  
  /*
  	Function: dbg_msg
  
  	Prints a debug message.
  
  	Parameters:
  		sys - A string that describes what system the message belongs to
  		fmt - A printf styled format string.
  
  	Remarks:
  		Does nothing in release version of the library.
  
  	See Also:
  		<dbg_assert>
  */
  void dbg_msg(const char *sys, const char *fmt, ...);
  
  /* Group: Memory */
  
  /*
  	Function: mem_alloc
  		Allocates memory.
  
  	Parameters:
  		size - Size of the needed block.
  		alignment - Alignment for the block.
  
  	Returns:
  		Returns a pointer to the newly allocated block. Returns a
  		null pointer if the memory couldn't be allocated.
  
  	Remarks:
  		- Passing 0 to size will allocated the smallest amount possible
  		and return a unique pointer.
  
  	See Also:
  		<mem_free>
  */
  void *mem_alloc_debug(const char *filename, int line, unsigned size, unsigned alignment);
  #define mem_alloc(s,a) mem_alloc_debug(__FILE__, __LINE__, (s), (a))
  
  /*
  	Function: mem_free
  		Frees a block allocated through <mem_alloc>.
  
  	Remarks:
  		- In the debug version of the library the function will assert if
  		a non-valid block is passed, like a null pointer or a block that
  		isn't allocated.
  
  	See Also:
  		<mem_alloc>
  */
  void mem_free(void *block);
  
  /*
  	Function: mem_copy
  		Copies a a memory block.
  
  	Parameters:
  		dest - Destination.
  		source - Source to copy.
  		size - Size of the block to copy.
  
  	Remarks:
  		- This functions DOES NOT handles cases where source and
  		destination is overlapping.
  
  	See Also:
  		<mem_move>
  */
  void mem_copy(void *dest, const void *source, unsigned size);
  
  /*
  	Function: mem_move
  		Copies a a memory block
  
  	Parameters:
  		dest - Destination
  		source - Source to copy
  		size - Size of the block to copy
  
  	Remarks:
  		- This functions handles cases where source and destination
  		is overlapping
  
  	See Also:
  		<mem_copy>
  */
  void mem_move(void *dest, const void *source, unsigned size);
  
  /*
  	Function: mem_zero
  		Sets a complete memory block to 0
  
  	Parameters:
  		block - Pointer to the block to zero out
  		size - Size of the block
  */
  void mem_zero(void *block, unsigned size);
  
  /*
  	Function: mem_comp
  		Compares two blocks of memory
  
  	Parameters:
  		a - First block of data
  		b - Second block of data
  		size - Size of the data to compare
  
  	Returns:
  		<0 - Block a is lesser then block b
  		0 - Block a is equal to block b
  		>0 - Block a is greater then block b
  */
  int mem_comp(const void *a, const void *b, int size);
  
  /*
  	Function: mem_check
  		Validates the heap
  		Will trigger a assert if memory has failed.
  */
  int mem_check_imp();
  #define mem_check() dbg_assert_imp(__FILE__, __LINE__, mem_check_imp(), "Memory check failed")
  
  /* Group: File IO */
  enum {
  	IOFLAG_READ = 1,
  	IOFLAG_WRITE = 2,
  	IOFLAG_RANDOM = 4,
  
  	IOSEEK_START = 0,
  	IOSEEK_CUR = 1,
  	IOSEEK_END = 2
  };
  
  typedef struct IOINTERNAL *IOHANDLE;
  
  /*
  	Function: io_open
  		Opens a file.
  
  	Parameters:
  		filename - File to open.
  		flags - A set of flags. IOFLAG_READ, IOFLAG_WRITE, IOFLAG_RANDOM.
  
  	Returns:
  		Returns a handle to the file on success and 0 on failure.
  
  */
  IOHANDLE io_open(const char *filename, int flags);
  
  /*
  	Function: io_read
  		Reads data into a buffer from a file.
  
  	Parameters:
  		io - Handle to the file to read data from.
  		buffer - Pointer to the buffer that will recive the data.
  		size - Number of bytes to read from the file.
  
  	Returns:
  		Number of bytes read.
  
  */
  unsigned io_read(IOHANDLE io, void *buffer, unsigned size);
  
  /*
  	Function: io_skip
  		Skips data in a file.
  
  	Parameters:
  		io - Handle to the file.
  		size - Number of bytes to skip.
  
  	Returns:
  		Number of bytes skipped.
  */
  unsigned io_skip(IOHANDLE io, int size);
  
  /*
  	Function: io_write
  		Writes data from a buffer to file.
  
  	Parameters:
  		io - Handle to the file.
  		buffer - Pointer to the data that should be written.
  		size - Number of bytes to write.
  
  	Returns:
  		Number of bytes written.
  */
  unsigned io_write(IOHANDLE io, const void *buffer, unsigned size);
  
  /*
  	Function: io_write_newline
  		Writes newline to file.
  
  	Parameters:
  		io - Handle to the file.
  
  	Returns:
  		Number of bytes written.
  */
  unsigned io_write_newline(IOHANDLE io);
  
  /*
  	Function: io_seek
  		Seeks to a specified offset in the file.
  
  	Parameters:
  		io - Handle to the file.
  		offset - Offset from pos to stop.
  		origin - Position to start searching from.
  
  	Returns:
  		Returns 0 on success.
  */
  int io_seek(IOHANDLE io, int offset, int origin);
  
  /*
  	Function: io_tell
  		Gets the current position in the file.
  
  	Parameters:
  		io - Handle to the file.
  
  	Returns:
  		Returns the current position. -1L if an error occured.
  */
  long int io_tell(IOHANDLE io);
  
  /*
  	Function: io_length
  		Gets the total length of the file. Resetting cursor to the beginning
  
  	Parameters:
  		io - Handle to the file.
  
  	Returns:
  		Returns the total size. -1L if an error occured.
  */
  long int io_length(IOHANDLE io);
  
  /*
  	Function: io_close
  		Closes a file.
  
  	Parameters:
  		io - Handle to the file.
  
  	Returns:
  		Returns 0 on success.
  */
  int io_close(IOHANDLE io);
  
  /*
  	Function: io_flush
  		Empties all buffers and writes all pending data.
  
  	Parameters:
  		io - Handle to the file.
  
  	Returns:
  		Returns 0 on success.
  */
  int io_flush(IOHANDLE io);
  
  
  /*
  	Function: io_stdin
  		Returns an <IOHANDLE> to the standard input.
  */
  IOHANDLE io_stdin();
  
  /*
  	Function: io_stdout
  		Returns an <IOHANDLE> to the standard output.
  */
  IOHANDLE io_stdout();
  
  /*
  	Function: io_stderr
  		Returns an <IOHANDLE> to the standard error.
  */
  IOHANDLE io_stderr();
  
  
  /* Group: Threads */
  
  /*
  	Function: thread_sleep
  		Suspends the current thread for a given period.
  
  	Parameters:
  		milliseconds - Number of milliseconds to sleep.
  */
  void thread_sleep(int milliseconds);
  
  /*
  	Function: thread_create
  		Creates a new thread.
  
  	Parameters:
  		threadfunc - Entry point for the new thread.
  		user - Pointer to pass to the thread.
  
  */
  void *thread_create(void (*threadfunc)(void *), void *user);
  
  /*
  	Function: thread_wait
  		Waits for a thread to be done or destroyed.
  
  	Parameters:
  		thread - Thread to wait for.
  */
  void thread_wait(void *thread);
  
  /*
  	Function: thread_init
  		Creates a new thread.
  
  	Parameters:
  		threadfunc - Entry point for the new thread.
  		user - Pointer to pass to the thread.
  
  */
  void *thread_init(void (*threadfunc)(void *), void *user);
  
  /*
  	Function: thread_destroy
  		Destroys a thread.
  
  	Parameters:
  		thread - Thread to destroy.
  */
  void thread_destroy(void *thread);
  
  /*
  	Function: thread_yeild
  		Yeild the current threads execution slice.
  */
  void thread_yield();
  
  /*
  	Function: thread_detach
  		Puts the thread in the detached thread, guaranteeing that
  		resources of the thread will be freed immediately when the
  		thread terminates.
  
  	Parameters:
  		thread - Thread to detach
  */
  void thread_detach(void *thread);
  
  /* Group: Locks */
  typedef void* LOCK;
  
  LOCK lock_create();
  void lock_destroy(LOCK lock);
  
  int lock_try(LOCK lock);
  void lock_wait(LOCK lock);
  void lock_release(LOCK lock);
  void lock_unlock(LOCK lock);
  
  
  /* Group: Semaphores */
  
  #if !defined(CONF_PLATFORM_MACOSX)
  	#if defined(CONF_FAMILY_UNIX)
  		#include <semaphore.h>
  		typedef sem_t SEMAPHORE;
  	#elif defined(CONF_FAMILY_WINDOWS)
  		typedef void* SEMAPHORE;
  	#else
  		#error missing sempahore implementation
  	#endif
  
  	void semaphore_init(SEMAPHORE *sem);
  	void semaphore_wait(SEMAPHORE *sem);
  	void semaphore_signal(SEMAPHORE *sem);
  	void semaphore_destroy(SEMAPHORE *sem);
  #endif
  
  /* Group: Timer */
  #ifdef __GNUC__
  /* if compiled with -pedantic-errors it will complain about long
  	not being a C90 thing.
  */
  __extension__ typedef long long int64;
  #else
  typedef long long int64;
  #endif
  /*
  	Function: time_get
  		Fetches a sample from a high resolution timer.
  
  	Returns:
  		Current value of the timer.
  
  	Remarks:
  		To know how fast the timer is ticking, see <time_freq>.
  */
  int64 time_get();
  
  /*
  	Function: time_freq
  		Returns the frequency of the high resolution timer.
  
  	Returns:
  		Returns the frequency of the high resolution timer.
  */
  int64 time_freq();
  
  /*
  	Function: time_timestamp
  		Retrives the current time as a UNIX timestamp
  
  	Returns:
  		The time as a UNIX timestamp
  */
  int time_timestamp();
  
  /* Group: Network General */
  typedef struct
  {
  	int type;
  	int ipv4sock;
  	int ipv6sock;
  } NETSOCKET;
  
  enum
  {
  	NETADDR_MAXSTRSIZE = 1+(8*4+7)+1+1+5+1, // [XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX]:XXXXX
  
  	NETTYPE_INVALID = 0,
  	NETTYPE_IPV4 = 1,
  	NETTYPE_IPV6 = 2,
  	NETTYPE_LINK_BROADCAST = 4,
  	NETTYPE_ALL = NETTYPE_IPV4|NETTYPE_IPV6
  };
  
  typedef struct
  {
  	unsigned int type;
  	unsigned char ip[16];
  	unsigned short port;
  } NETADDR;
  
  /*
  	Function: net_init
  		Initiates network functionallity.
  
  	Returns:
  		Returns 0 on success,
  
  	Remarks:
  		You must call this function before using any other network
  		functions.
  */
  int net_init();
  
  /*
  	Function: net_host_lookup
  		Does a hostname lookup by name and fills out the passed
  		NETADDR struct with the recieved details.
  
  	Returns:
  		0 on success.
  */
  int net_host_lookup(const char *hostname, NETADDR *addr, int types);
  
  /*
  	Function: net_addr_comp
  		Compares two network addresses.
  
  	Parameters:
  		a - Address to compare
  		b - Address to compare to.
  
  	Returns:
  		<0 - Address a is lesser then address b
  		0 - Address a is equal to address b
  		>0 - Address a is greater then address b
  */
  int net_addr_comp(const NETADDR *a, const NETADDR *b);
  
  /*
  	Function: net_addr_str
  		Turns a network address into a representive string.
  
  	Parameters:
  		addr - Address to turn into a string.
  		string - Buffer to fill with the string.
  		max_length - Maximum size of the string.
  		add_port - add port to string or not
  
  	Remarks:
  		- The string will always be zero terminated
  
  */
  void net_addr_str(const NETADDR *addr, char *string, int max_length, int add_port);
  
  /*
  	Function: net_addr_from_str
  		Turns string into a network address.
  
  	Returns:
  		0 on success
  
  	Parameters:
  		addr - Address to fill in.
  		string - String to parse.
  */
  int net_addr_from_str(NETADDR *addr, const char *string);
  
  /* Group: Network UDP */
  
  /*
  	Function: net_udp_create
  		Creates a UDP socket and binds it to a port.
  
  	Parameters:
  		bindaddr - Address to bind the socket to.
  
  	Returns:
  		On success it returns an handle to the socket. On failure it
  		returns NETSOCKET_INVALID.
  */
  NETSOCKET net_udp_create(NETADDR bindaddr);
  
  /*
  	Function: net_udp_send
  		Sends a packet over an UDP socket.
  
  	Parameters:
  		sock - Socket to use.
  		addr - Where to send the packet.
  		data - Pointer to the packet data to send.
  		size - Size of the packet.
  
  	Returns:
  		On success it returns the number of bytes sent. Returns -1
  		on error.
  */
  int net_udp_send(NETSOCKET sock, const NETADDR *addr, const void *data, int size);
  
  /*
  	Function: net_udp_recv
  		Recives a packet over an UDP socket.
  
  	Parameters:
  		sock - Socket to use.
  		addr - Pointer to an NETADDR that will recive the address.
  		data - Pointer to a buffer that will recive the data.
  		maxsize - Maximum size to recive.
  
  	Returns:
  		On success it returns the number of bytes recived. Returns -1
  		on error.
  */
  int net_udp_recv(NETSOCKET sock, NETADDR *addr, void *data, int maxsize);
  
  /*
  	Function: net_udp_close
  		Closes an UDP socket.
  
  	Parameters:
  		sock - Socket to close.
  
  	Returns:
  		Returns 0 on success. -1 on error.
  */
  int net_udp_close(NETSOCKET sock);
  
  
  /* Group: Network TCP */
  
  /*
  	Function: net_tcp_create
  		Creates a TCP socket.
  
  	Parameters:
  		bindaddr - Address to bind the socket to.
  
  	Returns:
  		On success it returns an handle to the socket. On failure it returns NETSOCKET_INVALID.
  */
  NETSOCKET net_tcp_create(NETADDR bindaddr);
  
  /*
  	Function: net_tcp_listen
  		Makes the socket start listening for new connections.
  
  	Parameters:
  		sock - Socket to start listen to.
  		backlog - Size of the queue of incomming connections to keep.
  
  	Returns:
  		Returns 0 on success.
  */
  int net_tcp_listen(NETSOCKET sock, int backlog);
  
  /*
  	Function: net_tcp_accept
  		Polls a listning socket for a new connection.
  
  	Parameters:
  		sock - Listning socket to poll.
  		new_sock - Pointer to a socket to fill in with the new socket.
  		addr - Pointer to an address that will be filled in the remote address (optional, can be NULL).
  
  	Returns:
  		Returns a non-negative integer on success. Negative integer on failure.
  */
  int net_tcp_accept(NETSOCKET sock, NETSOCKET *new_sock, NETADDR *addr);
  
  /*
  	Function: net_tcp_connect
  		Connects one socket to another.
  
  	Parameters:
  		sock - Socket to connect.
  		addr - Address to connect to.
  
  	Returns:
  		Returns 0 on success.
  
  */
  int net_tcp_connect(NETSOCKET sock, const NETADDR *addr);
  
  /*
  	Function: net_tcp_send
  		Sends data to a TCP stream.
  
  	Parameters:
  		sock - Socket to send data to.
  		data - Pointer to the data to send.
  		size - Size of the data to send.
  
  	Returns:
  		Number of bytes sent. Negative value on failure.
  */
  int net_tcp_send(NETSOCKET sock, const void *data, int size);
  
  /*
  	Function: net_tcp_recv
  		Recvives data from a TCP stream.
  
  	Parameters:
  		sock - Socket to recvive data from.
  		data - Pointer to a buffer to write the data to
  		max_size - Maximum of data to write to the buffer.
  
  	Returns:
  		Number of bytes recvived. Negative value on failure. When in
  		non-blocking mode, it returns 0 when there is no more data to
  		be fetched.
  */
  int net_tcp_recv(NETSOCKET sock, void *data, int maxsize);
  
  /*
  	Function: net_tcp_close
  		Closes a TCP socket.
  
  	Parameters:
  		sock - Socket to close.
  
  	Returns:
  		Returns 0 on success. Negative value on failure.
  */
  int net_tcp_close(NETSOCKET sock);
  
  /* Group: Strings */
  
  /*
  	Function: str_append
  		Appends a string to another.
  
  	Parameters:
  		dst - Pointer to a buffer that contains a string.
  		src - String to append.
  		dst_size - Size of the buffer of the dst string.
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  		- Garantees that dst string will contain zero-termination.
  */
  void str_append(char *dst, const char *src, int dst_size);
  
  /*
  	Function: str_next_token
  		Writes the next token after str into buf, returns the rest of the string.
  	Parameters:
  		str - Pointer to string.
  		delim - Delimiter for tokenization.
  		buffer - Buffer to store token in.
  		buffer_size - Size of the buffer.
  	Returns:
  		Pointer to rest of the string.
  	Remarks:
  		- The token is always null-terminated.
  */
  const char *str_next_token(const char *str, const char *delim, char *buffer, int buffer_size);
  
  /*
  	Function: str_in_list
  		Checks if needle is in list delimited by delim
  	Parameters:
  		list - List
  		delim - List delimiter.
  		needle - Item that is being looked for.
  	Returns:
  		1 - Item is in list.
  		0 - Item isn't in list.
  */
  int str_in_list(const char *list, const char *delim, const char *needle);
  
  //TeeUniverses
  void str_append_num(char *dst, const char *src, int dst_size, int num);
  
  /*
  	Function: str_copy
  		Copies a string to another.
  
  	Parameters:
  		dst - Pointer to a buffer that shall recive the string.
  		src - String to be copied.
  		dst_size - Size of the buffer dst.
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  		- Garantees that dst string will contain zero-termination.
  */
  void str_copy(char *dst, const char *src, int dst_size);
  
  /*
  	Function: str_length
  		Returns the length of a zero terminated string.
  
  	Parameters:
  		str - Pointer to the string.
  
  	Returns:
  		Length of string in bytes excluding the zero termination.
  */
  int str_length(const char *str);
  
  /*
  	Function: str_format
  		Performs printf formating into a buffer.
  
  	Parameters:
  		buffer - Pointer to the buffer to recive the formated string.
  		buffer_size - Size of the buffer.
  		format - printf formating string.
  		... - Parameters for the formating.
  
  	Remarks:
  		- See the C manual for syntax for the printf formating string.
  		- The strings are treated as zero-termineted strings.
  		- Garantees that dst string will contain zero-termination.
  */
  void str_format(char *buffer, int buffer_size, const char *format, ...);
  
  /*
  	Function: str_sanitize_strong
  		Replaces all characters below 32 and above 127 with whitespace.
  
  	Parameters:
  		str - String to sanitize.
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  */
  void str_sanitize_strong(char *str);
  
  /*
  	Function: str_sanitize_cc
  		Replaces all characters below 32 with whitespace.
  
  	Parameters:
  		str - String to sanitize.
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  */
  void str_sanitize_cc(char *str);
  
  /*
  	Function: str_sanitize
  		Replaces all characters below 32 with whitespace with
  		exception to \t, \n and \r.
  
  	Parameters:
  		str - String to sanitize.
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  */
  void str_sanitize(char *str);
  
  /*
  	Function: str_skip_to_whitespace
  		Skips leading non-whitespace characters(all but ' ', '\t', '\n', '\r').
  
  	Parameters:
  		str - Pointer to the string.
  
  	Returns:
  		Pointer to the first whitespace character found
  		within the string.
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  */
  char *str_skip_to_whitespace(char *str);
  
  /*
  	Function: str_skip_whitespaces
  		Skips leading whitespace characters(' ', '\t', '\n', '\r').
  
  	Parameters:
  		str - Pointer to the string.
  
  	Returns:
  		Pointer to the first non-whitespace character found
  		within the string.
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  */
  char *str_skip_whitespaces(char *str);
  
  /*
  	Function: str_comp_nocase
  		Compares to strings case insensitive.
  
  	Parameters:
  		a - String to compare.
  		b - String to compare.
  
  	Returns:
  		<0 - String a is lesser then string b
  		0 - String a is equal to string b
  		>0 - String a is greater then string b
  
  	Remarks:
  		- Only garanted to work with a-z/A-Z.
  		- The strings are treated as zero-termineted strings.
  */
  int str_comp_nocase(const char *a, const char *b);
  
  /*
  	Function: str_comp_nocase_num
  		Compares up to num characters of two strings case insensitive.
  
  	Parameters:
  		a - String to compare.
  		b - String to compare.
  		num - Maximum characters to compare
  
  	Returns:
  		<0 - String a is lesser than string b
  		0 - String a is equal to string b
  		>0 - String a is greater than string b
  
  	Remarks:
  		- Only garanted to work with a-z/A-Z.
  		- The strings are treated as zero-termineted strings.
  */
  int str_comp_nocase_num(const char *a, const char *b, const int num);
  
  /*
  	Function: str_comp
  		Compares to strings case sensitive.
  
  	Parameters:
  		a - String to compare.
  		b - String to compare.
  
  	Returns:
  		<0 - String a is lesser then string b
  		0 - String a is equal to string b
  		>0 - String a is greater then string b
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  */
  int str_comp(const char *a, const char *b);
  
  /*
  	Function: str_comp_num
  		Compares up to num characters of two strings case sensitive.
  
  	Parameters:
  		a - String to compare.
  		b - String to compare.
  		num - Maximum characters to compare
  
  	Returns:
  		<0 - String a is lesser then string b
  		0 - String a is equal to string b
  		>0 - String a is greater then string b
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  */
  int str_comp_num(const char *a, const char *b, const int num);
  
  /*
  	Function: str_comp_filenames
  		Compares two strings case sensitive, digit chars will be compared as numbers.
  
  	Parameters:
  		a - String to compare.
  		b - String to compare.
  
  	Returns:
  		<0 - String a is lesser then string b
  		0 - String a is equal to string b
  		>0 - String a is greater then string b
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  */
  int str_comp_filenames(const char *a, const char *b);
  
  /*
  	Function: str_find_nocase
  		Finds a string inside another string case insensitive.
  
  	Parameters:
  		haystack - String to search in
  		needle - String to search for
  
  	Returns:
  		A pointer into haystack where the needle was found.
  		Returns NULL of needle could not be found.
  
  	Remarks:
  		- Only garanted to work with a-z/A-Z.
  		- The strings are treated as zero-termineted strings.
  */
  const char *str_find_nocase(const char *haystack, const char *needle);
  
  /*
  	Function: str_find
  		Finds a string inside another string case sensitive.
  
  	Parameters:
  		haystack - String to search in
  		needle - String to search for
  
  	Returns:
  		A pointer into haystack where the needle was found.
  		Returns NULL of needle could not be found.
  
  	Remarks:
  		- The strings are treated as zero-termineted strings.
  */
  const char *str_find(const char *haystack, const char *needle);
  
  /*
  	Function: str_hex
  		Takes a datablock and generates a hexstring of it.
  
  	Parameters:
  		dst - Buffer to fill with hex data
  		dst_size - size of the buffer
  		data - Data to turn into hex
  		data - Size of the data
  
  	Remarks:
  		- The desination buffer will be zero-terminated
  */
  void str_hex(char *dst, int dst_size, const void *data, int data_size);
  
  /*
  	Function: str_timestamp
  		Copies a time stamp in the format year-month-day_hour-minute-second to the string.
  
  	Parameters:
  		buffer - Pointer to a buffer that shall receive the time stamp string.
  		buffer_size - Size of the buffer.
  
  	Remarks:
  		- Guarantees that buffer string will contain zero-termination.
  */
  void str_timestamp(char *buffer, int buffer_size);
  void str_timestamp_ex(time_t time, char *buffer, int buffer_size, const char *format);
  
  /* Group: Filesystem */
  
  /*
  	Function: fs_listdir
  		Lists the files in a directory
  
  	Parameters:
  		dir - Directory to list
  		cb - Callback function to call for each entry
  		type - Type of the directory
  		user - Pointer to give to the callback
  
  	Returns:
  		Always returns 0.
  */
  typedef int (*FS_LISTDIR_CALLBACK)(const char *name, int is_dir, int dir_type, void *user);
  int fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user);
  
  /*
  	Function: fs_makedir
  		Creates a directory
  
  	Parameters:
  		path - Directory to create
  
  	Returns:
  		Returns 0 on success. Negative value on failure.
  
  	Remarks:
  		Does not create several directories if needed. "a/b/c" will result
  		in a failure if b or a does not exist.
  */
  int fs_makedir(const char *path);
  
  /*
  	Function: fs_storage_path
  		Fetches per user configuration directory.
  
  	Returns:
  		Returns 0 on success. Negative value on failure.
  
  	Remarks:
  		- Returns ~/.appname on UNIX based systems
  		- Returns ~/Library/Applications Support/appname on Mac OS X
  		- Returns %APPDATA%/Appname on Windows based systems
  */
  int fs_storage_path(const char *appname, char *path, int max);
  
  /*
  	Function: fs_is_dir
  		Checks if directory exists
  
  	Returns:
  		Returns 1 on success, 0 on failure.
  */
  int fs_is_dir(const char *path);
  
  /*
  	Function: fs_chdir
  		Changes current working directory
  
  	Returns:
  		Returns 0 on success, 1 on failure.
  */
  int fs_chdir(const char *path);
  
  /*
  	Function: fs_getcwd
  		Gets the current working directory.
  
  	Returns:
  		Returns a pointer to the buffer on success, 0 on failure.
  */
  char *fs_getcwd(char *buffer, int buffer_size);
  
  /*
  	Function: fs_parent_dir
  		Get the parent directory of a directory
  
  	Parameters:
  		path - The directory string
  
  	Returns:
  		Returns 0 on success, 1 on failure.
  
  	Remarks:
  		- The string is treated as zero-termineted string.
  */
  int fs_parent_dir(char *path);
  
  /*
  	Function: fs_remove
  		Deletes the file with the specified name.
  
  	Parameters:
  		filename - The file to delete
  
  	Returns:
  		Returns 0 on success, 1 on failure.
  
  	Remarks:
  		- The strings are treated as zero-terminated strings.
  */
  int fs_remove(const char *filename);
  
  /*
  	Function: fs_rename
  		Renames the file or directory. If the paths differ the file will be moved.
  
  	Parameters:
  		oldname - The actual name
  		newname - The new name
  
  	Returns:
  		Returns 0 on success, 1 on failure.
  
  	Remarks:
  		- The strings are treated as zero-terminated strings.
  */
  int fs_rename(const char *oldname, const char *newname);
  
  /*
  	Group: Undocumented
  */
  
  
  /*
  	Function: net_tcp_connect_non_blocking
  
  	DOCTODO: serp
  */
  int net_tcp_connect_non_blocking(NETSOCKET sock, NETADDR bindaddr);
  
  /*
  	Function: net_set_non_blocking
  
  	DOCTODO: serp
  */
  int net_set_non_blocking(NETSOCKET sock);
  
  /*
  	Function: net_set_non_blocking
  
  	DOCTODO: serp
  */
  int net_set_blocking(NETSOCKET sock);
  
  /*
  	Function: net_errno
  
  	DOCTODO: serp
  */
  int net_errno();
  
  /*
  	Function: net_would_block
  
  	DOCTODO: serp
  */
  int net_would_block();
  
  int net_socket_read_wait(NETSOCKET sock, int time);
  
  void mem_debug_dump(IOHANDLE file);
  
  void swap_endian(void *data, unsigned elem_size, unsigned num);
  
  
  typedef void (*DBG_LOGGER)(const char *line);
  void dbg_logger(DBG_LOGGER logger);
  
  void dbg_logger_stdout();
  void dbg_logger_debugger();
  void dbg_logger_file(const char *filename);
  
  typedef struct
  {
  	int allocated;
  	int active_allocations;
  	int total_allocations;
  } MEMSTATS;
  
  const MEMSTATS *mem_stats();
  
  typedef struct
  {
  	int sent_packets;
  	int sent_bytes;
  	int recv_packets;
  	int recv_bytes;
  } NETSTATS;
  
  
  void net_stats(NETSTATS *stats);
  
  int str_toint(const char *str);
  float str_tofloat(const char *str);
  int str_isspace(char c);
  char str_uppercase(char c);
  unsigned str_quickhash(const char *str);
  
  /*
  	Function: gui_messagebox
  		Display plain OS-dependent message box
  
  	Parameters:
  		title - title of the message box
  		message - text to display
  */
  void gui_messagebox(const char *title, const char *message);
  
  int str_utf8_isstart(char c);
  
  const char *str_utf8_skip_whitespaces(const char *str);
  
  /*
  	Function: str_utf8_rewind
  		Moves a cursor backwards in an utf8 string
  
  	Parameters:
  		str - utf8 string
  		cursor - position in the string
  
  	Returns:
  		New cursor position.
  
  	Remarks:
  		- Won't move the cursor less then 0
  */
  int str_utf8_rewind(const char *str, int cursor);
  
  /*
  	Function: str_utf8_forward
  		Moves a cursor forwards in an utf8 string
  
  	Parameters:
  		str - utf8 string
  		cursor - position in the string
  
  	Returns:
  		New cursor position.
  
  	Remarks:
  		- Won't move the cursor beyond the zero termination marker
  */
  int str_utf8_forward(const char *str, int cursor);
  
  /*
  	Function: str_utf8_decode
  		Decodes an utf8 character
  
  	Parameters:
  		ptr - pointer to an utf8 string. this pointer will be moved forward
  
  	Returns:
  		Unicode value for the character. -1 for invalid characters and 0 for end of string.
  
  	Remarks:
  		- This function will also move the pointer forward.
  */
  int str_utf8_decode(const char **ptr);
  
  /*
  	Function: str_utf8_encode
  		Encode an utf8 character
  
  	Parameters:
  		ptr - Pointer to a buffer that should recive the data. Should be able to hold at least 4 bytes.
  
  	Returns:
  		Number of bytes put into the buffer.
  
  	Remarks:
  		- Does not do zero termination of the string.
  */
  int str_utf8_encode(char *ptr, int chr);
  
  /*
  	Function: str_utf8_check
  		Checks if a strings contains just valid utf8 characters.
  
  	Parameters:
  		str - Pointer to a possible utf8 string.
  
  	Returns:
  		0 - invalid characters found.
  		1 - only valid characters found.
  
  	Remarks:
  		- The string is treated as zero-terminated utf8 string.
  */
  int str_utf8_check(const char *str);
  
  /*
  	Function: secure_random_init
  		Initializes the secure random module.
  		You *MUST* check the return value of this function.
  
  	Returns:
  		0 - Initialization succeeded.
  		1 - Initialization failed.
  */
  int secure_random_init();
  
  /*
  	Function: secure_random_fill
  		Fills the buffer with the specified amount of random bytes.
  
  	Parameters:
  		buffer - Pointer to the start of the buffer.
  		length - Length of the buffer.
  */
  void secure_random_fill(void *bytes, unsigned length);
  
  #ifdef __cplusplus
  }
  #endif
  
  #endif
  