From b3de59ae2426fb44b743a5994748a1ed488053a4 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sun, 19 Oct 2025 11:25:15 +0100 Subject: [PATCH] ds: datetime: convert to new object system --- ds/datetime.c | 238 ++++++++++++++++++++++++---------- ds/datetime.h | 17 --- ds/include/blue/ds/datetime.h | 35 +++-- 3 files changed, 188 insertions(+), 102 deletions(-) delete mode 100644 ds/datetime.h diff --git a/ds/datetime.c b/ds/datetime.c index 30949c0..d35055d 100644 --- a/ds/datetime.c +++ b/ds/datetime.c @@ -1,25 +1,22 @@ -#include "datetime.h" - #include #include #include -static void datetime_to_string(const struct b_dsref *obj, struct b_stream *out); +/*** PRIVATE DATA *************************************************************/ -static struct b_dsref_type datetime_type = { - .t_name = "corelib::datetime", - .t_flags = B_DSREF_FUNDAMENTAL, - .t_id = B_DSREF_TYPE_DATETIME, - .t_instance_size = sizeof(struct b_datetime), - .t_to_string = datetime_to_string, +struct b_datetime_p { + unsigned int dt_year, dt_month, dt_day; + unsigned short dt_hour, dt_min, dt_sec; + unsigned int dt_msec; + + bool dt_has_date, dt_has_time, dt_localtime; + unsigned short dt_zone_offset_hour, dt_zone_offset_minute; + bool dt_zone_offset_negative; }; -struct b_datetime *b_datetime_create(void) -{ - return (struct b_datetime *)b_dsref_type_instantiate(&datetime_type); -} +/*** PRIVATE FUNCTIONS ********************************************************/ -static bool is_leap_year(const struct b_datetime *dt) +static bool is_leap_year(const struct b_datetime_p *dt) { if ((dt->dt_year % 400) == 0) { return true; @@ -32,17 +29,17 @@ static bool is_leap_year(const struct b_datetime *dt) return false; } -static bool is_year_valid(const struct b_datetime *dt) +static bool is_year_valid(const struct b_datetime_p *dt) { return dt->dt_year >= 0; } -static bool is_month_valid(const struct b_datetime *dt) +static bool is_month_valid(const struct b_datetime_p *dt) { return dt->dt_month >= 1 && dt->dt_month <= 12; } -static bool is_day_valid(const struct b_datetime *dt) +static bool is_day_valid(const struct b_datetime_p *dt) { if (dt->dt_day < 1) { return false; @@ -69,7 +66,7 @@ static bool is_day_valid(const struct b_datetime *dt) } } -static bool is_time_valid(const struct b_datetime *dt) +static bool is_time_valid(const struct b_datetime_p *dt) { if (!(dt->dt_hour >= 0 && dt->dt_hour <= 23)) { return false; @@ -86,7 +83,7 @@ static bool is_time_valid(const struct b_datetime *dt) return true; } -static bool is_zone_valid(const struct b_datetime *dt) +static bool is_zone_valid(const struct b_datetime_p *dt) { if (!(dt->dt_zone_offset_hour >= 0 && dt->dt_zone_offset_hour <= 23)) { return false; @@ -99,7 +96,7 @@ static bool is_zone_valid(const struct b_datetime *dt) return true; } -static bool validate(const struct b_datetime *dt) +static bool validate(const struct b_datetime_p *dt) { if (dt->dt_has_date) { if (!is_year_valid(dt)) { @@ -128,13 +125,15 @@ static bool validate(const struct b_datetime *dt) return true; } -struct b_datetime *parse_rfc3339(const char *s) +static b_datetime *parse_rfc3339(const char *s) { - struct b_datetime *dt = b_datetime_create(); - if (!dt) { + b_datetime *d = b_datetime_create(); + if (!d) { return NULL; } + struct b_datetime_p *dt = b_object_get_private(d, B_TYPE_DATETIME); + size_t len = strlen(s); size_t i = 0, c = 0; @@ -304,37 +303,14 @@ struct b_datetime *parse_rfc3339(const char *s) dt->dt_has_date = has_date; dt->dt_has_time = has_time; - return dt; + return d; fail: - b_datetime_release(dt); + b_datetime_unref(d); return NULL; } -struct b_datetime *b_datetime_parse(enum b_datetime_format format, const char *s) -{ - struct b_datetime *dt = NULL; - - switch (format) { - case B_DATETIME_FORMAT_RFC3339: - dt = parse_rfc3339(s); - break; - default: - return NULL; - } - - if (!dt) { - return NULL; - } - - if (!validate(dt)) { - b_datetime_release(dt); - return NULL; - } - - return dt; -} - -enum b_status encode_rfc3339(const struct b_datetime *dt, struct b_stream *out) +static enum b_status encode_rfc3339( + const struct b_datetime_p *dt, struct b_stream *out) { if (dt->dt_has_date) { b_stream_write_fmt( @@ -372,8 +348,8 @@ enum b_status encode_rfc3339(const struct b_datetime *dt, struct b_stream *out) return B_SUCCESS; } -void b_datetime_to_string( - const b_datetime *dt, b_datetime_format format, struct b_string *dest) +static void datetime_to_string( + const struct b_datetime_p *dt, b_datetime_format format, b_string *dest) { struct b_stream *out; b_string_open_stream(dest, &out); @@ -389,74 +365,187 @@ void b_datetime_to_string( b_stream_close(out); } -bool b_datetime_is_localtime(const b_datetime *dt) +static bool datetime_is_localtime(const struct b_datetime_p *dt) { return dt->dt_localtime; } -bool b_datetime_has_date(const b_datetime *dt) +static bool datetime_has_date(const struct b_datetime_p *dt) { return dt->dt_has_date; } -bool b_datetime_has_time(const b_datetime *dt) +static bool datetime_has_time(const struct b_datetime_p *dt) { return dt->dt_has_time; } -long b_datetime_year(const b_datetime *dt) +static long datetime_year(const struct b_datetime_p *dt) { return dt->dt_year; } -long b_datetime_month(const b_datetime *dt) +static long datetime_month(const struct b_datetime_p *dt) { return dt->dt_month; } -long b_datetime_day(const b_datetime *dt) +static long datetime_day(const struct b_datetime_p *dt) { return dt->dt_day; } -long b_datetime_hour(const b_datetime *dt) +static long datetime_hour(const struct b_datetime_p *dt) { return dt->dt_hour; } -long b_datetime_minute(const b_datetime *dt) +static long datetime_minute(const struct b_datetime_p *dt) { return dt->dt_min; } -long b_datetime_second(const b_datetime *dt) +static long datetime_second(const struct b_datetime_p *dt) { return dt->dt_sec; } -long b_datetime_subsecond(const b_datetime *dt) +static long datetime_subsecond(const struct b_datetime_p *dt) { return dt->dt_msec; } -bool b_datetime_zone_offset_is_negative(const b_datetime *dt) +static bool datetime_zone_offset_is_negative(const struct b_datetime_p *dt) { return dt->dt_zone_offset_negative; } -long b_datetime_zone_offset_hour(const b_datetime *dt) +static long datetime_zone_offset_hour(const struct b_datetime_p *dt) { return dt->dt_zone_offset_hour; } -long b_datetime_zone_offset_minute(const b_datetime *dt) +static long datetime_zone_offset_minute(const struct b_datetime_p *dt) { return dt->dt_zone_offset_minute; } -static void datetime_to_string(const struct b_dsref *obj, struct b_stream *out) +/*** PUBLIC FUNCTIONS *********************************************************/ + +b_datetime *b_datetime_parse(enum b_datetime_format format, const char *s) { - struct b_datetime *dt = B_DATETIME(obj); + b_datetime *dt = NULL; + + switch (format) { + case B_DATETIME_FORMAT_RFC3339: + dt = parse_rfc3339(s); + break; + default: + return NULL; + } + + if (!dt) { + return NULL; + } + + struct b_datetime_p *p = b_object_get_private(dt, B_TYPE_DATETIME); + + if (!validate(p)) { + b_datetime_unref(dt); + return NULL; + } + + return dt; +} + +void b_datetime_to_string( + const b_datetime *dt, b_datetime_format format, b_string *dest) +{ + B_CLASS_DISPATCH_STATIC( + B_TYPE_DATETIME, datetime_to_string, dt, format, dest); +} + +bool b_datetime_is_localtime(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_is_localtime, dt); +} + +bool b_datetime_has_date(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_has_date, dt); +} + +bool b_datetime_has_time(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_has_time, dt); +} + +long b_datetime_year(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_year, dt); +} + +long b_datetime_month(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_month, dt); +} + +long b_datetime_day(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_day, dt); +} + +long b_datetime_hour(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_hour, dt); +} + +long b_datetime_minute(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_minute, dt); +} + +long b_datetime_second(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_second, dt); +} + +long b_datetime_subsecond(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_subsecond, dt); +} + +bool b_datetime_zone_offset_is_negative(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0( + B_TYPE_DATETIME, datetime_zone_offset_is_negative, dt); +} + +long b_datetime_zone_offset_hour(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_zone_offset_hour, dt); +} + +long b_datetime_zone_offset_minute(const b_datetime *dt) +{ + B_CLASS_DISPATCH_STATIC_0(B_TYPE_DATETIME, datetime_zone_offset_minute, dt); +} + +/*** VIRTUAL FUNCTIONS ********************************************************/ + +static void datetime_init(b_object *obj, void *priv) +{ + struct b_datetime_p *dt = priv; +} + +static void datetime_fini(b_object *obj, void *priv) +{ + struct b_datetime_p *dt = priv; +} + +static void _datetime_to_string(const b_object *obj, struct b_stream *out) +{ + struct b_datetime_p *dt = b_object_get_private(obj, B_TYPE_DATETIME); if (dt->dt_has_date) { b_stream_write_fmt( @@ -486,3 +575,18 @@ static void datetime_to_string(const struct b_dsref *obj, struct b_stream *out) } } } + +/*** CLASS DEFINITION *********************************************************/ + +B_TYPE_CLASS_DEFINITION_BEGIN(b_datetime) + B_TYPE_CLASS_INTERFACE_BEGIN(b_object, B_TYPE_OBJECT) + B_INTERFACE_ENTRY(to_string) = _datetime_to_string; + B_TYPE_CLASS_INTERFACE_END(b_object, B_TYPE_OBJECT) +B_TYPE_CLASS_DEFINITION_END(b_datetime) + +B_TYPE_DEFINITION_BEGIN(b_datetime) + B_TYPE_ID(0x06a6030b, 0x1e3c, 0x4be2, 0xbd23, 0xf34f4a8e68be); + B_TYPE_CLASS(b_datetime_class); + B_TYPE_INSTANCE_INIT(datetime_init); + B_TYPE_INSTANCE_INIT(datetime_fini); +B_TYPE_DEFINITION_END(b_datetime) diff --git a/ds/datetime.h b/ds/datetime.h deleted file mode 100644 index 74300c7..0000000 --- a/ds/datetime.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef _BLUELIB_DATETIME_H_ -#define _BLUELIB_DATETIME_H_ - -#include "object.h" - -struct b_datetime { - struct b_dsref dt_base; - unsigned int dt_year, dt_month, dt_day; - unsigned short dt_hour, dt_min, dt_sec; - unsigned int dt_msec; - - bool dt_has_date, dt_has_time, dt_localtime; - unsigned short dt_zone_offset_hour, dt_zone_offset_minute; - bool dt_zone_offset_negative; -}; - -#endif diff --git a/ds/include/blue/ds/datetime.h b/ds/include/blue/ds/datetime.h index 8c05755..7d33a2d 100644 --- a/ds/include/blue/ds/datetime.h +++ b/ds/include/blue/ds/datetime.h @@ -1,34 +1,31 @@ -#ifndef BLUELIB_DATETIME_H_ -#define BLUELIB_DATETIME_H_ +#ifndef BLUE_DS_DATETIME_H_ +#define BLUE_DS_DATETIME_H_ +#include #include -#include -#include #include -struct b_string; +B_DECLS_BEGIN; -#define B_DATETIME(p) ((b_datetime *)(p)) +#define B_TYPE_DATETIME (b_datetime_get_type()) -typedef struct b_datetime b_datetime; +B_DECLARE_TYPE(b_datetime); + +B_TYPE_CLASS_DECLARATION_BEGIN(b_datetime) +B_TYPE_CLASS_DECLARATION_END(b_datetime) typedef enum b_datetime_format { B_DATETIME_FORMAT_RFC3339 = 1, } b_datetime_format; -BLUE_API b_datetime *b_datetime_create(void); +BLUE_API b_type b_datetime_get_type(void); + +B_TYPE_DEFAULT_CONSTRUCTOR(b_datetime, B_TYPE_DATETIME); + BLUE_API b_datetime *b_datetime_parse(b_datetime_format format, const char *s); BLUE_API void b_datetime_to_string( - const b_datetime *dt, b_datetime_format format, struct b_string *dest); - -static inline b_datetime *b_datetime_retain(b_datetime *dt) -{ - return B_DATETIME(b_retain(B_DSREF(dt))); -} -static inline void b_datetime_release(b_datetime *dt) -{ - b_release(B_DSREF(dt)); -} + const b_datetime *dt, b_datetime_format format, + B_TYPE_FWDREF(b_string) * dest); BLUE_API bool b_datetime_is_localtime(const b_datetime *dt); BLUE_API bool b_datetime_has_date(const b_datetime *dt); @@ -46,4 +43,6 @@ BLUE_API bool b_datetime_zone_offset_is_negative(const b_datetime *dt); BLUE_API long b_datetime_zone_offset_hour(const b_datetime *dt); BLUE_API long b_datetime_zone_offset_minute(const b_datetime *dt); +B_DECLS_END; + #endif