dqn: Cleanup more documentation
This commit is contained in:
parent
580b8a6882
commit
55dbc25110
46
dqn.h
46
dqn.h
@ -1,3 +1,49 @@
|
||||
// NOTE: [$CFGM] Config macros =====================================================================
|
||||
//
|
||||
// #define DQN_IMPLEMENTATION
|
||||
// Define this in one and only one C++ file to enable the implementation
|
||||
// code of the header file
|
||||
//
|
||||
// #define DQN_NO_ASSERT
|
||||
// Turn all assertion macros to no-ops
|
||||
//
|
||||
// #define DQN_NO_CHECK_BREAK
|
||||
// Disable debug break when a check macro's expression fails. Instead only
|
||||
// the error will be logged.
|
||||
//
|
||||
// #define DQN_NO_WIN32_MIN_HEADER
|
||||
// Define this to stop this library from defining a minimal subset of Win32
|
||||
// prototypes and definitions in this file. Useful for stopping redefinition
|
||||
// of symbols if another library includes "Windows.h"
|
||||
//
|
||||
// #define DQN_STATIC_API
|
||||
// Apply static to all function definitions and disable external linkage to
|
||||
// other translation units.
|
||||
//
|
||||
// #define DQN_STB_SPRINTF_HEADER_ONLY
|
||||
// Define this to stop this library from defining
|
||||
// STB_SPRINTF_IMPLEMENTATION. Useful if another library uses and includes
|
||||
// "stb_sprintf.h"
|
||||
//
|
||||
// #define DQN_MEMSET_BYTE 0
|
||||
// Change the byte that DQN_MEMSET will clear memory with. By default this
|
||||
// is set to 0. Some of this library API accepts are clear memory parameter
|
||||
// to scrub memory after certain operations.
|
||||
//
|
||||
// #define DQN_LEAK_TRACING
|
||||
// When defined to some allocating calls in the library will automatically
|
||||
// get passed in the file name, function name, line number and an optional
|
||||
// leak_msg.
|
||||
|
||||
#if defined(DQN_LEAK_TRACING)
|
||||
#error Leak tracing not supported because we enter an infinite leak tracing loop tracing our own allocations made to tracks leaks in the internal leak table.
|
||||
#endif
|
||||
|
||||
//
|
||||
// #define DQN_DEBUG_THREAD_CONTEXT
|
||||
// Define this macro to record allocation stats for arenas used in the
|
||||
// thread context. The thread context arena stats can be printed by using
|
||||
// Dqn_Library_DumpThreadContextArenaStat.
|
||||
#if !defined(DQN_H)
|
||||
#define DQN_H
|
||||
#include <stdarg.h> // va_list
|
||||
|
88
dqn_core.h
88
dqn_core.h
@ -1,7 +1,6 @@
|
||||
// NOTE: Table Of Contents =========================================================================
|
||||
// Index | Disable #define | Description
|
||||
// =================================================================================================
|
||||
// [$CFGM] Config macros | | Compile time customisation of library
|
||||
// [$CMAC] Compiler macros | | Macros for the compiler
|
||||
// [$MACR] Macros | | Define macros used in the library
|
||||
// [$TYPE] Typedefs | | Typedefs used in the library
|
||||
@ -11,52 +10,6 @@
|
||||
// [$CALL] Dqn_CallSite | | Source code location/tracing
|
||||
// ===================+=================+===========================================================
|
||||
|
||||
// NOTE: [$CFGM] Config macros =====================================================================
|
||||
// #define DQN_IMPLEMENTATION
|
||||
// Define this in one and only one C++ file to enable the implementation
|
||||
// code of the header file
|
||||
//
|
||||
// #define DQN_NO_ASSERT
|
||||
// Turn all assertion macros to no-ops
|
||||
//
|
||||
// #define DQN_NO_CHECK_BREAK
|
||||
// Disable debug break when a check macro's expression fails. Instead only
|
||||
// the error will be logged.
|
||||
//
|
||||
// #define DQN_NO_WIN32_MINIMAL_HEADER
|
||||
// Define this to stop this library from defining a minimal subset of Win32
|
||||
// prototypes and definitions in this file. Useful for stopping redefinition
|
||||
// of symbols if another library includes "Windows.h"
|
||||
//
|
||||
// #define DQN_STATIC_API
|
||||
// Apply static to all function definitions and disable external linkage to
|
||||
// other translation units.
|
||||
//
|
||||
// #define DQN_STB_SPRINTF_HEADER_ONLY
|
||||
// Define this to stop this library from defining
|
||||
// STB_SPRINTF_IMPLEMENTATION. Useful if another library uses and includes
|
||||
// "stb_sprintf.h"
|
||||
//
|
||||
// #define DQN_MEMSET_BYTE 0
|
||||
// Change the byte that DQN_MEMSET will clear memory with. By default this
|
||||
// is set to 0. Some of this library API accepts are clear memory parameter
|
||||
// to scrub memory after certain operations.
|
||||
//
|
||||
// #define DQN_LEAK_TRACING
|
||||
// When defined to some allocating calls in the library will automatically
|
||||
// get passed in the file name, function name, line number and an optional
|
||||
// leak_msg.
|
||||
|
||||
#if defined(DQN_LEAK_TRACING)
|
||||
#error Leak tracing not supported because we enter an infinite leak tracing loop tracing our own allocations made to tracks leaks in the internal leak table.
|
||||
#endif
|
||||
|
||||
//
|
||||
// #define DQN_DEBUG_THREAD_CONTEXT
|
||||
// Define this macro to record allocation stats for arenas used in the
|
||||
// thread context. The thread context arena stats can be printed by using
|
||||
// Dqn_Library_DumpThreadContextArenaStat.
|
||||
//
|
||||
// NOTE: [$CMAC] Compiler macros ===================================================================
|
||||
// NOTE: Warning! Order is important here, clang-cl on Windows defines _MSC_VER
|
||||
#if defined(_MSC_VER)
|
||||
@ -191,7 +144,7 @@
|
||||
#define DQN_GIGABYTES(val) (1024ULL * DQN_MEGABYTES(val))
|
||||
|
||||
// NOTE: Time Macros ===============================================================================
|
||||
#define DQN_SECONDS_TO_MS(val) ((val) * 1000.0f)
|
||||
#define DQN_SECONDS_TO_MS(val) ((val) * 1000)
|
||||
#define DQN_MINS_TO_S(val) ((val) * 60ULL)
|
||||
#define DQN_HOURS_TO_S(val) (DQN_MINS_TO_S(val) * 60ULL)
|
||||
#define DQN_DAYS_TO_S(val) (DQN_HOURS_TO_S(val) * 24ULL)
|
||||
@ -237,7 +190,27 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DQN_INVALID_CODE_PATHF(fmt, ...) DQN_ASSERTF(0, fmt, ##__VA_ARGS__)
|
||||
#define DQN_INVALID_CODE_PATH DQN_INVALID_CODE_PATHF("Invalid code path triggered")
|
||||
|
||||
// NOTE: Check macro ===============================================================================
|
||||
// Assert the expression given in debug, whilst in release- assertion is
|
||||
// removed and the expression is evaluated and returned.
|
||||
//
|
||||
// This function provides dual logic which allows handling of the condition
|
||||
// gracefully in release mode, but asserting in debug mode. This is an internal
|
||||
// function, prefer the @see DQN_CHECK macros.
|
||||
//
|
||||
// Returns true if the expression evaluated to true, false otherwise.
|
||||
//
|
||||
#if 0
|
||||
bool flag = true;
|
||||
if (!DQN_CHECKF(flag, "Flag was false!")) {
|
||||
// This branch will execute!
|
||||
}
|
||||
#endif
|
||||
#define DQN_CHECK(expr) DQN_CHECKF(expr, "")
|
||||
|
||||
#if defined(DQN_NO_CHECK_BREAK)
|
||||
#define DQN_CHECKF(expr, fmt, ...) \
|
||||
((expr) ? true : (Dqn_Log_TypeFCallSite(Dqn_LogType_Warning, DQN_CALL_SITE, fmt, ## __VA_ARGS__), false))
|
||||
@ -246,30 +219,13 @@
|
||||
((expr) ? true : (Dqn_Log_TypeFCallSite(Dqn_LogType_Error, DQN_CALL_SITE, fmt, ## __VA_ARGS__), DQN_DEBUG_BREAK, false))
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
DQN_API bool DQN_CHECKF_(bool assertion_expr, Dqn_CallSite call_site, char const *fmt, ...)
|
||||
{
|
||||
bool result = assertion_expr;
|
||||
if (!result) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
Dqn_Log_TypeFVCallSite(Dqn_LogType_Error, call_site, fmt, args);
|
||||
va_end(args);
|
||||
DQN_DEBUG_BREAK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
// NOTE: Zero initialisation macro =================================================================
|
||||
#if defined(__cplusplus)
|
||||
#define DQN_ZERO_INIT {}
|
||||
#else
|
||||
#define DQN_ZERO_INIT {0}
|
||||
#endif
|
||||
|
||||
#define DQN_INVALID_CODE_PATHF(fmt, ...) DQN_ASSERTF(0, fmt, ##__VA_ARGS__)
|
||||
#define DQN_INVALID_CODE_PATH DQN_INVALID_CODE_PATHF("Invalid code path triggered")
|
||||
|
||||
// NOTE: Defer Macro ===============================================================================
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
|
379
dqn_misc.h
379
dqn_misc.h
@ -78,264 +78,157 @@ DQN_API void Dqn_Library_LeakTraceMarkFree (Dqn_CallSite call_site, void
|
||||
|
||||
// NOTE: [$BITS] Dqn_Bit ===========================================================================
|
||||
DQN_API void Dqn_Bit_UnsetInplace(uint32_t *flags, uint32_t bitfield);
|
||||
DQN_API void Dqn_Bit_SetInplace(uint32_t *flags, uint32_t bitfield);
|
||||
DQN_API bool Dqn_Bit_IsSet(uint32_t bits, uint32_t bits_to_set);
|
||||
DQN_API bool Dqn_Bit_IsNotSet(uint32_t bits, uint32_t bits_to_check);
|
||||
DQN_API void Dqn_Bit_SetInplace (uint32_t *flags, uint32_t bitfield);
|
||||
DQN_API bool Dqn_Bit_IsSet (uint32_t bits, uint32_t bits_to_set);
|
||||
DQN_API bool Dqn_Bit_IsNotSet (uint32_t bits, uint32_t bits_to_check);
|
||||
|
||||
// NOTE: [$SAFE] Dqn_Safe ==========================================================================
|
||||
// Assert the expression given in debug, whilst in release- assertion is
|
||||
// removed and the expression is evaluated and returned.
|
||||
// @proc Dqn_Safe_AddI64, Dqn_Safe_MulI64
|
||||
// @desc Add/multiply 2 I64's together, safe asserting that the operation does
|
||||
// not overflow.
|
||||
// @return The result of operation, INT64_MAX if it overflowed.
|
||||
|
||||
// @proc Dqn_Safe_AddU64, Dqn_Safe_MulU64
|
||||
// @desc Add/multiply 2 U64's together, safe asserting that the operation does
|
||||
// not overflow.
|
||||
// @return The result of operation, UINT64_MAX if it overflowed.
|
||||
|
||||
// @proc Dqn_Safe_SubU64, Dqn_Safe_SubU32
|
||||
// @desc Subtract 2xU64 or 2xU32's together, safe asserting that the operation
|
||||
// does not overflow.
|
||||
// @return The result of operation, 0 if it overflowed.
|
||||
|
||||
// @proc Dqn_Safe_SaturateCastUSizeToInt,
|
||||
// Dqn_Safe_SaturateCastUSizeToI8,
|
||||
// Dqn_Safe_SaturateCastUSizeToI16,
|
||||
// Dqn_Safe_SaturateCastUSizeToI32,
|
||||
// Dqn_Safe_SaturateCastUSizeToI64
|
||||
//
|
||||
// This function provides dual logic which allows handling of the condition
|
||||
// gracefully in release mode, but asserting in debug mode. This is an internal
|
||||
// function, prefer the @see DQN_CHECK macros.
|
||||
// Dqn_Safe_SaturateCastU64ToUInt,
|
||||
// Dqn_Safe_SaturateCastU64ToU8,
|
||||
// Dqn_Safe_SaturateCastU64ToU16,
|
||||
// Dqn_Safe_SaturateCastU64ToU32,
|
||||
//
|
||||
// @param assertion_expr[in] Expressin to assert on
|
||||
// @param fmt[in] Format string for providing a message on assertion
|
||||
// @return True if the expression evaluated to true, false otherwise.
|
||||
DQN_API bool DQN_CHECKF_(bool assertion_expr, Dqn_CallSite call_site, char const *fmt, ...);
|
||||
// Dqn_Safe_SaturateCastUSizeToU8,
|
||||
// Dqn_Safe_SaturateCastUSizeToU16,
|
||||
// Dqn_Safe_SaturateCastUSizeToU32,
|
||||
// Dqn_Safe_SaturateCastUSizeToU64
|
||||
//
|
||||
// Dqn_Safe_SaturateCastISizeToInt,
|
||||
// Dqn_Safe_SaturateCastISizeToI8,
|
||||
// Dqn_Safe_SaturateCastISizeToI16,
|
||||
// Dqn_Safe_SaturateCastISizeToI32,
|
||||
// Dqn_Safe_SaturateCastISizeToI64,
|
||||
//
|
||||
// int Dqn_Safe_SaturateCastISizeToUInt,
|
||||
// Dqn_Safe_SaturateCastISizeToU8,
|
||||
// Dqn_Safe_SaturateCastISizeToU16,
|
||||
// Dqn_Safe_SaturateCastISizeToU32,
|
||||
// Dqn_Safe_SaturateCastISizeToU64,
|
||||
//
|
||||
// Dqn_Safe_SaturateCastI64ToISize,
|
||||
// Dqn_Safe_SaturateCastI64ToI8,
|
||||
// Dqn_Safe_SaturateCastI64ToI16,
|
||||
// Dqn_Safe_SaturateCastI64ToI32,
|
||||
//
|
||||
// Dqn_Safe_SaturateCastIntToI8,
|
||||
// Dqn_Safe_SaturateCastIntToU8,
|
||||
// Dqn_Safe_SaturateCastIntToU16,
|
||||
// Dqn_Safe_SaturateCastIntToU32,
|
||||
// Dqn_Safe_SaturateCastIntToU64,
|
||||
//
|
||||
// @desc Truncate the lhs operand to the right clamping the result to the max
|
||||
// value of the desired data type. Safe asserts if clamping occurs.
|
||||
//
|
||||
// The following sentinel values are returned when saturated,
|
||||
// USize -> Int: INT_MAX
|
||||
// USize -> I8: INT8_MAX
|
||||
// USize -> I16: INT16_MAX
|
||||
// USize -> I32: INT32_MAX
|
||||
// USize -> I64: INT64_MAX
|
||||
//
|
||||
// U64 -> UInt: UINT_MAX
|
||||
// U64 -> U8: UINT8_MAX
|
||||
// U64 -> U16: UINT16_MAX
|
||||
// U64 -> U32: UINT32_MAX
|
||||
//
|
||||
// USize -> U8: UINT8_MAX
|
||||
// USize -> U16: UINT16_MAX
|
||||
// USize -> U32: UINT32_MAX
|
||||
// USize -> U64: UINT64_MAX
|
||||
//
|
||||
// ISize -> Int: INT_MIN or INT_MAX
|
||||
// ISize -> I8: INT8_MIN or INT8_MAX
|
||||
// ISize -> I16: INT16_MIN or INT16_MAX
|
||||
// ISize -> I32: INT32_MIN or INT32_MAX
|
||||
// ISize -> I64: INT64_MIN or INT64_MAX
|
||||
//
|
||||
// ISize -> UInt: 0 or UINT_MAX
|
||||
// ISize -> U8: 0 or UINT8_MAX
|
||||
// ISize -> U16: 0 or UINT16_MAX
|
||||
// ISize -> U32: 0 or UINT32_MAX
|
||||
// ISize -> U64: 0 or UINT64_MAX
|
||||
//
|
||||
// I64 -> ISize: DQN_ISIZE_MIN or DQN_ISIZE_MAX
|
||||
// I64 -> I8: INT8_MIN or INT8_MAX
|
||||
// I64 -> I16: INT16_MIN or INT16_MAX
|
||||
// I64 -> I32: INT32_MIN or INT32_MAX
|
||||
//
|
||||
// Int -> I8: INT8_MIN or INT8_MAX
|
||||
// Int -> I16: INT16_MIN or INT16_MAX
|
||||
// Int -> U8: 0 or UINT8_MAX
|
||||
// Int -> U16: 0 or UINT16_MAX
|
||||
// Int -> U32: 0 or UINT32_MAX
|
||||
// Int -> U64: 0 or UINT64_MAX
|
||||
|
||||
// NOTE: Dqn_Safe Arithmetic
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Add 2 I64's together, safe asserting that the operation does not overflow.
|
||||
/// @return The result of operation, INT64_MAX if it overflowed.
|
||||
DQN_API int64_t Dqn_Safe_AddI64(int64_t a, int64_t b);
|
||||
DQN_API int64_t Dqn_Safe_AddI64 (int64_t a, int64_t b);
|
||||
DQN_API int64_t Dqn_Safe_MulI64 (int64_t a, int64_t b);
|
||||
|
||||
/// Multiply 2 I64's together, safe asserting that the operation does not
|
||||
/// overflow.
|
||||
/// @return The result of operation, IINT64_MAX if it overflowed.
|
||||
DQN_API int64_t Dqn_Safe_MulI64(int64_t a, int64_t b);
|
||||
DQN_API uint64_t Dqn_Safe_AddU64 (uint64_t a, uint64_t b);
|
||||
DQN_API uint64_t Dqn_Safe_MulU64 (uint64_t a, uint64_t b);
|
||||
|
||||
/// Add 2 U64's together, safe asserting that the operation does not overflow.
|
||||
/// @return The result of operation, UINT64_MAX if it overflowed.
|
||||
DQN_API uint64_t Dqn_Safe_AddU64(uint64_t a, uint64_t b);
|
||||
DQN_API uint64_t Dqn_Safe_SubU64 (uint64_t a, uint64_t b);
|
||||
DQN_API uint32_t Dqn_Safe_SubU32 (uint32_t a, uint32_t b);
|
||||
|
||||
/// Subtract 2 U64's together, safe asserting that the operation does not
|
||||
/// overflow.
|
||||
/// @return The result of operation, 0 if it overflowed.
|
||||
DQN_API uint64_t Dqn_Safe_SubU64(uint64_t a, uint64_t b);
|
||||
DQN_API int Dqn_Safe_SaturateCastUSizeToInt (Dqn_usize val);
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastUSizeToI8 (Dqn_usize val);
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastUSizeToI16 (Dqn_usize val);
|
||||
DQN_API int32_t Dqn_Safe_SaturateCastUSizeToI32 (Dqn_usize val);
|
||||
DQN_API int64_t Dqn_Safe_SaturateCastUSizeToI64 (Dqn_usize val);
|
||||
|
||||
/// Multiple 2 U64's together, safe asserting that the operation does not
|
||||
/// overflow.
|
||||
/// @return The result of operation, UINT64_MAX if it overflowed.
|
||||
DQN_API uint64_t Dqn_Safe_MulU64(uint64_t a, uint64_t b);
|
||||
DQN_API unsigned int Dqn_Safe_SaturateCastU64ToUInt (uint64_t val);
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastU64ToU8 (uint64_t val);
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastU64ToU16 (uint64_t val);
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastU64ToU32 (uint64_t val);
|
||||
|
||||
/// Subtract 2 U32's together, safe asserting that the operation does not
|
||||
/// overflow.
|
||||
/// @return The result of operation, 0 if it overflowed.
|
||||
DQN_API uint32_t Dqn_Safe_SubU32(uint32_t a, uint32_t b);
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastUSizeToU8 (Dqn_usize val);
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastUSizeToU16 (Dqn_usize val);
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastUSizeToU32 (Dqn_usize val);
|
||||
DQN_API uint64_t Dqn_Safe_SaturateCastUSizeToU64 (Dqn_usize val);
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastUSizeToI*
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Truncate a usize to int clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API int Dqn_Safe_SaturateCastUSizeToInt(Dqn_usize val);
|
||||
DQN_API int Dqn_Safe_SaturateCastISizeToInt (Dqn_isize val);
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastISizeToI8 (Dqn_isize val);
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastISizeToI16 (Dqn_isize val);
|
||||
DQN_API int32_t Dqn_Safe_SaturateCastISizeToI32 (Dqn_isize val);
|
||||
DQN_API int64_t Dqn_Safe_SaturateCastISizeToI64 (Dqn_isize val);
|
||||
|
||||
/// Truncate a usize to I8 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT8_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastUSizeToI8(Dqn_usize val);
|
||||
|
||||
/// Truncate a usize to I16 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT16_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastUSizeToI16(Dqn_usize val);
|
||||
|
||||
/// Truncate a usize to I32 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT32_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API int32_t Dqn_Safe_SaturateCastUSizeToI32(Dqn_usize val);
|
||||
|
||||
/// Truncate a usize to I64 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT64_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API int64_t Dqn_Safe_SaturateCastUSizeToI64(Dqn_usize val);
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastU64ToU*
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Truncate a u64 to uint clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or UINT_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API unsigned int Dqn_Safe_SaturateCastU64ToUInt(uint64_t val);
|
||||
|
||||
/// Truncate a u64 to u8 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or UINT8_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastU64ToU8(uint64_t val);
|
||||
|
||||
/// Truncate a u64 to u16 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or UINT16_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastU64ToU16(uint64_t val);
|
||||
|
||||
/// Truncate a u64 to u32 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or UINT32_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastU64ToU32(uint64_t val);
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastUSizeToU*
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Truncate a usize to U8 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or UINT8_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastUSizeToU8(Dqn_usize val);
|
||||
|
||||
/// Truncate a usize to U16 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or UINT16_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastUSizeToU16(Dqn_usize val);
|
||||
|
||||
/// Truncate a usize to U32 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or UINT32_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastUSizeToU32(Dqn_usize val);
|
||||
|
||||
/// Truncate a usize to U64 clamping the result to the max value of the desired
|
||||
/// data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or UINT64_MAX if the value would go out of the
|
||||
/// valid range when casted.
|
||||
DQN_API uint64_t Dqn_Safe_SaturateCastUSizeToU64(Dqn_usize val);
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastISizeToI*
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Truncate an isize to int clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT_MIN or INT_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API int Dqn_Safe_SaturateCastISizeToInt(Dqn_isize val);
|
||||
|
||||
/// Truncate an isize to I8 clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT8_MIN or INT8_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastISizeToI8(Dqn_isize val);
|
||||
|
||||
/// Truncate an isize to I16 clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT16_MIN or INT16_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastISizeToI16(Dqn_isize val);
|
||||
|
||||
/// Truncate an isize to I32 clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT32_MIN or INT32_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API int32_t Dqn_Safe_SaturateCastISizeToI32(Dqn_isize val);
|
||||
|
||||
/// Truncate an isize to I64 clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT64_MIN or INT64_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API int64_t Dqn_Safe_SaturateCastISizeToI64(Dqn_isize val);
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastISizeToU*
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Truncate an isize to uint clamping the result to 0 and the max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or 0 or UINT_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API unsigned int Dqn_Safe_SaturateCastISizeToUInt(Dqn_isize val);
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastISizeToU8 (Dqn_isize val);
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastISizeToU16 (Dqn_isize val);
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastISizeToU32 (Dqn_isize val);
|
||||
DQN_API uint64_t Dqn_Safe_SaturateCastISizeToU64 (Dqn_isize val);
|
||||
|
||||
/// Truncate an isize to U8 clamping the result to 0 and the max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or 0 or UINT8_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastISizeToU8(Dqn_isize val);
|
||||
DQN_API Dqn_isize Dqn_Safe_SaturateCastI64ToISize (int64_t val);
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastI64ToI8 (int64_t val);
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastI64ToI16 (int64_t val);
|
||||
DQN_API int32_t Dqn_Safe_SaturateCastI64ToI32 (int64_t val);
|
||||
|
||||
/// Truncate an isize to U16 clamping the result to 0 and the max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or 0 or UINT16_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastISizeToU16(Dqn_isize val);
|
||||
|
||||
/// Truncate an isize to U32 clamping the result to 0 and the max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or 0 or UINT32_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastISizeToU32(Dqn_isize val);
|
||||
|
||||
/// Truncate an isize to U64 clamping the result to 0 and the max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or 0 or UINT64_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API uint64_t Dqn_Safe_SaturateCastISizeToU64(Dqn_isize val);
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastI64To*
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Truncate an I64 to isize clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or DQN_ISIZE_MIN or DQN_ISIZE_MAX if the value
|
||||
/// would go out of the valid range when casted.
|
||||
DQN_API Dqn_isize Dqn_Safe_SaturateCastI64ToISize(Dqn_isize val);
|
||||
|
||||
/// Truncate an I64 to I8 clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT8_MIN or INT8_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastI64ToI8(int64_t val);
|
||||
|
||||
/// Truncate an I64 to I16 clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT16_MIN or INT16_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastI64ToI16(int64_t val);
|
||||
|
||||
/// Truncate an I64 to I32 clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT32_MIN or INT32_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API int32_t Dqn_Safe_SaturateCastI64ToI32(int64_t val);
|
||||
|
||||
// NOTE: Dqn_Safe_SaturateCastIntTo*
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Truncate an int to I8 clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT8_MIN or INT8_MAX if the value
|
||||
/// would go out of the valid range when casted.
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastIntToI8(int val);
|
||||
|
||||
/// Truncate an int to I16 clamping the result to the min and max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or INT16_MIN or INT16_MAX if the value
|
||||
/// would go out of the valid range when casted.
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastIntToI16(int val);
|
||||
|
||||
/// Truncate an int to U8 clamping the result to 0 and the max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or 0 or UINT8_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastIntToU8(int val);
|
||||
|
||||
/// Truncate an int to U16 clamping the result to 0 and the max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or 0 or UINT16_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastIntToU16(int val);
|
||||
|
||||
/// Truncate an int to U32 clamping the result to 0 and the max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or 0 or UINT32_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastIntToU32(int val);
|
||||
|
||||
/// Truncate an int to U64 clamping the result to 0 and the max value of the
|
||||
/// desired data type. Safe asserts if clamping occurs.
|
||||
/// @return The truncated value or 0 or UINT64_MAX if the value would go
|
||||
/// out of the valid range when casted.
|
||||
DQN_API uint64_t Dqn_Safe_SaturateCastIntToU64(int val);
|
||||
DQN_API int8_t Dqn_Safe_SaturateCastIntToI8 (int val);
|
||||
DQN_API int16_t Dqn_Safe_SaturateCastIntToI16 (int val);
|
||||
DQN_API uint8_t Dqn_Safe_SaturateCastIntToU8 (int val);
|
||||
DQN_API uint16_t Dqn_Safe_SaturateCastIntToU16 (int val);
|
||||
DQN_API uint32_t Dqn_Safe_SaturateCastIntToU32 (int val);
|
||||
DQN_API uint64_t Dqn_Safe_SaturateCastIntToU64 (int val);
|
||||
|
||||
// NOTE: [$TCTX] Dqn_ThreadContext =================================================================
|
||||
// Each thread is assigned in their thread-local storage (TLS) scratch and
|
||||
|
@ -924,16 +924,16 @@ DQN_API Dqn_FsFile Dqn_Fs_OpenFile(Dqn_String8 path, Dqn_FsFileOpen open_mode, u
|
||||
if (handle == INVALID_HANDLE_VALUE) {
|
||||
Dqn_WinErrorMsg msg = Dqn_Win_LastError();
|
||||
result.error_size =
|
||||
DQN_CAST(uint16_t) Dqn_SNPrintF2DotsOnOverflow(result.error,
|
||||
DQN_ARRAY_UCOUNT(result.error),
|
||||
"Open file failed: %.*s for \"%.*s\"",
|
||||
DQN_STRING_FMT(msg),
|
||||
DQN_STRING_FMT(path));
|
||||
DQN_CAST(uint16_t) Dqn_SNPrintFDotTruncate(result.error,
|
||||
DQN_ARRAY_UCOUNT(result.error),
|
||||
"Open file failed: %.*s for \"%.*s\"",
|
||||
DQN_STRING_FMT(msg),
|
||||
DQN_STRING_FMT(path));
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
if (access & Dqn_FsFileAccess_Execute) {
|
||||
result.error_size = DQN_CAST(uint16_t) Dqn_SNPrintF2DotsOnOverflow(
|
||||
result.error_size = DQN_CAST(uint16_t) Dqn_SNPrintFDotTruncate(
|
||||
result.error,
|
||||
DQN_ARRAY_UCOUNT(result.error),
|
||||
"Open file failed: execute access not supported for \"%.*s\"",
|
||||
@ -1008,10 +1008,10 @@ DQN_API bool Dqn_Fs_WriteFile(Dqn_FsFile *file, char const *buffer, Dqn_usize si
|
||||
if (!result) {
|
||||
Dqn_WinErrorMsg msg = Dqn_Win_LastError();
|
||||
file->error_size =
|
||||
DQN_CAST(uint16_t) Dqn_SNPrintF2DotsOnOverflow(file->error,
|
||||
DQN_ARRAY_UCOUNT(file->error),
|
||||
"Write file failed: %.*s for %.*s",
|
||||
DQN_STRING_FMT(msg));
|
||||
DQN_CAST(uint16_t) Dqn_SNPrintFDotTruncate(file->error,
|
||||
DQN_ARRAY_UCOUNT(file->error),
|
||||
"Write file failed: %.*s for %.*s",
|
||||
DQN_STRING_FMT(msg));
|
||||
}
|
||||
#else
|
||||
result = fwrite(buffer, DQN_CAST(Dqn_usize)size, 1 /*count*/, file->handle) == 1 /*count*/;
|
||||
|
350
dqn_platform.h
350
dqn_platform.h
@ -10,6 +10,15 @@
|
||||
// =================================================================================================
|
||||
|
||||
// NOTE: [$FSYS] Dqn_Fs ============================================================================
|
||||
// NOTE: FS Manipulation =======================================================
|
||||
// TODO(dqn): We should have a Dqn_String8 interface and a CString interface
|
||||
//
|
||||
// NOTE: API ===================================================================
|
||||
// @proc Dqn_FsDelete
|
||||
// @desc Delete the item specified at the path. This function *CAN* not delete directories unless
|
||||
// the directory is empty.
|
||||
// @return True if deletion was successful, false otherwise
|
||||
|
||||
enum Dqn_FsInfoType
|
||||
{
|
||||
Dqn_FsInfoType_Unknown,
|
||||
@ -27,45 +36,43 @@ struct Dqn_FsInfo
|
||||
uint64_t size;
|
||||
};
|
||||
|
||||
// NOTE: File System API
|
||||
// =============================================================================
|
||||
// TODO(dqn): We should have a Dqn_String8 interface and a CString interface
|
||||
DQN_API bool Dqn_Fs_Exists(Dqn_String8 path);
|
||||
DQN_API bool Dqn_Fs_DirExists(Dqn_String8 path);
|
||||
DQN_API Dqn_FsInfo Dqn_Fs_GetInfo(Dqn_String8 path);
|
||||
DQN_API bool Dqn_Fs_Copy(Dqn_String8 src, Dqn_String8 dest, bool overwrite);
|
||||
DQN_API bool Dqn_Fs_Exists (Dqn_String8 path);
|
||||
DQN_API bool Dqn_Fs_DirExists(Dqn_String8 path);
|
||||
DQN_API Dqn_FsInfo Dqn_Fs_GetInfo (Dqn_String8 path);
|
||||
DQN_API bool Dqn_Fs_Copy (Dqn_String8 src, Dqn_String8 dest, bool overwrite);
|
||||
DQN_API bool Dqn_Fs_MakeDir (Dqn_String8 path);
|
||||
DQN_API bool Dqn_Fs_Move (Dqn_String8 src, Dqn_String8 dest, bool overwrite);
|
||||
DQN_API bool Dqn_Fs_Delete (Dqn_String8 path);
|
||||
|
||||
DQN_API bool Dqn_Fs_MakeDir(Dqn_String8 path);
|
||||
DQN_API bool Dqn_Fs_Move(Dqn_String8 src, Dqn_String8 dest, bool overwrite);
|
||||
// NOTE: R/W Entire File ===========================================================================
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_Fs_WriteString8, Dqn_Fs_WriteCString8
|
||||
// @desc Write the string to a file at the path overwriting if necessary.
|
||||
|
||||
// TODO(dqn): This doesn't work on directories unless you delete the files
|
||||
// in that directory first.
|
||||
DQN_API bool Dqn_Fs_Delete(Dqn_String8 path);
|
||||
// @proc Dqn_Fs_ReadString8, Dqn_Fs_ReadCString8
|
||||
// @desc Read the file at the path to a string.
|
||||
|
||||
// NOTE: Read/Write Entire File API
|
||||
// =============================================================================
|
||||
// file_size: (Optional) The size of the file in bytes, the allocated buffer is (file_size + 1 [null terminator]) in bytes.
|
||||
DQN_API bool Dqn_Fs_WriteCString8(char const *file_path, Dqn_usize file_path_size, char const *buffer, Dqn_usize buffer_size);
|
||||
DQN_API bool Dqn_Fs_WriteString8(Dqn_String8 file_path, Dqn_String8 buffer);
|
||||
|
||||
/// Read a file at the specified path into memory.
|
||||
/// @param[in] path Path to the file to read
|
||||
/// @param[in] path_size The string size of the file path
|
||||
/// @param[out] file_size (Optional) Pass a pointer to receive the number of bytes read
|
||||
/// @param[in] allocator Allocator used to read the file to memory with
|
||||
/// @return A cstring with the read file, null pointer on failure.
|
||||
#define Dqn_Fs_ReadCString8(path, path_size, file_size, allocator) Dqn_Fs_ReadCString8_(DQN_LEAK_TRACE path, path_size, file_size, allocator)
|
||||
DQN_API char *Dqn_Fs_ReadCString8_(DQN_LEAK_TRACE_FUNCTION char const *path, Dqn_usize path_size, Dqn_usize *file_size, Dqn_Allocator allocator);
|
||||
|
||||
/// Read a file at the specified path into memory.
|
||||
/// @param[in] file_path Path to the file to read
|
||||
/// @param[in] allocator Allocator used to read the file to memory with
|
||||
/// @return A string with the read file, invalid string on failure.
|
||||
#define Dqn_Fs_ReadString8(path, allocator) Dqn_Fs_ReadString8_(DQN_LEAK_TRACE path, allocator)
|
||||
DQN_API Dqn_String8 Dqn_Fs_ReadString8_(DQN_LEAK_TRACE_FUNCTION Dqn_String8 path, Dqn_Allocator allocator);
|
||||
|
||||
// NOTE: Read/Write File Stream API
|
||||
// =============================================================================
|
||||
DQN_API bool Dqn_Fs_WriteCString8(char const *file_path, Dqn_usize file_path_size, char const *buffer, Dqn_usize buffer_size);
|
||||
DQN_API bool Dqn_Fs_WriteString8 (Dqn_String8 file_path, Dqn_String8 buffer);
|
||||
|
||||
// NOTE: Internal ==================================================================================
|
||||
DQN_API char *Dqn_Fs_ReadCString8_(DQN_LEAK_TRACE_FUNCTION char const *path, Dqn_usize path_size, Dqn_usize *file_size, Dqn_Allocator allocator);
|
||||
DQN_API Dqn_String8 Dqn_Fs_ReadString8_ (DQN_LEAK_TRACE_FUNCTION Dqn_String8 path, Dqn_Allocator allocator);
|
||||
|
||||
// NOTE: R/W Stream API ============================================================================
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_Fs_OpenFile
|
||||
// @desc Open a handle to the file
|
||||
|
||||
// @proc Dqn_Fs_WriteFile
|
||||
// @desc Append to the file specified by the handle with the given buffer.
|
||||
|
||||
// @proc Dqn_Fs_CloseFile
|
||||
// @desc Close the file at specified by the handle
|
||||
|
||||
struct Dqn_FsFile
|
||||
{
|
||||
void *handle;
|
||||
@ -90,12 +97,35 @@ enum Dqn_FsFileAccess
|
||||
Dqn_FsFileAccess_All = Dqn_FsFileAccess_ReadWrite | Dqn_FsFileAccess_Execute,
|
||||
};
|
||||
|
||||
DQN_API Dqn_FsFile Dqn_Fs_OpenFile(Dqn_String8 path, Dqn_FsFileOpen open_mode, uint32_t access);
|
||||
DQN_API bool Dqn_Fs_WriteFile(Dqn_FsFile *file, char const *buffer, Dqn_usize size);
|
||||
DQN_API void Dqn_Fs_CloseFile(Dqn_FsFile *file);
|
||||
DQN_API Dqn_FsFile Dqn_Fs_OpenFile (Dqn_String8 path, Dqn_FsFileOpen open_mode, uint32_t access);
|
||||
DQN_API bool Dqn_Fs_WriteFile(Dqn_FsFile *file, char const *buffer, Dqn_usize size);
|
||||
DQN_API void Dqn_Fs_CloseFile(Dqn_FsFile *file);
|
||||
|
||||
// NOTE: File system paths =========================================================================
|
||||
// Helper data structure for building paths suitable for OS consumption.
|
||||
//
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_FsPath_AddRef, Dqn_FsPath_Add
|
||||
// @desc Append a path to the file path. The passed in path can be specify
|
||||
// both a single level or multiple directories with different path separators.
|
||||
// The path will be decomposed into individual sections in the function.
|
||||
//
|
||||
// For example passing
|
||||
// - "path/to/your/desired/folder" is valid
|
||||
// - "path" is valid
|
||||
// - "path/to\your/desired\folder" is valid
|
||||
|
||||
// @proc Dqn_FsPath_Pop
|
||||
// @desc Remove the last appended path level from the current path stored in
|
||||
// the FsPath.
|
||||
//
|
||||
// For example "path/to/your/desired/folder" popped produces
|
||||
// "path/to/your/desired"
|
||||
|
||||
// @proc Dqn_FsPath_ConvertString8
|
||||
// @desc Convert the path specified in the string to the OS native separated
|
||||
// path.
|
||||
|
||||
// NOTE: Filesystem paths
|
||||
// =============================================================================
|
||||
#if !defined(Dqn_FsPathOSSeperator)
|
||||
#if defined(DQN_OS_WIN32)
|
||||
#define Dqn_FsPathOSSeperator "\\"
|
||||
@ -125,7 +155,6 @@ DQN_API bool Dqn_FsPath_Add (Dqn_Arena *arena, Dqn_FsPath *
|
||||
DQN_API bool Dqn_FsPath_Pop (Dqn_FsPath *fs_path);
|
||||
DQN_API Dqn_String8 Dqn_FsPath_BuildWithSeparator(Dqn_Arena *arena, Dqn_FsPath const *fs_path, Dqn_String8 path_separator);
|
||||
DQN_API Dqn_String8 Dqn_FsPath_ConvertString8 (Dqn_Arena *arena, Dqn_String8 path);
|
||||
|
||||
#define Dqn_FsPath_BuildFwdSlash(arena, fs_path) Dqn_FsPath_BuildWithSeparator(arena, fs_path, DQN_STRING8("/"))
|
||||
#define Dqn_FsPath_BuildBackSlash(arena, fs_path) Dqn_FsPath_BuildWithSeparator(arena, fs_path, DQN_STRING8("\\"))
|
||||
|
||||
@ -138,6 +167,11 @@ DQN_API Dqn_String8 Dqn_FsPath_ConvertString8 (Dqn_Arena *arena, Dqn_String8
|
||||
#endif
|
||||
|
||||
// NOTE: [$DATE] Dqn_Date ==========================================================================
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_Date_EpochTime
|
||||
// @desc Produce the time elapsed since the Unix epoch
|
||||
// (e.g. 1970-01-01T00:00:00Z) in seconds
|
||||
|
||||
struct Dqn_DateHMSTimeString
|
||||
{
|
||||
char date[DQN_ARRAY_UCOUNT("YYYY-MM-SS")];
|
||||
@ -158,13 +192,10 @@ struct Dqn_DateHMSTime
|
||||
uint8_t seconds;
|
||||
};
|
||||
|
||||
// @return The current time at the point of invocation
|
||||
DQN_API Dqn_DateHMSTime Dqn_Date_HMSLocalTimeNow();
|
||||
DQN_API Dqn_DateHMSTime Dqn_Date_HMSLocalTimeNow ();
|
||||
DQN_API Dqn_DateHMSTimeString Dqn_Date_HMSLocalTimeStringNow(char date_separator = '-', char hms_separator = ':');
|
||||
DQN_API Dqn_DateHMSTimeString Dqn_Date_HMSLocalTimeString(Dqn_DateHMSTime time, char date_separator = '-', char hms_separator = ':');
|
||||
|
||||
// return: The time elapsed since Unix epoch (1970-01-01T00:00:00Z) in seconds
|
||||
DQN_API uint64_t Dqn_Date_EpochTime();
|
||||
DQN_API Dqn_DateHMSTimeString Dqn_Date_HMSLocalTimeString (Dqn_DateHMSTime time, char date_separator = '-', char hms_separator = ':');
|
||||
DQN_API uint64_t Dqn_Date_EpochTime ();
|
||||
|
||||
// NOTE: [$W32H] Win32 Min Header ==================================================================
|
||||
#if defined(DQN_OS_WIN32)
|
||||
@ -192,71 +223,70 @@ DQN_API uint64_t Dqn_Date_EpochTime();
|
||||
#endif // !defined(DQN_NO_WIN32_MIN_HEADER) && !defined(_INC_WINDOWS)
|
||||
|
||||
// NOTE: [$WIND] Dqn_Win ===========================================================================
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_Win_LastErrorToBuffer, Dqn_Win_LastError
|
||||
// @desc Retrieve the latest error code and message Windows produced for the
|
||||
// most recent Win32 API call.
|
||||
|
||||
// @proc Dqn_Win_MakeProcessDPIAware
|
||||
// @desc Call once at application start-up to ensure that the application is
|
||||
// DPI aware on Windows and ensure that application UI is scaled up
|
||||
// appropriately for the monitor.
|
||||
|
||||
struct Dqn_WinErrorMsg
|
||||
{
|
||||
unsigned long code;
|
||||
char data[DQN_KILOBYTES(64) - 1]; // Maximum error size
|
||||
unsigned long size;
|
||||
};
|
||||
DQN_API void Dqn_Win_LastErrorToBuffer(Dqn_WinErrorMsg *msg);
|
||||
DQN_API void Dqn_Win_LastErrorToBuffer(Dqn_WinErrorMsg *msg);
|
||||
DQN_API Dqn_WinErrorMsg Dqn_Win_LastError();
|
||||
DQN_API void Dqn_Win_MakeProcessDPIAware();
|
||||
|
||||
/// Call once at application start-up to ensure that the application is DPI
|
||||
/// aware on Windows and ensure that application UI is scaled up appropriately
|
||||
/// for the monitor.
|
||||
DQN_API void Dqn_Win_MakeProcessDPIAware();
|
||||
// NOTE: Windows String8 <-> String16 ===========================================
|
||||
// Convert a UTF8 <-> UTF16 string.
|
||||
//
|
||||
// The exact size buffer required for this function can be determined by
|
||||
// calling this function with the 'dest' set to null and 'dest_size' set to 0,
|
||||
// the return size is the size required for conversion not-including space for
|
||||
// the null-terminator. This function *always* null-terminates the input
|
||||
// buffer.
|
||||
//
|
||||
// Returns the number of u8's (for UTF16->8) OR u16's (for UTF8->16)
|
||||
// written/required for conversion. 0 if there was a conversion error and can be
|
||||
// queried using 'Dqn_Win_LastError'
|
||||
|
||||
// NOTE: Windows String8 To String16
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Convert a UTF8 to UTF16 string.
|
||||
///
|
||||
/// The exact size buffer required for this function can be determined by
|
||||
/// calling this function with the 'dest' set to null and 'dest_size' set to 0,
|
||||
/// the return size is the size required for conversion not-including space for
|
||||
/// the null-terminator. This function *always* null-terminates the input
|
||||
/// buffer.
|
||||
///
|
||||
/// @return The number of u16's written/required for conversion. 0 if there was
|
||||
/// a conversion error and can be queried using 'Dqn_Win_LastError'
|
||||
DQN_API int Dqn_Win_CString8ToCString16(const char *src, int src_size, wchar_t *dest, int dest_size);
|
||||
DQN_API int Dqn_Win_String8ToCString16(Dqn_String8 src, wchar_t *dest, int dest_size);
|
||||
DQN_API Dqn_String16 Dqn_Win_String8ToString16Allocator(Dqn_String8 src, Dqn_Allocator allocator);
|
||||
DQN_API int Dqn_Win_CString8ToCString16 (char const *src, int src_size, wchar_t *dest, int dest_size);
|
||||
DQN_API int Dqn_Win_String8ToCString16 (Dqn_String8 src, wchar_t *dest, int dest_size);
|
||||
DQN_API Dqn_String16 Dqn_Win_String8ToString16Allocator (Dqn_String8 src, Dqn_Allocator allocator);
|
||||
|
||||
// NOTE: Windows String16 To String8
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Convert a UTF16 to UTF8 string.
|
||||
///
|
||||
/// The exact size buffer required for this function can be determined by
|
||||
/// calling this function with the 'dest' set to null and 'dest_size' set to 0,
|
||||
/// the return size is the size required for conversion not-including space for
|
||||
/// the null-terminator. This function *always* null-terminates the input
|
||||
/// buffer.
|
||||
///
|
||||
/// @return The number of u8's written/required for conversion. 0 if there was
|
||||
/// a conversion error and can be queried using 'Dqn_Win_LastError'
|
||||
DQN_API int Dqn_Win_CString16ToCString8(const wchar_t *src, int src_size, char *dest, int dest_size);
|
||||
DQN_API Dqn_String8 Dqn_Win_CString16ToString8Allocator(const wchar_t *src, int src_size, Dqn_Allocator allocator);
|
||||
DQN_API int Dqn_Win_String16ToCString8(Dqn_String16 src, char *dest, int dest_size);
|
||||
DQN_API Dqn_String8 Dqn_Win_String16ToString8Allocator(Dqn_String16 src, Dqn_Allocator allocator);
|
||||
DQN_API int Dqn_Win_CString16ToCString8 (wchar_t const *src, int src_size, char *dest, int dest_size);
|
||||
DQN_API Dqn_String8 Dqn_Win_CString16ToString8Allocator(wchar_t const *src, int src_size, Dqn_Allocator allocator);
|
||||
DQN_API int Dqn_Win_String16ToCString8 (Dqn_String16 src, char *dest, int dest_size);
|
||||
DQN_API Dqn_String8 Dqn_Win_String16ToString8Allocator (Dqn_String16 src, Dqn_Allocator allocator);
|
||||
|
||||
// NOTE: Windows Executable Directory
|
||||
// -----------------------------------------------------------------------------
|
||||
/// Evaluate the current executable's directory that is running when this
|
||||
/// function is called.
|
||||
/// @param[out] buffer The buffer to write the executable directory into. Set
|
||||
/// this to null to calculate the required buffer size for the directory.
|
||||
/// @param[in] size The size of the buffer given. Set this to 0 to calculate the
|
||||
/// required buffer size for the directory.
|
||||
/// @return The length of the executable directory string. If this return value
|
||||
/// exceeds the capacity of the 'buffer', the 'buffer' is untouched.
|
||||
DQN_API Dqn_usize Dqn_Win_EXEDirW(wchar_t *buffer, Dqn_usize size);
|
||||
DQN_API Dqn_String16 Dqn_Win_EXEDirWArena(Dqn_Arena *arena);
|
||||
// NOTE: Path navigatoin ===========================================================================
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_Win_EXEDirW, Dqn_Win_EXEDirWArena
|
||||
// @desc Evaluate the current executable's directory that is running when this
|
||||
// function is called.
|
||||
// @param[out] buffer The buffer to write the executable directory into. Set
|
||||
// this to null to calculate the required buffer size for the directory.
|
||||
// @param[in] size The size of the buffer given. Set this to 0 to calculate the
|
||||
// required buffer size for the directory.
|
||||
// @return The length of the executable directory string. If this return value
|
||||
// exceeds the capacity of the 'buffer', the 'buffer' is untouched.
|
||||
|
||||
// @param[in] size (Optional) The size of the current directory string returned
|
||||
// @param[in] suffix (Optional) A suffix to append to the current working directory
|
||||
// @param[in] suffix_size (Optional) The size of the suffix to append
|
||||
DQN_API Dqn_String8 Dqn_Win_WorkingDir(Dqn_Allocator allocator, Dqn_String8 suffix);
|
||||
DQN_API Dqn_String16 Dqn_Win_WorkingDirW(Dqn_Allocator allocator, Dqn_String16 suffix);
|
||||
// @proc Dqn_Win_WorkingDir, Dqn_Win_WorkingDirW
|
||||
// @param[in] suffix (Optional) A suffix to append to the current working directory
|
||||
|
||||
// @proc Dqn_Win_FolderIterate, Dqn_Win_FolderWIterate
|
||||
// @desc Iterate the files in the specified folder at the path
|
||||
#if 0
|
||||
for (Dqn_WinFolderIterator it = {}; Dqn_Win_FolderIterate("C:/your/path/", &it); ) {
|
||||
printf("%.*s\n", DQN_STRING_FMT(it.file_name));
|
||||
}
|
||||
#endif
|
||||
|
||||
struct Dqn_Win_FolderIteratorW
|
||||
{
|
||||
@ -272,11 +302,36 @@ struct Dqn_Win_FolderIterator
|
||||
char file_name_buf[512];
|
||||
};
|
||||
|
||||
DQN_API bool Dqn_Win_FolderIterate(Dqn_String8 path, Dqn_Win_FolderIterator *it);
|
||||
DQN_API bool Dqn_Win_FolderWIterate(Dqn_String16 path, Dqn_Win_FolderIteratorW *it);
|
||||
DQN_API Dqn_usize Dqn_Win_EXEDirW (wchar_t *buffer, Dqn_usize size);
|
||||
DQN_API Dqn_String16 Dqn_Win_EXEDirWArena (Dqn_Arena *arena);
|
||||
DQN_API Dqn_String8 Dqn_Win_WorkingDir (Dqn_Allocator allocator, Dqn_String8 suffix);
|
||||
DQN_API Dqn_String16 Dqn_Win_WorkingDirW (Dqn_Allocator allocator, Dqn_String16 suffix);
|
||||
DQN_API bool Dqn_Win_FolderIterate (Dqn_String8 path, Dqn_Win_FolderIterator *it);
|
||||
DQN_API bool Dqn_Win_FolderWIterate(Dqn_String16 path, Dqn_Win_FolderIteratorW *it);
|
||||
|
||||
#if !defined(DQN_NO_WINNET)
|
||||
// NOTE: [$WINN] Dqn_WinNet ========================================================================
|
||||
// TODO(dqn): Useful options to expose in the handle
|
||||
// https://docs.microsoft.com/en-us/windows/win32/wininet/option-flags
|
||||
// INTERNET_OPTION_CONNECT_RETRIES -- default is 5 retries
|
||||
// INTERNET_OPTION_CONNECT_TIMEOUT -- milliseconds
|
||||
// INTERNET_OPTION_RECEIVE_TIMEOUT
|
||||
// INTERNET_OPTION_SEND_TIMEOUT
|
||||
//
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_Win_NetHandleInitHTTPMethod, Dqn_Win_NetHandleInitHTTPMethodCString
|
||||
// @desc Setup a handle to the URL with the given HTTP verb.
|
||||
//
|
||||
// This function is the same as calling Dqn_Win_NetHandleInit() followed by
|
||||
// Dqn_Win_NetHandleSetHTTPMethod().
|
||||
//
|
||||
// @param http_method The HTTP request type, e.g. "GET" or "POST" e.t.c
|
||||
|
||||
// @proc Dqn_Win_NetHandleSetHTTPMethod
|
||||
// @desc Set the HTTP request method for the given handle. This function can
|
||||
// be used on a pre-existing valid handle that has at the minimum been
|
||||
// initialised.
|
||||
|
||||
enum Dqn_WinNetHandleState
|
||||
{
|
||||
Dqn_WinNetHandleState_Invalid,
|
||||
@ -324,34 +379,6 @@ struct Dqn_WinNetHandle
|
||||
Dqn_WinNetHandleState state;
|
||||
};
|
||||
|
||||
// TODO(dqn): Useful options to expose in the handle
|
||||
// https://docs.microsoft.com/en-us/windows/win32/wininet/option-flags
|
||||
// INTERNET_OPTION_CONNECT_RETRIES -- default is 5 retries
|
||||
// INTERNET_OPTION_CONNECT_TIMEOUT -- milliseconds
|
||||
// INTERNET_OPTION_RECEIVE_TIMEOUT
|
||||
// INTERNET_OPTION_SEND_TIMEOUT
|
||||
|
||||
// Setup a handle to the URL with the given HTTP verb.
|
||||
DQN_API Dqn_WinNetHandle Dqn_Win_NetHandleInitCString(char const *url, int url_size);
|
||||
DQN_API Dqn_WinNetHandle Dqn_Win_NetHandleInit(Dqn_String8 url);
|
||||
|
||||
// Setup a handle to the URL with the given HTTP verb.
|
||||
//
|
||||
// This function is the same as calling Dqn_Win_NetHandleInit() followed by
|
||||
// Dqn_Win_NetHandleSetHTTPMethod().
|
||||
//
|
||||
// @param http_method The HTTP request type, e.g. "GET" or "POST" e.t.c
|
||||
DQN_API Dqn_WinNetHandle Dqn_Win_NetHandleInitHTTPMethodCString(char const *url, int url_size, char const *http_method);
|
||||
DQN_API Dqn_WinNetHandle Dqn_Win_NetHandleInitHTTPMethod(Dqn_String8 url, Dqn_String8 http_method);
|
||||
|
||||
DQN_API void Dqn_Win_NetHandleClose(Dqn_WinNetHandle *handle);
|
||||
DQN_API bool Dqn_Win_NetHandleIsValid(Dqn_WinNetHandle const *handle);
|
||||
DQN_API void Dqn_Win_NetHandleSetUserAgentCString(Dqn_WinNetHandle *handle, char const *user_agent, int user_agent_size);
|
||||
|
||||
// Set the HTTP request method for the given handle. This function can be used
|
||||
// on a pre-existing valid handle that has at the minimum been initialised.
|
||||
DQN_API bool Dqn_Win_NetHandleSetHTTPMethod(Dqn_WinNetHandle *handle, char const *method);
|
||||
|
||||
enum Dqn_WinNetHandleRequestHeaderFlag
|
||||
{
|
||||
Dqn_WinNetHandleRequestHeaderFlag_Add,
|
||||
@ -360,9 +387,6 @@ enum Dqn_WinNetHandleRequestHeaderFlag
|
||||
Dqn_WinNetHandleRequestHeaderFlag_Count,
|
||||
};
|
||||
|
||||
DQN_API bool Dqn_Win_NetHandleSetRequestHeaderCString8(Dqn_WinNetHandle *handle, char const *header, int header_size, uint32_t mode);
|
||||
DQN_API bool Dqn_Win_NetHandleSetRequestHeaderString8(Dqn_WinNetHandle *handle, Dqn_String8 header, uint32_t mode);
|
||||
|
||||
struct Dqn_WinNetHandleResponse
|
||||
{
|
||||
Dqn_String8 raw_headers;
|
||||
@ -373,33 +397,35 @@ struct Dqn_WinNetHandleResponse
|
||||
uint64_t content_length;
|
||||
Dqn_String8 content_type;
|
||||
};
|
||||
DQN_API Dqn_WinNetHandleResponse Dqn_Win_NetHandleSendRequest(Dqn_WinNetHandle *handle, Dqn_Allocator allocator, char const *post_data, unsigned long post_data_size);
|
||||
|
||||
DQN_API bool Dqn_Win_NetHandlePump(Dqn_WinNetHandle *handle, char *dest, int dest_size, size_t *download_size);
|
||||
DQN_API char * Dqn_Win_NetHandlePumpCString8(Dqn_WinNetHandle *handle, Dqn_Arena *arena, size_t *download_size);
|
||||
DQN_API Dqn_String8 Dqn_Win_NetHandlePumpString8(Dqn_WinNetHandle *handle, Dqn_Arena *arena);
|
||||
|
||||
DQN_API void Dqn_Win_NetHandlePumpToCRTFile(Dqn_WinNetHandle *handle, FILE *file);
|
||||
DQN_API char *Dqn_Win_NetHandlePumpToAllocCString(Dqn_WinNetHandle *handle, size_t *download_size);
|
||||
DQN_API Dqn_String8 Dqn_Win_NetHandlePumpToAllocString(Dqn_WinNetHandle *handle);
|
||||
DQN_API Dqn_WinNetHandle Dqn_Win_NetHandleInitCString (char const *url, int url_size);
|
||||
DQN_API Dqn_WinNetHandle Dqn_Win_NetHandleInit (Dqn_String8 url);
|
||||
DQN_API Dqn_WinNetHandle Dqn_Win_NetHandleInitHTTPMethodCString (char const *url, int url_size, char const *http_method);
|
||||
DQN_API Dqn_WinNetHandle Dqn_Win_NetHandleInitHTTPMethod (Dqn_String8 url, Dqn_String8 http_method);
|
||||
DQN_API void Dqn_Win_NetHandleClose (Dqn_WinNetHandle *handle);
|
||||
DQN_API bool Dqn_Win_NetHandleIsValid (Dqn_WinNetHandle const *handle);
|
||||
DQN_API void Dqn_Win_NetHandleSetUserAgentCString (Dqn_WinNetHandle *handle, char const *user_agent, int user_agent_size);
|
||||
DQN_API bool Dqn_Win_NetHandleSetHTTPMethod (Dqn_WinNetHandle *handle, char const *method);
|
||||
DQN_API bool Dqn_Win_NetHandleSetRequestHeaderCString8(Dqn_WinNetHandle *handle, char const *header, int header_size, uint32_t mode);
|
||||
DQN_API bool Dqn_Win_NetHandleSetRequestHeaderString8 (Dqn_WinNetHandle *handle, Dqn_String8 header, uint32_t mode);
|
||||
DQN_API Dqn_WinNetHandleResponse Dqn_Win_NetHandleSendRequest (Dqn_WinNetHandle *handle, Dqn_Allocator allocator, char const *post_data, unsigned long post_data_size);
|
||||
DQN_API bool Dqn_Win_NetHandlePump (Dqn_WinNetHandle *handle, char *dest, int dest_size, size_t *download_size);
|
||||
DQN_API char * Dqn_Win_NetHandlePumpCString8 (Dqn_WinNetHandle *handle, Dqn_Arena *arena, size_t *download_size);
|
||||
DQN_API Dqn_String8 Dqn_Win_NetHandlePumpString8 (Dqn_WinNetHandle *handle, Dqn_Arena *arena);
|
||||
DQN_API void Dqn_Win_NetHandlePumpToCRTFile (Dqn_WinNetHandle *handle, FILE *file);
|
||||
DQN_API char * Dqn_Win_NetHandlePumpToAllocCString (Dqn_WinNetHandle *handle, size_t *download_size);
|
||||
DQN_API Dqn_String8 Dqn_Win_NetHandlePumpToAllocString (Dqn_WinNetHandle *handle);
|
||||
#endif // !defined(DQN_NO_WINNET)
|
||||
#endif // defined(DQN_OS_WIN32)
|
||||
|
||||
// NOTE: [$OSYS] Dqn_OS ============================================================================
|
||||
/// Generate cryptographically secure bytes
|
||||
DQN_API bool Dqn_OS_SecureRNGBytes(void *buffer, uint32_t size);
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_OS_SecureRNGBytes
|
||||
// @desc Generate cryptographically secure bytes
|
||||
|
||||
// return: The directory without the trailing '/' or ('\' for windows). Empty
|
||||
// string with a nullptr if it fails.
|
||||
DQN_API Dqn_String8 Dqn_OS_EXEDir(Dqn_Allocator allocator);
|
||||
|
||||
DQN_API void Dqn_OS_SleepMs(Dqn_uint milliseconds);
|
||||
|
||||
DQN_API uint64_t Dqn_OS_PerfCounterNow ();
|
||||
DQN_API Dqn_f64 Dqn_OS_PerfCounterS (uint64_t begin, uint64_t end);
|
||||
DQN_API Dqn_f64 Dqn_OS_PerfCounterMs (uint64_t begin, uint64_t end);
|
||||
DQN_API Dqn_f64 Dqn_OS_PerfCounterMicroS(uint64_t begin, uint64_t end);
|
||||
DQN_API Dqn_f64 Dqn_OS_PerfCounterNs (uint64_t begin, uint64_t end);
|
||||
// @proc Dqn_OS_EXEDir
|
||||
// @desc Retrieve the executable directory without the trailing '/' or
|
||||
// ('\' for windows). If this fails an empty string is returned.
|
||||
|
||||
/// Record time between two time-points using the OS's performance counter.
|
||||
struct Dqn_OSTimer
|
||||
@ -408,12 +434,20 @@ struct Dqn_OSTimer
|
||||
uint64_t end;
|
||||
};
|
||||
|
||||
DQN_API Dqn_OSTimer Dqn_OS_TimerBegin();
|
||||
DQN_API void Dqn_OS_TimerEnd (Dqn_OSTimer *timer);
|
||||
DQN_API Dqn_f64 Dqn_OS_TimerS (Dqn_OSTimer timer);
|
||||
DQN_API Dqn_f64 Dqn_OS_TimerMs (Dqn_OSTimer timer);
|
||||
DQN_API Dqn_f64 Dqn_OS_TimerMicroS (Dqn_OSTimer timer);
|
||||
DQN_API Dqn_f64 Dqn_OS_TimerNs (Dqn_OSTimer timer);
|
||||
DQN_API bool Dqn_OS_SecureRNGBytes (void *buffer, uint32_t size);
|
||||
DQN_API Dqn_String8 Dqn_OS_EXEDir (Dqn_Allocator allocator);
|
||||
DQN_API void Dqn_OS_SleepMs (Dqn_uint milliseconds);
|
||||
DQN_API uint64_t Dqn_OS_PerfCounterNow ();
|
||||
DQN_API Dqn_f64 Dqn_OS_PerfCounterS (uint64_t begin, uint64_t end);
|
||||
DQN_API Dqn_f64 Dqn_OS_PerfCounterMs (uint64_t begin, uint64_t end);
|
||||
DQN_API Dqn_f64 Dqn_OS_PerfCounterMicroS(uint64_t begin, uint64_t end);
|
||||
DQN_API Dqn_f64 Dqn_OS_PerfCounterNs (uint64_t begin, uint64_t end);
|
||||
DQN_API Dqn_OSTimer Dqn_OS_TimerBegin ();
|
||||
DQN_API void Dqn_OS_TimerEnd (Dqn_OSTimer *timer);
|
||||
DQN_API Dqn_f64 Dqn_OS_TimerS (Dqn_OSTimer timer);
|
||||
DQN_API Dqn_f64 Dqn_OS_TimerMs (Dqn_OSTimer timer);
|
||||
DQN_API Dqn_f64 Dqn_OS_TimerMicroS (Dqn_OSTimer timer);
|
||||
DQN_API Dqn_f64 Dqn_OS_TimerNs (Dqn_OSTimer timer);
|
||||
|
||||
// OS_TimedBlock provides a extremely primitive way of measuring the duration of
|
||||
// code blocks, by sprinkling DQN_OS_TIMED_BLOCK_RECORD("record label"), you can
|
||||
|
@ -589,7 +589,7 @@ DQN_API Dqn_String8 Dqn_String8_Copy_(DQN_LEAK_TRACE_FUNCTION Dqn_Allocator allo
|
||||
}
|
||||
|
||||
// NOTE: [$STRB] Dqn_String8Builder ================================================================
|
||||
bool Dqn_String8Builder_AppendRef(Dqn_String8Builder *builder, Dqn_String8 string)
|
||||
DQN_API bool Dqn_String8Builder_AppendRef(Dqn_String8Builder *builder, Dqn_String8 string)
|
||||
{
|
||||
if (!builder || !string.data || string.size <= 0)
|
||||
return false;
|
||||
@ -612,14 +612,14 @@ bool Dqn_String8Builder_AppendRef(Dqn_String8Builder *builder, Dqn_String8 strin
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Dqn_String8Builder_AppendCopy(Dqn_String8Builder *builder, Dqn_String8 string)
|
||||
DQN_API bool Dqn_String8Builder_AppendCopy(Dqn_String8Builder *builder, Dqn_String8 string)
|
||||
{
|
||||
Dqn_String8 copy = Dqn_String8_Copy(builder->allocator, string);
|
||||
bool result = Dqn_String8Builder_AppendRef(builder, copy);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Dqn_String8Builder_AppendFV_(DQN_LEAK_TRACE_FUNCTION Dqn_String8Builder *builder, char const *fmt, va_list args)
|
||||
DQN_API bool Dqn_String8Builder_AppendFV_(DQN_LEAK_TRACE_FUNCTION Dqn_String8Builder *builder, char const *fmt, va_list args)
|
||||
{
|
||||
Dqn_String8 string = Dqn_String8_InitFV(builder->allocator, fmt, args);
|
||||
if (string.size == 0)
|
||||
@ -631,7 +631,7 @@ bool Dqn_String8Builder_AppendFV_(DQN_LEAK_TRACE_FUNCTION Dqn_String8Builder *bu
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Dqn_String8Builder_AppendF(Dqn_String8Builder *builder, char const *fmt, ...)
|
||||
DQN_API bool Dqn_String8Builder_AppendF(Dqn_String8Builder *builder, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
@ -640,7 +640,7 @@ bool Dqn_String8Builder_AppendF(Dqn_String8Builder *builder, char const *fmt, ..
|
||||
return result;
|
||||
}
|
||||
|
||||
Dqn_String8 Dqn_String8Builder_Build(Dqn_String8Builder const *builder, Dqn_Allocator allocator)
|
||||
DQN_API Dqn_String8 Dqn_String8Builder_Build(Dqn_String8Builder const *builder, Dqn_Allocator allocator)
|
||||
{
|
||||
Dqn_String8 result = DQN_ZERO_INIT;
|
||||
if (!builder || builder->string_size <= 0 || builder->count <= 0)
|
||||
@ -662,7 +662,7 @@ Dqn_String8 Dqn_String8Builder_Build(Dqn_String8Builder const *builder, Dqn_Allo
|
||||
|
||||
#if !defined(DQN_NO_JSON_BUILDER)
|
||||
// NOTE: [$JSON] Dqn_JSONBuilder ===================================================================
|
||||
Dqn_JSONBuilder Dqn_JSONBuilder_Init(Dqn_Allocator allocator, int spaces_per_indent)
|
||||
DQN_API Dqn_JSONBuilder Dqn_JSONBuilder_Init(Dqn_Allocator allocator, int spaces_per_indent)
|
||||
{
|
||||
Dqn_JSONBuilder result = {};
|
||||
result.spaces_per_indent = spaces_per_indent;
|
||||
@ -670,13 +670,13 @@ Dqn_JSONBuilder Dqn_JSONBuilder_Init(Dqn_Allocator allocator, int spaces_per_ind
|
||||
return result;
|
||||
}
|
||||
|
||||
Dqn_String8 Dqn_JSONBuilder_Build(Dqn_JSONBuilder const *builder, Dqn_Allocator allocator)
|
||||
DQN_API Dqn_String8 Dqn_JSONBuilder_Build(Dqn_JSONBuilder const *builder, Dqn_Allocator allocator)
|
||||
{
|
||||
Dqn_String8 result = Dqn_String8Builder_Build(&builder->string_builder, allocator);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_KeyValue(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value)
|
||||
DQN_API void Dqn_JSONBuilder_KeyValue(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value)
|
||||
{
|
||||
if (key.size == 0 && value.size == 0)
|
||||
return;
|
||||
@ -729,14 +729,14 @@ void Dqn_JSONBuilder_KeyValue(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_Str
|
||||
builder->last_item = item;
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_KeyValueFV(Dqn_JSONBuilder *builder, Dqn_String8 key, char const *value_fmt, va_list args)
|
||||
DQN_API void Dqn_JSONBuilder_KeyValueFV(Dqn_JSONBuilder *builder, Dqn_String8 key, char const *value_fmt, va_list args)
|
||||
{
|
||||
Dqn_ThreadScratch scratch = Dqn_Thread_GetScratch(builder->string_builder.allocator.user_context);
|
||||
Dqn_String8 value = Dqn_String8_InitFV(scratch.allocator, value_fmt, args);
|
||||
Dqn_JSONBuilder_KeyValue(builder, key, value);
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_KeyValueF(Dqn_JSONBuilder *builder, Dqn_String8 key, char const *value_fmt, ...)
|
||||
DQN_API void Dqn_JSONBuilder_KeyValueF(Dqn_JSONBuilder *builder, Dqn_String8 key, char const *value_fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, value_fmt);
|
||||
@ -744,47 +744,47 @@ void Dqn_JSONBuilder_KeyValueF(Dqn_JSONBuilder *builder, Dqn_String8 key, char c
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_ObjectBeginNamed(Dqn_JSONBuilder *builder, Dqn_String8 name)
|
||||
DQN_API void Dqn_JSONBuilder_ObjectBeginNamed(Dqn_JSONBuilder *builder, Dqn_String8 name)
|
||||
{
|
||||
Dqn_JSONBuilder_KeyValue(builder, name, DQN_STRING8("{"));
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_ObjectEnd(Dqn_JSONBuilder *builder)
|
||||
DQN_API void Dqn_JSONBuilder_ObjectEnd(Dqn_JSONBuilder *builder)
|
||||
{
|
||||
Dqn_JSONBuilder_KeyValue(builder, DQN_STRING8(""), DQN_STRING8("}"));
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_ArrayBeginNamed(Dqn_JSONBuilder *builder, Dqn_String8 name)
|
||||
DQN_API void Dqn_JSONBuilder_ArrayBeginNamed(Dqn_JSONBuilder *builder, Dqn_String8 name)
|
||||
{
|
||||
Dqn_JSONBuilder_KeyValue(builder, name, DQN_STRING8("["));
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_ArrayEnd(Dqn_JSONBuilder *builder)
|
||||
DQN_API void Dqn_JSONBuilder_ArrayEnd(Dqn_JSONBuilder *builder)
|
||||
{
|
||||
Dqn_JSONBuilder_KeyValue(builder, DQN_STRING8(""), DQN_STRING8("]"));
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_StringNamed(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value)
|
||||
DQN_API void Dqn_JSONBuilder_StringNamed(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value)
|
||||
{
|
||||
Dqn_JSONBuilder_KeyValueF(builder, key, "\"%.*s\"", value.size, value.data);
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_LiteralNamed(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value)
|
||||
DQN_API void Dqn_JSONBuilder_LiteralNamed(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value)
|
||||
{
|
||||
Dqn_JSONBuilder_KeyValueF(builder, key, "%.*s", value.size, value.data);
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_U64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, uint64_t value)
|
||||
DQN_API void Dqn_JSONBuilder_U64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, uint64_t value)
|
||||
{
|
||||
Dqn_JSONBuilder_KeyValueF(builder, key, "%I64u", value);
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_I64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, int64_t value)
|
||||
DQN_API void Dqn_JSONBuilder_I64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, int64_t value)
|
||||
{
|
||||
Dqn_JSONBuilder_KeyValueF(builder, key, "%I64d", value);
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_F64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, double value, int decimal_places)
|
||||
DQN_API void Dqn_JSONBuilder_F64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, double value, int decimal_places)
|
||||
{
|
||||
if (!builder)
|
||||
return;
|
||||
@ -797,22 +797,22 @@ void Dqn_JSONBuilder_F64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, double
|
||||
char float_fmt[16];
|
||||
if (decimal_places > 0) {
|
||||
// NOTE: Emit the format string "%.<decimal_places>f" i.e. %.1f
|
||||
snprintf(float_fmt, sizeof(float_fmt), "%%.%df", decimal_places);
|
||||
STB_SPRINTF_DECORATE(snprintf)(float_fmt, sizeof(float_fmt), "%%.%df", decimal_places);
|
||||
} else {
|
||||
// NOTE: Emit the format string "%f"
|
||||
snprintf(float_fmt, sizeof(float_fmt), "%%f");
|
||||
STB_SPRINTF_DECORATE(snprintf)(float_fmt, sizeof(float_fmt), "%%f");
|
||||
}
|
||||
|
||||
char fmt[32];
|
||||
if (key.size)
|
||||
snprintf(fmt, sizeof(fmt), "\"%%.*s\": %s", float_fmt);
|
||||
STB_SPRINTF_DECORATE(snprintf)(fmt, sizeof(fmt), "\"%%.*s\": %s", float_fmt);
|
||||
else
|
||||
snprintf(fmt, sizeof(fmt), "%s", float_fmt);
|
||||
STB_SPRINTF_DECORATE(snprintf)(fmt, sizeof(fmt), "%s", float_fmt);
|
||||
|
||||
Dqn_JSONBuilder_KeyValueF(builder, key, fmt, value);
|
||||
}
|
||||
|
||||
void Dqn_JSONBuilder_BoolNamed(Dqn_JSONBuilder *builder, Dqn_String8 key, bool value)
|
||||
DQN_API void Dqn_JSONBuilder_BoolNamed(Dqn_JSONBuilder *builder, Dqn_String8 key, bool value)
|
||||
{
|
||||
Dqn_String8 value_string = value ? DQN_STRING8("true") : DQN_STRING8("false");
|
||||
Dqn_JSONBuilder_KeyValueF(builder, key, "%.*s", value_string.size, value_string.data);
|
||||
@ -1193,7 +1193,8 @@ DQN_API Dqn_String8 Dqn_Bin_HexToBytesArena(Dqn_Arena *arena, Dqn_String8 hex)
|
||||
}
|
||||
#endif // !defined(DQN_NO_HEX)
|
||||
|
||||
DQN_API int Dqn_SNPrintF2DotsOnOverflow(char *buffer, int size, char const *fmt, ...)
|
||||
// NOTE: Other =====================================================================================
|
||||
DQN_API int Dqn_SNPrintFDotTruncate(char *buffer, int size, char const *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
|
283
dqn_strings.h
283
dqn_strings.h
@ -17,13 +17,13 @@
|
||||
// @desc Calculate the size of a cstring literal/array at compile time
|
||||
// @param literal The cstring literal/array to calculate the size for
|
||||
// @return The size of the cstring not including the null-terminating byte
|
||||
//
|
||||
|
||||
// @proc Dqn_CString8_FSize, Dqn_CString8_FVSize
|
||||
// Calculate the required size to format the given format cstring.
|
||||
// @param[in] fmt The format string to calculate the size for
|
||||
// @return The size required to format the string, not including the null
|
||||
// terminator.
|
||||
//
|
||||
|
||||
// @proc Dqn_CString8_Size
|
||||
// @desc Calculate the string length of the null-terminated string.
|
||||
// @param[in] a The string whose length is to be determined
|
||||
@ -369,32 +369,31 @@ DQN_API Dqn_String8 Dqn_String8_Copy_ (DQN_LEAK_TRACE_FUNCTION Dq
|
||||
|
||||
#if !defined(DQN_NO_FSTRING8)
|
||||
// NOTE: [$FSTR] Dqn_FString8 ======================================================================
|
||||
// NOTE: API
|
||||
//
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_FString8_InitF
|
||||
// @desc Create a fixed string from the format string. The result string is
|
||||
// null-terminated.
|
||||
// @param fmt[in] Format string specifier to create the fixed string from
|
||||
// @return The created string, truncated if there was insufficient space
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_Max
|
||||
// @desc @param string[in] The string to query the maximum capacity of
|
||||
// @return Maximum capacity of the fixed string
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_Clear
|
||||
// @desc Reset the characters in the string
|
||||
// @param string[in] The string to clear
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_AppendFV
|
||||
// @desc Append a format string to the fixed string. On failure the string is
|
||||
// appended to but truncated ensuring null-termination.
|
||||
// @param string[in] The string to append to
|
||||
// @param fmt[in] Format string to append to the fixed string
|
||||
// @return True if append was successful, false otherwise.
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_AppendF
|
||||
// @desc @copydocs Dqn_FString8_AppendF
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_AppendCString8
|
||||
// @desc Append a cstring to the fixed string. On failure the string is
|
||||
// appended to but truncated ensuring null-termination.
|
||||
@ -402,7 +401,7 @@ DQN_API Dqn_String8 Dqn_String8_Copy_ (DQN_LEAK_TRACE_FUNCTION Dq
|
||||
// @param value[in] Cstring to append to the fixed string
|
||||
// @param size[in] Size of the cstring
|
||||
// @return True if append was successful, false otherwise.
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_Append
|
||||
// @desc Append a string to the fixed string. On failure the string is
|
||||
// appended to but truncated ensuring null-termination.
|
||||
@ -410,23 +409,23 @@ DQN_API Dqn_String8 Dqn_String8_Copy_ (DQN_LEAK_TRACE_FUNCTION Dq
|
||||
// @param value[in] String to append to the fixed string
|
||||
// determined before appending.
|
||||
// @return True if append was successful, false otherwise.
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_ToString8
|
||||
// @desc Convert a fixed string to a string. The string holds a reference to the
|
||||
// fixed string and is invalidated once fixed string is deleted.
|
||||
// @param string[in] The fixed string to create a string from
|
||||
// @return String referencing the contents of `string`
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_Eq
|
||||
// @desc @see Dqn_String8_Eq
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_EqString8
|
||||
// @desc @see Dqn_String8_Eq
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_EqInsensitive
|
||||
// @desc Compare a string for equality, case insensitive
|
||||
// @see Dqn_String8_Eq
|
||||
//
|
||||
|
||||
// @proc Dqn_FString8_EqString8Insensitive
|
||||
// @desc Compare a string for equality, case insensitive
|
||||
// @see Dqn_String8_Eq
|
||||
@ -467,6 +466,31 @@ template <Dqn_usize A, Dqn_usize B> bool Dqn_FString8_EqFString8Insen
|
||||
#endif // !defined(DQN_NO_FSTRING8)
|
||||
|
||||
// NOTE: [$STRB] Dqn_String8Builder ================================================================
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_String8Builder_AppendRef, Dqn_String8_AppendCopy,
|
||||
// Dqn_String8_AppendFV, Dqn_String8_AppendF
|
||||
// @desc Append a string to the list of strings in the builder.
|
||||
//
|
||||
// The string is appended to the builder as follows
|
||||
// - AppendRef: By reference
|
||||
// - AppendCopy: By copy using the builder's allocator to copy the string
|
||||
// - AppendFV, AppendF: Using a format string, allocated using the builder's
|
||||
// allocator
|
||||
//
|
||||
// The string's data must persist whilst the string builder is being used.
|
||||
// @param builder The builder to append the string to
|
||||
// @param string The string to append to the builder
|
||||
// @return True if append was successful, false if parameters are invalid
|
||||
// or memory allocation failure.
|
||||
|
||||
// @proc Dqn_String8Builder_Build
|
||||
// @desc Build the list of strings into the final composite string from the
|
||||
// string builder
|
||||
// @param builder The string builder to build the string from
|
||||
// @param allocator The allocator to use to build the string
|
||||
// @return The string if build was successful, empty string if parameters are
|
||||
// invalid or memory allocation failure.
|
||||
|
||||
struct Dqn_String8Builder
|
||||
{
|
||||
Dqn_Allocator allocator; ///< Allocator to use to back the string list
|
||||
@ -476,45 +500,50 @@ struct Dqn_String8Builder
|
||||
Dqn_usize count; ///< The number of links in the linked list of strings
|
||||
};
|
||||
|
||||
/// Append a string to the list of strings in the builder by reference.
|
||||
/// The string's data must persist whilst the string builder is being used.
|
||||
/// @param builder The builder to append the string to
|
||||
/// @param string The string to append to the builder
|
||||
/// @return True if append was successful, false if parameters are invalid
|
||||
/// or memory allocation failure.
|
||||
bool Dqn_String8Builder_AppendRef(Dqn_String8Builder *builder, Dqn_String8 string);
|
||||
#define Dqn_String8Builder_AppendFV(builder, fmt, args) Dqn_String8Builder_AppendFV_(DQN_LEAK_TRACE builder, fmt, args)
|
||||
DQN_API bool Dqn_String8Builder_AppendF (Dqn_String8Builder *builder, char const *fmt, ...);
|
||||
DQN_API bool Dqn_String8Builder_AppendRef (Dqn_String8Builder *builder, Dqn_String8 string);
|
||||
DQN_API bool Dqn_String8Builder_AppendCopy(Dqn_String8Builder *builder, Dqn_String8 string);
|
||||
DQN_API Dqn_String8 Dqn_String8Builder_Build (Dqn_String8Builder const *builder, Dqn_Allocator allocator);
|
||||
|
||||
/// Append a string to the list of strings in the builder by copy.
|
||||
/// The string is copied using the builder's allocator before appending.
|
||||
/// @param builder The builder to append the string to
|
||||
/// @param string The string to append to the builder
|
||||
/// @return True if append was successful, false if parameters are invalid
|
||||
/// or memory allocation failure.
|
||||
bool Dqn_String8Builder_AppendCopy(Dqn_String8Builder *builder, Dqn_String8 string);
|
||||
|
||||
/// @copydoc Dqn_String8Builder_AppendF
|
||||
/// @param args The variable argument list to use in the format string
|
||||
#define Dqn_String8Builder_AppendFV(builder, fmt, args) Dqn_String8Builder_AppendFV_(DQN_LEAK_TRACE builder, fmt, args)
|
||||
bool Dqn_String8Builder_AppendFV_(DQN_LEAK_TRACE_FUNCTION Dqn_String8Builder *builder, char const *fmt, va_list args);
|
||||
|
||||
/// Append a printf-style format string to the list of strings in the builder.
|
||||
/// @param builder The builder to append the string to
|
||||
/// @param fmt The format string to use
|
||||
/// @return True if append was successful, false if parameters are invalid
|
||||
/// or memory allocation failure.
|
||||
bool Dqn_String8Builder_AppendF(Dqn_String8Builder *builder, char const *fmt, ...);
|
||||
|
||||
/// Build the list of strings into the final composite string from the string
|
||||
/// builder
|
||||
/// @param builder The string builder to build the string from
|
||||
/// @param allocator The allocator to use to build the string
|
||||
/// @return The string if build was successful, empty string if parameters are
|
||||
/// invalid or memory allocation failure.
|
||||
Dqn_String8 Dqn_String8Builder_Build(Dqn_String8Builder const *builder, Dqn_Allocator allocator);
|
||||
// NOTE: Internal ==================================================================================
|
||||
DQN_API bool Dqn_String8Builder_AppendFV_ (DQN_LEAK_TRACE_FUNCTION Dqn_String8Builder *builder, char const *fmt, va_list args);
|
||||
|
||||
#if !defined(DQN_NO_JSON_BUILDER)
|
||||
// NOTE: [$JSON] Dqn_JSONBuilder ===================================================================
|
||||
// Basic helper class to construct JSON output to a string
|
||||
// TODO(dqn): We need to write tests for this
|
||||
//
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_JSONBuilder_Build
|
||||
// @desc Convert the internal JSON buffer in the builder into a string.
|
||||
// @param[in] arena The allocator to use to build the string
|
||||
|
||||
// @proc Dqn_JSONBuilder_KeyValue, Dqn_JSONBuilder_KeyValueF
|
||||
// @desc Add a JSON key value pair untyped. The value is emitted directly
|
||||
// without checking the contents of value.
|
||||
//
|
||||
// All other functions internally call into this function which is the main
|
||||
// workhorse of the builder.
|
||||
|
||||
// @proc Dqn_JSON_Builder_ObjectEnd
|
||||
// @desc End a JSON object in the builder, generates internally a '}' string
|
||||
|
||||
// @proc Dqn_JSON_Builder_ArrayEnd
|
||||
// @desc End a JSON array in the builder, generates internally a ']' string
|
||||
|
||||
// @proc Dqn_JSONBuilder_LiteralNamed
|
||||
// @desc Add a named JSON key-value object whose value is directly written to
|
||||
// the following '"<key>": <value>' (e.g. useful for emitting the 'null'
|
||||
// value)
|
||||
|
||||
// @proc Dqn_JSONBuilder_U64Named, Dqn_JSONBuilder_U64,
|
||||
// Dqn_JSONBuilder_I64Named, Dqn_JSONBuilder_I64,
|
||||
// Dqn_JSONBuilder_F64Named, Dqn_JSONBuilder_F64,
|
||||
// Dqn_JSONBuilder_BoolNamed, Dqn_JSONBuilder_Bool,
|
||||
// @desc Add the named JSON data type as a key-value object. Generates
|
||||
// internally the string '"<key>": <value>'
|
||||
|
||||
enum Dqn_JSONBuilderItem {
|
||||
Dqn_JSONBuilderItem_Empty,
|
||||
Dqn_JSONBuilderItem_OpenContainer,
|
||||
@ -522,7 +551,6 @@ enum Dqn_JSONBuilderItem {
|
||||
Dqn_JSONBuilderItem_KeyValue,
|
||||
};
|
||||
|
||||
/// Basic helper class to construct JSON string output
|
||||
struct Dqn_JSONBuilder {
|
||||
bool use_stdout; ///< When set, ignore the string builder and dump immediately to stdout
|
||||
Dqn_String8Builder string_builder; ///< (Internal)
|
||||
@ -548,82 +576,29 @@ struct Dqn_JSONBuilder {
|
||||
Dqn_JSONBuilder_ArrayEnd(builder))
|
||||
|
||||
|
||||
/// Initialise a JSON builder
|
||||
Dqn_JSONBuilder Dqn_JSONBuilder_Init(Dqn_Allocator allocator, int spaces_per_indent);
|
||||
DQN_API Dqn_JSONBuilder Dqn_JSONBuilder_Init (Dqn_Allocator allocator, int spaces_per_indent);
|
||||
DQN_API Dqn_String8 Dqn_JSONBuilder_Build (Dqn_JSONBuilder const *builder, Dqn_Allocator allocator);
|
||||
DQN_API void Dqn_JSONBuilder_KeyValue (Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value);
|
||||
DQN_API void Dqn_JSONBuilder_KeyValueF (Dqn_JSONBuilder *builder, Dqn_String8 key, char const *value_fmt, ...);
|
||||
DQN_API void Dqn_JSONBuilder_ObjectBeginNamed(Dqn_JSONBuilder *builder, Dqn_String8 name);
|
||||
DQN_API void Dqn_JSONBuilder_ObjectEnd (Dqn_JSONBuilder *builder);
|
||||
DQN_API void Dqn_JSONBuilder_ArrayBeginNamed (Dqn_JSONBuilder *builder, Dqn_String8 name);
|
||||
DQN_API void Dqn_JSONBuilder_ArrayEnd (Dqn_JSONBuilder *builder);
|
||||
DQN_API void Dqn_JSONBuilder_StringNamed (Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value);
|
||||
DQN_API void Dqn_JSONBuilder_LiteralNamed (Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value);
|
||||
DQN_API void Dqn_JSONBuilder_U64Named (Dqn_JSONBuilder *builder, Dqn_String8 key, uint64_t value);
|
||||
DQN_API void Dqn_JSONBuilder_I64Named (Dqn_JSONBuilder *builder, Dqn_String8 key, int64_t value);
|
||||
DQN_API void Dqn_JSONBuilder_F64Named (Dqn_JSONBuilder *builder, Dqn_String8 key, double value, int decimal_places);
|
||||
DQN_API void Dqn_JSONBuilder_BoolNamed (Dqn_JSONBuilder *builder, Dqn_String8 key, bool value);
|
||||
|
||||
/// Convert the internal JSON buffer in the builder into a string.
|
||||
///
|
||||
/// @param[in] arena The allocator to use to build the string
|
||||
Dqn_String8 Dqn_JSONBuilder_Build(Dqn_JSONBuilder const *builder, Dqn_Allocator allocator);
|
||||
|
||||
/// Add a JSON key value pair untyped. The value is emitted directly without
|
||||
/// checking the contents of value.
|
||||
///
|
||||
/// All other functions internally call into this function which is the main
|
||||
/// workhorse of the builder.
|
||||
void Dqn_JSONBuilder_KeyValue(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value);
|
||||
|
||||
void Dqn_JSONBuilder_KeyValueF(Dqn_JSONBuilder *builder, Dqn_String8 key, char const *value_fmt, ...);
|
||||
|
||||
/// Begin a named JSON object for writing into in the builder
|
||||
///
|
||||
/// Generates internally a string like '"<name>": {'
|
||||
void Dqn_JSONBuilder_ObjectBeginNamed(Dqn_JSONBuilder *builder, Dqn_String8 name);
|
||||
#define Dqn_JSONBuilder_ObjectBegin(builder) Dqn_JSONBuilder_ObjectBeginNamed(builder, DQN_STRING8(""))
|
||||
|
||||
/// End a JSON object for writing into in the builder
|
||||
///
|
||||
/// Generates internally a string like '}'
|
||||
void Dqn_JSONBuilder_ObjectEnd(Dqn_JSONBuilder *builder);
|
||||
|
||||
/// Begin a named JSON array for writing into in the builder
|
||||
///
|
||||
/// Generates internally a string like '"<name>": ['
|
||||
void Dqn_JSONBuilder_ArrayBeginNamed(Dqn_JSONBuilder *builder, Dqn_String8 name);
|
||||
#define Dqn_JSONBuilder_ArrayBegin(builder) Dqn_JSONBuilder_ArrayBeginNamed(builder, DQN_STRING8(""))
|
||||
|
||||
/// Begin a named JSON array for writing into in the builder
|
||||
///
|
||||
/// Generates internally a string like ']'
|
||||
void Dqn_JSONBuilder_ArrayEnd(Dqn_JSONBuilder *builder);
|
||||
|
||||
/// Add a named JSON string key-value object
|
||||
///
|
||||
/// Generates internally a string like '"<key>": "<value>"'
|
||||
void Dqn_JSONBuilder_StringNamed(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value);
|
||||
#define Dqn_JSONBuilder_String(builder, value) Dqn_JSONBuilder_StringNamed(builder, DQN_STRING8(""), value)
|
||||
|
||||
/// Add a named JSON key-value object whose value is directly written
|
||||
///
|
||||
/// Generates internally a string like '"<key>": <value>' (e.g. useful for
|
||||
/// emitting the 'null' value)
|
||||
void Dqn_JSONBuilder_LiteralNamed(Dqn_JSONBuilder *builder, Dqn_String8 key, Dqn_String8 value);
|
||||
#define Dqn_JSONBuilder_Literal(builder, value) Dqn_JSONBuilder_LiteralNamed(builder, DQN_STRING8(""), value)
|
||||
|
||||
/// Add a named JSON u64 key-value object
|
||||
///
|
||||
/// Generates internally a string like '"<key>": <value>'
|
||||
void Dqn_JSONBuilder_U64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, uint64_t value);
|
||||
#define Dqn_JSONBuilder_U64(builder, value) Dqn_JSONBuilder_U64Named(builder, DQN_STRING8(""), value)
|
||||
|
||||
/// Add a JSON i64 key-value object
|
||||
///
|
||||
/// Generates internally a string like '"<key>": <value>'
|
||||
void Dqn_JSONBuilder_I64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, int64_t value);
|
||||
#define Dqn_JSONBuilder_I64(builder, value) Dqn_JSONBuilder_I64Named(builder, DQN_STRING8(""), value)
|
||||
|
||||
/// Add a JSON f64 key-value object
|
||||
///
|
||||
/// Generates internally a string like '"<key>": <value>'
|
||||
/// @param[in] decimal_places The number of decimal places to preserve. Maximum 16
|
||||
void Dqn_JSONBuilder_F64Named(Dqn_JSONBuilder *builder, Dqn_String8 key, double value, int decimal_places);
|
||||
#define Dqn_JSONBuilder_F64(builder, value) Dqn_JSONBuilder_F64Named(builder, DQN_STRING8(""), value)
|
||||
|
||||
/// Add a JSON bool key-value object
|
||||
///
|
||||
/// Generates internally a string like '"<key>": <value>'
|
||||
void Dqn_JSONBuilder_BoolNamed(Dqn_JSONBuilder *builder, Dqn_String8 key, bool value);
|
||||
#define Dqn_JSONBuilder_Bool(builder, value) Dqn_JSONBuilder_BoolNamed(builder, DQN_STRING8(""), value)
|
||||
#define Dqn_JSONBuilder_ObjectBegin(builder) Dqn_JSONBuilder_ObjectBeginNamed(builder, DQN_STRING8(""))
|
||||
#define Dqn_JSONBuilder_ArrayBegin(builder) Dqn_JSONBuilder_ArrayBeginNamed(builder, DQN_STRING8(""))
|
||||
#define Dqn_JSONBuilder_String(builder, value) Dqn_JSONBuilder_StringNamed(builder, DQN_STRING8(""), value)
|
||||
#define Dqn_JSONBuilder_Literal(builder, value) Dqn_JSONBuilder_LiteralNamed(builder, DQN_STRING8(""), value)
|
||||
#define Dqn_JSONBuilder_U64(builder, value) Dqn_JSONBuilder_U64Named(builder, DQN_STRING8(""), value)
|
||||
#define Dqn_JSONBuilder_I64(builder, value) Dqn_JSONBuilder_I64Named(builder, DQN_STRING8(""), value)
|
||||
#define Dqn_JSONBuilder_F64(builder, value) Dqn_JSONBuilder_F64Named(builder, DQN_STRING8(""), value)
|
||||
#define Dqn_JSONBuilder_Bool(builder, value) Dqn_JSONBuilder_BoolNamed(builder, DQN_STRING8(""), value)
|
||||
#endif // !defined(DQN_NO_JSON_BUIDLER)
|
||||
|
||||
// NOTE: [$CHAR] Dqn_Char ==========================================================================
|
||||
@ -643,9 +618,7 @@ DQN_API int Dqn_UTF16_EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint);
|
||||
|
||||
#if !defined(DQN_NO_HEX)
|
||||
// NOTE: [$BHEX] Dqn_Bin ===========================================================================
|
||||
//
|
||||
// NOTE: API
|
||||
//
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_Bin_U64ToHexU64String
|
||||
// @desc Convert a 64 bit number to a hex string
|
||||
// @param[in] number Number to convert to hexadecimal representation
|
||||
@ -653,21 +626,21 @@ DQN_API int Dqn_UTF16_EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint);
|
||||
// output of the hexadecimal string.
|
||||
// @return The hexadecimal representation of the number. This string is always
|
||||
// null-terminated.
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_U64ToHex
|
||||
// @copybrief Dqn_Bin_U64ToHexU64String
|
||||
//
|
||||
|
||||
// @param[in] allocator The memory allocator to use for the memory of the
|
||||
// hexadecimal string.
|
||||
// @copyparams Dqn_Bin_U64ToHexU64String
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_HexBufferToU64
|
||||
// @desc Convert a hexadecimal string a 64 bit value.
|
||||
// Asserts if the hex string is too big to be converted into a 64 bit number.
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_HexToU64
|
||||
// @copydoc Dqn_Bin_HexToU64
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_BytesToHexBuffer
|
||||
// @desc Convert a binary buffer into its hex representation into dest.
|
||||
//
|
||||
@ -676,15 +649,15 @@ DQN_API int Dqn_UTF16_EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint);
|
||||
//
|
||||
// @return True if the conversion into the dest buffer was successful, false
|
||||
// otherwise (e.g. invalid arguments).
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_BytesToHexBufferArena
|
||||
// @desc Convert a series of bytes into a string
|
||||
// @return A null-terminated hex string, null pointer if allocation failed
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_BytesToHexArena
|
||||
// @copydoc Dqn_Bin_BytesToHexBufferArena
|
||||
// @return A hex string, the string is invalid if conversion failed.
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_HexBufferToBytes
|
||||
// @desc Convert a hex string into binary at `dest`.
|
||||
//
|
||||
@ -700,20 +673,20 @@ DQN_API int Dqn_UTF16_EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint);
|
||||
//
|
||||
// @return The number of bytes written to `dest_size`, this value will *never*
|
||||
// be greater than `dest_size`.
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_HexToBytes
|
||||
// @desc String8 variant of @see Dqn_Bin_HexBufferToBytes
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_StringHexBufferToBytesUnchecked
|
||||
// @desc Unchecked variant of @see Dqn_Bin_HexBufferToBytes
|
||||
//
|
||||
// This function skips some string checks, it assumes the hex is a valid hex
|
||||
// stream and that the arguments are valid e.g. no trimming or 0x prefix
|
||||
// stripping is performed
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_String
|
||||
// @desc String8 variant of @see Dqn_Bin_HexBufferToBytesUnchecked
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_HexBufferToBytesArena
|
||||
// Dynamic allocating variant of @see Dqn_Bin_HexBufferToBytesUnchecked
|
||||
//
|
||||
@ -723,7 +696,7 @@ DQN_API int Dqn_UTF16_EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint);
|
||||
// @param[out] real_size The size of the buffer returned by the function
|
||||
//
|
||||
// @return The byte representation of the hex string.
|
||||
//
|
||||
|
||||
// @proc Dqn_Bin_HexToBytesArena
|
||||
// @copybrief Dqn_Bin_HexBufferToBytesArena
|
||||
//
|
||||
@ -731,6 +704,7 @@ DQN_API int Dqn_UTF16_EncodeCodepoint(uint16_t utf16[2], uint32_t codepoint);
|
||||
// @param[in] hex Hex string to convert into bytes
|
||||
//
|
||||
// @return The byte representation of the hex string.
|
||||
|
||||
struct Dqn_BinHexU64String
|
||||
{
|
||||
char data[2 /*0x*/ + 16 /*hex*/ + 1 /*null-terminator*/];
|
||||
@ -765,12 +739,20 @@ DQN_API Dqn_usize Dqn_Bin_HexToBytes (Dqn_String8 hex,
|
||||
DQN_API Dqn_String8 Dqn_Bin_HexToBytesArena (Dqn_Arena *arena, Dqn_String8 hex);
|
||||
#endif // !defined(DQN_NO_HEX)
|
||||
|
||||
/// Write the format string to the buffer truncating with a trailing ".." if
|
||||
/// there is insufficient space in the buffer followed by null-terminating the
|
||||
/// buffer (uses stb_sprintf underneath).
|
||||
/// @return The size of the string written to the buffer *not* including the
|
||||
/// null-terminator.
|
||||
DQN_API int Dqn_SNPrintF2DotsOnOverflow(char *buffer, int size, char const *fmt, ...);
|
||||
// NOTE: Other =====================================================================================
|
||||
// NOTE: API =======================================================================================
|
||||
// @proc Dqn_SNPrintFDotTruncate
|
||||
// @desc Write the format string to the buffer truncating with a trailing ".."
|
||||
// if there is insufficient space in the buffer followed by null-terminating
|
||||
// the buffer (uses stb_sprintf underneath).
|
||||
// @return The size of the string written to the buffer *not* including the
|
||||
// null-terminator.
|
||||
//
|
||||
// @proc Dqn_U64ToString
|
||||
// @desc Convert a 64 bit unsigned value to its string representation.
|
||||
// @param[in] val Value to convert into a string
|
||||
// @param[in] separator The separator to insert every 3 digits. Set this to
|
||||
// 0 if no separator is desired.
|
||||
|
||||
struct Dqn_U64String
|
||||
{
|
||||
@ -778,11 +760,8 @@ struct Dqn_U64String
|
||||
uint8_t size;
|
||||
};
|
||||
|
||||
/// Convert a 64 bit unsigned value to its string representation.
|
||||
/// @param[in] val Value to convert into a string
|
||||
/// @param[in] separator The separator to insert every 3 digits. Set this to
|
||||
/// 0 if no separator is desired.
|
||||
DQN_API Dqn_U64String Dqn_U64ToString(uint64_t val, char separator);
|
||||
DQN_API int Dqn_SNPrintFDotTruncate(char *buffer, int size, char const *fmt, ...);
|
||||
DQN_API Dqn_U64String Dqn_U64ToString (uint64_t val, char separator);
|
||||
|
||||
// NOTE: [$STBS] stb_sprintf =======================================================================
|
||||
// stb_sprintf - v1.10 - public domain snprintf() implementation
|
||||
|
Loading…
Reference in New Issue
Block a user