void xmlrpc_read_datetime_str_old(xmlrpc_env * const envP, const xmlrpc_value * const valueP, const char ** const stringValueP) { validateDatetimeType(envP, valueP); if (!envP->fault_occurred) { *stringValueP = XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); }
void xmlrpc_read_datetime(xmlrpc_env *const envP, const xmlrpc_value *const valueP, xmlrpc_datetime *const dtP) { validateDatetimeType(envP, valueP); if (!envP->fault_occurred) { *dtP = valueP->_value.dt; } }
void xmlrpc_read_datetime_usec(xmlrpc_env *const envP, const xmlrpc_value *const valueP, time_t *const secsP, unsigned int *const usecsP) { validateDatetimeType(envP, valueP); if (!envP->fault_occurred) { if (valueP->_value.dt.Y < 1970) xmlrpc_faultf(envP, "Year (%u) is too early to represent as " "a standard Unix time", valueP->_value.dt.Y); else { struct tm brokenTime; const char *error; brokenTime.tm_sec = valueP->_value.dt.s; brokenTime.tm_min = valueP->_value.dt.m; brokenTime.tm_hour = valueP->_value.dt.h; brokenTime.tm_mday = valueP->_value.dt.D; brokenTime.tm_mon = valueP->_value.dt.M - 1; brokenTime.tm_year = valueP->_value.dt.Y - 1900; xmlrpc_timegm(&brokenTime, secsP, &error); if (error) { /* Ideally, this wouldn't be possible - it wouldn't be possible to create an xmlrpc_value that doesn't actually represent a real datetime. But today, we're lazy and don't fully validate incoming XML-RPC <dateTime.iso8601> elements, and we also have the legacy xmlrpc_datetime_new_str() constructor to which the user may feed garbage. We should tighten that up and then simply assert here that xmlrpc_timegm() succeeded. */ xmlrpc_env_set_fault_formatted(envP, XMLRPC_PARSE_ERROR, "A datetime received in an XML-RPC message " "or generated with legacy Xmlrpc-c facilities " "does not validly describe a datetime. %s", error); xmlrpc_strfree(error); } else *usecsP = valueP->_value.dt.u; } } }
void xmlrpc_read_datetime_str(xmlrpc_env *const envP, const xmlrpc_value *const valueP, const char **const stringValueP) { /*---------------------------------------------------------------------------- This exists for backward compatibility. No normal modern program would want to see a datetime value in this format. Note that the format isn't even ISO 8601 -- it's a bizarre hybrid of two ISO 8601 formats. Do not extend this. This exists because Xmlrpc-c was at one time lazy and this was the only way to extract the value. An xmlrpc_value in those days represented a datetime with the actual XML-RPC wire format of a datetime, and this function simply returned a copy of it. -----------------------------------------------------------------------------*/ validateDatetimeType(envP, valueP); if (!envP->fault_occurred) { time_t secs; unsigned int usecs; xmlrpc_read_datetime_usec(envP, valueP, &secs, &usecs); if (!envP->fault_occurred) { struct tm brokenTime; char dtString[64]; xmlrpc_gmtime(secs, &brokenTime); /* Note that this format is NOT ISO 8601 -- it's a bizarre hybrid of two ISO 8601 formats. */ strftime(dtString, sizeof(dtString), "%Y%m%dT%H:%M:%S", &brokenTime); if (usecs != 0) { char usecString[64]; assert(usecs < 1000000); snprintf(usecString, sizeof(usecString), ".%06u", usecs); STRSCAT(dtString, usecString); } *stringValueP = strdup(dtString); if (*stringValueP == NULL) xmlrpc_faultf(envP, "Unable to allocate memory for datetime string"); } } }
void xmlrpc_read_datetime_str(xmlrpc_env * const envP, const xmlrpc_value * const valueP, const char ** const stringValueP) { validateDatetimeType(envP, valueP); if (!envP->fault_occurred) { const char * const contents = XMLRPC_MEMBLOCK_CONTENTS(char, &valueP->_block); *stringValueP = strdup(contents); if (*stringValueP == NULL) xmlrpc_env_set_fault_formatted( envP, XMLRPC_INTERNAL_ERROR, "Unable to allocate space " "for datetime string"); } }
void xmlrpc_read_datetime_str_old(xmlrpc_env *const envP, const xmlrpc_value *const valueP, const char **const stringValueP) { assert(valueP->_cache); validateDatetimeType(envP, valueP); if (!envP->fault_occurred) { const char **const readBufferP = valueP->_cache; if (!*readBufferP) /* Nobody's asked for the internal buffer before. Set it up. */ xmlrpc_read_datetime_str(envP, valueP, readBufferP); *stringValueP = *readBufferP; } }
void xmlrpc_read_datetime_8601(xmlrpc_env *const envP, const xmlrpc_value *const valueP, const char **const iso8601ValueP) { /*---------------------------------------------------------------------------- Get the datetime in ISO 8601 format. ISO 8601 allows a variety of representations for each datetime. The particular one we return is as in the following example. 19930214T131030,250000Z (13:10:30.25 on February 14, 1993) There are always 4 digits for the year. There are always 6 digits after the comma (microseconds). Midnight is hour 0, not 24. -----------------------------------------------------------------------------*/ validateDatetimeType(envP, valueP); if (!envP->fault_occurred) { xmlrpc_datetime dt; xmlrpc_read_datetime(envP, valueP, &dt); if (!envP->fault_occurred) { if (dt.Y > 9999) xmlrpc_faultf(envP, "Too far in future (year %u). " "ISO 8601 cannot " "represent years after AD 9999", dt.Y); else { xmlrpc_asprintf(iso8601ValueP, "%04u%02u%02uT%02u%02u%02u,%06uZ", dt.Y, dt.M, dt.D, dt.h, dt.m, dt.s, dt.u); if (xmlrpc_strnomem(*iso8601ValueP)) xmlrpc_faultf(envP, "Unable to allocate memory " "for datetime string"); if (envP->fault_occurred) xmlrpc_strfree(*iso8601ValueP); } } } }