aboutsummaryrefslogtreecommitdiff
path: root/sokol_fetch.h
diff options
context:
space:
mode:
authorAndre Weissflog <floooh@gmail.com>2023-01-31 20:29:02 +0100
committerAndre Weissflog <floooh@gmail.com>2023-01-31 20:29:02 +0100
commit138280be7c08d0c2a496c0acede64002740a5bdb (patch)
treed5eb3cf7477b178dbee3e1a54ae37b0a248ef9e6 /sokol_fetch.h
parent28c63b5473352a9d86c115da9448f61a2324c554 (diff)
sokol_fetch.h: add new-style logging, enabel request validation in release mode
Diffstat (limited to 'sokol_fetch.h')
-rw-r--r--sokol_fetch.h377
1 files changed, 255 insertions, 122 deletions
diff --git a/sokol_fetch.h b/sokol_fetch.h
index 1ac8c9e7..ae75d272 100644
--- a/sokol_fetch.h
+++ b/sokol_fetch.h
@@ -75,9 +75,11 @@
(1) initialize sokol-fetch with default parameters (but NOTE that the
default setup parameters provide a safe-but-slow "serialized"
- operation):
+ operation). In order to see any logging output in case or errors
+ you should always provide a logging function
+ (such as 'slog_func' from sokol_log.h):
- sfetch_setup(&(sfetch_desc_t){ 0 });
+ sfetch_setup(&(sfetch_desc_t){ .logger.func = slog_func });
(2) send a fetch-request to load a file from the current directory
into a buffer big enough to hold the entire file content:
@@ -834,26 +836,46 @@
was called, so you don't need to worry about thread-safety.
- LOG FUNCTION OVERRIDE
- =====================
- You can override the log function at initialization time like this:
+ ERROR REPORTING AND LOGGING
+ ===========================
+ To get any logging information at all you need to provide a logging callback in the setup call,
+ the easiest way is to use sokol_log.h:
- void my_log(const char* message, void* user_data) {
- printf("sfetch says: \s\n", message);
+ #include "sokol_log.h"
+
+ sfetch_setup(&(sfetch_desc_t){
+ // ...
+ .logger.func = slog_func
+ });
+
+ To override logging with your own callback, first write a logging function like this:
+
+ void my_log(const char* tag, // e.g. 'sfetch'
+ uint32_t log_level, // 0=panic, 1=error, 2=warn, 3=info
+ uint32_t log_item_id, // SFETCH_LOGITEM_*
+ const char* message_or_null, // a message string, may be nullptr in release mode
+ uint32_t line_nr, // line number in sokol_audio.h
+ const char* filename_or_null, // source filename, may be nullptr in release mode
+ void* user_data)
+ {
+ ...
}
- ...
- sfetch_setup(&(sfetch_desc_t){
- // ...
- .logger = {
- .log_cb = my_log,
- .user_data = ...,
- }
- });
- ...
+ ...and then setup sokol-fetch like this:
- If no overrides are provided, puts will be used on most platforms.
- On Android, __android_log_write will be used instead.
+ sfetch_setup(&(sfetch_desc_t){
+ .logger = {
+ .func = my_log,
+ .user_data = my_user_data,
+ }
+ });
+
+ The provided logging function must be reentrant (e.g. be callable from
+ different threads).
+
+ If you don't want to provide your own custom logger it is highly recommended to use
+ the standard logger in sokol_log.h instead, otherwise you won't see any warnings or
+ errors.
FUTURE PLANS / V2.0 IDEA DUMP
@@ -922,6 +944,55 @@ extern "C" {
#endif
/*
+ sfetch_log_item_t
+
+ Log items are defined via X-Macros, and expanded to an
+ enum 'saudio_log_item', and in debug mode only,
+ corresponding strings.
+
+ Used as parameter in the logging callback.
+*/
+#define _SFETCH_LOG_ITEMS \
+ _SFETCH_XMACRO(OK) \
+ _SFETCH_XMACRO(MALLOC_FAILED) \
+ _SFETCH_XMACRO(FILE_PATH_UTF8_DECODING_FAILED) \
+ _SFETCH_XMACRO(SEND_QUEUE_FULL) \
+ _SFETCH_XMACRO(REQUEST_CHANNEL_TOO_BIG) \
+ _SFETCH_XMACRO(REQUEST_PATH_IS_NULL) \
+ _SFETCH_XMACRO(REQUEST_PATH_TOO_LONG) \
+ _SFETCH_XMACRO(REQUEST_CALLBACK_MISSING) \
+ _SFETCH_XMACRO(REQUEST_CHUNK_SIZE_GREATER_BUFFER_SIZE) \
+ _SFETCH_XMACRO(REQUEST_USERDATA_PTR_IS_SET_BUT_USERDATA_SIZE_IS_NULL) \
+ _SFETCH_XMACRO(REQUEST_USERDATA_PTR_IS_NULL_BUT_USERDATA_SIZE_IS_NOT) \
+ _SFETCH_XMACRO(REQUEST_USERDATA_SIZE_TOO_BIG) \
+ _SFETCH_XMACRO(CLAMPING_NUM_CHANNELS_TO_MAX_CHANNELS) \
+ _SFETCH_XMACRO(REQUEST_POOL_FULL) \
+
+#define _SFETCH_XMACRO(item) SFETCH_LOGITEM_##item,
+typedef enum sfetch_log_item_t {
+ _SFETCH_LOG_ITEMS
+} sfetch_log_item_t;
+#undef _SFETCH_XMACRO
+
+/*
+ sfetch_logger_t
+
+ Used in sfetch_desc_t to provide a custom logging and error reporting
+ callback to sokol-fetch.
+*/
+typedef struct sfetch_logger_t {
+ void (*func)(
+ const char* tag, // always "sfetch"
+ uint32_t log_level, // 0=panic, 1=error, 2=warning, 3=info
+ uint32_t log_item_id, // SFETCH_LOGITEM_*
+ const char* message_or_null, // a message string, may be nullptr in release mode
+ uint32_t line_nr, // line number in sokol_fetch.h
+ const char* filename_or_null, // source filename, may be nullptr in release mode
+ void* user_data);
+ void* user_data;
+} sfetch_logger_t;
+
+/*
sfetch_range_t
A pointer-size pair struct to pass memory ranges into and out of sokol-fetch.
@@ -958,24 +1029,13 @@ typedef struct sfetch_allocator_t {
void* user_data;
} sfetch_allocator_t;
-/*
- sfetch_logger_t
-
- Used in sfetch_desc_t to provide custom log callbacks to sokol_fetch.h.
- Default behavior is SOKOL_LOG(message).
-*/
-typedef struct sfetch_logger_t {
- void (*log_cb)(const char* message, void* user_data);
- void* user_data;
-} sfetch_logger_t;
-
/* configuration values for sfetch_setup() */
typedef struct sfetch_desc_t {
uint32_t max_requests; // max number of active requests across all channels (default: 128)
uint32_t num_channels; // number of channels to fetch requests in parallel (default: 1)
uint32_t num_lanes; // max number of requests active on the same channel (default: 1)
sfetch_allocator_t allocator; // optional memory allocation overrides (default: malloc/free)
- sfetch_logger_t logger; // optional log function overrides (default: SOKOL_LOG(message))
+ sfetch_logger_t logger; // optional log function overrides (default: NO LOGGING!)
} sfetch_desc_t;
/* a request handle to identify an active fetch request, returned by sfetch_send() */
@@ -1065,7 +1125,14 @@ inline sfetch_handle_t sfetch_send(const sfetch_request_t& request) { return sfe
#endif
#endif // SOKOL_FETCH_INCLUDED
-/*--- IMPLEMENTATION ---------------------------------------------------------*/
+// ██╗███╗ ███╗██████╗ ██╗ ███████╗███╗ ███╗███████╗███╗ ██╗████████╗ █████╗ ████████╗██╗ ██████╗ ███╗ ██╗
+// ██║████╗ ████║██╔══██╗██║ ██╔════╝████╗ ████║██╔════╝████╗ ██║╚══██╔══╝██╔══██╗╚══██╔══╝██║██╔═══██╗████╗ ██║
+// ██║██╔████╔██║██████╔╝██║ █████╗ ██╔████╔██║█████╗ ██╔██╗ ██║ ██║ ███████║ ██║ ██║██║ ██║██╔██╗ ██║
+// ██║██║╚██╔╝██║██╔═══╝ ██║ ██╔══╝ ██║╚██╔╝██║██╔══╝ ██║╚██╗██║ ██║ ██╔══██║ ██║ ██║██║ ██║██║╚██╗██║
+// ██║██║ ╚═╝ ██║██║ ███████╗███████╗██║ ╚═╝ ██║███████╗██║ ╚████║ ██║ ██║ ██║ ██║ ██║╚██████╔╝██║ ╚████║
+// ╚═╝╚═╝ ╚═╝╚═╝ ╚══════╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝
+//
+// >>implementation
#ifdef SOKOL_FETCH_IMPL
#define SOKOL_FETCH_IMPL_INCLUDED (1)
@@ -1099,21 +1166,6 @@ inline sfetch_handle_t sfetch_send(const sfetch_request_t& request) { return sfe
#define SOKOL_ASSERT(c) assert(c)
#endif
-#if !defined(SOKOL_DEBUG)
- #define SFETCH_LOG(s)
-#else
- #define SFETCH_LOG(s) _sfetch_log(s)
- #ifndef SOKOL_LOG
- #if defined(__ANDROID__)
- #include <android/log.h>
- #define SOKOL_LOG(s) __android_log_write(ANDROID_LOG_INFO, "SOKOL_FETCH", s)
- #else
- #include <stdio.h>
- #define SOKOL_LOG(s) puts(s)
- #endif
- #endif
-#endif
-
#ifndef _SOKOL_PRIVATE
#if defined(__GNUC__) || defined(__clang__)
#define _SOKOL_PRIVATE __attribute__((unused)) static
@@ -1153,7 +1205,14 @@ inline sfetch_handle_t sfetch_send(const sfetch_request_t& request) { return sfe
#define _SFETCH_HAS_THREADS (1)
#endif
-/*=== private type definitions ===============================================*/
+// ███████╗████████╗██████╗ ██╗ ██╗ ██████╗████████╗███████╗
+// ██╔════╝╚══██╔══╝██╔══██╗██║ ██║██╔════╝╚══██╔══╝██╔════╝
+// ███████╗ ██║ ██████╔╝██║ ██║██║ ██║ ███████╗
+// ╚════██║ ██║ ██╔══██╗██║ ██║██║ ██║ ╚════██║
+// ███████║ ██║ ██║ ██║╚██████╔╝╚██████╗ ██║ ███████║
+// ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
+//
+// >>structs
typedef struct _sfetch_path_t {
char buf[SFETCH_MAX_PATH];
} _sfetch_path_t;
@@ -1312,7 +1371,54 @@ static __thread _sfetch_t* _sfetch;
static _sfetch_t* _sfetch;
#endif
-/*=== general helper functions and macros =====================================*/
+// ██╗ ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗
+// ██║ ██╔═══██╗██╔════╝ ██╔════╝ ██║████╗ ██║██╔════╝
+// ██║ ██║ ██║██║ ███╗██║ ███╗██║██╔██╗ ██║██║ ███╗
+// ██║ ██║ ██║██║ ██║██║ ██║██║██║╚██╗██║██║ ██║
+// ███████╗╚██████╔╝╚██████╔╝╚██████╔╝██║██║ ╚████║╚██████╔╝
+// ╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝
+//
+// >>logging
+#if defined(SOKOL_DEBUG)
+#define _SFETCH_XMACRO(item) #item,
+static const char* _sfetch_log_messages[] = {
+ _SFETCH_LOG_ITEMS
+};
+#undef _SFETCH_XMACRO
+#endif // SOKOL_DEBUG
+
+#define _SFETCH_PANIC(code) _sfetch_log(SFETCH_LOGITEM_ ##code, 0, __LINE__)
+#define _SFETCH_ERROR(code) _sfetch_log(SFETCH_LOGITEM_ ##code, 1, __LINE__)
+#define _SFETCH_WARN(code) _sfetch_log(SFETCH_LOGITEM_ ##code, 2, __LINE__)
+#define _SFETCH_INFO(code) _sfetch_log(SFETCH_LOGITEM_ ##code, 3, __LINE__)
+
+static void _sfetch_log(sfetch_log_item_t log_item, uint32_t log_level, uint32_t line_nr) {
+ if (_sfetch->desc.logger.func) {
+// #if defined(SOKOL_DEBUG)
+// const char* filename = __FILE__;
+// const char* message = _sfetch_log_messages[log_item];
+// #else
+ const char* filename = 0;
+ const char* message = 0;
+// #endif
+ _sfetch->desc.logger.func("sfetch", log_level, log_item, message, line_nr, filename, _sfetch->desc.logger.user_data);
+ }
+ else {
+ // for log level PANIC it would be 'undefined behaviour' to continue
+ if (log_level == 0) {
+ abort();
+ }
+ }
+}
+
+// ███╗ ███╗███████╗███╗ ███╗ ██████╗ ██████╗ ██╗ ██╗
+// ████╗ ████║██╔════╝████╗ ████║██╔═══██╗██╔══██╗╚██╗ ██╔╝
+// ██╔████╔██║█████╗ ██╔████╔██║██║ ██║██████╔╝ ╚████╔╝
+// ██║╚██╔╝██║██╔══╝ ██║╚██╔╝██║██║ ██║██╔══██╗ ╚██╔╝
+// ██║ ╚═╝ ██║███████╗██║ ╚═╝ ██║╚██████╔╝██║ ██║ ██║
+// ╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝
+//
+// >>memory
#define _sfetch_def(val, def) (((val) == 0) ? (def) : (val))
_SOKOL_PRIVATE void _sfetch_clear(void* ptr, size_t size) {
@@ -1329,7 +1435,9 @@ _SOKOL_PRIVATE void* _sfetch_malloc_with_allocator(const sfetch_allocator_t* all
else {
ptr = malloc(size);
}
- SOKOL_ASSERT(ptr);
+ if (0 == ptr) {
+ _SFETCH_PANIC(MALLOC_FAILED);
+ }
return ptr;
}
@@ -1352,17 +1460,6 @@ _SOKOL_PRIVATE void _sfetch_free(void* ptr) {
}
}
-#if defined(SOKOL_DEBUG)
-_SOKOL_PRIVATE void _sfetch_log(const char* msg) {
- if (_sfetch->desc.logger.log_cb) {
- _sfetch->desc.logger.log_cb(msg, _sfetch->desc.logger.user_data);
- }
- else {
- SOKOL_LOG(msg);
- }
-}
-#endif
-
_SOKOL_PRIVATE _sfetch_t* _sfetch_ctx(void) {
return _sfetch;
}
@@ -1388,21 +1485,14 @@ _SOKOL_PRIVATE _sfetch_path_t _sfetch_path_make(const char* str) {
return res;
}
-_SOKOL_PRIVATE uint32_t _sfetch_make_id(uint32_t index, uint32_t gen_ctr) {
- return (gen_ctr<<16) | (index & 0xFFFF);
-}
-
-_SOKOL_PRIVATE sfetch_handle_t _sfetch_make_handle(uint32_t slot_id) {
- sfetch_handle_t h;
- h.id = slot_id;
- return h;
-}
-
-_SOKOL_PRIVATE uint32_t _sfetch_slot_index(uint32_t slot_id) {
- return slot_id & 0xFFFF;
-}
-
-/*=== a circular message queue ===============================================*/
+// ███╗ ███╗███████╗███████╗███████╗ █████╗ ██████╗ ███████╗ ██████╗ ██╗ ██╗███████╗██╗ ██╗███████╗
+// ████╗ ████║██╔════╝██╔════╝██╔════╝██╔══██╗██╔════╝ ██╔════╝ ██╔═══██╗██║ ██║██╔════╝██║ ██║██╔════╝
+// ██╔████╔██║█████╗ ███████╗███████╗███████║██║ ███╗█████╗ ██║ ██║██║ ██║█████╗ ██║ ██║█████╗
+// ██║╚██╔╝██║██╔══╝ ╚════██║╚════██║██╔══██║██║ ██║██╔══╝ ██║▄▄ ██║██║ ██║██╔══╝ ██║ ██║██╔══╝
+// ██║ ╚═╝ ██║███████╗███████║███████║██║ ██║╚██████╔╝███████╗ ╚██████╔╝╚██████╔╝███████╗╚██████╔╝███████╗
+// ╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ ╚══▀▀═╝ ╚═════╝ ╚══════╝ ╚═════╝ ╚══════╝
+//
+// >>message queue
_SOKOL_PRIVATE uint32_t _sfetch_ring_wrap(const _sfetch_ring_t* rb, uint32_t i) {
return i % rb->num;
}
@@ -1484,7 +1574,28 @@ _SOKOL_PRIVATE uint32_t _sfetch_ring_peek(const _sfetch_ring_t* rb, uint32_t ind
return rb->buf[rb_index];
}
-/*=== request pool implementation ============================================*/
+// ██████╗ ███████╗ ██████╗ ██╗ ██╗███████╗███████╗████████╗ ██████╗ ██████╗ ██████╗ ██╗
+// ██╔══██╗██╔════╝██╔═══██╗██║ ██║██╔════╝██╔════╝╚══██╔══╝ ██╔══██╗██╔═══██╗██╔═══██╗██║
+// ██████╔╝█████╗ ██║ ██║██║ ██║█████╗ ███████╗ ██║ ██████╔╝██║ ██║██║ ██║██║
+// ██╔══██╗██╔══╝ ██║▄▄ ██║██║ ██║██╔══╝ ╚════██║ ██║ ██╔═══╝ ██║ ██║██║ ██║██║
+// ██║ ██║███████╗╚██████╔╝╚██████╔╝███████╗███████║ ██║ ██║ ╚██████╔╝╚██████╔╝███████╗
+// ╚═╝ ╚═╝╚══════╝ ╚══▀▀═╝ ╚═════╝ ╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
+//
+// >>request pool
+_SOKOL_PRIVATE uint32_t _sfetch_make_id(uint32_t index, uint32_t gen_ctr) {
+ return (gen_ctr<<16) | (index & 0xFFFF);
+}
+
+_SOKOL_PRIVATE sfetch_handle_t _sfetch_make_handle(uint32_t slot_id) {
+ sfetch_handle_t h;
+ h.id = slot_id;
+ return h;
+}
+
+_SOKOL_PRIVATE uint32_t _sfetch_slot_index(uint32_t slot_id) {
+ return slot_id & 0xFFFF;
+}
+
_SOKOL_PRIVATE void _sfetch_item_init(_sfetch_item_t* item, uint32_t slot_id, const sfetch_request_t* request) {
SOKOL_ASSERT(item && (0 == item->handle.id));
SOKOL_ASSERT(request && request->path);
@@ -1614,7 +1725,14 @@ _SOKOL_PRIVATE _sfetch_item_t* _sfetch_pool_item_lookup(_sfetch_pool_t* pool, ui
return 0;
}
-/*=== PLATFORM WRAPPER FUNCTIONS =============================================*/
+// ██████╗ ██████╗ ███████╗██╗██╗ ██╗
+// ██╔══██╗██╔═══██╗██╔════╝██║╚██╗██╔╝
+// ██████╔╝██║ ██║███████╗██║ ╚███╔╝
+// ██╔═══╝ ██║ ██║╚════██║██║ ██╔██╗
+// ██║ ╚██████╔╝███████║██║██╔╝ ██╗
+// ╚═╝ ╚═════╝ ╚══════╝╚═╝╚═╝ ╚═╝
+//
+// >>posix
#if _SFETCH_PLATFORM_POSIX
_SOKOL_PRIVATE _sfetch_file_handle_t _sfetch_file_open(const _sfetch_path_t* path) {
return fopen(path->buf, "rb");
@@ -1771,6 +1889,14 @@ _SOKOL_PRIVATE void _sfetch_thread_dequeue_outgoing(_sfetch_thread_t* thread, _s
}
#endif /* _SFETCH_PLATFORM_POSIX */
+// ██╗ ██╗██╗███╗ ██╗██████╗ ██████╗ ██╗ ██╗███████╗
+// ██║ ██║██║████╗ ██║██╔══██╗██╔═══██╗██║ ██║██╔════╝
+// ██║ █╗ ██║██║██╔██╗ ██║██║ ██║██║ ██║██║ █╗ ██║███████╗
+// ██║███╗██║██║██║╚██╗██║██║ ██║██║ ██║██║███╗██║╚════██║
+// ╚███╔███╔╝██║██║ ╚████║██████╔╝╚██████╔╝╚███╔███╔╝███████║
+// ╚══╝╚══╝ ╚═╝╚═╝ ╚═══╝╚═════╝ ╚═════╝ ╚══╝╚══╝ ╚══════╝
+//
+// >>windows
#if _SFETCH_PLATFORM_WINDOWS
_SOKOL_PRIVATE bool _sfetch_win32_utf8_to_wide(const char* src, wchar_t* dst, int dst_num_bytes) {
SOKOL_ASSERT(src && dst && (dst_num_bytes > 1));
@@ -1790,7 +1916,7 @@ _SOKOL_PRIVATE bool _sfetch_win32_utf8_to_wide(const char* src, wchar_t* dst, in
_SOKOL_PRIVATE _sfetch_file_handle_t _sfetch_file_open(const _sfetch_path_t* path) {
wchar_t w_path[SFETCH_MAX_PATH];
if (!_sfetch_win32_utf8_to_wide(path->buf, w_path, sizeof(w_path))) {
- SFETCH_LOG("_sfetch_file_open: error converting UTF-8 path to wide string");
+ _SFETCH_ERROR(FILE_PATH_UTF8_CONVERSION_FAILED);
return 0;
}
_sfetch_file_handle_t h = CreateFileW(
@@ -1950,7 +2076,14 @@ _SOKOL_PRIVATE void _sfetch_thread_dequeue_outgoing(_sfetch_thread_t* thread, _s
}
#endif /* _SFETCH_PLATFORM_WINDOWS */
-/*=== IO CHANNEL implementation ==============================================*/
+// ██████╗██╗ ██╗ █████╗ ███╗ ██╗███╗ ██╗███████╗██╗ ███████╗
+// ██╔════╝██║ ██║██╔══██╗████╗ ██║████╗ ██║██╔════╝██║ ██╔════╝
+// ██║ ███████║███████║██╔██╗ ██║██╔██╗ ██║█████╗ ██║ ███████╗
+// ██║ ██╔══██║██╔══██║██║╚██╗██║██║╚██╗██║██╔══╝ ██║ ╚════██║
+// ╚██████╗██║ ██║██║ ██║██║ ╚████║██║ ╚████║███████╗███████╗███████║
+// ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═══╝╚═╝ ╚═══╝╚══════╝╚══════╝╚══════╝
+//
+// >>channels
/* per-channel request handler for native platforms accessing the local filesystem */
#if _SFETCH_HAS_THREADS
@@ -2074,7 +2207,6 @@ _SOKOL_PRIVATE void* _sfetch_channel_thread_func(void* arg) {
#endif /* _SFETCH_HAS_THREADS */
#if _SFETCH_PLATFORM_EMSCRIPTEN
-/*=== embedded Javascript helper functions ===================================*/
EM_JS(void, sfetch_js_send_head_request, (uint32_t slot_id, const char* path_cstr), {
const path_str = UTF8ToString(path_cstr);
const req = new XMLHttpRequest();
@@ -2308,7 +2440,7 @@ _SOKOL_PRIVATE bool _sfetch_channel_send(_sfetch_channel_t* chn, uint32_t slot_i
return true;
}
else {
- SFETCH_LOG("sfetch_send: user_sent queue is full)");
+ _SFETCH_ERROR(SEND_QUEUE_FULL);
return false;
}
}
@@ -2449,45 +2581,39 @@ _SOKOL_PRIVATE void _sfetch_channel_dowork(_sfetch_channel_t* chn, _sfetch_pool_
}
}
-/*=== private high-level functions ===========================================*/
_SOKOL_PRIVATE bool _sfetch_validate_request(_sfetch_t* ctx, const sfetch_request_t* req) {
- #if defined(SOKOL_DEBUG)
- if (req->channel >= ctx->desc.num_channels) {
- SFETCH_LOG("_sfetch_validate_request: request.channel too big!");
- return false;
- }
- if (!req->path) {
- SFETCH_LOG("_sfetch_validate_request: request.path is null!");
- return false;
- }
- if (strlen(req->path) >= (SFETCH_MAX_PATH-1)) {
- SFETCH_LOG("_sfetch_validate_request: request.path is too long (must be < SFETCH_MAX_PATH-1)");
- return false;
- }
- if (!req->callback) {
- SFETCH_LOG("_sfetch_validate_request: request.callback missing");
- return false;
- }
- if (req->chunk_size > req->buffer.size) {
- SFETCH_LOG("_sfetch_validate_request: request.chunk_size is greater request.buffer.size)");
- return false;
- }
- if (req->user_data.ptr && (req->user_data.size == 0)) {
- SFETCH_LOG("_sfetch_validate_request: request.user_data.ptr is set, but request.user_data.size is null");
- return false;
- }
- if (!req->user_data.ptr && (req->user_data.size > 0)) {
- SFETCH_LOG("_sfetch_validate_request: request.user_data.ptr is null, but request.user_data.size is not");
- return false;
- }
- if (req->user_data.size > SFETCH_MAX_USERDATA_UINT64 * sizeof(uint64_t)) {
- SFETCH_LOG("_sfetch_validate_request: request.user_data.size is too big (see SFETCH_MAX_USERDATA_UINT64");
- return false;
- }
- #else
- /* silence unused warnings in release*/
- (void)(ctx && req);
- #endif
+ if (req->channel >= ctx->desc.num_channels) {
+ _SFETCH_ERROR(REQUEST_CHANNEL_TOO_BIG);
+ return false;
+ }
+ if (!req->path) {
+ _SFETCH_ERROR(REQUEST_PATH_IS_NULL);
+ return false;
+ }
+ if (strlen(req->path) >= (SFETCH_MAX_PATH-1)) {
+ _SFETCH_ERROR(REQUEST_PATH_TOO_LONG);
+ return false;
+ }
+ if (!req->callback) {
+ _SFETCH_ERROR(REQUEST_CALLBACK_MISSING);
+ return false;
+ }
+ if (req->chunk_size > req->buffer.size) {
+ _SFETCH_ERROR(REQUEST_CHUNK_SIZE_GREATER_BUFFER_SIZE);
+ return false;
+ }
+ if (req->user_data.ptr && (req->user_data.size == 0)) {
+ _SFETCH_ERROR(REQUEST_USERDATA_PTR_IS_SET_BUT_USERDATA_SIZE_IS_NULL);
+ return false;
+ }
+ if (!req->user_data.ptr && (req->user_data.size > 0)) {
+ _SFETCH_ERROR(REQUEST_USERDATA_PTR_IS_NULL_BUT_USERDATA_SIZE_IS_NOT);
+ return false;
+ }
+ if (req->user_data.size > SFETCH_MAX_USERDATA_UINT64 * sizeof(uint64_t)) {
+ _SFETCH_ERROR(REQUEST_USERDATA_SIZE_TOO_BIG);
+ return false;
+ }
return true;
}
@@ -2500,7 +2626,14 @@ _SOKOL_PRIVATE sfetch_desc_t _sfetch_desc_defaults(const sfetch_desc_t* desc) {
return res;
}
-/*=== PUBLIC API FUNCTIONS ===================================================*/
+// ██████╗ ██╗ ██╗██████╗ ██╗ ██╗ ██████╗
+// ██╔══██╗██║ ██║██╔══██╗██║ ██║██╔════╝
+// ██████╔╝██║ ██║██████╔╝██║ ██║██║
+// ██╔═══╝ ██║ ██║██╔══██╗██║ ██║██║
+// ██║ ╚██████╔╝██████╔╝███████╗██║╚██████╗
+// ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝
+//
+// >>public
SOKOL_API_IMPL void sfetch_setup(const sfetch_desc_t* desc_) {
SOKOL_ASSERT(desc_);
SOKOL_ASSERT(0 == _sfetch);
@@ -2517,7 +2650,7 @@ SOKOL_API_IMPL void sfetch_setup(const sfetch_desc_t* desc_) {
/* replace zero-init items with default values */
if (ctx->desc.num_channels > SFETCH_MAX_CHANNELS) {
ctx->desc.num_channels = SFETCH_MAX_CHANNELS;
- SFETCH_LOG("sfetch_setup: clamping num_channels to SFETCH_MAX_CHANNELS");
+ _SFETCH_WARN(CLAMPING_NUM_CHANNELS_TO_MAX_CHANNELS);
}
/* setup the global request item pool */
@@ -2589,7 +2722,7 @@ SOKOL_API_IMPL sfetch_handle_t sfetch_send(const sfetch_request_t* request) {
uint32_t slot_id = _sfetch_pool_item_alloc(&ctx->pool, request);
if (0 == slot_id) {
- SFETCH_LOG("sfetch_send: request pool exhausted (too many active requests)");
+ _SFETCH_WARN(REQUEST_POOL_FULL);
return invalid_handle;
}
if (!_sfetch_channel_send(&ctx->chn[request->channel], slot_id)) {