Files

117 lines
2.3 KiB
C
Raw Permalink Normal View History

#include <bshell/file.h>
#include <bshell/line-source.h>
#include <errno.h>
#include <fx/collections/array.h>
#include <fx/string.h>
#include <stdlib.h>
#include <string.h>
static enum bshell_status get_name(
struct bshell_line_source *src,
char *buf,
size_t count,
size_t *nr_read)
{
struct bshell_file *f = (struct bshell_file *)src;
*nr_read = snprintf(buf, count, "%s", f->f_path);
return BSHELL_SUCCESS;
}
static enum bshell_status get_row(
struct bshell_line_source *src,
size_t row,
char *buf,
size_t count,
size_t *nr_read)
{
struct bshell_file *f = (struct bshell_file *)src;
2026-05-24 20:14:51 +01:00
size_t nr_rows = fx_array_get_size(f->f_lines);
if (row > nr_rows) {
return BSHELL_ERR_EOF;
}
2026-05-24 20:14:51 +01:00
fx_value *line_v = fx_array_get_ref(f->f_lines, row - 1);
fx_string *line = NULL;
fx_value_get_object(line_v, &line);
const char *line_str = fx_string_get_cstr(line);
size_t line_len = fx_string_get_size(line, FX_STRLEN_NORMAL);
size_t copy_len = fx_min(ulong, count, line_len);
memcpy(buf, line_str, copy_len);
buf[copy_len] = 0;
buf[strcspn(buf, "\n")] = 0;
*nr_read = copy_len;
return BSHELL_SUCCESS;
}
static enum bshell_status readline(
struct bshell_line_source *src,
fx_stringstream *out)
{
struct bshell_file *f = (struct bshell_file *)src;
fx_wchar c = FX_WCHAR_INVALID;
size_t nr_read = 0;
while (1) {
fx_status status = fx_stream_read_char(f->f_strp, &c);
if (!FX_OK(status)) {
break;
}
fx_stream_write_char(out, c);
nr_read++;
if (c == '\n') {
break;
}
}
if (nr_read == 0) {
return BSHELL_ERR_EOF;
}
return BSHELL_SUCCESS;
}
enum bshell_status bshell_file_open(const char *path, struct bshell_file **out)
{
FILE *fp = fopen(path, "r");
if (!fp) {
return bshell_status_from_errno(errno);
}
fx_stream *strp = fx_stream_open_fp(fp);
struct bshell_file *file = malloc(sizeof *file);
if (!file) {
fclose(fp);
return BSHELL_ERR_NO_MEMORY;
}
memset(file, 0x0, sizeof *file);
file->f_base.s_get_name = get_name;
file->f_base.s_get_row = get_row;
file->f_base.s_readline = readline;
file->f_fp = fp;
file->f_strp = strp;
file->f_path = fx_strdup(path);
file->f_lines = fx_array_create();
*out = file;
return BSHELL_SUCCESS;
}
void bshell_file_close(struct bshell_file *file)
{
fx_stream_unref(file->f_strp);
fx_array_unref(file->f_lines);
free(file->f_path);
fclose(file->f_fp);
free(file);
}