MODE: INLINE
#include <cstring>
static inline size_t date_freeze_len (const Date& date) {
if (date.timezone()->is_local) return sizeof(ptime_t);
return sizeof(ptime_t) + date.timezone()->name.length();
}
static inline void date_freeze (const Date& date, char* buf) {
if (sizeof(ptime_t) == 8) *((ptime_t*)buf) = panda::h2be64(date.epoch());
else *((ptime_t*)buf) = panda::h2be32(date.epoch());
buf += sizeof(ptime_t);
if (date.timezone()->is_local) *buf = 0;
else {
auto len = date.timezone()->name.length();
std::memcpy(buf, date.timezone()->name.data(), len);
buf[len] = 0;
}
}
static inline const char* date_thaw (ptime_t* epoch, const Timezone** zone, const char* ptr, size_t len) {
if (len < sizeof(ptime_t)) throw "Date: cannot 'thaw' - corrupted data";
if (sizeof(ptime_t) == 8) *epoch = panda::be2h64(*((ptime_t*)ptr));
else *epoch = panda::be2h32(*((ptime_t*)ptr));
ptr += sizeof(ptime_t);
if (*ptr == 0) {
*zone = NULL;
return ptr;
}
size_t znlen = strlen(ptr);
if (znlen) *zone = tzget(ptr);
return ptr + znlen;
}
MODULE = Date PACKAGE = Date
PROTOTYPES: DISABLE
Date* Date::HOOK_CLONE () {
RETVAL = new Date(*THIS);
PROTO = Object(ST(0)).stash();
}
SV* Date::STORABLE_freeze (bool) {
size_t len = date_freeze_len(*THIS);
RETVAL = newSV(len);
SvPOK_on(RETVAL);
char* buf = SvPVX(RETVAL);
date_freeze(*THIS, buf);
SvCUR_set(RETVAL, len);
}
Date* STORABLE_attach (SV* CLASS, bool, SV* serialized) {
STRLEN len;
const char* str = SvPV(serialized, len);
ptime_t epoch;
const Timezone* zone = nullptr;
date_thaw(&epoch, &zone, str, len);
RETVAL = new Date(epoch, zone);
PROTO = CLASS;
}
ptime_t Date::TO_JSON () {
RETVAL = THIS->epoch();
}
MODULE = Date PACKAGE = Date::Rel
PROTOTYPES: DISABLE
DateRel* DateRel::HOOK_CLONE () {
RETVAL = new DateRel(*THIS);
PROTO = Object(ST(0)).stash();
}
string DateRel::STORABLE_freeze (bool) {
RETVAL = THIS->from() ? THIS->to_string(DateRel::Format::iso8601i) : THIS->to_string();
}
DateRel* STORABLE_attach (SV* CLASS, bool, string_view serialized) {
RETVAL = new DateRel(serialized);
PROTO = CLASS;
}