11#include <ascii-chat/options/manpage/resources.h>
12#include <ascii-chat/embedded_resources.h>
13#include <ascii-chat/log/logging.h>
28static asciichat_error_t load_single_resource(
const char **out_content,
size_t *out_len,
29 int (*get_resource_func)(FILE **out_file,
const char **out_content,
31 const char *resource_name) {
32 if (!out_content || !out_len) {
33 return SET_ERRNO(ERROR_INVALID_PARAM,
"Invalid output pointers for %s", resource_name);
37 const char *content = NULL;
41 int result = get_resource_func(&file, &content, &len);
43 return SET_ERRNO(ERROR_CONFIG,
"Failed to load %s resource", resource_name);
50 *out_content = content;
52 log_debug(
"Loaded %s from embedded resources (%zu bytes)", resource_name, len);
60 if (fseek(file, 0, SEEK_END) != 0) {
62 return SET_ERRNO_SYS(ERROR_CONFIG,
"Failed to seek %s file", resource_name);
65 long file_size = ftell(file);
68 return SET_ERRNO_SYS(ERROR_CONFIG,
"Failed to get %s file size", resource_name);
71 if (fseek(file, 0, SEEK_SET) != 0) {
73 return SET_ERRNO_SYS(ERROR_CONFIG,
"Failed to seek %s file", resource_name);
81 return SET_ERRNO(ERROR_CONFIG,
"Failed to allocate memory for %s (%zu bytes)", resource_name,
buffer_size);
85 size_t bytes_read = fread(buffer, 1, (
size_t)file_size, file);
88 if (bytes_read != (
size_t)file_size) {
90 return SET_ERRNO_SYS(ERROR_CONFIG,
"Failed to read complete %s file (%zu/%lu bytes read)", resource_name,
91 bytes_read, (
unsigned long)file_size);
95 buffer[(size_t)file_size] =
'\0';
97 *out_content = buffer;
98 *out_len = (size_t)file_size;
99 log_debug(
"Loaded %s from filesystem (%zu bytes)", resource_name, *out_len);
103 return SET_ERRNO(ERROR_CONFIG,
"Invalid %s resource state (neither file nor content available)", resource_name);
109 return SET_ERRNO(ERROR_INVALID_PARAM,
"resources pointer cannot be NULL");
113 resources->template_content = NULL;
114 resources->template_len = 0;
115 resources->content_sections = NULL;
116 resources->content_len = 0;
117 resources->is_embedded =
false;
118 resources->allocated =
false;
121 asciichat_error_t err = load_single_resource(&resources->template_content, &resources->template_len,
123 if (err != ASCIICHAT_OK) {
129 resources->content_sections = NULL;
130 resources->content_len = 0;
135 resources->is_embedded =
true;
137 resources->is_embedded =
false;
142 resources->allocated =
false;
144 resources->allocated =
true;
147 log_debug(
"Resources loaded successfully (embedded=%d, allocated=%d)", resources->is_embedded, resources->allocated);
157 if (resources->allocated) {
160 if (resources->template_content) {
161 char *template_ptr = (
char *)resources->template_content;
162 SAFE_FREE(template_ptr);
164 if (resources->content_sections) {
165 char *content_ptr = (
char *)resources->content_sections;
166 SAFE_FREE(content_ptr);
172 resources->template_content = NULL;
173 resources->template_len = 0;
174 resources->content_sections = NULL;
175 resources->content_len = 0;
176 resources->is_embedded =
false;
177 resources->allocated =
false;
186 return resources->template_content != NULL && resources->template_len > 0;
int get_manpage_template(FILE **out_file, const char **out_content, size_t *out_len)
void release_manpage_resources(FILE *file)
int buffer_size
Size of circular buffer.
void manpage_resources_destroy(manpage_resources_t *resources)
asciichat_error_t manpage_resources_load(manpage_resources_t *resources)
bool manpage_resources_is_valid(const manpage_resources_t *resources)