135 lines
3.2 KiB
C
135 lines
3.2 KiB
C
#include "string_buffer.h"
|
|
#include "options.h"
|
|
#include "assert.h"
|
|
|
|
/*****************************************************************************
|
|
* STRING BUFFER
|
|
* ***************************************************************************/
|
|
|
|
string_buffer_t* create_string_buffer(size_t sz)
|
|
{
|
|
string_buffer_t *result = (string_buffer_t *)F_MALLOC(sizeof(string_buffer_t));
|
|
if (result == NULL)
|
|
return NULL;
|
|
result->str = F_MALLOC(sz);
|
|
if (result->str == NULL) {
|
|
F_FREE(result);
|
|
return NULL;
|
|
}
|
|
result->str_sz = sz;
|
|
|
|
return result;
|
|
}
|
|
|
|
void destroy_string_buffer(string_buffer_t *buffer)
|
|
{
|
|
if (buffer == NULL)
|
|
return;
|
|
F_FREE(buffer->str);
|
|
buffer->str = NULL;
|
|
F_FREE(buffer);
|
|
}
|
|
|
|
fort_status_t realloc_string_buffer_without_copy(string_buffer_t *buffer)
|
|
{
|
|
assert(buffer);
|
|
char *new_str = (char*)F_MALLOC(buffer->str_sz * 2);
|
|
if (new_str == NULL) {
|
|
return F_MEMORY_ERROR;
|
|
}
|
|
F_FREE(buffer->str);
|
|
buffer->str = new_str;
|
|
buffer->str_sz *= 2;
|
|
return F_SUCCESS;
|
|
}
|
|
|
|
fort_status_t fill_buffer_from_string(string_buffer_t *buffer, const char *str)
|
|
{
|
|
assert(buffer);
|
|
assert(str);
|
|
|
|
size_t sz = strlen(str);
|
|
char * copy = F_STRDUP(str);
|
|
if (copy == NULL)
|
|
return F_MEMORY_ERROR;
|
|
|
|
while (sz >= buffer->str_sz) {
|
|
int status = realloc_string_buffer_without_copy(buffer);
|
|
if (!IS_SUCCESS(status)) {
|
|
return status;
|
|
}
|
|
}
|
|
F_FREE(buffer->str);
|
|
buffer->str = copy;
|
|
|
|
return F_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
size_t buffer_text_height(string_buffer_t *buffer)
|
|
{
|
|
if (buffer == NULL || buffer->str == NULL || strlen(buffer->str) == 0) {
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
size_t buffer_text_width(string_buffer_t *buffer)
|
|
{
|
|
if (buffer == NULL || buffer->str == NULL) {
|
|
return 0;
|
|
}
|
|
return strlen(buffer->str);
|
|
}
|
|
|
|
|
|
int buffer_printf(string_buffer_t *buffer, size_t buffer_row, size_t table_column, char *buf, size_t buf_len, const context_t *context)
|
|
{
|
|
if (buffer == NULL || buffer->str == NULL
|
|
|| buffer_row >= buffer_text_height(buffer) || buf_len == 0) {
|
|
return -1;
|
|
}
|
|
|
|
size_t content_width = buffer_text_width(buffer);
|
|
if ((buf_len - 1) < content_width)
|
|
return -1;
|
|
|
|
int left = 0;
|
|
int right = 0;
|
|
|
|
switch (fort_options_column_alignment(context, table_column)) {
|
|
case LeftAligned:
|
|
left = 0;
|
|
right = (buf_len - 1) - content_width;
|
|
break;
|
|
case CenterAligned:
|
|
left = ((buf_len - 1) - content_width) / 2;
|
|
right = ((buf_len - 1) - content_width) - left;
|
|
break;
|
|
case RightAligned:
|
|
left = (buf_len - 1) - content_width;
|
|
right = 0;
|
|
break;
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
if (left < 0 || right < 0)
|
|
return -1;
|
|
|
|
|
|
int written = 0;
|
|
written += snprint_n_chars(buf + written, buf_len - written, left, ' ');
|
|
if (written < 0)
|
|
return written;
|
|
|
|
written += snprintf(buf + written, buf_len - written, "%*s", (int)content_width, buffer->str);
|
|
if (written < 0)
|
|
return written;
|
|
|
|
written += snprint_n_chars(buf + written, buf_len - written, right, ' ');
|
|
return written;
|
|
}
|
|
|