libioutil Implement a file reader
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m23s
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m23s
This commit is contained in:
46
ce/ce.c
46
ce/ce.c
@@ -1,5 +1,6 @@
|
|||||||
#include <arena.h>
|
#include <arena.h>
|
||||||
#include <desc.h>
|
#include <desc.h>
|
||||||
|
#include <filereader.h>
|
||||||
#include <filewriter.h>
|
#include <filewriter.h>
|
||||||
#include <liballoc.h>
|
#include <liballoc.h>
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
@@ -386,7 +387,6 @@ static void mkfile (struct context* context, char** file_paths, size_t files_cou
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void cat (struct context* context, char** file_paths, size_t files_count) {
|
static void cat (struct context* context, char** file_paths, size_t files_count) {
|
||||||
struct desc desc;
|
|
||||||
char volume[VOLUME_MAX];
|
char volume[VOLUME_MAX];
|
||||||
const char* path;
|
const char* path;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -399,29 +399,39 @@ static void cat (struct context* context, char** file_paths, size_t files_count)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = volume_open (volume)) < 0) {
|
struct filereader fr;
|
||||||
cprintf (context, "ERROR could not open volume '%s': %s\n", volume, str_status[-ret]);
|
if ((ret = filereader_init (&fr, volume, path)) < 0) {
|
||||||
continue;
|
cprintf (context, "ERROR could not initialize filereader for '%s:%s'\n", volume, path);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
describe (path, &desc);
|
size_t chunk_size = 1024;
|
||||||
|
char* buffer = arena_malloc (&arena, chunk_size);
|
||||||
|
|
||||||
if (desc.type != FS_FILE)
|
size_t chunks = fr.file_size / chunk_size;
|
||||||
goto close;
|
size_t rem = fr.file_size % chunk_size;
|
||||||
|
|
||||||
char* buffer = malloc (desc.size + 1);
|
for (size_t chunk = 0; chunk < chunks; chunk++) {
|
||||||
|
if ((ret = filereader_read (&fr, (uint8_t*)buffer, chunk_size)) < 0) {
|
||||||
|
filereader_fini (&fr);
|
||||||
|
cprintf (context, "ERROR filereader failed to read from '%s:%s'\n", volume, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (buffer == NULL)
|
mail_send (e_pgid, buffer, chunk_size);
|
||||||
goto close;
|
}
|
||||||
|
|
||||||
memset (buffer, 0, desc.size + 1);
|
if (rem > 0) {
|
||||||
read_file (path, 0, (uint8_t*)buffer, desc.size);
|
if ((ret = filereader_read (&fr, (uint8_t*)buffer, rem)) < 0) {
|
||||||
cprintf (context, "%s\n", buffer);
|
filereader_fini (&fr);
|
||||||
|
cprintf (context, "ERROR filereader failed to read from '%s:%s'\n", volume, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
close:
|
mail_send (e_pgid, buffer, rem);
|
||||||
if (buffer != NULL)
|
}
|
||||||
free (buffer);
|
|
||||||
volume_close ();
|
filereader_fini (&fr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -566,12 +576,14 @@ static void execute_redir (struct ast_redir* redir, struct context* context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rem > 0) {
|
||||||
if ((ret = filewriter_write (&fw, (uint8_t*)&context->strbuf.items[chunks * chunk_size], rem)) <
|
if ((ret = filewriter_write (&fw, (uint8_t*)&context->strbuf.items[chunks * chunk_size], rem)) <
|
||||||
0) {
|
0) {
|
||||||
filewriter_fini (&fw);
|
filewriter_fini (&fw);
|
||||||
cprintf (context, "ERROR filewriter failed to write to '%s:%s'\n", volume, path);
|
cprintf (context, "ERROR filewriter failed to write to '%s:%s'\n", volume, path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
filewriter_fini (&fw);
|
filewriter_fini (&fw);
|
||||||
}
|
}
|
||||||
|
|||||||
61
libioutil/filereader.c
Normal file
61
libioutil/filereader.c
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#include <desc.h>
|
||||||
|
#include <filereader.h>
|
||||||
|
#include <path_defs.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <system.h>
|
||||||
|
|
||||||
|
int filereader_init (struct filereader* fw, const char* volume, const char* path) {
|
||||||
|
memset (fw, 0, sizeof (*fw));
|
||||||
|
strncpy (fw->volume, volume, VOLUME_MAX);
|
||||||
|
strncpy (fw->path, path, PATH_MAX);
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
struct desc desc;
|
||||||
|
|
||||||
|
if ((ret = volume_open (fw->volume)) < 0)
|
||||||
|
return -FR_VOLUME_OPEN_ERROR;
|
||||||
|
|
||||||
|
if ((ret = describe (fw->path, &desc)) < 0) {
|
||||||
|
volume_close ();
|
||||||
|
return -FR_DESC_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc.type != FS_FILE)
|
||||||
|
return -FR_NOT_FILE;
|
||||||
|
|
||||||
|
fw->file_size = desc.size;
|
||||||
|
fw->flags |= FR_OPEN;
|
||||||
|
|
||||||
|
return FR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filereader_fini (struct filereader* fw) {
|
||||||
|
if ((fw->flags & FR_OPEN)) {
|
||||||
|
volume_close ();
|
||||||
|
fw->flags &= ~FR_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FR_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int filereader_read (struct filereader* fw, uint8_t* buffer, size_t buffer_size) {
|
||||||
|
if (!(fw->flags & FR_OPEN))
|
||||||
|
return -FR_VOLUME_NOT_OPENED;
|
||||||
|
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (buffer_size > 0) {
|
||||||
|
if (!(fw->read_cursor + buffer_size <= fw->file_size))
|
||||||
|
return -FR_CURSOR_OOB;
|
||||||
|
|
||||||
|
if ((ret = read_file (fw->path, fw->read_cursor, buffer, buffer_size)) < 0)
|
||||||
|
return -FR_READ_ERROR;
|
||||||
|
|
||||||
|
fw->read_cursor += buffer_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FR_OK;
|
||||||
|
}
|
||||||
33
libioutil/filereader.h
Normal file
33
libioutil/filereader.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#ifndef _LIBIOUTIL_FILEREADER_H
|
||||||
|
#define _LIBIOUTIL_FILEREADER_H
|
||||||
|
|
||||||
|
#include <path_defs.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define FR_OK 0
|
||||||
|
#define FR_VOLUME_OPEN_ERROR 1
|
||||||
|
#define FR_DESC_ERROR 2
|
||||||
|
#define FR_NOT_FILE 3
|
||||||
|
#define FR_VOLUME_NOT_OPENED 4
|
||||||
|
#define FR_READ_ERROR 5
|
||||||
|
#define FR_CURSOR_OOB 6
|
||||||
|
|
||||||
|
#define FR_OPEN (1 << 31)
|
||||||
|
|
||||||
|
struct filereader {
|
||||||
|
char volume[VOLUME_MAX];
|
||||||
|
char path[PATH_MAX];
|
||||||
|
size_t read_cursor;
|
||||||
|
size_t file_size;
|
||||||
|
uint32_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
int filereader_init (struct filereader* fw, const char* volume, const char* path);
|
||||||
|
|
||||||
|
int filereader_fini (struct filereader* fw);
|
||||||
|
|
||||||
|
int filereader_read (struct filereader* fw, uint8_t* buffer, size_t buffer_size);
|
||||||
|
|
||||||
|
#endif // _LIBIOUTIL_FILEREADER_H
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
c += filewriter.c
|
c += filewriter.c \
|
||||||
|
filereader.c
|
||||||
|
|
||||||
o += filewriter.o
|
o += filewriter.o \
|
||||||
|
filereader.o
|
||||||
|
|||||||
Reference in New Issue
Block a user