Continuing to try and implement filesystems.

This commit is contained in:
Thomas Touhey 2017-07-01 17:22:39 +02:00
parent 089863770d
commit 563d6102ac
13 changed files with 366 additions and 106 deletions

View File

@ -20,6 +20,7 @@
# define LIBCASIO_BUILTIN_H
# include "cdefs.h"
# include "stream.h"
# include "fs.h"
# ifndef LIBCASIO_DISABLED_FILE
# include <stdio.h>
# endif
@ -74,7 +75,8 @@ CASIO_EXTERN int CASIO_EXPORT casio_opencom_windows
/* ************************************************************************* */
/* Make a local POSIX filesystem interface. */
# if defined(__linux__) || (defined(__APPLE__) && defined(__MACH__))
/* TODO */
CASIO_EXTERN int CASIO_EXPORT casio_open_posix_fs
OF((casio_filesystem_t **casio__filesystem));
# else
# define LIBCASIO_DISABLED_POSIX_FS
# endif

View File

@ -93,52 +93,68 @@ typedef void casio_fs_list_func_t OF((void *casio__cookie,
/* ************************************************************************* */
/* The filesystem is a private structure that represents a file system.
*
* The `casio_fs_stat` callback is to get information about a file or
* directory. */
* Once all of the operations are done, the user shall close the filesystem.
* This is the callback to free/close custom elements. */
typedef int casio_fs_close_t OF((void *casio__cookie));
/* From here, we will work with paths.
* Instead of having to convert the path every time, we will use native paths
* on the user side; they can be made how you want. */
typedef int casio_fs_makepath_t
OF((void *casio__cookie, void **casio__native_path,
casio_path_t *casio__path));
typedef void casio_fs_freepath_t
OF((void *casio__cookie, void *casio__native_path));
/* The `casio_fs_stat` callback is used to gather information about
* any element in your filesystem: files, directories, ... */
typedef int casio_fs_stat_t
OF((void *casio__cookie, casio_path_t *casio__path,
OF((void *casio__cookie, void *casio__native_path,
casio_stat_t *casio__stat));
/* The `casio_fs_makedir` callback creates a directory. */
/* The `casio_fs_makedir` callback is used to create a directory. */
typedef int casio_fs_makedir_t
OF((void *casio__cookie, casio_path_t *casio__path));
OF((void *casio__cookie, void *casio__native_path));
/* The `casio_fs_del` callback deletes a file or directory. */
/* The `casio_fs_del` callback is used to delete an element of any type
* from your filesystem. */
typedef int casio_fs_del_t
OF((void *casio__cookie, casio_path_t *casio__path));
OF((void *casio__cookie, void *casio__native_path));
/* The `casio_fs_move` callback renames/moves a file into an
* other directory, eventually with an other name. */
/* The `casio_fs_move` callback is used to move an element of your filesystem
* to an other location. */
typedef int casio_fs_move_t
OF((void *casio__cookie, casio_path_t *casio__orig,
casio_path_t *casio__dest));
OF((void *casio__cookie, void *casio__native_orig,
void *casio__native_dest));
/* The `casio_fs_open` callback makes a stream out of a file with a path. */
/* The `casio_fs_open` callback is used to make a stream out of an element
* of your filesystem. */
typedef int casio_fs_open_t
OF((void *casio__cookie, const void *casio__path, casio_off_t size,
OF((void *casio__cookie, void *casio__path, casio_off_t size,
casio_openmode_t casio__mode, casio_stream_t **stream));
/* The `casio_fs_list` callback lists files in a directory. */
/* The `casio_fs_list` callback is used to list files in a directory. */
typedef int casio_fs_list_t
OF((void *casio__cookie, casio_path_t *casio__path,
casio_fs_list_func_t *casio__callback, void *casio__cbcookie));
/* The `casio_fs_close` callback is called when the filesystem interface
* is closed. */
typedef int casio_fs_close_t OF((void *casio__cookie));
/* And here is the structure with all of the functions.
* It is the one used when you want to open a libcasio filesystem interface
* abstraction. */
struct casio_fsfuncs_s {
casio_fs_close_t *casio_fsfuncs_close;
casio_fs_makepath_t *casio_fsfuncs_makepath;
casio_fs_freepath_t *casio_fsfuncs_freepath;
casio_fs_stat_t *casio_fsfuncs_stat;
casio_fs_makedir_t *casio_fsfuncs_makedir;
casio_fs_del_t *casio_fsfuncs_del;
@ -146,21 +162,31 @@ struct casio_fsfuncs_s {
casio_fs_list_t *casio_fsfuncs_list;
casio_fs_open_t *casio_fsfuncs_open;
casio_fs_close_t *casio_fsfuncs_close;
};
/* ************************************************************************* */
/* Filesystem public functions */
/* ************************************************************************* */
CASIO_BEGIN_DECLS
/* Open a custom filesystem. */
CASIO_EXTERN int CASIO_EXPORT casio_open_fs
OF((casio_filesystem_t **casio__fs,
void *casio__cookie, const char *casio__dirsep,
const casio_fsfuncs_t *casio__funcs));
OF((casio_filesystem_t **casio__filesystem,
void *casio__cookie, const casio_fsfuncs_t *casio__funcs));
/* Manipulate native paths. */
CASIO_EXTERN int CASIO_EXPORT casio_make_native_path
OF((casio_filesystem_t *casio__filesystem,
void **casio__native_path, casio_path_t *casio__path));
CASIO_EXTERN void CASIO_EXPORT casio_free_native_path
OF((casio_filesystem_t *casio__filesystem,
void *casio__native_path));
/* Make a directory. */
CASIO_EXTERN int CASIO_EXPORT casio_makedir
OF((casio_filesystem_t *casio__fs, const char *casio__path));
OF((casio_filesystem_t *casio__fs, casio_path_t *casio__path));
CASIO_END_DECLS
CASIO_END_NAMESPACE

View File

@ -1,5 +1,5 @@
/* ****************************************************************************
* fs/builtin/posix/path.c -- POSIX path conversions.
* fs/builtin/posix/frompath.c -- POSIX path to libcasio path.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
@ -38,61 +38,6 @@ CASIO_LOCAL casio_pathnode_t *makepathnode(size_t size)
return (node);
}
/**
* casio_make_posix_path:
* Make a POSIX path from a platform-agnostic path.
*
* @arg ppath the path to make.
* @arg array the path array.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_make_posix_path(char **ppath, casio_path_t *array)
{
size_t length; const casio_pathnode_t *node;
char *path;
/* Make up the length and validate. */
length = !(array->casio_path_flags & casio_pathflag_rel);
node = array->casio_path_nodes;
while (node) {
size_t nodesize = node->casio_pathnode_size;
/* Check that there is no forbidden characters. */
if (memchr(node->casio_pathnode_name, 0, nodesize)
|| memchr(node->casio_pathnode_name, '/', nodesize))
return (casio_error_invalid);
/* Iterate on the node, add to the length. */
length += nodesize;
node = node->casio_pathnode_next;
if (node) length++; /* '/' */
}
/* Allocate the path. */
*ppath = malloc(length + 1);
path = *ppath; if (!path) return (casio_error_alloc);
/* Fill the path. */
if (~array->casio_path_flags & casio_pathflag_rel)
*path++ = '/';
node = array->casio_path_nodes;
while (node) {
size_t nodesize = node->casio_pathnode_size;
/* Copy the node data. */
memcpy(path, node->casio_pathnode_name, nodesize);
path += nodesize;
/* Iterate on the node, copy a slash if needed. */
node = node->casio_pathnode_next;
if (node) *path++ = '/';
}
/* No error has occured! */
return (0);
}
/**
* casio_make_posix_path_array:
* Make a path array from a POSIX path.

View File

@ -0,0 +1,43 @@
/* ****************************************************************************
* fs/builtin/posix/open.c -- open a POSIX filesystem.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "posix.h"
#ifndef LIBCASIO_DISABLED_POSIX_FS
/* Callbacks. */
CASIO_LOCAL casio_fsfuncs_t posix_fs_funcs = {
NULL, &casio_make_posix_path, &casio_free_posix_path,
&casio_posix_stat, NULL, NULL, NULL,
NULL, NULL
};
/**
* casio_open_posix_fs:
* Open a POSIX filesystem interface.
*
* @arg fs the filesystem interface to make.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_open_posix_fs(casio_filesystem_t **fs)
{
return (casio_open_fs(fs, NULL, &posix_fs_funcs));
}
#endif

View File

@ -25,15 +25,18 @@
/* Path conversions. */
CASIO_EXTERN int CASIO_EXPORT casio_make_posix_path
OF((char **casio__path, casio_path_t *casio__array));
CASIO_EXTERN int CASIO_EXPORT casio_make_posix_path
OF((void *casio__cookie, void **casio__path, casio_path_t *casio__array));
CASIO_EXTERN void CASIO_EXPORT casio_free_posix_path
OF((void *casio__cookie, void *casio__path));
CASIO_EXTERN int CASIO_EXPORT casio_make_posix_path_array
OF((casio_path_t **casio__path, const char *casio__rawpath));
/* File information gathering. */
CASIO_EXTERN int CASIO_EXPORT casio_posix_stat
OF((void *casio__cookie, casio_path_t *casio__path,
OF((void *casio__cookie, void *casio__path,
casio_stat_t *casio__file_info));
# endif

View File

@ -24,27 +24,21 @@
* POSIX stat.
*
* @arg cookie the POSIX cookie.
* @arg apath the path to get.
* @arg path the POSIX path to get.
* @arg stat the file information to fill.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_posix_stat(void *cookie,
casio_path_t *apath, casio_stat_t *file_info)
void *path, casio_stat_t *file_info)
{
int err; char *path = NULL;
struct stat statbuf;
(void)cookie;
/* Make the POSIX path. */
err = casio_make_posix_path(&path, apath);
if (err) return (err);
/* Make the stat. */
if (lstat(path, &statbuf)) {
if (lstat((char*)path, &statbuf)) {
/* FIXME: different kinds of errnos? */
err = casio_error_unknown;
goto fail;
return (casio_error_unknown);
}
/* Gather the type. */
@ -76,11 +70,7 @@ int CASIO_EXPORT casio_posix_stat(void *cookie,
/* Get the rest, and return. */
file_info->casio_stat_flags = 0;
file_info->casio_stat_size = statbuf.st_size;
err = 0;
fail:
free(path);
return (err);
return (0);
}
#endif

View File

@ -0,0 +1,94 @@
/* ****************************************************************************
* fs/builtin/posix/topath.c -- POSIX path conversions.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "posix.h"
#ifndef LIBCASIO_DISABLED_POSIX_FS
/**
* casio_make_posix_path:
* Make a POSIX path from a platform-agnostic path.
*
* @arg cookie the filesystem cookie (unused).
* @arg ppath the path to make.
* @arg array the path array.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_make_posix_path(void *cookie,
void **ppath, casio_path_t *array)
{
size_t length; const casio_pathnode_t *node;
char *path;
(void)cookie;
/* Make up the length and validate. */
length = !(array->casio_path_flags & casio_pathflag_rel);
node = array->casio_path_nodes;
while (node) {
size_t nodesize = node->casio_pathnode_size;
/* Check that there is no forbidden characters. */
if (memchr(node->casio_pathnode_name, 0, nodesize)
|| memchr(node->casio_pathnode_name, '/', nodesize))
return (casio_error_invalid);
/* Iterate on the node, add to the length. */
length += nodesize;
node = node->casio_pathnode_next;
if (node) length++; /* '/' */
}
/* Allocate the path. */
*ppath = casio_alloc(length + 1, 1);
path = (char*)*ppath;
if (!path) return (casio_error_alloc);
/* Fill the path. */
if (~array->casio_path_flags & casio_pathflag_rel)
*path++ = '/';
node = array->casio_path_nodes;
while (node) {
size_t nodesize = node->casio_pathnode_size;
/* Copy the node data. */
memcpy(path, node->casio_pathnode_name, nodesize);
path += nodesize;
/* Iterate on the node, copy a slash if needed. */
node = node->casio_pathnode_next;
if (node) *path++ = '/';
}
/* No error has occured! */
return (0);
}
/**
* casio_free_posix_path:
* Free a POSIX path.
*
* @arg cookie the cookie.
* @arg nat the native path.
*/
void CASIO_EXPORT casio_free_posix_path(void *cookie, void *nat)
{
casio_free(nat);
}
#endif

View File

@ -22,8 +22,6 @@
struct casio_filesystem_s {
void *casio_filesystem_cookie;
const char *casio_filesystem_path_encoding;
casio_fsfuncs_t casio_filesystem_functions;
};

47
src/fs/makedir.c Normal file
View File

@ -0,0 +1,47 @@
/* ****************************************************************************
* fs/path.c -- make a directory on a libcasio filesystem.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "fs.h"
/**
* casio_makedir:
* Make a directory.
*
* @arg fs the filesystem.
* @arg path the path of the directory to make.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_makedir(casio_filesystem_t *fs, casio_path_t *path)
{
casio_fs_makedir_t *makedir;
int err; void *nat = NULL;
/* Get the callback. */
makedir = fs->casio_filesystem_functions.casio_fsfuncs_makedir;
if (!makedir) return (casio_error_op);
/* Get the native path. */
err = casio_make_native_path(fs, &nat, path);
if (err) return (err);
/* Make the directory, free the native path, return. */
err = (*makedir)(fs->casio_filesystem_cookie, nat);
casio_free_native_path(fs, nat);
return (err);
}

49
src/fs/open.c Normal file
View File

@ -0,0 +1,49 @@
/* ****************************************************************************
* fs/open.c -- open a libcasio filesystem.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "fs.h"
/**
* casio_open_fs:
* Open a filesystem.
*
* @arg pfs the filesystem to open.
* @arg cookie the filesystem cookie.
* @arg funcs the filesystem callbacks.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_open_fs(casio_filesystem_t **pfs,
void *cookie, const casio_fsfuncs_t *funcs)
{
int err; casio_filesystem_t *fs;
/* Allocate the filesystem. */
*pfs = malloc(sizeof(casio_filesystem_t)); fs = *pfs;
if (!fs) { err = casio_error_alloc; goto fail; }
/* Copy the data into it. */
fs->casio_filesystem_cookie = cookie;
memcpy(&fs->casio_filesystem_functions, funcs, sizeof(casio_fsfuncs_t));
return (0);
fail:
if (funcs->casio_fsfuncs_close)
(*funcs->casio_fsfuncs_close)(cookie);
return (err);
}

62
src/fs/path.c Normal file
View File

@ -0,0 +1,62 @@
/* ****************************************************************************
* fs/path.c -- filesystem native path management utilities.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libcasio.
* libcasio is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libcasio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libcasio; if not, see <http://www.gnu.org/licenses/>.
* ************************************************************************* */
#include "fs.h"
/**
* casio_make_native_path:
* Make a filesystem native path.
*
* @arg fs the filesystem.
* @arg nat the native path to make.
* @arg path the path to convert.
* @return the error code (0 if ok).
*/
int CASIO_EXPORT casio_make_native_path(casio_filesystem_t *fs,
void **nat, casio_path_t *path)
{
casio_fs_makepath_t *makepath;
/* Get the callback. */
makepath = fs->casio_filesystem_functions.casio_fsfuncs_makepath;
if (!makepath) return (casio_error_op);
/* Make the native path. */
return ((*makepath)(fs->casio_filesystem_cookie, nat, path));
}
/**
* casio_free_native_path:
* Free a filesystem native path.
*
* @arg fs the filesystem.
* @arg nat the native path to free.
*/
void CASIO_EXPORT casio_free_native_path(casio_filesystem_t *fs, void *nat)
{
casio_fs_freepath_t *freepath;
/* Get the callback. */
freepath = fs->casio_filesystem_functions.casio_fsfuncs_freepath;
if (!freepath) return ;
/* Free the native path. */
(*freepath)(fs->casio_filesystem_cookie, nat);
}

View File

@ -40,6 +40,7 @@ int CASIO_EXPORT casio_decode_mcs_capture(casio_mcsfile_t **h,
DREAD(hd)
/* make final head and file */
head->casio_mcshead_count = 1;
head->casio_mcshead_width = be16toh(hd.casio_mcs_captureheader_width);
head->casio_mcshead_height = be16toh(hd.casio_mcs_captureheader_height);
err = casio_make_mcsfile(h, head);
@ -92,6 +93,8 @@ int CASIO_EXPORT casio_decode_mcs_picture(casio_mcsfile_t **h,
unsigned char *pics_raw = NULL; size_t pic_size;
/* make final head */
msg((ll_info, "Size is 0x%04X", head->casio_mcshead_size));
head->casio_mcshead_count = head->casio_mcshead_size / 1024;
head->casio_mcshead_width = 128;
head->casio_mcshead_height = 64;
err = casio_make_mcsfile(h, head);

View File

@ -88,10 +88,8 @@ int CASIO_EXPORT casio_prepare_mcsfile(casio_mcsfile_t *handle,
/* allocate the set of pixels */
case casio_mcstype_pict: case casio_mcstype_capt:
/* set count */
head->casio_mcshead_count = 1;
if (head->casio_mcshead_type == casio_mcstype_pict)
head->casio_mcshead_count = 2;
/* NOTICE: count used to be deduced from type,
* but not anymore. */
/* allocate directory */
if (head->casio_mcshead_count <= 1)