diff --git a/.gitmodules b/.gitmodules index f67c09e..e69de29 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +0,0 @@ -[submodule "tools/fontcharacter_reference"] - path = tools/fontcharacter_reference - url = https://github.com/cakeisalie5/fontcharacter_reference.git -[submodule "tools/.fontcharacter-root"] - path = tools/.fontcharacter-root - url = https://github.com/cakeisalie5/fontcharacter-python.git diff --git a/Makefile.vars b/Makefile.vars index 8e5262c..012eb6a 100755 --- a/Makefile.vars +++ b/Makefile.vars @@ -57,7 +57,7 @@ ANAMES := lib$(NAME).lib lib$(NAME).a lib$(NAME).dll.a # Required libs - LIBS := zlib + LIBS := zlib libfontcharacter #******************************************************************************# # Binary utilities # diff --git a/README.md b/README.md index beb08f8..26fc5fb 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,10 @@ I took these as a reference because these are the ones I work with. | [python3](https://www.python.org/) | >= 3.5 | ### Runtime dependencies -| Name | Version | -| -------------------------------------------------- | -------- | -| [zlib](http://zlib.net/) | >= 1.2.8 | +| Name | Version | +| ------------------------------------------------------------------- | -------- | +| [zlib](http://zlib.net/) | >= 1.2.8 | +| [libfontcharacter](https://github.com/cakeisalie5/libfontcharacter) | >= 1.0 | ## Building Just `./configure` then `make`. diff --git a/configure b/configure index b7fb374..bf795bb 100755 --- a/configure +++ b/configure @@ -18,6 +18,7 @@ more_warnings= # Build options target= +no_file= static= windows= optimize_size= @@ -62,6 +63,7 @@ Build options: --static build a static library (by default, dynamic) --windows build DLLs and .libs instead of ELF and archives --optimize-size optimize size instead of speed + --no-file do not use the libc FILE interface --loglevel=LOGLEVEL library log level [$loglevel] Installation options: @@ -125,6 +127,7 @@ for arg ; do case "$arg" in --static) static=y ;; --windows) windows=y ;; --optimize-size) optimize_size=y ;; +--no-file) no_file=y ;; --loglevel=*) level="${arg#*=}" # check if is in array @@ -213,8 +216,8 @@ fi make mrproper MAKE_FULL_LOG=y 1>/dev/null 2>/dev/null # Create the configuration header -opt= -# [no option yet.] +opt="--version=${version}" +[ "$no_file" ] && opt+=" --no-file" tools/write-header-config $opt >include/libg1m/config.h # Do it! diff --git a/doc/g1m_fcstombs.3.txt b/doc/g1m_fcstombs.3.txt deleted file mode 100644 index ac2eb71..0000000 --- a/doc/g1m_fcstombs.3.txt +++ /dev/null @@ -1,47 +0,0 @@ -G1M_FCSTOMBS(3) -=============== -Thomas "Cakeisalie5" Touhey -:Email: thomas@touhey.fr -:man source: libg1m -:man manual: libg1m manual - -NAME ----- -g1m_fcstombs - convert a FONTCHARACTER string to a multi-byte string - -SYNOPSIS --------- -[source,c] ----- -#include - -size_t g1m_fcstombs(char *dst, const FONTCHARACTER *src, size_t n); ----- - -DESCRIPTION ------------ -Makes a multi-byte string out of a FONTCHARACTER string. If *dst* is *NULL*, -only the size will be calculated. Occupies max *n* character, terminating -zero included. - -Will end the created string if *n > 0*. If a nul character is found in the -source string, it will be copied and won't be counted. - -RETURN VALUE ------------- -The size of the FONTCHARACTER string. - -EXAMPLE -------- -[source,c] ----- -size_t len = g1m_fcstombs(NULL, fcs, n); -char *s = malloc(len + 1); -if (!s) - return (malloc_pls); -g1m_fcstombs(s, fcs, n); ----- - -SEE ALSO --------- -*libg1m*(3), *g1m_mbstofcs*(3) diff --git a/doc/g1m_fctomb.3.txt b/doc/g1m_fctomb.3.txt deleted file mode 100644 index be8e7c8..0000000 --- a/doc/g1m_fctomb.3.txt +++ /dev/null @@ -1,35 +0,0 @@ -G1M_FCTOMB(3) -============= -Thomas "Cakeisalie5" Touhey -:Email: thomas@touhey.fr -:man source: libg1m -:man manual: libg1m manual - -NAME ----- -g1m_fctomb - FONTCHARACTER to multi-byte - -SYNOPSIS --------- -[source,c] ----- -#include - -int g1m_fctomb(char *s, FONTCHARACTER fc); ----- - -DESCRIPTION ------------ -Convert a FONTCHARACTER character to its multibyte representation, -and stores it at the beginning of the character array pointed to by *s*. - -The programmer must ensure that there is room for at least FC_MB_MAX bytes -at *s*. - -RETURN VALUE ------------- -This function returns the length of the calculated multibyte function. - -SEE ALSO --------- -*libg1m*(3), *g1m_mbtofc*(3) diff --git a/doc/g1m_mbstofcs.3.txt b/doc/g1m_mbstofcs.3.txt deleted file mode 100644 index 1294c41..0000000 --- a/doc/g1m_mbstofcs.3.txt +++ /dev/null @@ -1,53 +0,0 @@ -G1M_MBSTOFCS(3) -=============== -Thomas "Cakeisalie5" Touhey -:Email: thomas@touhey.fr -:man source: libg1m -:man manual: libg1m manual - -NAME ----- -g1m_mbstofcs - convert a multi-byte string to a FONTCHARACTER string - -SYNOPSIS --------- -[source,c] ----- -#include - -size_t g1m_mbstofcs(FONTCHARACTER *dest, const char *src, size_t n); ----- - -DESCRIPTION ------------ -Makes a FONTCHARACTER string out of a multi-byte string. If **dest* is *NULL*, -only the size will be calculated. *n* is the size of the destination buffer, -if it's zero, unlimited space is supposed (useful if you don't know the size -of the destination buffer you're going to allocate yet). - -Will always end the destination buffer. If a nul character was found in the -source string, it will not be counted and copy/counting will stop there. - -If an invalid multi-byte sequence is found, will simply act as if a nul -character was found in the source string. - -RETURN VALUE ------------- -The size of the calculated FONTCHARACTER string. - -EXAMPLE -------- -[source,c] ----- -size_t len = g1m_mbstofcs(NULL, src, 0); -if (len == (size_t)-1) - return (oops_i_did_it_again); -FONTCHARACTER *fcs = malloc(sizeof(FONTCHARACTER) * (len + 1)); -if (!fcs) - return (malloc_me_baby_one_more_time); -g1m_mbstofcs(fcs, src, len + 1); ----- - -SEE ALSO --------- -*libg1m*(3), *g1m_fcstombs*(3) diff --git a/doc/g1m_mbtofc.3.txt b/doc/g1m_mbtofc.3.txt deleted file mode 100644 index a0369e2..0000000 --- a/doc/g1m_mbtofc.3.txt +++ /dev/null @@ -1,33 +0,0 @@ -G1M_MBTOFC(3) -============= -Thomas "Cakeisalie5" Touhey -:Email: thomas@touhey.fr -:man source: libg1m -:man manual: libg1m manual - -NAME ----- -g1m_mbtofc - convert a multi-byte sequence to a FONTCHARACTER char - -SYNOPSIS --------- -[source,c] ----- -#include - -int g1m_mbtofc(FONTCHARACTER *pfc, const char *s, size_t n); ----- - -DESCRIPTION ------------ -Make a FONTCHARACTER out of a multi-byte sequence from **s*. *n* is the -maximum size of *s* (if zero, considered as *FC_MB_MAX*). - -RETURN VALUE ------------- --1 if an incomplete multi-byte sequence was found, zero if the found character -was a terminating character, the size of the multi-byte sequence otherwise. - -SEE ALSO --------- -*libg1m*(3), *g1m_fctomb*(3) diff --git a/include/libg1m.h b/include/libg1m.h index c358e15..d5bc22b 100644 --- a/include/libg1m.h +++ b/include/libg1m.h @@ -9,9 +9,11 @@ /* ************************************************************************** */ #ifndef LIBG1M_H # define LIBG1M_H +# include +# include # include -# include # include +# include # include # include # include @@ -25,30 +27,27 @@ extern "C" { /* ************************************************************************** */ /* Errors */ /* ************************************************************************** */ -/* main enumeration */ -typedef enum { - g1m_noerror, +/* WARNING: Whenever you add/remove errors, think about updating core/strerror! + * --- + * First, the none error. */ +# define g1m_noerror 0x00 - /* no stream sent -- if lib made the libc calls, check errno */ - g1m_error_nostream, - /* could not read from stream */ - g1m_error_noread, - /* could not seek in stream */ - g1m_error_noseek, +/* Then, the miscallenous errors */ +# define g1m_error_alloc 0x01 +# define g1m_error_op 0x02 - /* wrong type */ - g1m_error_wrong_type, +/* Then, the stream errors */ +# define g1m_error_nostream 0x10 +# define g1m_error_noread 0x11 +# define g1m_error_noseek 0x12 - /* magic or control problem */ - g1m_error_magic, - /* unexpected EOF */ - g1m_error_eof, - /* memory allocation problem */ - g1m_error_alloc, +/* Then, the decoding errors */ +# define g1m_error_magic 0x20 +# define g1m_error_eof 0x21 +# define g1m_error_wrong_type 0x22 - /* operation not supported for this type */ - g1m_error_op, -} g1m_error_t; +/* Error type -- for compatibility with old programs using enum */ +typedef int g1m_error_t; /* Message getting macro */ extern const char *g1m_error_strings[]; @@ -59,28 +58,30 @@ extern const char *g1m_error_strings[]; /* MCS-Related types */ /* ************************************************************************** */ /* BCD matrix - real and complex */ -typedef struct { - struct bcd real; - struct bcd imgn; +typedef struct g1m_mcs_cell_s { + g1m_bcd_t real; + g1m_bcd_t imgn; int used; } g1m_mcs_cell_t; /* MCS file type */ +typedef unsigned int g1m_mcsfile_type_t; +# define g1m_mcstype_unknown 0x000 +# define g1m_mcstype_program 0x001 +# define g1m_mcstype_list 0x002 +# define g1m_mcstype_mat 0x004 +# define g1m_mcstype_pict 0x008 +# define g1m_mcstype_capt 0x010 +# define g1m_mcstype_spreadsheet 0x020 +# define g1m_mcstype_string 0x040 +# define g1m_mcstype_setup 0x080 +# define g1m_mcstype_alphamem 0x100 +# define g1m_mcstype_vct 0x200 + +/* MCS file type aliases */ # define g1m_mcstype_picture g1m_mcstype_pict # define g1m_mcstype_capture g1m_mcstype_capt -# define g1m_mcstype_vector g1m_mcstype_vct -typedef enum { - g1m_mcstype_program = 0x01, - g1m_mcstype_list = 0x02, - g1m_mcstype_mat = 0x04, - g1m_mcstype_pict = 0x08, - g1m_mcstype_capt = 0x10, - g1m_mcstype_spreadsheet = 0x20, - g1m_mcstype_string = 0x40, - g1m_mcstype_setup = 0x80, - g1m_mcstype_alphamem = 0x100, - g1m_mcstype_vct = 0x200, -} g1m_mcsfile_type_t; +# define g1m_mcstype_vector g1m_mcstype_vct /* uses id */ # define g1m_mcstype_uses_id(T) ((T) & (\ @@ -90,9 +91,9 @@ typedef enum { # define g1m_get_id_minor(I) ((I) & 31) /* mcs file */ -# define g1m_has_password(F) (F)->password[0] +# define g1m_has_password(F) (F)->password[0] # define g1m_remove_password(F) (F)->password[0] = 0 -typedef struct { +typedef struct g1m_mcsfile_s { /* file type */ unsigned int type; @@ -125,25 +126,45 @@ typedef struct { } g1m_mcsfile_t; /* version */ -typedef struct { +typedef struct g1m_version_s { int major; int minor; int revision; } g1m_version_t; +/* ************************************************************************** */ +/* Storage files */ +/* ************************************************************************** */ +/* storage file type */ +typedef unsigned int g1m_filetype_t; +# define g1m_filetype_directory 0x01 +# define g1m_filetype_generic 0x02 + +/* storage file structure */ +typedef struct g1m_file_s { + /* meta info */ + unsigned int type; + struct g1m_file_s *parent; + int deleted; + + /* content */ + void *content; +} g1m_file_t; + /* ************************************************************************** */ /* E-activities related types */ /* ************************************************************************** */ -/* line type */ -# define g1m_linetype_pict g1m_linetype_picture -# define g1m_linetype_heading g1m_linetype_title -# define g1m_linetype_standard_heading g1m_linetype_title -typedef enum { - g1m_linetype_title = 0x01, - g1m_linetype_text = 0x02, - g1m_linetype_picture = 0x04, - g1m_linetype_eact = 0x08 -} g1m_eact_line_type_t; +/* Line type */ +typedef unsigned int g1m_eact_line_type_t; +# define g1m_linetype_title 0x01 +# define g1m_linetype_text 0x02 +# define g1m_linetype_picture 0x04 +# define g1m_linetype_eact 0x08 + +/* Line type aliases */ +# define g1m_linetype_pict g1m_linetype_picture +# define g1m_linetype_heading g1m_linetype_title +# define g1m_linetype_standard_heading g1m_linetype_title /* line */ typedef struct g1m_line_s { @@ -164,27 +185,27 @@ typedef struct g1m_line_s { /* ************************************************************************** */ /* General types */ /* ************************************************************************** */ -/* type */ -# define g1m_type_pict g1m_type_picture -# define g1m_type_eactivity g1m_type_eact -# define g1m_type_add_in g1m_type_addin -typedef enum { - g1m_type_addin = 0x01, - g1m_type_mcs = 0x02, - g1m_type_eact = 0x04, - g1m_type_pict = 0x08, - g1m_type_lang = 0x10, - g1m_type_fkey = 0x20, - g1m_type_storage = 0x40 -} g1m_type_t; +/* General type */ +typedef unsigned int g1m_type_t; +# define g1m_type_addin 0x01 +# define g1m_type_mcs 0x02 +# define g1m_type_eact 0x04 +# define g1m_type_picture 0x08 +# define g1m_type_lang 0x10 +# define g1m_type_fkey 0x20 +# define g1m_type_storage 0x40 -/* platform */ -typedef enum { - g1m_platform_none = 0x00, - g1m_platform_fx = 0x01, - g1m_platform_cp = 0x02, - g1m_platform_cg = 0x04 -} g1m_platform_t; +/* General type aliases */ +# define g1m_type_pict g1m_type_picture +# define g1m_type_eactivity g1m_type_eact +# define g1m_type_add_in g1m_type_addin + +/* Platform */ +typedef unsigned int g1m_platform_t; +# define g1m_platform_none 0x00 +# define g1m_platform_fx 0x01 +# define g1m_platform_cp 0x02 +# define g1m_platform_cg 0x04 /* handle */ typedef struct { @@ -206,6 +227,9 @@ typedef struct { /* MCS list */ g1m_mcsfile_t **files; + /* Storage files list */ + g1m_file_t **sfiles; + /* Messages list */ char **messages; @@ -231,7 +255,7 @@ int g1m_fopen(g1m_t **handle, const char *path, FILE *stream, g1m_type_t expected_type); /* open MCS handle (this one is mainly for `libp7`) */ -int g1m_parse_mcsfile_content(g1m_mcsfile_t **handle, FILE *stream, +int g1m_decode_mcsfile_content(g1m_mcsfile_t **handle, g1m_buffer_t *buffer, int raw_type, const unsigned char *groupname, const unsigned char *dirname, const unsigned char *filename, uint_fast32_t filesize); diff --git a/include/libg1m/basic.h b/include/libg1m/basic.h deleted file mode 100644 index 941d24c..0000000 --- a/include/libg1m/basic.h +++ /dev/null @@ -1,49 +0,0 @@ -/* ************************************************************************** */ -/* _____ _ */ -/* libg1m/basic.h |_ _|__ _ _| |__ ___ _ _ */ -/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ -/* | | (_) | |_| | | | | __/ |_| | */ -/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2017/01/07 17:00:25 |___/ */ -/* */ -/* ************************************************************************** */ -#ifndef LIBG1M_BASIC_H -# define LIBG1M_BASIC_H -# define CBASIC_MAX_ARGUMENTS 3 - -/* libg1m has utilities for interacting with Basic programs! - * Everything is basically a statement, but when it's just a - * value/variable/..., it's instruction 0x00 with one argument. - * - * Here are the types an argument can take: */ - -enum g1m_argument_type { - g1m_argtype_value, - g1m_argtype_variable, - g1m_argtype_string, - g1m_argtype_list, - g1m_argtype_mat, -}; - -/* And here's the structure of a statement: */ - -typedef struct g1m_basic_statement_s { - FONTCHARACTER opcode; - int argtype, id; - - /* BCD values */ - struct bcd real; - struct bcd imgn; - - /* arguments */ - int nargs; - struct g1m_basic_statement_s *args; -} g1m_bst_t; - -/* And here is the function to fetch an instruction from a program content - * buffer: */ - -int g1m_fetch_instruction(const FONTCHARACTER *buf, size_t size, - size_t *isize, g1m_bst_t *statement); - -#endif /* LIBG1M_BASIC_H */ diff --git a/include/libg1m/bcd.h b/include/libg1m/bcd.h index e19a511..0f9839e 100644 --- a/include/libg1m/bcd.h +++ b/include/libg1m/bcd.h @@ -32,22 +32,22 @@ extern "C" { * * The other 15 digits are the mantissa. So the number is: (M ** (E + 1)) */ -struct bcd { +typedef struct bcd { /* the BCD value itself */ unsigned char BCDval[9]; /* some 4-bytes alignment stuff */ unsigned char _align[3]; -}; +} g1m_bcd_t; /* ************************************************************************** */ /* BCD utilities */ /* ************************************************************************** */ /* Arithmetic */ -int g1m_bcd_is_nonzero(struct bcd *bcd); +int g1m_bcd_is_nonzero(g1m_bcd_t *bcd); /* String/BCD */ -char *g1m_bcdtoa(struct bcd *bcd); +char *g1m_bcdtoa(g1m_bcd_t *bcd); /* ************************************************************************** */ /* Inline BCD utilities */ @@ -60,7 +60,7 @@ char *g1m_bcdtoa(struct bcd *bcd); * @return a boolean. */ -static inline int g1m_bcd_is_negative(struct bcd *bcd) +static inline int g1m_bcd_is_negative(g1m_bcd_t *bcd) { return (bcd->BCDval[0] >= 0x50); } @@ -73,7 +73,7 @@ static inline int g1m_bcd_is_negative(struct bcd *bcd) * @return a boolean. */ -static inline int g1m_bcd_high_bit(struct bcd *bcd) +static inline int g1m_bcd_high_bit(g1m_bcd_t *bcd) { return (bcd->BCDval[0] & 0x80); } diff --git a/include/libg1m/buffer.h b/include/libg1m/buffer.h new file mode 100644 index 0000000..495caef --- /dev/null +++ b/include/libg1m/buffer.h @@ -0,0 +1,40 @@ +/* ************************************************************************** */ +/* _____ _ */ +/* libg1m/buffer.h |_ _|__ _ _| |__ ___ _ _ */ +/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ +/* | | (_) | |_| | | | | __/ |_| | */ +/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ +/* Last updated: 2017/02/12 16:04:33 |___/ */ +/* */ +/* ************************************************************************** */ +#ifndef LIBG1M_BUFFER_H +# define LIBG1M_BUFFER_H +# include +# include + +/* This file is there so it is possible to use a custom buffer for file + * transferring. There are two use cases: + * - if you use a buffer to send data: the size of the element to send should + * be put in `size`, and the `read` function will be used; + * - if you use a buffer to receive data: if the `announce` function is set, + * it will be called with the size of the file to receive, in order to + * prepare space for the file. If the announce function returns an error, + * then the file will not be sent. + * + * Here are the used functions: */ + +typedef int (*g1m_buffer_read_t)(void*, unsigned char*, size_t); +typedef int (*g1m_buffer_write_t)(void*, const unsigned char*, size_t); +typedef int (*g1m_buffer_announce_t)(void*, uint_fast32_t size); + +/* And here is the structure of a buffer: */ + +typedef struct { + void *cookie; + + g1m_buffer_read_t read; + g1m_buffer_write_t write; + g1m_buffer_announce_t announce; +} g1m_buffer_t; + +#endif /* LIBG1M_BUFFER_H */ diff --git a/include/libg1m/color.h b/include/libg1m/color.h index 7e18791..f19c4a4 100644 --- a/include/libg1m/color.h +++ b/include/libg1m/color.h @@ -18,21 +18,21 @@ * * These colors are the following: */ -typedef enum { - g1m_color_black = 0, - g1m_color_blue = 1, - g1m_color_green = 2, - g1m_color_cyan = 3, - g1m_color_red = 4, - g1m_color_magenta = 5, - g1m_color_yellow = 6, - g1m_color_white = 7 -} g1m_color_t; +typedef int g1m_color_t; +# define g1m_color_black 0x0 +# define g1m_color_blue 0x1 +# define g1m_color_green 0x2 +# define g1m_color_cyan 0x3 +# define g1m_color_red 0x4 +# define g1m_color_magenta 0x5 +# define g1m_color_yellow 0x6 +# define g1m_color_white 0x7 /* And here are some macros to help you out: */ -# define g1m_marker_color(C) (((C) & 0xf0) >> 4) -# define g1m_char_color(C) ((C) & 0xf) +# define g1m_marker_color(C) (((C) & 0xf0) >> 4) +# define g1m_char_color(C) ((C) & 0xf) + # define g1m_character_color(C) g1m_char_color(C) #endif /* LIBG1M_COLOR_H */ diff --git a/include/libg1m/fontcharacter.h b/include/libg1m/fontcharacter.h deleted file mode 100644 index daeb8b8..0000000 --- a/include/libg1m/fontcharacter.h +++ /dev/null @@ -1,43 +0,0 @@ -/* ************************************************************************** */ -/* _____ _ */ -/* libg1m/fontcharacter.h |_ _|__ _ _| |__ ___ _ _ */ -/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ -/* | | (_) | |_| | | | | __/ |_| | */ -/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/11/21 09:26:47 |___/ */ -/* */ -/* ************************************************************************** */ -#ifndef LIBG1M_FONTCHARACTER_H -# define LIBG1M_FONTCHARACTER_H -# include -# include -# define FC_MB_MAX 2 -# ifdef __cplusplus -extern "C" { -# endif - -/* ************************************************************************** */ -/* Main type */ -/* ************************************************************************** */ -/* CASIO's character encoding, named `FONTCHARACTER` by its SDK, is a simple - * multibyte one : if the character is a special one, then the next one is - * to read. - * - * Special characters are: 0x7F, 0xF7, 0xF9, 0xE5, 0xE6, 0xE7. */ -typedef uint16_t FONTCHARACTER; - -/* ************************************************************************** */ -/* Utilities */ -/* ************************************************************************** */ -/* encoding characters */ -int g1m_mbtofc(FONTCHARACTER *pfc, const char *s, size_t n); -int g1m_fctomb(char *s, FONTCHARACTER fc); - -/* encoding strings */ -size_t g1m_mbstofcs(FONTCHARACTER *dst, const char *src, size_t n); -size_t g1m_fcstombs(char *dst, const FONTCHARACTER *src, size_t n); - -# ifdef __cplusplus -} -# endif -#endif /* LIBG1M_FONTCHARACTER_H */ diff --git a/include/libg1m/format.h b/include/libg1m/format.h index 67cb75e..8dfa5a7 100644 --- a/include/libg1m/format.h +++ b/include/libg1m/format.h @@ -70,7 +70,9 @@ struct standard_header { * We also thought the subtype was only one-byte long, but the C2P came along * with its "c2p\0\0\0" subtype. * - * All main ID/types correspondances are in the `src/utils/type.c` file. */ + * All main ID/types correspondances are in the `src/utils/type.c` file. + * From a user program, you can use the functions + * in `include/libg1m/formatutils.h`. */ # pragma pack() diff --git a/include/libg1m/format/storage.h b/include/libg1m/format/storage.h index f7b4003..f06aec0 100644 --- a/include/libg1m/format/storage.h +++ b/include/libg1m/format/storage.h @@ -32,8 +32,11 @@ struct storage_entry { /* the type number - see below */ uint16_t type; - /* the unique number of the entry */ - uint16_t uuid; + /* the number of the entry + * if this field is 0x00, just ignore the entry. + * we don't know why entries with this field set to 0x00 exist... + * (probably backups?) */ + uint16_t id; /* the raw subheader */ uint8_t raw_subheader[28]; @@ -50,26 +53,46 @@ enum storage_entry_type { storage_entrytype_fragment = 0x130, }; -/* The list has 0x800 entries, and occupies the two first sectors (or maybe - * just one, but it looks like data storage starts at sector 3). Entries with - * a type being 0xFFFF should not be read. */ +/* The special nibble is usually zero when deleted, and non-zero when active. + * According to Simon Lothar, this is because it is possible to clear bits + * on the flash by flashwriting a short value only; but when it comes to + * set bits, it becomes more tricky. + * + * This is also why optimizing is not done straight away (to save the flash + * a little). + * + * The list can have to 0x800 entries, and occupies the first sector. + * Simon Lothar says the list can expand to the second sector (which is used + * only if there is no space in the index sector or the other data sectors). + * Entries with the 0xFFFF type should not be read. + * + * Some entry types can have parents. In this case, they have parent type, + * and parent number fields. This is because elements with different types + * follow different numerations; so the type field is here on which numeration + * to search for the member. If the parent type is 0xFFFF (or -1, as some say), + * then there is no parent. + * + * For now, only directories as parents for files have been encountered. */ /* ************************************************************************** */ /* Sectors */ /* ************************************************************************** */ /* Sectors represent the physical sectors of the storage memory (space!). - * Simon Lothar says that there are 27 entries for them (or 25 "not on the - * AU" in the other documentation, whatever that means). If the logical number - * is 0xFFFFFFFF, the sector is unused. First sector contains gibberish in the - * logical number field, as it's occupied by the directory. + * They are 64 KiB large. * - * Their special nibble is either 0x04 or 0x00, I don't know why yet. - * Here is their subheader structure: */ + * Simon Lothar says that there are 27 entries for them (or 14 on the AU models + * because of australian exam regulations). If the logical number + * is 0xFFFFFFFF, the sector is unused. (sometimes the logical number field + * contains gibberish, I don't know why yet) + * + * Their special nibble is either 0x04 or 0x00, the signification of it is not + * known to me yet. Here is their subheader structure: */ struct storage_sector { /* the sector start address - 0xFF */ uint32_t startaddr; - /* the sector ID - because for some reason, fragments won't use the uuid */ + /* the sector ID - probably not using the UUID so sectors can + * not be set as parent nodes :) */ uint32_t logical_sector_number; }; @@ -82,8 +105,9 @@ struct storage_sector { * Here is their subheader structure: */ struct storage_directory { - /* the directory reference - looks unusable */ - uint32_t directory_reference; + /* the parent type and id */ + uint16_t parent_type; + uint16_t parent_id; /* the name (FONTCHARACTER-encoded) */ FONTCHARACTER name[12]; @@ -98,13 +122,9 @@ struct storage_directory { * Here is their subheader structure: */ struct storage_file { - /* the directory reference - * - is `storage_entrytype_directory` if the file is in a subdirectory. - * - is 0xFFFF otherwise. */ - uint16_t directory_reference; - - /* the directory number - should be read only if is in a subdirectory. */ - uint16_t directory_number; + /* the parent type and id (not functional?) */ + uint16_t parent_type; + uint16_t parent_id; /* the name (FONTCHARACTER-encoded) */ FONTCHARACTER name[12]; @@ -117,36 +137,40 @@ struct storage_file { * Fragments are in fact links to the sectors, with some more info. * * Their special nibble have the same meaning that for files... but are not - * always accurate, so only check on files. - * Here is their subheader structure: */ + * always accurate, so only check on files! + * + * The first fragment corresponding to a file contain this file's type, + * probably detected when the file is transferred. Here are the + * known values: */ + +enum storage_file_type { + g1m_storage_filetype_unknown = 0x01, + g1m_storage_filetype_addin = 0x02, /* G1A */ + g1m_storage_filetype_mcs = 0x06, /* G1M */ + g1m_storage_filetype_g2r = 0x2E, /* G1R */ +}; + +/* Why is the file type here and not in the file header? I don't know. + * And here is the fragments' subheader structure: */ struct storage_fragment { - /* the file ID */ - uint32_t file_uuid; + /* the parent (file node) type and id */ + uint16_t parent_type; + uint16_t parent_id; - /* the file type (probably detected when the file is transferred): - * - 0x01 for an unknown type; - * - 0x02 for an add-in (G1A); - * - 0x06 for an MCS archive (G1M); - * - 0x2E for an MCS archive with setup (G1R). - * - * why is it here and not in the file entry data? you've got a point. */ + /* the file type */ uint16_t file_type; - /* the fragment count */ + /* the fragment count and id */ uint16_t fragment_count; - - /* the fragment number */ uint16_t fragment_id; /* the sector id that the fragment is linked to */ uint16_t fragment_sector_id; - /* offset of the used bytes in sector */ - uint16_t used_bytes_offset; - - /* number of used bytes in sector */ - uint16_t used_bytes; + /* number and offset in the sector of the fragment's bytes */ + uint16_t data_offset; + uint16_t data_length; }; #endif /* LIBG1M_FORMAT_STORAGE_H */ diff --git a/include/libg1m/internals.h b/include/libg1m/internals.h index 31a9e95..a749e11 100644 --- a/include/libg1m/internals.h +++ b/include/libg1m/internals.h @@ -42,22 +42,12 @@ /* ************************************************************************** */ /* read with EOF check */ #define READ(TO, SZ) { \ - size_t READ_size = fread(TO, 1, SZ, stream); \ - if (!READ_size) { \ - log_error("READING failed: read %" PRIuSIZE "/%" PRIuSIZE \ - " bytes, %" PRIuSIZE " missing.", READ_size, SZ, \ - (SZ) - READ_size); \ - return (g1m_error_eof); \ - }} -#define GREAD(TO, SZ) { \ - size_t READ_size = fread(TO, 1, SZ, stream); \ - if (!READ_size) { \ - log_error("READING failed: read %" PRIuSIZE "/%" PRIuSIZE \ - " bytes, %" PRIuSIZE " missing.", READ_size, SZ, \ - (SZ) - READ_size); \ - err = g1m_error_eof; \ - goto fail; \ - }} + int READ_err = (*buffer->read)(buffer->cookie, (void*)(TO), (SZ)); \ + if (READ_err) return (READ_err); \ +} +#define GREAD(TO, SZ) \ + if ((err = (*buffer->read)(buffer->cookie, (void*)(TO), (SZ)))) \ + goto fail; /* read with EOF check, declare var before */ #define DREAD(NAM, STRUCT) \ struct STRUCT NAM; \ @@ -66,36 +56,31 @@ struct STRUCT NAM; \ GREAD(&NAM, sizeof(struct STRUCT)) /* skip */ -#define SKIP(SZ) \ - if (g1m_parse_skip(stream, SZ, NULL)) return (g1m_error_eof); +#define SKIP(SZ) { \ + int SKIP_err = g1m_skip(buffer, SZ, NULL); \ + if (SKIP_err) return (SKIP_err); \ +} /* ************************************************************************** */ /* Specific parsing functions */ /* ************************************************************************** */ +typedef int (g1m_decode_function)(g1m_t*, g1m_buffer_t*, + struct standard_header*); + /* types */ -int g1m_parse_g3p(g1m_t *handle, FILE *stream, - struct standard_header *std); -int g1m_parse_c2p(g1m_t *handle, FILE *stream, - struct standard_header *std); -int g1m_parse_mcs(g1m_t *handle, FILE *stream, - struct standard_header *std); -int g1m_parse_eact(g1m_t * handle, FILE *stream, - struct standard_header *std); -int g1m_parse_addin(g1m_t *handle, FILE *stream, - struct standard_header *std); -int g1m_parse_addin_cg(g1m_t *handle, FILE *stream, - struct standard_header *std); -int g1m_parse_lang(g1m_t *handle, FILE *stream, - struct standard_header *std); -int g1m_parse_lang_cg(g1m_t *handle, FILE *stream, - struct standard_header *std); -int g1m_parse_fkey(g1m_t *handle, FILE *stream, - struct standard_header *std); -int g1m_parse_storage(g1m_t *handle, FILE *stream, - struct standard_header *std); +g1m_decode_function g1m_decode_g3p; +g1m_decode_function g1m_decode_c2p; +g1m_decode_function g1m_decode_mcs; +g1m_decode_function g1m_decode_eact; +g1m_decode_function g1m_decode_addin; +g1m_decode_function g1m_decode_addin_cg; +g1m_decode_function g1m_decode_lang; +g1m_decode_function g1m_decode_lang_cg; +g1m_decode_function g1m_decode_fkey; +g1m_decode_function g1m_decode_storage; /* others */ -int g1m_parse_fkey_cg_content(g1m_t *handle, FILE *stream, +int g1m_decode_fkey_cg_content(g1m_t *handle, g1m_buffer_t *buffer, uint_fast32_t zonesize, uint32_t *pchecksum); /* ************************************************************************** */ @@ -125,7 +110,7 @@ G1M_PROTOTYPE_PIX(16bits) /* Utilities */ /* ************************************************************************** */ /* Parsing */ -int g1m_parse(g1m_t *handle, const char *path, FILE *stream, +int g1m_decode(g1m_t *handle, const char *path, g1m_buffer_t *buffer, g1m_type_t expected_type); /* Making */ @@ -138,9 +123,12 @@ void g1m_free_mcs(g1m_t *handle); void g1m_free_line_content(g1m_line_t *line); /* Skipping */ -int g1m_parse_skip(FILE *stream, size_t size, uint_fast32_t *checksum); +int g1m_skip(g1m_buffer_t *buffer, size_t size, uint_fast32_t *checksum); /* Checksum-ing */ uint32_t g1m_checksum32(void *mem, size_t size, uint32_t checksum); +/* File buffer */ +int g1m_filebuffer_read(void *vcookie, unsigned char *buf, size_t size); + #endif /* LIBG1M_INTERNALS_H */ diff --git a/src/basic/instruction.c.draft b/src/basic/instruction.c.draft deleted file mode 100644 index d6556b6..0000000 --- a/src/basic/instruction.c.draft +++ /dev/null @@ -1,232 +0,0 @@ -/* ************************************************************************** */ -/* _____ _ */ -/* basic/instruction.c |_ _|__ _ _| |__ ___ _ _ */ -/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ -/* | | (_) | |_| | | | | __/ |_| | */ -/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2017/01/07 14:55:53 |___/ */ -/* */ -/* ************************************************************************** */ -#include -#define go_forward(N) *buf += (N); *size -= (N) - -/* ************************************************************************** */ -/* Utilities */ -/* ************************************************************************** */ -/** - * parse_bcd: - * Parse a BCD. - * - * @arg buf the FONTCHARACTER buffer. - * @arg size the buffer size. - * @arg real the real part. - * @arg imgn the imaginary part. - * @return the error. - */ - -static int fetch_bcd(const FONTCHARACTER **buf, size_t *size, - struct bcd *real, struct bcd *imgn) -{ - /* TODO */ - return (g1m_error_eof); -} - -/** - * fetch_int: - * Decode an integer. - * - * @arg buf the FONTCHARACTER buffer. - * @arg size the buffer size. - * @arg num the integer to parse. - */ - -static int fetch_int(const FONTCHARACTER **buf, size_t *size, int *id) -{ - /* check the ans */ - if (**buf == 0xC0) { *id = g1m_ans; (*buf)++; (*size)--; return (0); } - - /* peek and get the size of the number */ - int i; for (i = 0; i < *size && (*buf)[i] >= '0' && (*buf)[i] <= '9'; i++); - - /* get the number */ - int numsize = i; - *id = 0; while (i-- >= 0) *id = *id * 10 + (*buf)[i] - '0'; - - /* go forward and ok */ - go_forward(numsize); - return (0); -} - -/** - * fetch_argument: - * Decode an argument. - * - * @arg buf the FONTCHARACTER buffer. - * @arg size the buffer size. - * @arg arg the argument structure. - * @return if there was an error - */ - -#define VAR(ID) (struct argument){.type = g1m_argtype_var, .id = (ID)} -static int fetch_argument(const FONTCHARACTER **buf, size_t *size, - struct argument *arg) -{ - /* check if we have at least one character */ - if (!*size) return (g1m_error_eof); - - /* check if is something special */ - FONTCHARACTER op = **buf; - if (opcode == 0xF93F) { arg->type = g1m_argtype_string; goto parse_id; } - if (opcode == 0x7F40) { arg->type = g1m_argtype_mat; goto parse_let; } - if (opcode == 0x7F51) { arg->type = g1m_argtype_list; goto parse_id; } - - /* check if it's a var */ - if (op == 0xC0) *arg = VAR(g1m_ans); - else if (op == 0xCE) *arg = VAR(g1m_theta); - else if (op == 0xCD) *arg = VAR(g1m_r); - else if (op >= 'A' && op <= 'Z') *arg = VAR(op - 'A'); - else { - int err = fetch_bcd(buf, size, &arg->real, &arg->imgn); - if (err) return (fetch_statement(buf, size, arg->statement)); - return (err); - } - - /* was a var */ - go_forward(1); - return (0); - - /* it's something with an ID! */ -parse_id: - go_forward(1); - return (fetch_int(buf, size, &arg->id)); - - /* it's something with a letter ID! */ -parse_let: - go_forward(1); - return (fetch_let(buf, size, &arg->id)); -} - -/* ************************************************************************** */ -/* Statements */ -/* ************************************************************************** */ -/* Statements */ -struct statement { - /* the start opcode */ - FONTCHARACTER opcode; - - /* number of arguments */ - int nargs; - - /* finishes with a parenthesis */ - int par; -}; - -/* Known statements */ -static const struct statement statements[] = { - /* Locate x,x,x */ - {0xF710, 3, 0}, - /* Send(A) */ - {0xF711, 1, 1}, - /* Receive(A) */ - {0xF712, 1, 1}, - - {0, 0} -}; - -/* Infix statements */ -static const struct statement infix_statements[] = { - /* x! */ - {0xEA, 1, 0}, - /* a = b */ - {0x3D, 2, 0}, - - {0, 0} -}; - -/** - * fetch_raw_statement: - * Fetch a statement. - * - * @arg buf the FONTCHARACTER buffer pointer. - * @arg size the FONTCHARACTER buffer size pointer. - * @arg st the statement pointer. - * @arg fst the first argument - * @arg infix is infix (boolean!) - * @return the error. - */ - -static int fetch_raw_statement(const FONTCHARACTER **buf, size_t *size, - struct statement *st, struct argument *fst, int infix) -{ - /* check if there is at least space for one opcode */ - if (!*size) return (1); - - /* get the statements tab */ - const struct *sts = - (const *struct statement[]){statements, infix_statements}[infix]; - - /* check which opcode it is */ - FONTCHARACTER op = **buf; - const struct *st; - for (st = sts; st->opcode && st->opcode != op; st++); - if (!st) return (1); - - /* prepare the arguments */ - int nargs = st->nargs; - struct argument *args = malloc(nargs * sizeof(struct argument)); - if (!args) return (1); - if (nargs) memcpy(&args[0], fst, sizeof(struct argument)); - - /* iterate */ - int last = infix - 1; - for (int i = infix; i < nargs; i++) { - /* parse the arg */ - if (fetch_argument(buf, size, &args[i])) - return (1); - - /* check the comma */ - if (i < last && (!*size || **buf != ',')) - return (1); - go_forward(1); - } - - /* check right parenthesis */ - if (st->par && *size && **buf != ')') - return (1); - if (*size) { go_forward(1); } - - /* no error */ - return (0); -} - -/** - * fetch_statement: - * Fetch a statement. - */ - -/* ************************************************************************** */ -/* Main function */ -/* ************************************************************************** */ -/** - * g1m_fetch_instruction: - * Fetch the instruction. - * - * @arg buf the FONTCHARACTER buffer. - * @arg size the FONTCHARACTER buffer size. - * @arg statement the statement. - * @return if negative: the negative libg1m error code. - * otherwise: the size of the instruction. - */ - -int g1m_fetch_instruction(const FONTCHARACTER *buf, size_t size, - g1m_bst_t *statement) -{ - size_t sav = size; - - /* start by free-ing statement content? */ - /* TODO */ - - /* check it it's a statement */ - int err = fetch_statement(&buf, &size, &statement, 0); - return (err ? -err : (int)(sav - size)); -} diff --git a/src/parse/addin.c b/src/decode/addin.c similarity index 91% rename from src/parse/addin.c rename to src/decode/addin.c index 1651a5c..2bc4dfa 100644 --- a/src/parse/addin.c +++ b/src/decode/addin.c @@ -1,10 +1,10 @@ /* ************************************************************************** */ /* _____ _ */ -/* parse/addin.c |_ _|__ _ _| |__ ___ _ _ */ +/* decode/addin.c |_ _|__ _ _| |__ ___ _ _ */ /* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ /* | | (_) | |_| | | | | __/ |_| | */ /* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/12/01 13:33:45 |___/ */ +/* Last updated: 2017/02/19 23:01:18 |___/ */ /* */ /* ************************************************************************** */ #include @@ -65,18 +65,20 @@ static void addin_set_data(g1m_t *handle, } /** - * g1m_parse_addin: - * Parse "normal" add-in (after Standard Header). + * g1m_decode_addin: + * Decodes a "normal" add-in (after Standard Header). * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @return the error code (0 if ok). */ -int g1m_parse_addin(g1m_t *handle, FILE *stream, +int g1m_decode_addin(g1m_t *handle, g1m_buffer_t *buffer, struct standard_header *std) { + int err = 0; (void)std; + /* get the subheader */ DREAD(hd, g1a_subheader) @@ -112,20 +114,20 @@ int g1m_parse_addin(g1m_t *handle, FILE *stream, - sizeof(struct g1a_subheader)) /* no errors */ - return (0); + return (err); } /** - * g1m_parse_addin_cg: - * Parse fx-CG add-in (after Standard Header). + * g1m_decode_addin_cg: + * Decode fx-CG add-in (after Standard Header). * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg std the standard header. * @return the error code (0 if ok). */ -int g1m_parse_addin_cg(g1m_t *handle, FILE *stream, +int g1m_decode_addin_cg(g1m_t *handle, g1m_buffer_t *buffer, struct standard_header *std) { int err = 0; @@ -179,7 +181,7 @@ int g1m_parse_addin_cg(g1m_t *handle, FILE *stream, } /* skip content for now */ - if ((err = g1m_parse_skip(stream, content_size, &checksum))) + if ((err = g1m_skip(buffer, content_size, &checksum))) goto fail; /* check the sum (yo!) */ diff --git a/src/parse/eact.c b/src/decode/eact.c similarity index 76% rename from src/parse/eact.c rename to src/decode/eact.c index e663c7e..c01c771 100644 --- a/src/parse/eact.c +++ b/src/decode/eact.c @@ -1,6 +1,15 @@ /* ************************************************************************** */ /* _____ _ */ -/* parse/eact.c |_ _|__ _ _| |__ ___ _ _ */ +/* decode/eact.c |_ _|__ _ _| |__ ___ _ _ */ +/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ +/* | | (_) | |_| | | | | __/ |_| | */ +/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ +/* Last updated: 2017/02/19 23:01:18 |___/ */ +/* */ +/* ************************************************************************** */ +/* ************************************************************************** */ +/* _____ _ */ +/* decode/eact.c |_ _|__ _ _| |__ ___ _ _ */ /* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ /* | | (_) | |_| | | | | __/ |_| | */ /* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ @@ -13,12 +22,12 @@ /* Content parsing */ /* ************************************************************************** */ /* line content parsing function prototype */ -static int eact_parse_line(g1m_line_t *handle, uint8_t *buf, size_t size, +static int eact_decode_line(g1m_line_t *handle, uint8_t *buf, size_t size, uint_fast8_t type); /** - * eact_parse_content_eact: - * Parse an EACT in an EACT, from the subheader. + * eact_decode_content_eact: + * Decodes an EACT in an EACT, from the subheader. * * @arg handle the handle. * @arg buf the buffer. @@ -26,7 +35,7 @@ static int eact_parse_line(g1m_line_t *handle, uint8_t *buf, size_t size, * @return the error code (0 if ok). */ -static int eact_parse_content_eact(g1m_line_t *handle, uint8_t *buf, +static int eact_decode_content_eact(g1m_line_t *handle, uint8_t *buf, size_t bufsize) { int err; @@ -100,7 +109,7 @@ static int eact_parse_content_eact(g1m_line_t *handle, uint8_t *buf, goto loop_fail; /* look for the line type */ - err = eact_parse_line(line, &buf[entry_offset], linesize, entry_type); + err = eact_decode_line(line, &buf[entry_offset], linesize, entry_type); if (err) goto loop_fail; /* store and continue */ @@ -127,12 +136,12 @@ fail: struct eact_content_type_corresp { const char *type; - int (*parse)(g1m_line_t*, uint8_t*, size_t); + int (*decode)(g1m_line_t*, uint8_t*, size_t); }; /* Correspondance list */ static struct eact_content_type_corresp eact_content_types[] = { - {"@EACT\0\0", eact_parse_content_eact}, + {"@EACT\0\0", eact_decode_content_eact}, {} }; @@ -140,8 +149,8 @@ static struct eact_content_type_corresp eact_content_types[] = { /* Line parsing */ /* ************************************************************************** */ /** - * eact_parse_line_content: - * Parse an E-Activity content. + * eact_decode_line_content: + * Decodes an E-Activity content. * * @arg handle the handle. * @arg buf the buffer. @@ -149,7 +158,7 @@ static struct eact_content_type_corresp eact_content_types[] = { * @return the error code (0 if ok). */ -static int eact_parse_line_content(g1m_line_t *handle, uint8_t *buf, +static int eact_decode_line_content(g1m_line_t *handle, uint8_t *buf, size_t size) { /* read content header */ @@ -173,19 +182,19 @@ static int eact_parse_line_content(g1m_line_t *handle, uint8_t *buf, /* check for content type */ struct eact_content_type_corresp *ctype = eact_content_types; - while (ctype->parse) { + while (ctype->decode) { if (!memcmp(hd.type, ctype->type, 8)) break ; ctype++; } - if (!ctype->parse) { + if (!ctype->decode) { log_error("Unknown content type: '%.8s'", hd.type); return (0); } - /* then parse */ + /* then decode */ int err; - if ((err = (*ctype->parse)(handle, buf, size))) + if ((err = (*ctype->decode)(handle, buf, size))) return (err); /* otherwise, no error. */ @@ -193,8 +202,8 @@ static int eact_parse_line_content(g1m_line_t *handle, uint8_t *buf, } /** - * eact_parse_line_calculation: - * Parse a calculation. + * eact_decode_line_calculation: + * Decodes a calculation. * * @arg handle the handle. * @arg buf the buffer. @@ -202,7 +211,7 @@ static int eact_parse_line_content(g1m_line_t *handle, uint8_t *buf, * @return the error code (0 if ok). */ -static int eact_parse_line_calculation(g1m_line_t *handle, uint8_t *buf, +static int eact_decode_line_calculation(g1m_line_t *handle, uint8_t *buf, size_t size) { (void)handle; @@ -215,8 +224,8 @@ static int eact_parse_line_calculation(g1m_line_t *handle, uint8_t *buf, } /** - * eact_parse_line_result: - * Parse a calculation result. + * eact_decode_line_result: + * Decodes a calculation result. * * @arg handle the handle. * @arg buf the buffer. @@ -224,7 +233,7 @@ static int eact_parse_line_calculation(g1m_line_t *handle, uint8_t *buf, * @return the error code (0 if ok). */ -static int eact_parse_line_result(g1m_line_t *handle, uint8_t *buf, size_t size) +static int eact_decode_line_result(g1m_line_t *handle, uint8_t *buf, size_t size) { (void)handle; (void)buf; @@ -236,8 +245,8 @@ static int eact_parse_line_result(g1m_line_t *handle, uint8_t *buf, size_t size) } /** - * eact_parse_line_stdheading: - * Parse standard heading line. + * eact_decode_line_stdheading: + * Decodes standard heading line. * * @arg handle the handle. * @arg buf the buffer. @@ -245,7 +254,7 @@ static int eact_parse_line_result(g1m_line_t *handle, uint8_t *buf, size_t size) * @return the error code (0 if ok). */ -static int eact_parse_line_stdheading(g1m_line_t *handle, uint8_t *buf, +static int eact_decode_line_stdheading(g1m_line_t *handle, uint8_t *buf, size_t size) { /* log */ @@ -262,8 +271,8 @@ static int eact_parse_line_stdheading(g1m_line_t *handle, uint8_t *buf, } /** - * eact_parse_line_picture: - * Parse picture line. + * eact_decode_line_picture: + * Decodes picture line. * * @arg handle the handle. * @arg buf the buffer. @@ -271,7 +280,7 @@ static int eact_parse_line_stdheading(g1m_line_t *handle, uint8_t *buf, * @return the error code (0 if ok). */ -static int eact_parse_line_picture(g1m_line_t *handle, uint8_t *buf, +static int eact_decode_line_picture(g1m_line_t *handle, uint8_t *buf, size_t size) { /* log */ @@ -284,13 +293,13 @@ static int eact_parse_line_picture(g1m_line_t *handle, uint8_t *buf, while (*(++p)) *p = be16toh(*p); /* get the size of the multi-byte string */ - size_t sz = g1m_fcstombs(NULL, s, 0); + size_t sz = fc_wcstombs(NULL, s, 0); if (sz == (size_t)-1) return (g1m_error_magic); /* make the string */ handle->content = malloc(sizeof(FONTCHARACTER) * (sz + 1)); if (!handle->content) return (g1m_error_alloc); - g1m_fcstombs(handle->content, s, 0); + fc_wcstombs(handle->content, s, 0); /* don't forget to set the handle type! */ handle->type = g1m_linetype_picture; @@ -300,8 +309,8 @@ static int eact_parse_line_picture(g1m_line_t *handle, uint8_t *buf, } /** - * eact_parse_line_text: - * Parse text line. + * eact_decode_line_text: + * Decodes a text line. * * @arg handle the handle. * @arg buf the buffer. @@ -309,7 +318,7 @@ static int eact_parse_line_picture(g1m_line_t *handle, uint8_t *buf, * @return the error code (0 if ok). */ -static int eact_parse_line_text(g1m_line_t *handle, uint8_t *buf, size_t size) +static int eact_decode_line_text(g1m_line_t *handle, uint8_t *buf, size_t size) { /* log */ log_info("Text raw data is:"); @@ -326,8 +335,8 @@ static int eact_parse_line_text(g1m_line_t *handle, uint8_t *buf, size_t size) } /** - * eact_parse_line_code: - * Parse code line. + * eact_decode_line_code: + * Decodes code line. * * @arg handle the handle. * @arg buf the buffer. @@ -335,7 +344,7 @@ static int eact_parse_line_text(g1m_line_t *handle, uint8_t *buf, size_t size) * @return the error code (0 if ok). */ -static int eact_parse_line_code(g1m_line_t *handle, uint8_t *buf, size_t size) +static int eact_decode_line_code(g1m_line_t *handle, uint8_t *buf, size_t size) { (void)handle; (void)buf; @@ -353,32 +362,32 @@ static int eact_parse_line_code(g1m_line_t *handle, uint8_t *buf, size_t size) struct eact_line_type_corresp { int rawtype; - int (*parse)(g1m_line_t*, uint8_t*, size_t); + int (*decode)(g1m_line_t*, uint8_t*, size_t); const char *info; }; /* All correspondances */ static struct eact_line_type_corresp eact_line_types[] = { - {eact_ltype_calc, eact_parse_line_calculation, + {eact_ltype_calc, eact_decode_line_calculation, "calculation"}, - {eact_ltype_calc_result, eact_parse_line_result, + {eact_ltype_calc_result, eact_decode_line_result, "calculation result"}, - {eact_ltype_content, eact_parse_line_content, + {eact_ltype_content, eact_decode_line_content, "content"}, - {eact_ltype_stdheading, eact_parse_line_stdheading, + {eact_ltype_stdheading, eact_decode_line_stdheading, "standard heading"}, - {eact_ltype_picture, eact_parse_line_picture, + {eact_ltype_picture, eact_decode_line_picture, "picture"}, - {eact_ltype_text, eact_parse_line_text, + {eact_ltype_text, eact_decode_line_text, "pure text"}, - {eact_ltype_code, eact_parse_line_code, + {eact_ltype_code, eact_decode_line_code, "text mixed with functions"}, {} }; /** - * eact_parse_line: - * Parse a line [content]. + * eact_decode_line: + * decode a line [content]. * * @arg handle the handle. * @arg buf the buffer. @@ -387,7 +396,7 @@ static struct eact_line_type_corresp eact_line_types[] = { * @return the error code (0 if ok). */ -static int eact_parse_line(g1m_line_t *handle, uint8_t *buf, size_t size, +static int eact_decode_line(g1m_line_t *handle, uint8_t *buf, size_t size, uint_fast8_t type) { /* initialize handle */ @@ -395,40 +404,40 @@ static int eact_parse_line(g1m_line_t *handle, uint8_t *buf, size_t size, /* look for the line type */ struct eact_line_type_corresp *linetype = eact_line_types; - while (linetype->parse) { + while (linetype->decode) { if (linetype->rawtype == type) break; linetype++; } - if (!linetype->parse) { + if (!linetype->decode) { log_error("unknown line type: %02x", type); return (0); } /* act */ log_info("line type is '%s' (0x%02x)", linetype->info, type); - return ((*linetype->parse)(handle, buf, size)); + return ((*linetype->decode)(handle, buf, size)); } /* ************************************************************************** */ /* Main parsing functions */ /* ************************************************************************** */ /** - * g1m_parse_eact: - * Parse an EACT. + * g1m_decode_eact: + * Decodes an EACT. * * Thanks to Julese50 for his help on e-acts parsing. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @return the error code (0 if ok). */ -int g1m_parse_eact(g1m_t * handle, FILE *stream, +int g1m_decode_eact(g1m_t * handle, g1m_buffer_t *buffer, struct standard_header *std) { (void)std; - /* parse the header */ + /* decode the header */ DREAD(hd, eact_header) /* correct endianess */ @@ -460,6 +469,6 @@ int g1m_parse_eact(g1m_t * handle, FILE *stream, /* prepare handle */ handle->line = &handle->_linedata; - /* parse content */ - return (eact_parse_line_content(handle->line, buf, bufsize)); + /* decode content */ + return (eact_decode_line_content(handle->line, buf, bufsize)); } diff --git a/src/parse/fkey.c b/src/decode/fkey.c similarity index 87% rename from src/parse/fkey.c rename to src/decode/fkey.c index f6ed3a0..ac5a5dc 100644 --- a/src/parse/fkey.c +++ b/src/decode/fkey.c @@ -1,10 +1,10 @@ /* ************************************************************************** */ /* _____ _ */ -/* parse/fkey.c |_ _|__ _ _| |__ ___ _ _ */ +/* decode/fkey.c |_ _|__ _ _| |__ ___ _ _ */ /* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ /* | | (_) | |_| | | | | __/ |_| | */ /* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/12/17 00:21:32 |___/ */ +/* Last updated: 2017/02/19 23:01:18 |___/ */ /* */ /* ************************************************************************** */ #include @@ -52,16 +52,16 @@ static uint32_t **fkeydup3(uint8_t *fkey) /* fx function keys file parsing utilities */ /* ************************************************************************** */ /** - * g1m_parse_fkey: - * Parse fx function keys files. + * g1m_decode_fkey: + * Decode fx function keys files. * * @arg handle the libg1m handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg std pointer to the standard header. * @return the error code (0 if ok). */ -int g1m_parse_fkey(g1m_t *handle, FILE *stream, +int g1m_decode_fkey(g1m_t *handle, g1m_buffer_t *buffer, struct standard_header *std) { (void)std; @@ -125,23 +125,23 @@ fail: /* cg function keys file parsing utilities */ /* ************************************************************************** */ /** - * g1m_parse_fkey_cg_content: - * Parse fx-CG key files. + * g1m_decode_fkey_cg_content: + * Decode fx-CG key files. * - * In fact, the main parsing function is `g1m_parse_lang_cg` (they really + * In fact, the main parsing function is `g1m_decode_lang_cg` (they really * have the same subheader). TODO * * @arg handle the libg1m handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @return the error code (0 if ok). */ -int g1m_parse_fkey_cg_content(g1m_t *handle, FILE *stream, +int g1m_decode_fkey_cg_content(g1m_t *handle, g1m_buffer_t *buffer, uint_fast32_t zonesize, uint32_t *pchecksum) { handle->type = 0x00; //handle->type = g1m_type_fkey; - (void)stream; + (void)buffer; (void)zonesize; (void)pchecksum; return (g1m_error_magic); diff --git a/src/parse/lang.c b/src/decode/lang.c similarity index 90% rename from src/parse/lang.c rename to src/decode/lang.c index ce93c91..e3fd1d9 100644 --- a/src/parse/lang.c +++ b/src/decode/lang.c @@ -1,10 +1,10 @@ /* ************************************************************************** */ /* _____ _ */ -/* parse/lang.c |_ _|__ _ _| |__ ___ _ _ */ +/* decode/lang.c |_ _|__ _ _| |__ ___ _ _ */ /* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ /* | | (_) | |_| | | | | __/ |_| | */ /* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/12/01 13:33:45 |___/ */ +/* Last updated: 2017/02/19 23:01:18 |___/ */ /* */ /* ************************************************************************** */ #include @@ -13,15 +13,15 @@ /* fx language files parsing */ /* ************************************************************************** */ /** - * g1m_parse_lang: - * Parse fx language files. + * g1m_decode_lang: + * Decode fx language files. * * @arg handle the libg1m handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @return the error code (0 if ok). */ -int g1m_parse_lang(g1m_t *handle, FILE *stream, +int g1m_decode_lang(g1m_t *handle, g1m_buffer_t *buffer, struct standard_header *std) { (void)std; @@ -92,17 +92,17 @@ fail: /* cg language files parsing */ /* ************************************************************************** */ /** - * g1m_parse_lang_cg_content: - * Parse the content of the message zone size for a G3L language file. + * g1m_decode_lang_cg_content: + * Decode the content of the message zone size for a G3L language file. * * @arg handle the libg1m handle. - * @arg stream the stream to read from. + * @arg buffer the buffer to read from. * @arg zonesize the message zone size. * @arg pchecksum pointer to the checksum to contribute to. * @return the error code (0 if ok). */ -static int g1m_parse_lang_cg_content(g1m_t *handle, FILE *stream, +static int g1m_decode_lang_cg_content(g1m_t *handle, g1m_buffer_t *buffer, uint_fast32_t zonesize, uint32_t *pchecksum) { int err; uint32_t checksum = *pchecksum; @@ -183,16 +183,16 @@ fail: } /** - * g1m_parse_lang_cg: - * Parse fx-CG language files. + * g1m_decode_lang_cg: + * Decode fx-CG language files. * * @arg handle the libg1m handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg std the standard header. * @return the error code (0 if ok). */ -int g1m_parse_lang_cg(g1m_t *handle, FILE *stream, +int g1m_decode_lang_cg(g1m_t *handle, g1m_buffer_t *buffer, struct standard_header *std) { /* set handle type */ @@ -224,7 +224,7 @@ int g1m_parse_lang_cg(g1m_t *handle, FILE *stream, size_t zonesize = hd.filesize - sizeof(struct standard_header) - sizeof(struct g3l_subheader) - sizeof(struct g3l_footer); if (hd.magic[0] == 0x04) - err = g1m_parse_lang_cg_content(handle, stream, zonesize, &checksum); + err = g1m_decode_lang_cg_content(handle, buffer, zonesize, &checksum); else return (g1m_error_magic); if (err) return (g1m_error_magic); diff --git a/src/parse/main.c b/src/decode/main.c similarity index 79% rename from src/parse/main.c rename to src/decode/main.c index 8b7531a..e234a08 100644 --- a/src/parse/main.c +++ b/src/decode/main.c @@ -1,10 +1,10 @@ /* ************************************************************************** */ /* _____ _ */ -/* parse/main.c |_ _|__ _ _| |__ ___ _ _ */ +/* decode/main.c |_ _|__ _ _| |__ ___ _ _ */ /* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ /* | | (_) | |_| | | | | __/ |_| | */ /* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/12/01 13:33:45 |___/ */ +/* Last updated: 2017/02/19 23:01:18 |___/ */ /* */ /* ************************************************************************** */ #include @@ -18,66 +18,65 @@ struct corresp { unsigned int type; /* result */ - int (*read)(g1m_t*, FILE*, struct standard_header*); + g1m_decode_function *decode; }; /* The correspondances */ static struct corresp parsing_functions[] = { /* add-ins */ {g1m_platform_fx, g1m_type_addin, - g1m_parse_addin}, + g1m_decode_addin}, {g1m_platform_cg, g1m_type_addin, - g1m_parse_addin_cg}, + g1m_decode_addin_cg}, /* mcs */ {g1m_platform_fx, g1m_type_mcs, - g1m_parse_mcs}, + g1m_decode_mcs}, {g1m_platform_cg, g1m_type_mcs, - g1m_parse_mcs}, + g1m_decode_mcs}, /* language files */ {g1m_platform_fx, g1m_type_lang, - g1m_parse_lang}, + g1m_decode_lang}, {g1m_platform_cg, g1m_type_lang, - g1m_parse_lang_cg}, + g1m_decode_lang_cg}, /* function keys file */ {g1m_platform_fx, g1m_type_fkey, - g1m_parse_fkey}, + g1m_decode_fkey}, {g1m_platform_cg, g1m_type_fkey, - g1m_parse_lang_cg}, + g1m_decode_lang_cg}, /* e-activities */ {g1m_platform_fx, g1m_type_eact, - g1m_parse_eact}, + g1m_decode_eact}, /* pictures */ {g1m_platform_cg, g1m_type_pict, - g1m_parse_g3p}, + g1m_decode_g3p}, {g1m_platform_cp, g1m_type_pict, - g1m_parse_c2p}, + g1m_decode_c2p}, /* storage */ - {g1m_platform_none, g1m_type_storage, - g1m_parse_storage}, + /*{g1m_platform_none, g1m_type_storage, + g1m_decode_storage},*/ {0, 0, NULL} }; /** - * find_parse_function: + * find_decode_function: * Find the parsing function. * * @arg handle the handle. * @arg path the file path. * @arg std pointer to the standard header. - * @arg rd pointer to the read function. + * @arg rd pointer to the decode function. * @return the error code (0 if ok). */ -static int find_parse_function(g1m_t *handle, const char *path, - struct standard_header *std, - int (**rd)(g1m_t*, FILE*, struct standard_header*)) +static int find_decode_function(g1m_t *handle, const char *path, + struct standard_header *std, g1m_decode_function **rd) { /* get the type */ unsigned int platform, type; @@ -99,7 +98,7 @@ static int find_parse_function(g1m_t *handle, const char *path, /* look for corresponding parsing function */ struct corresp *c = parsing_functions - 1; - while ((++c)->read) { + while ((++c)->decode) { if (c->type != type) continue; if (c->platform != platform) @@ -107,7 +106,7 @@ static int find_parse_function(g1m_t *handle, const char *path, break; } - if (!c->read) { + if (!c->decode) { log_fatal("No parsing function was found for this type."); return (g1m_error_magic); } @@ -115,7 +114,7 @@ static int find_parse_function(g1m_t *handle, const char *path, /* set the vars */ handle->type = type; handle->platform = platform; - *rd = c->read; + *rd = c->decode; return (0); } @@ -123,20 +122,20 @@ static int find_parse_function(g1m_t *handle, const char *path, /* Main parsing function */ /* ************************************************************************** */ /** - * g1m_parse: - * Parse a G1M file. + * g1m_decode: + * Decode a G1M file. * * Read the standard header, correct endianness, check magic numbers, * then read subparts according to the G1M type. * * @arg handle the handle. * @arg path the file path. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg expected_type the expected type. * @return the error code (0 if ok). */ -int g1m_parse(g1m_t *handle, const char *path, FILE *stream, +int g1m_decode(g1m_t *handle, const char *path, g1m_buffer_t *buffer, g1m_type_t expected_type) { /* initialize the handle */ @@ -158,8 +157,8 @@ int g1m_parse(g1m_t *handle, const char *path, FILE *stream, hd.number = be16toh(hd.number); /* get type */ - int (*read_func)(g1m_t*, FILE*, struct standard_header*); int err; - if ((err = find_parse_function(handle, path, &hd, &read_func))) + g1m_decode_function *read_func; int err; + if ((err = find_decode_function(handle, path, &hd, &read_func))) return (err); /* check if the type is alright */ @@ -170,6 +169,6 @@ int g1m_parse(g1m_t *handle, const char *path, FILE *stream, log_info("Standard Header filesize is %" PRIu32 "o.", hd.filesize); log_info("Standard Header num is %" PRIu16 ".", hd.number); - /* subparse. */ - return ((*read_func)(handle, stream, &hd)); + /* subdecode. */ + return ((*read_func)(handle, buffer, &hd)); } diff --git a/src/parse/mcs.c b/src/decode/mcs.c similarity index 84% rename from src/parse/mcs.c rename to src/decode/mcs.c index 5ad6f1e..54ceeec 100644 --- a/src/parse/mcs.c +++ b/src/decode/mcs.c @@ -1,10 +1,10 @@ /* ************************************************************************** */ /* _____ _ */ -/* parse/mcs.c |_ _|__ _ _| |__ ___ _ _ */ +/* decode/mcs.c |_ _|__ _ _| |__ ___ _ _ */ /* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ /* | | (_) | |_| | | | | __/ |_| | */ /* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/12/01 13:33:45 |___/ */ +/* Last updated: 2017/02/19 23:01:18 |___/ */ /* */ /* ************************************************************************** */ #include @@ -17,13 +17,13 @@ * get_image: * Allocate space, and convert monochromic image to 0x0RGB. * - * @arg stream the stream from which to read. + * @arg buffer the buffer to read from. * @arg img the image to make. * @arg width the image width. * @arg height the image height. */ -static int get_image(FILE *stream, uint32_t ***img, +static int get_image(g1m_buffer_t *buffer, uint32_t ***img, unsigned int width, unsigned int height) { /* get raw pixels */ @@ -67,16 +67,16 @@ static int get_image(FILE *stream, uint32_t ***img, /* MCS file parsing */ /* ************************************************************************** */ /** - * mcs_parse_program: - * Parse a program. + * mcs_decode_program: + * Decode a program. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg length the data length. * @return the error code (0 if ok). */ -static int mcs_parse_program(g1m_mcsfile_t *handle, FILE *stream, +static int mcs_decode_program(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t length) { /* read header */ @@ -103,16 +103,16 @@ static int mcs_parse_program(g1m_mcsfile_t *handle, FILE *stream, } /** - * mcs_parse_spreadsheet: - * Parse a spreadsheet. + * mcs_decode_spreadsheet: + * Decode a spreadsheet. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg length the data length. * @return the error code (0 if ok). */ -static int mcs_parse_spreadsheet(g1m_mcsfile_t *handle, FILE *stream, +static int mcs_decode_spreadsheet(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t length) { /* read header */ @@ -138,7 +138,7 @@ static int mcs_parse_spreadsheet(g1m_mcsfile_t *handle, FILE *stream, uint_fast32_t cols = 0; /* log some info */ - log_info("%" PRIuFAST32 " columns to parse!", colcount); + log_info("%" PRIuFAST32 " columns to read!", colcount); if (colcount) { /* get the column directory */ @@ -228,16 +228,16 @@ static int mcs_parse_spreadsheet(g1m_mcsfile_t *handle, FILE *stream, } /** - * mcs_parse_list: - * Parse an List. + * mcs_decode_list: + * Decode an List. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg size the length. * @return the error code (0 if ok). */ -static int mcs_parse_list(g1m_mcsfile_t *handle, FILE *stream, +static int mcs_decode_list(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t size) { /* read header */ @@ -323,16 +323,16 @@ static int mcs_parse_list(g1m_mcsfile_t *handle, FILE *stream, } /** - * mcs_parse_matrix: - * Parse a matrix. + * mcs_decode_matrix: + * Decode a matrix. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg length the data length. * @return the error code (0 if ok). */ -static int mcs_parse_matrix(g1m_mcsfile_t *handle, FILE *stream, +static int mcs_decode_matrix(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t length) { g1m_mcs_cell_t **tab, *rws; @@ -427,16 +427,16 @@ fail: } /** - * mcs_parse_capture: - * Parse a capture. + * mcs_decode_capture: + * Decode a capture. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg length the data length. * @return the error code (0 if ok). */ -static int mcs_parse_capture(g1m_mcsfile_t *handle, FILE *stream, +static int mcs_decode_capture(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t length) { /* read header */ @@ -454,20 +454,20 @@ static int mcs_parse_capture(g1m_mcsfile_t *handle, FILE *stream, log_info("capture is %dx%d sized", handle->width, handle->height); /* get the image and return */ - return (get_image(stream, &handle->image, handle->width, handle->height)); + return (get_image(buffer, &handle->image, handle->width, handle->height)); } /** - * mcs_parse_picture: - * Parse a picture. + * mcs_decode_picture: + * Decode a picture. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg length the data length. * @return the error code (0 if ok). */ -static int mcs_parse_picture(g1m_mcsfile_t *handle, FILE *stream, +static int mcs_decode_picture(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t length) { int err; @@ -477,13 +477,13 @@ static int mcs_parse_picture(g1m_mcsfile_t *handle, FILE *stream, handle->height = 64; /* get the first image */ - if ((err = get_image(stream, &handle->image, 128, 64))) { + if ((err = get_image(buffer, &handle->image, 128, 64))) { log_fatal("Failed to get the first image."); return (err); } /* and the second */ - if ((err = get_image(stream, &handle->second_image, 128, 64))) { + if ((err = get_image(buffer, &handle->second_image, 128, 64))) { log_fatal("Failed to get the second image."); return (err); } @@ -493,16 +493,16 @@ static int mcs_parse_picture(g1m_mcsfile_t *handle, FILE *stream, } /** - * mcs_parse_string: - * Parse string. + * mcs_decode_string: + * Decode an MCS string. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg length the data length. * @return the error code (0 if ok). */ -static int mcs_parse_string(g1m_mcsfile_t *handle, FILE *stream, +static int mcs_decode_string(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t length) { (void)handle; @@ -515,16 +515,16 @@ static int mcs_parse_string(g1m_mcsfile_t *handle, FILE *stream, } /** - * mcs_parse_setup: - * Parse settings. + * mcs_decode_setup: + * Decode settings. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg length the data length. * @return the error code (0 if ok). */ -static int mcs_parse_setup(g1m_mcsfile_t *handle, FILE *stream, +static int mcs_decode_setup(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t length) { (void)handle; @@ -535,16 +535,16 @@ static int mcs_parse_setup(g1m_mcsfile_t *handle, FILE *stream, } /** - * mcs_parse_alphamem: - * Parse alphamem. + * mcs_decode_alphamem: + * Decode alpha memory (variables). * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg length the data length. * @return the error code (0 if ok). */ -static int mcs_parse_alphamem(g1m_mcsfile_t *handle, FILE *stream, +static int mcs_decode_alphamem(g1m_mcsfile_t *handle, g1m_buffer_t *buffer, uint_fast32_t length) { /* read the data */ @@ -589,63 +589,63 @@ static int mcs_parse_alphamem(g1m_mcsfile_t *handle, FILE *stream, /* Type correspondance list */ /* ************************************************************************** */ /* MCS file parsing function type */ -typedef int (*mcs_parse_func_t)(g1m_mcsfile_t*, FILE*, uint_fast32_t); +typedef int (*mcs_decode_func_t)(g1m_mcsfile_t*, g1m_buffer_t*, uint_fast32_t); /* Correspondance type */ struct mcs_corresp { unsigned int type; - mcs_parse_func_t parse; + mcs_decode_func_t decode; }; /* All correspondances */ static struct mcs_corresp mcs_types[] = { - {g1m_mcstype_program, mcs_parse_program,}, - {g1m_mcstype_list, mcs_parse_list}, - {g1m_mcstype_mat, mcs_parse_matrix}, - {g1m_mcstype_vct, mcs_parse_matrix}, - {g1m_mcstype_spreadsheet, mcs_parse_spreadsheet}, - {g1m_mcstype_pict, mcs_parse_picture}, - {g1m_mcstype_capt, mcs_parse_capture}, - {g1m_mcstype_string, mcs_parse_string}, - {g1m_mcstype_setup, mcs_parse_setup}, - {g1m_mcstype_alphamem, mcs_parse_alphamem}, + {g1m_mcstype_program, mcs_decode_program,}, + {g1m_mcstype_list, mcs_decode_list}, + {g1m_mcstype_mat, mcs_decode_matrix}, + {g1m_mcstype_vct, mcs_decode_matrix}, + {g1m_mcstype_spreadsheet, mcs_decode_spreadsheet}, + {g1m_mcstype_pict, mcs_decode_picture}, + {g1m_mcstype_capt, mcs_decode_capture}, + {g1m_mcstype_string, mcs_decode_string}, + {g1m_mcstype_setup, mcs_decode_setup}, + {g1m_mcstype_alphamem, mcs_decode_alphamem}, {} }; /** - * lookup_mcsfile_parse: + * lookup_mcsfile_decode: * Lookup for a parsing function for an MCS file type. * * @arg type the libg1m MCS file type. * @return the function (NULL if not found). */ -static mcs_parse_func_t lookup_mcsfile_parse(unsigned int type) +static mcs_decode_func_t lookup_mcsfile_decode(unsigned int type) { /* lookup for the type */ struct mcs_corresp *c = mcs_types; - while (c->parse) { + while (c->decode) { if (type == c->type) break; c++; } /* return the function */ - return (c->parse); + return (c->decode); } /* ************************************************************************** */ /* Public API functions */ /* ************************************************************************** */ /** - * g1m_parse_mcsfile_content: - * Parse MCS file content. + * g1m_decode_mcsfile_content: + * Decode MCS file content. * * Part of the public API because of the Protocol 7, where file is sent * without its header (only with specific subheaders). * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg raw_type the raw file type. * @arg groupname the groupname (up to 16 bytes to read). * @arg dirname the directory name (up to 8 bytes are read). @@ -654,7 +654,7 @@ static mcs_parse_func_t lookup_mcsfile_parse(unsigned int type) * @return the error code (0 if ok). */ -int g1m_parse_mcsfile_content(g1m_mcsfile_t **handle, FILE *stream, +int g1m_decode_mcsfile_content(g1m_mcsfile_t **handle, g1m_buffer_t *buffer, int raw_type, const unsigned char *groupname, const unsigned char *dirname, const unsigned char *filename, uint_fast32_t filesize) @@ -684,8 +684,8 @@ int g1m_parse_mcsfile_content(g1m_mcsfile_t **handle, FILE *stream, } /* look for the parsing function */ - mcs_parse_func_t parse = lookup_mcsfile_parse(type); - if (!parse) { + mcs_decode_func_t decode = lookup_mcsfile_decode(type); + if (!decode) { log_error("No dedicated parsing function for this type was found!"); goto notparsing; } @@ -693,7 +693,7 @@ int g1m_parse_mcsfile_content(g1m_mcsfile_t **handle, FILE *stream, /* read it */ h->type = type; strncpy(h->name, (char*)filename, 8); - int err = (*parse)(h, stream, filesize); + int err = (*decode)(h, buffer, filesize); /* free if error, and return */ if (err) { @@ -722,16 +722,16 @@ notparsing:; } /** - * g1m_parse_mcs: - * Parse an MCS file, after the Standard Header. + * g1m_decode_mcs: + * Decode an MCS file, after the Standard Header. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg num number of sizes. * @return the error code (0 if ok). */ -int g1m_parse_mcs(g1m_t *handle, FILE *stream, +int g1m_decode_mcs(g1m_t *handle, g1m_buffer_t *buffer, struct standard_header *std) { int err = g1m_error_alloc; @@ -776,8 +776,8 @@ int g1m_parse_mcs(g1m_t *handle, FILE *stream, /* decode */ handle->files[handle->count] = NULL; - err = g1m_parse_mcsfile_content(&handle->files[handle->count], - stream, fhd.filetype, hd.intname, fhd.dirname, + err = g1m_decode_mcsfile_content(&handle->files[handle->count], + buffer, fhd.filetype, hd.intname, fhd.dirname, fhd.filename, fhd.datalength); if (err) return (err); handle->count++; diff --git a/src/parse/picture.c b/src/decode/picture.c similarity index 90% rename from src/parse/picture.c rename to src/decode/picture.c index 01ff7f7..53c845e 100644 --- a/src/parse/picture.c +++ b/src/decode/picture.c @@ -1,10 +1,10 @@ /* ************************************************************************** */ /* _____ _ */ -/* parse/picture.c |_ _|__ _ _| |__ ___ _ _ */ +/* decode/picture.c |_ _|__ _ _| |__ ___ _ _ */ /* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ /* | | (_) | |_| | | | | __/ |_| | */ /* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/12/01 13:33:45 |___/ */ +/* Last updated: 2017/02/19 23:01:18 |___/ */ /* */ /* ************************************************************************** */ #include @@ -27,16 +27,16 @@ static void g3p_deobfuscate(uint8_t *buf, size_t n) } /** - * g1m_parse_g3p: - * Parse a G3P file. + * g1m_decode_g3p: + * Decode a G3P file. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @arg std the standard header. * @return the error code (0 if ok). */ -int g1m_parse_g3p(g1m_t *handle, FILE *stream, +int g1m_decode_g3p(g1m_t *handle, g1m_buffer_t *buffer, struct standard_header *std) { /* get the G3P global header */ @@ -133,20 +133,20 @@ int g1m_parse_g3p(g1m_t *handle, FILE *stream, } /** - * g1m_parse_c2p: - * Parse Classpad images. + * g1m_decode_c2p: + * Decode Classpad images. * * @arg handle the handle. - * @arg stream the stream to parse from. + * @arg buffer the buffer to read from. * @return the error code (0 if ok). */ -int g1m_parse_c2p(g1m_t *handle, FILE *stream, +int g1m_decode_c2p(g1m_t *handle, g1m_buffer_t *buffer, struct standard_header *std) { (void)std; (void)handle; - (void)stream; + (void)buffer; /* TODO */ log_info("C2P files are not managed yet."); log_info("Size is %" PRIuSIZE " o", sizeof(struct c2p_subheader)); diff --git a/src/decode/storage.c.draft b/src/decode/storage.c.draft new file mode 100644 index 0000000..c15b2a6 --- /dev/null +++ b/src/decode/storage.c.draft @@ -0,0 +1,113 @@ +/* ************************************************************************** */ +/* _____ _ */ +/* decode/storage.c |_ _|__ _ _| |__ ___ _ _ */ +/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ +/* | | (_) | |_| | | | | __/ |_| | */ +/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ +/* Last updated: 2017/02/19 23:01:18 |___/ */ +/* */ +/* ************************************************************************** */ +#include +#define MAX_SECTORS 27 +#define SUB(V, TYPE) \ + case storage_entrytype_##TYPE:; struct storage_##TYPE *V = \ + (struct storage_##TYPE*)&entry->raw_subheader; + +/* ************************************************************************** */ +/* Main functions */ +/* ************************************************************************** */ +/** + * g1m_decode_storage: + * Decode storage files. + * + * @arg handle the libg1m handle. + * @arg buffer the buffer to read from. + * @arg std the standard header. + * @return the error code (0 if ok). + */ + +int g1m_decode_storage(g1m_t *handle, g1m_buffer_t *buffer, + struct standard_header *std) +{ + (void)std; int err, ret = 0; + handle->type = 0x00; + log_info("Storage memory!"); + /* skip the first 0x270000 - 0x20 bytes */ + SKIP(0x270000 - sizeof(struct standard_header)) + + /* get the entries */ + struct storage_entry storage_entries[0x800]; + READ(storage_entries, 0x800 * sizeof(struct storage_entry)) + + /* read the sectors and directories */ + uint32_t sectors[MAX_SECTORS] = {0}; /* sectors offsets */ + uint32_t max_sector_end = 0; + for (int id = 0; id < 0x800; id++) { + struct storage_entry *entry = storage_entries[id]; + entry->type = be16toh(entry.type); + entry->uuid = be16toh(entry.uuid); + + int special = (entry.type & 0xF000) >> 12; + switch (entry.type & 0xFFF) { + SUB(sh, sector) + uint32_t addr = be32toh(sh->startaddr); + uint32_t logical = be32toh(sh->logical_sector_number); + if (addr > max_sector_end) + max_sector_end = addr; + if (logical != 0xFFFFFFFF) + sectors[logical] - 0x290000; + break; + + SUB(dh, directory) + int active = (special == 0x05); + dh->name; + break; + } + } + + /* correct sector end, and calculate how much data we need to gather */ + max_sector_end = max_sector_end + 0x10000; + uint8_t *buf = malloc(max_sector_end - 0x290000); + if (!buf) return (g1m_error_alloc); + GREAD(buf, max_sector_end - 0x290000); + + /* look for files and fragments */ + for (int id = 0; id < 0x800; id++) { + struct storage_entry *entry = storage_entries[id]; + + /* check that entry is a directory */ + if ((entry->type & 0xFFF) != storage_entrytype_file + || !entry->uuid) continue; + int special = (entry.type & 0xF000) >> 12; + + /* get subheader */ + struct storage_file *fh = + (struct storage_file*)entry->raw_subheader; + fh->directory_reference = be16toh(fh->directory_number); + fh->directory_number = be16toh(fh->directory_number); + + /* check if is in a directory */ + unsigned int indir = 0; + //if (fh->directory_reference != 0xFFFF && + if (fh->directory_reference == storage_entrytype_directory) + indir = fh->directory_number; + + /* work out */ + uint_fast32_t size = 0; + int id_f = id; + for (; id_f < 0x800; id_f++) { + /* check that entry is fragment */ + struct storage_entry *entry = storage_entries[id_f]; + if ((entry.type & 0xFFF) != storage_entrytype_fragment) break; + + /* add size */ + size += used_bytes; + } + } + + /* no error */ + ret = 0; +fail: + free(buf); + return (ret); +} diff --git a/src/fontcharacter/character.c b/src/fontcharacter/character.c deleted file mode 100644 index 9912b1c..0000000 --- a/src/fontcharacter/character.c +++ /dev/null @@ -1,84 +0,0 @@ -/* ************************************************************************** */ -/* _____ _ */ -/* fontcharacter/character.c |_ _|__ _ _| |__ ___ _ _ */ -/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ -/* | | (_) | |_| | | | | __/ |_| | */ -/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/11/21 13:29:30 |___/ */ -/* */ -/* ************************************************************************** */ -#include -#include - -/** - * g1m_mbtofc: - * Multi-byte to FONTCHARACTER. - * - * Based on what is said in the fx-9860G SDK. - * Let's hope it stays true. - * - * Based on how `mbtowc` works. - * - * @arg pfc pointer to the FONTCHARACTER character. - * @arg s the multi-byte source string. - * @arg n the size of the destination buffer. - * @return the number of bytes used (-1 if error). - */ - -int g1m_mbtofc(FONTCHARACTER *pfc, const char *s, size_t n) -{ - /* null string? */ - if (!s) return (-1); - - /* so that the 'no size = unlimited' (n == 0) case is easy to manage */ - n--; - - /* nul character? */ - if (!*s) - return (0); - - /* extended char? */ - const unsigned char *us = (const unsigned char*)s; - if (*us && strchr("\x7F\xF7\xF9\xE5\xE6\xE7", *us)) { - if (!n) return (-1); - *pfc = *us; - *pfc <<= 8; - *pfc |= *(us + 1); - return (2); - } - - /* single-byte character! */ - *pfc = *us; - return (1); -} - -/** - * g1m_fctomb: - * FONTCHARACTER to multi-byte. - * - * Based on the same document, and on how `wctomb` works. - * - * Do you think a battery has self-consciousness? - * - * @arg s pointer to the multi-byte string. - * @arg fc the FONTCHARACTER character. - * @return the - */ - -int g1m_fctomb(char *s, FONTCHARACTER fc) -{ - /* no string? */ - if (!s) - return (-1); - - /* extended? */ - if (fc > 0xff) { - *s++ = (fc >> 8) & 0xff; - *s = fc & 0xff; - return (2); - } - - /* normal char. */ - *s = fc; - return (fc != 0); -} diff --git a/src/fontcharacter/string.c b/src/fontcharacter/string.c deleted file mode 100644 index c820ff8..0000000 --- a/src/fontcharacter/string.c +++ /dev/null @@ -1,84 +0,0 @@ -/* ************************************************************************** */ -/* _____ _ */ -/* fontcharacter/string.c |_ _|__ _ _| |__ ___ _ _ */ -/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ -/* | | (_) | |_| | | | | __/ |_| | */ -/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/11/21 13:29:30 |___/ */ -/* */ -/* ************************************************************************** */ -#include -#include - -/** - * g1m_mbstofcs: - * Multi-byte string to FONTCHARACTER string. - * - * This function imitates `mbstowcs` (unicode), but for CASIO's encoding. - * You should be able to use it the same way. - * - * @arg dest the destination. - * @arg src the source. - * @arg n the size of the source. - * @return the size of the destination. - */ - -size_t g1m_mbstofcs(FONTCHARACTER *dest, const char *src, size_t n) -{ - size_t len = 0; - n--; /* terminating character */ - - while (n--) { - /* read the FONTCHARACTER char */ - FONTCHARACTER fc; - int count = g1m_mbtofc(&fc, src, 0); - if (count <= 0) - break; - - /* write the entry and iterate */ - if (dest) *dest++ = fc; - src += count; - len++; - } - - /* write the terminating entry and return length */ - if (dest) *dest = 0; - return (len); -} - -/** - * g1m_fcstombs: - * FONTCHARACTER string to multi-byte string conversion. - * - * This function imitates `wcstombs` (unicode), but for CASIO's encoding. - * You should be able to use it the same way. - * - * @arg dst the destination. - * @arg src the source. - * @arg n the size of the source. - * @return the size of the destination. - */ - -size_t g1m_fcstombs(char *dst, const FONTCHARACTER *src, size_t n) -{ - char buf[2]; - size_t len = 0; - n--; /* terminating character */ - - /* main loop */ - while (n--) { - /* to multi-byte */ - int count = g1m_fctomb(buf, *src++); - if (count <= 0) break; - - /* copy */ - if (dst) { - memcpy(dst, buf, count); - dst += count; - } - len += count; - n -= count; - } - if (dst) *dst = 0; - return (len); -} diff --git a/src/parse/storage.c b/src/parse/storage.c deleted file mode 100644 index 0757d85..0000000 --- a/src/parse/storage.c +++ /dev/null @@ -1,125 +0,0 @@ -/* ************************************************************************** */ -/* _____ _ */ -/* parse/storage.c |_ _|__ _ _| |__ ___ _ _ */ -/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ -/* | | (_) | |_| | | | | __/ |_| | */ -/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ -/* Last updated: 2016/12/25 13:38:52 |___/ */ -/* */ -/* ************************************************************************** */ -#include -#define SUB(V, TYPE) \ - case storage_entrytype_##TYPE:; \ - struct storage_##TYPE *V = (struct storage_##TYPE*)&entry.raw_subheader; - -/** - * rawfctombs: - * Temporary function, from raw FONTCHARACTER to multi-byte using buffers. - * - * @arg raw the raw buffer - * @arg count the number of fontcharacters in the count - * @arg final the final multi-byte buffer - */ - -static void rawfctombs(FONTCHARACTER *raw, int count, char *final) -{ - /* copy the raw data into a null-terminated buffer */ - FONTCHARACTER traw[count + 1]; traw[count] = 0; - memcpy(traw, raw, count * sizeof(FONTCHARACTER)); - - /* big endian to host the raw buffer, and null terminate it */ - int i; - for (i = 0; traw[i] != 0xffff && i < count; i++) - traw[i] = be16toh(traw[i]); - traw[i] = 0; - - g1m_fcstombs(final, traw, 0); -} - -/** - * g1m_parse_storage: - * Parse storage files. - * - * @arg handle the libg1m handle. - * @arg stream the stream to read from. - * @arg std the standard header. - * @return the error code (0 if ok). - */ - -int g1m_parse_storage(g1m_t *handle, FILE *stream, - struct standard_header *std) -{ - (void)std; - handle->type = 0x00; - /* skip the first 0x270000 - 0x20 bytes */ - SKIP(0x270000 - sizeof(struct standard_header)) - - /* read */ - log_info("Storage memory!"); - - /* read the entries */ - for (int id = 1; id < 0x800; id++) { - /* read the entry */ - DREAD(entry, storage_entry) - if (entry.type == 0xFFFF) - continue; - entry.type = be16toh(entry.type); - entry.uuid = be16toh(entry.uuid); - - /* read it */ - int special = (entry.type & 0xF000) >> 12; - switch (entry.type & 0xFFF) { - SUB(sh, sector) - int unused = (sh->logical_sector_number == 0xFFFFFFFF); - log_info("[%02d,%02" PRIu16 "] Is a%ssector.", id, entry.uuid, - (unused) ? "n unused " : " "); - sh->startaddr = be32toh(sh->startaddr); - log_info("- Starts at address 0x%08" PRIx32, sh->startaddr); -#if LOGLEVEL <= ll_info - sh->logical_sector_number = be32toh(sh->logical_sector_number); - if (!unused) log_info("- Logical number: 0x%08" PRIu32, - sh->logical_sector_number); -#endif - break; - - SUB(dh, directory) - log_info("[%02d,%02" PRIu16 "] Is a%s directory.", id, entry.uuid, - (special == 0x05) ? "n active" : " deleted"); -#if LOGLEVEL <= ll_info - char dirname[25]; rawfctombs(dh->name, 12, dirname); - log_info("- Directory name: %s", dirname); -#endif - break; - - SUB(fh, file) - log_info("[%02d,%02" PRIu16 "] Is a%s file.", id, entry.uuid, - (special == 0x05) ? "n active" : " deleted"); -#if LOGLEVEL <= ll_info - char filename[25]; rawfctombs(fh->name, 12, filename); - log_info("- File name: %s", filename); - - if (be16toh(fh->directory_reference) == storage_entrytype_directory) - log_info("- Is in directory #%" PRIu16, - be16toh(fh->directory_number)); - else log_info("- Is in root."); -#endif - break; - - SUB(fgh, fragment) - log_info("[%02d,%02" PRIu16 "] Is a fragment.", id, entry.uuid); - log_info("- Points at sector #%" PRIu16, - be16toh(fgh->fragment_sector_id)); - log_info("- Is %" PRIu16 "/%" PRIu16 - " (%" PRIu16 "o at offset 0x%04" PRIx16 ")", - be16toh(fgh->fragment_id), be16toh(fgh->fragment_count), - be16toh(fgh->used_bytes), be16toh(fgh->used_bytes_offset)); - break; - - default: /* we should know all of the types, but we never know */ - log_info("[%02d,%02" PRIu16 "] Is unknown.", id, entry.uuid); - } - } - - /* no error */ - return (0); -} diff --git a/src/user/open.c b/src/user/open.c index 2ba67f4..6234834 100644 --- a/src/user/open.c +++ b/src/user/open.c @@ -62,8 +62,14 @@ int g1m_fopen(g1m_t **handle, const char *path, FILE *stream, *handle = malloc(sizeof(g1m_t)); if (!*handle) return (g1m_error_alloc); + /* make the buffer */ + g1m_buffer_t buffer = { + .cookie = stream, + .read = g1m_filebuffer_read + }; + /* fill it by parsing opened file */ - if ((err = g1m_parse(*handle, path, stream, expected))) { + if ((err = g1m_decode(*handle, path, &buffer, expected))) { free(*handle); *handle = NULL; return (err); diff --git a/src/utils/filebuffer.c b/src/utils/filebuffer.c new file mode 100644 index 0000000..7c7ca51 --- /dev/null +++ b/src/utils/filebuffer.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* _____ _ */ +/* utils/filebuffer.c |_ _|__ _ _| |__ ___ _ _ */ +/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */ +/* | | (_) | |_| | | | | __/ |_| | */ +/* By: thomas |_|\___/ \__,_|_| |_|\___|\__, |.fr */ +/* Last updated: 2017/02/19 22:35:20 |___/ */ +/* */ +/* ************************************************************************** */ +#include +#ifndef G1M_DISABLED_FILE + +/** + * g1m_filebuffer_read: + * Read from a filebuffer. + * + * @arg vcookie the FILE* (uncasted) + * @arg buf the buffer to fill. + * @arg size the size to read. + * @return the error (if any). + */ + +int g1m_filebuffer_read(void *vcookie, unsigned char *buf, size_t size) +{ + FILE *file = (void*)vcookie; + size_t read = fread(buf, 1, size, file); + if (!read) { + log_error("READING failed: read %" PRIuSIZE "/%" PRIuSIZE + " bytes, %" PRIuSIZE " missing.", read, size, size - read); + return (g1m_error_eof); + } + + /* no error */ + return (0); +} + +#endif diff --git a/src/utils/skip.c b/src/utils/skip.c index df4629f..e8d9938 100644 --- a/src/utils/skip.c +++ b/src/utils/skip.c @@ -10,69 +10,43 @@ #include /** - * g1m_parse_skip: + * g1m_skip: * Skip some bytes. * * I've made two loops to avoid conditions in each loop iteration - * when checksum is not calculated. + * when checksum is not calculated. Yeah, I know. #YOLO. * - * @arg stream the stream where to skip bytes. + * @arg buffer the buffer from which to read. * @arg size the size to skip. * @arg checksum pointer to the checksum variable if there is one. */ -int g1m_parse_skip(FILE *stream, size_t size, uint_fast32_t *checksum) +int g1m_skip(g1m_buffer_t *buffer, size_t size, uint_fast32_t *checksum) { - uint8_t buf[1024]; -#if LOGLEVEL <= ll_error - size_t size_ini = size; -#endif + uint8_t buf[1024]; int err; + size_t rd = 0; uint_fast32_t add = 0; - if (checksum) { - uint_fast32_t add = 0; - while (1) { - /* if no size left, exit */ - if (!size) break; + while (1) { + /* if no size left, exit */ + if (!size) break; - /* read that much */ - { - size_t curlen = min(size, 1024); - size_t read_len = fread(buf, 1, curlen, stream); - size -= read_len; - if (read_len < curlen) { - log_error("SKIPPING failed, skipped " - "%" PRIuSIZE "/%" PRIuSIZE " bytes, " - "%" PRIuSIZE " missing", - size_ini - size, size_ini, size); - return (g1m_error_eof); - } - - /* feed the checksum */ - add = g1m_checksum32(buf, curlen, add); + /* read that much */ + { + size_t curlen = min(size, 1024); + if ((err = (*buffer->read)(buffer->cookie, buf, curlen))) { + log_error("Skipping has failed after %zu bytes", size); + return (err); } - } - *checksum += add; - } else { - while (1) { - /* if no size left, exit */ - if (!size) break; + rd += curlen; - /* read that much */ - { - size_t curlen = min(size, 1024); - size_t read_len = fread(buf, 1, curlen, stream); - size -= read_len; - if (read_len < curlen) { - log_error("SKIPPING failed, skipped " - "%" PRIuSIZE "/%" PRIuSIZE " bytes, " - "%" PRIuSIZE " missing", - size_ini - size, size_ini, size); - return (g1m_error_eof); - } - } + /* feed the checksum */ + add = g1m_checksum32(buf, curlen, add); } } + /* add to checksum */ + if (checksum) *checksum += add; + /* no error */ return (0); } diff --git a/tools/.fontcharacter-root b/tools/.fontcharacter-root deleted file mode 160000 index 2f4680d..0000000 --- a/tools/.fontcharacter-root +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 2f4680d042f84787bf39fb93e4448599b5e2baa3 diff --git a/tools/fontcharacter b/tools/fontcharacter deleted file mode 120000 index 0ad8288..0000000 --- a/tools/fontcharacter +++ /dev/null @@ -1 +0,0 @@ -.fontcharacter-root/fontcharacter \ No newline at end of file diff --git a/tools/fontcharacter_reference b/tools/fontcharacter_reference deleted file mode 160000 index 1f382d0..0000000 --- a/tools/fontcharacter_reference +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1f382d0797f7534df408e858a9182bd11c9dddea diff --git a/tools/write-header-config b/tools/write-header-config index a837879..e3198f6 100755 --- a/tools/write-header-config +++ b/tools/write-header-config @@ -3,24 +3,53 @@ # Arguments # #******************************************************************************# # Initialize the variables -gint= no_file= +version= # Read the arguments for arg ; do case "$arg" in ---gint) gint=y ;; --no-file) no_file=y ;; +--version=*) version="${arg#*=}" ;; *) echo "'${arg}': Did not read." ;; esac; done +# Make version as numbers +vnum=$(echo ${version} | cut -d- -f1) +version_major=$(( $(echo ${vnum} | cut -d. -f1) )) +version_minor=$(( $(echo ${vnum} | cut -s -d. -f2) )) +version_rev=$(( $(echo ${vnum} | cut -s -d. -f3) )) +version_indev=$(echo ${version} | cut -s -d- -f2) +version_indev=$([ ${version_indev} ] && echo 1 || echo 0) + +# Constitute version thingies +version_num=$(printf "0x%02X%02X%04X" \ + ${version_major} ${version_minor} ${version_rev}) + #******************************************************************************# # Write the file # #******************************************************************************# +# Beginning cat <<_EOF #ifndef LIBG1M_CONFIG_H # define LIBG1M_CONFIG_H +# define LIBG1M_VERSION "${version}" +# define LIBG1M_VERNUM ${version_num} +# define LIBG1M_MAJOR ${version_major} +# define LIBG1M_MINOR ${version_minor} +# define LIBG1M_REV ${version_rev} +# define LIBG1M_INDEV ${version_indev} -# --- no option yet! --- +_EOF +# File part +if [ "$no_file" ]; then cat <<_EOF +/* FILE interface is disabled */ +# define G1M_DISABLED_FILE 1 + +_EOF +fi + +# End of the file +cat <<_EOF #endif /* LIBG1M_CONFIG_H */ _EOF