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 <ivy/file.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.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,
|
struct ivy_line_source *src, char *buf, size_t count, size_t *nr_read,
|
||||||
const char *prompt)
|
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;
|
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);
|
*nr_read = strlen(buf);
|
||||||
return IVY_OK;
|
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);
|
struct ivy_file *file = malloc(sizeof *file);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return NULL;
|
fclose(fp);
|
||||||
|
return IVY_ERR_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(file, 0x0, sizeof *file);
|
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_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)
|
void ivy_file_close(struct ivy_file *file)
|
||||||
{
|
{
|
||||||
|
b_array_release(file->f_lines);
|
||||||
|
free(file->f_path);
|
||||||
fclose(file->f_fp);
|
fclose(file->f_fp);
|
||||||
free(file);
|
free(file);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,16 @@
|
|||||||
#include <ivy/misc.h>
|
#include <ivy/misc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
struct b_array;
|
||||||
|
|
||||||
struct ivy_file {
|
struct ivy_file {
|
||||||
struct ivy_line_source f_base;
|
struct ivy_line_source f_base;
|
||||||
|
struct b_array *f_lines;
|
||||||
|
char *f_path;
|
||||||
FILE *f_fp;
|
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);
|
IVY_API void ivy_file_close(struct ivy_file *file);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,5 +21,6 @@ enum ivy_status {
|
|||||||
|
|
||||||
IVY_API const char *ivy_status_to_string(enum ivy_status 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_b_status(enum b_status status);
|
||||||
|
IVY_API enum ivy_status ivy_status_from_errno(int err);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <blue/core/status.h>
|
#include <blue/core/status.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <ivy/status.h>
|
#include <ivy/status.h>
|
||||||
|
|
||||||
#define ENUM_STR(x) \
|
#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;
|
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