VVVVVV/desktop_version/src/Textbook.c

113 lines
2.5 KiB
C

#include "Textbook.h"
#include <SDL.h>
#include "Alloc.h"
#include "Vlogging.h"
void textbook_init(Textbook* textbook)
{
textbook->pages_used = 0;
textbook->protect = false;
}
void textbook_clear(Textbook* textbook)
{
if (textbook->protect)
{
return;
}
for (short p = 0; p < textbook->pages_used; p++)
{
VVV_free(textbook->page[p]);
}
textbook->pages_used = 0;
}
void textbook_set_protected(Textbook* textbook, bool protect)
{
/* A protected textbook is silently not cleared when requested.
* Not a memory leak as long as you unprotect and clear at some point. */
textbook->protect = protect;
}
const void* textbook_store_raw(Textbook* textbook, const void* data, size_t data_len)
{
if (data == NULL)
{
return NULL;
}
if (data_len > TEXTBOOK_PAGE_SIZE)
{
vlog_warn(
"Cannot store data of %ld bytes in Textbook, max page size is %d",
data_len,
TEXTBOOK_PAGE_SIZE
);
return NULL;
}
/* Find a suitable page to place our text on */
short found_page = -1;
for (short p = 0; p < textbook->pages_used; p++)
{
size_t free = TEXTBOOK_PAGE_SIZE - textbook->page_len[p];
if (data_len <= free)
{
found_page = p;
break;
}
}
if (found_page == -1)
{
/* Create a new page then */
found_page = textbook->pages_used;
if (found_page >= TEXTBOOK_MAX_PAGES)
{
vlog_warn(
"Textbook is full! %hd pages used (%d chars per page)",
textbook->pages_used,
TEXTBOOK_PAGE_SIZE
);
return NULL;
}
textbook->page[found_page] = (char*) SDL_malloc(TEXTBOOK_PAGE_SIZE);
if (textbook->page[found_page] == NULL)
{
return NULL;
}
textbook->page_len[found_page] = 0;
textbook->pages_used++;
}
size_t cursor = textbook->page_len[found_page];
char* added_text = &textbook->page[found_page][cursor];
SDL_memcpy(added_text, data, data_len);
textbook->page_len[found_page] += data_len;
return added_text;
}
const char* textbook_store(Textbook* textbook, const char* text)
{
if (text == NULL)
{
return NULL;
}
if (text[0] == '\0')
{
/* Don't go and store a single null terminator when we have one right here for you: */
return "";
}
return (const char*) textbook_store_raw(textbook, text, SDL_strlen(text)+1);
}