common: implement s_get_row and s_get_name in ivy_file
This commit is contained in:
@@ -1,8 +1,44 @@
|
||||
#include <blue/object/array.h>
|
||||
#include <blue/object/string.h>
|
||||
#include <errno.h>
|
||||
#include <ivy/file.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static enum ivy_status file_readline(
|
||||
static enum ivy_status get_name(
|
||||
struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read)
|
||||
{
|
||||
struct ivy_file *f = (struct ivy_file *)src;
|
||||
*nr_read = snprintf(buf, count, "%s", f->f_path);
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
static enum ivy_status get_row(
|
||||
struct ivy_line_source *src, size_t row, char *buf, size_t count,
|
||||
size_t *nr_read)
|
||||
{
|
||||
struct ivy_file *f = (struct ivy_file *)src;
|
||||
size_t nr_rows = b_array_size(f->f_lines);
|
||||
|
||||
if (row > nr_rows) {
|
||||
return IVY_ERR_EOF;
|
||||
}
|
||||
|
||||
b_string *line = B_STRING(b_array_at(f->f_lines, row - 1));
|
||||
|
||||
const char *line_str = b_string_ptr(line);
|
||||
size_t line_len = b_string_get_size(line, B_STRLEN_NORMAL);
|
||||
size_t copy_len = b_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 IVY_OK;
|
||||
}
|
||||
|
||||
static enum ivy_status readline(
|
||||
struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read,
|
||||
const char *prompt)
|
||||
{
|
||||
@@ -16,27 +52,45 @@ static enum ivy_status file_readline(
|
||||
return feof(f->f_fp) ? IVY_ERR_EOF : IVY_ERR_IO_FAILURE;
|
||||
}
|
||||
|
||||
b_string *line_str = b_string_create_from_cstr(buf);
|
||||
b_array_append(f->f_lines, B_OBJECT(line_str));
|
||||
b_string_release(line_str);
|
||||
|
||||
*nr_read = strlen(buf);
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
struct ivy_file *ivy_file_from_fp(FILE *fp)
|
||||
enum ivy_status ivy_file_open(const char *path, struct ivy_file **out)
|
||||
{
|
||||
FILE *fp = fopen(path, "r");
|
||||
if (!fp) {
|
||||
return ivy_status_from_errno(errno);
|
||||
}
|
||||
|
||||
struct ivy_file *file = malloc(sizeof *file);
|
||||
if (!file) {
|
||||
return NULL;
|
||||
fclose(fp);
|
||||
return IVY_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_base.s_readline = file_readline;
|
||||
file->f_path = b_strdup(path);
|
||||
file->f_lines = b_array_create();
|
||||
|
||||
return file;
|
||||
*out = file;
|
||||
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
void ivy_file_close(struct ivy_file *file)
|
||||
{
|
||||
b_array_release(file->f_lines);
|
||||
free(file->f_path);
|
||||
fclose(file->f_fp);
|
||||
free(file);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
#include <ivy/misc.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct b_array;
|
||||
|
||||
struct ivy_file {
|
||||
struct ivy_line_source f_base;
|
||||
struct b_array *f_lines;
|
||||
char *f_path;
|
||||
FILE *f_fp;
|
||||
};
|
||||
|
||||
IVY_API struct ivy_file *ivy_file_from_fp(FILE *fp);
|
||||
IVY_API enum ivy_status ivy_file_open(const char *path, struct ivy_file **out);
|
||||
IVY_API void ivy_file_close(struct ivy_file *file);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,5 +21,6 @@ enum ivy_status {
|
||||
|
||||
IVY_API const char *ivy_status_to_string(enum ivy_status status);
|
||||
IVY_API enum ivy_status ivy_status_from_b_status(enum b_status status);
|
||||
IVY_API enum ivy_status ivy_status_from_errno(int err);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <blue/core/status.h>
|
||||
#include <errno.h>
|
||||
#include <ivy/status.h>
|
||||
|
||||
#define ENUM_STR(x) \
|
||||
@@ -34,3 +35,14 @@ enum ivy_status ivy_status_from_b_status(enum b_status status)
|
||||
return IVY_ERR_INTERNAL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
enum ivy_status ivy_status_from_errno(int err)
|
||||
{
|
||||
switch (err) {
|
||||
ENUM_CONVERT(0, IVY_OK);
|
||||
ENUM_CONVERT(ENOENT, IVY_ERR_NO_ENTRY);
|
||||
ENUM_CONVERT(ENOMEM, IVY_ERR_NO_MEMORY);
|
||||
default:
|
||||
return IVY_ERR_INTERNAL_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user