in src/dt.c [669:754]
dt_status_t dt_to_string(const dt_representation_t *representation, const char *fmt,
char *str_buffer, size_t str_buffer_size)
{
struct tm tm = {0};
dt_status_t status = DT_UNKNOWN_ERROR;
size_t fmt_len = 0;
char fmt_buffer[255] = {0};
int fractional_seconds_format_pos = 0;
size_t fmt_start_pos = 0;
size_t fractional_seconds_format_length = 0;
size_t fractional_seconds_precision = 0;
size_t str_buffer_eos_pos = 0;
size_t characters_appended = 0;
size_t i = 0;
if (!representation || !fmt || !str_buffer || str_buffer_size <= 0) {
return DT_INVALID_ARGUMENT;
}
// Checking for too long format string
fmt_len = strlen(fmt);
if (fmt_len >= sizeof(fmt_buffer)) {
return DT_OVERFLOW;
}
status = dt_representation_to_tm(representation, &tm);
if (status != DT_OK) {
return status;
}
while (fmt_start_pos < fmt_len) {
// Searching for fractional format placeholder
fractional_seconds_format_pos = dt_parse_fractional_seconds_format(fmt + fmt_start_pos,
&fractional_seconds_format_length, &fractional_seconds_precision);
if (fractional_seconds_format_pos < 0) {
// No fractional seconds placeholder found -> serializing date-time value against the rest of the format string
characters_appended = strftime(str_buffer + str_buffer_eos_pos, str_buffer_size - str_buffer_eos_pos,
fmt + fmt_start_pos, &tm);
if ((characters_appended == 0) && (fmt_len > fmt_start_pos) && (fmt_len - fmt_start_pos < str_buffer_size - str_buffer_eos_pos)) {
// if format string in wrong format, windows std library's function strftime return 0
str_buffer[str_buffer_eos_pos] = fmt[fmt_start_pos];
str_buffer_eos_pos++;
fmt_start_pos++;
str_buffer[str_buffer_eos_pos] = '\0';
continue;
}
if (characters_appended <= 0) {
return DT_OVERFLOW;
}
str_buffer_eos_pos += characters_appended;
break;
} else {
if (fractional_seconds_format_pos > 0) {
// Extracting leading data to the buffer and serializing date-time value according this format
memcpy(fmt_buffer, fmt + fmt_start_pos, fractional_seconds_format_pos);
fmt_buffer[fractional_seconds_format_pos] = '\0';
characters_appended = strftime(str_buffer + str_buffer_eos_pos, str_buffer_size - str_buffer_eos_pos,
fmt_buffer, &tm);
if (characters_appended <= 0) {
return DT_OVERFLOW;
}
str_buffer_eos_pos += characters_appended;
}
fmt_start_pos += (fractional_seconds_format_pos + fractional_seconds_format_length);
// Serializing fractional seconds
if (fractional_seconds_precision == 0) {
fractional_seconds_precision = 9;
}
for (i = 0; i < fractional_seconds_precision; ++i) {
char cur_digit = '\0';
// Checking for free space in result buffer
if (str_buffer_eos_pos >= str_buffer_size - 1) {
return DT_OVERFLOW;
}
cur_digit = (int) floor(representation->nano_second / pow(10, 8 - i)) % 10 + '0';
str_buffer[str_buffer_eos_pos] = cur_digit;
++str_buffer_eos_pos;
}
str_buffer[str_buffer_eos_pos] = '\0';
}
}
return DT_OK;
}