ds: datetime: convert to new object system
This commit is contained in:
238
ds/datetime.c
238
ds/datetime.c
@@ -1,25 +1,22 @@
|
|||||||
#include "datetime.h"
|
|
||||||
|
|
||||||
#include <blue/core/stream.h>
|
#include <blue/core/stream.h>
|
||||||
#include <blue/ds/datetime.h>
|
#include <blue/ds/datetime.h>
|
||||||
#include <blue/ds/string.h>
|
#include <blue/ds/string.h>
|
||||||
|
|
||||||
static void datetime_to_string(const struct b_dsref *obj, struct b_stream *out);
|
/*** PRIVATE DATA *************************************************************/
|
||||||
|
|
||||||
static struct b_dsref_type datetime_type = {
|
struct b_datetime_p {
|
||||||
.t_name = "corelib::datetime",
|
unsigned int dt_year, dt_month, dt_day;
|
||||||
.t_flags = B_DSREF_FUNDAMENTAL,
|
unsigned short dt_hour, dt_min, dt_sec;
|
||||||
.t_id = B_DSREF_TYPE_DATETIME,
|
unsigned int dt_msec;
|
||||||
.t_instance_size = sizeof(struct b_datetime),
|
|
||||||
.t_to_string = datetime_to_string,
|
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)
|
/*** PRIVATE FUNCTIONS ********************************************************/
|
||||||
{
|
|
||||||
return (struct b_datetime *)b_dsref_type_instantiate(&datetime_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
if ((dt->dt_year % 400) == 0) {
|
||||||
return true;
|
return true;
|
||||||
@@ -32,17 +29,17 @@ static bool is_leap_year(const struct b_datetime *dt)
|
|||||||
return false;
|
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;
|
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;
|
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) {
|
if (dt->dt_day < 1) {
|
||||||
return false;
|
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)) {
|
if (!(dt->dt_hour >= 0 && dt->dt_hour <= 23)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -86,7 +83,7 @@ static bool is_time_valid(const struct b_datetime *dt)
|
|||||||
return true;
|
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)) {
|
if (!(dt->dt_zone_offset_hour >= 0 && dt->dt_zone_offset_hour <= 23)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -99,7 +96,7 @@ static bool is_zone_valid(const struct b_datetime *dt)
|
|||||||
return true;
|
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 (dt->dt_has_date) {
|
||||||
if (!is_year_valid(dt)) {
|
if (!is_year_valid(dt)) {
|
||||||
@@ -128,13 +125,15 @@ static bool validate(const struct b_datetime *dt)
|
|||||||
return true;
|
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();
|
b_datetime *d = b_datetime_create();
|
||||||
if (!dt) {
|
if (!d) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct b_datetime_p *dt = b_object_get_private(d, B_TYPE_DATETIME);
|
||||||
|
|
||||||
size_t len = strlen(s);
|
size_t len = strlen(s);
|
||||||
|
|
||||||
size_t i = 0, c = 0;
|
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_date = has_date;
|
||||||
dt->dt_has_time = has_time;
|
dt->dt_has_time = has_time;
|
||||||
return dt;
|
return d;
|
||||||
fail:
|
fail:
|
||||||
b_datetime_release(dt);
|
b_datetime_unref(d);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct b_datetime *b_datetime_parse(enum b_datetime_format format, const char *s)
|
static enum b_status encode_rfc3339(
|
||||||
{
|
const struct b_datetime_p *dt, struct b_stream *out)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (dt->dt_has_date) {
|
if (dt->dt_has_date) {
|
||||||
b_stream_write_fmt(
|
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;
|
return B_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void b_datetime_to_string(
|
static void datetime_to_string(
|
||||||
const b_datetime *dt, b_datetime_format format, struct b_string *dest)
|
const struct b_datetime_p *dt, b_datetime_format format, b_string *dest)
|
||||||
{
|
{
|
||||||
struct b_stream *out;
|
struct b_stream *out;
|
||||||
b_string_open_stream(dest, &out);
|
b_string_open_stream(dest, &out);
|
||||||
@@ -389,74 +365,187 @@ void b_datetime_to_string(
|
|||||||
b_stream_close(out);
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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) {
|
if (dt->dt_has_date) {
|
||||||
b_stream_write_fmt(
|
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)
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -1,34 +1,31 @@
|
|||||||
#ifndef BLUELIB_DATETIME_H_
|
#ifndef BLUE_DS_DATETIME_H_
|
||||||
#define BLUELIB_DATETIME_H_
|
#define BLUE_DS_DATETIME_H_
|
||||||
|
|
||||||
|
#include <blue/core/macros.h>
|
||||||
#include <blue/core/status.h>
|
#include <blue/core/status.h>
|
||||||
#include <blue/ds/object.h>
|
|
||||||
#include <blue/ds/type.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
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 {
|
typedef enum b_datetime_format {
|
||||||
B_DATETIME_FORMAT_RFC3339 = 1,
|
B_DATETIME_FORMAT_RFC3339 = 1,
|
||||||
} b_datetime_format;
|
} 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 b_datetime *b_datetime_parse(b_datetime_format format, const char *s);
|
||||||
BLUE_API void b_datetime_to_string(
|
BLUE_API void b_datetime_to_string(
|
||||||
const b_datetime *dt, b_datetime_format format, struct b_string *dest);
|
const b_datetime *dt, b_datetime_format format,
|
||||||
|
B_TYPE_FWDREF(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));
|
|
||||||
}
|
|
||||||
|
|
||||||
BLUE_API bool b_datetime_is_localtime(const b_datetime *dt);
|
BLUE_API bool b_datetime_is_localtime(const b_datetime *dt);
|
||||||
BLUE_API bool b_datetime_has_date(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_hour(const b_datetime *dt);
|
||||||
BLUE_API long b_datetime_zone_offset_minute(const b_datetime *dt);
|
BLUE_API long b_datetime_zone_offset_minute(const b_datetime *dt);
|
||||||
|
|
||||||
|
B_DECLS_END;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user