/* (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" #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: */ 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 #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: */ 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: */ 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: */ 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 . 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: */ 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: */ 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: */ 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 to the standard input. */ IOHANDLE io_stdin(); /* Function: io_stdout Returns an to the standard output. */ IOHANDLE io_stdout(); /* Function: io_stderr Returns an 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_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); /* Group: Semaphores */ #if !defined(CONF_PLATFORM_MACOSX) #if defined(CONF_FAMILY_UNIX) #include 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 . */ 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_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); /* 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); /* 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); #ifdef __cplusplus } #endif #endif