Changed the way type is detected
This commit is contained in:
parent
4474d276f1
commit
c728eff645
|
@ -1,10 +1,10 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* libg1m/format/main.h |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* libg1m/format.h |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/02 14:15:46 |___/ */
|
||||
/* Last updated: 2016/12/01 13:33:58 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#ifndef LIBG1M_FORMAT_H
|
||||
|
@ -35,17 +35,11 @@
|
|||
* it can simply be obtained by bitwise-AND-ing with 0xff. */
|
||||
|
||||
struct standard_header {
|
||||
/* the file identifier - see below */
|
||||
/* the file identifier */
|
||||
uint8_t main_id[8];
|
||||
|
||||
/* our filetype! */
|
||||
uint8_t type;
|
||||
|
||||
/* magic numbers, not always the same:
|
||||
* - for fx-CG formats: {0x00, 0x01, 0x00, 0x01, 0x00}
|
||||
* - for C2P: "2p\0\0\0"
|
||||
* - otherwise: {0x00, 0x10, 0x00, 0x10, 0x00} */
|
||||
uint8_t magic[5];
|
||||
/* our subtype! */
|
||||
uint8_t subtype[6];
|
||||
|
||||
/* first control byte: filesize LSB + 0x41 */
|
||||
uint8_t control;
|
||||
|
@ -70,67 +64,17 @@ struct standard_header {
|
|||
};
|
||||
|
||||
/* At the beginning, we thought "USBPower" was some magic sequence we would
|
||||
* systematically find in the "main_id" field. But a counter example came:
|
||||
* the G3L, where the main ID was "Ly755 ".
|
||||
* systematically find in the "main_id" field. But counter examples came:
|
||||
* the G3L, whose main ID was "Ly755 ", and the C2P.
|
||||
*
|
||||
* So here are the known main IDs: */
|
||||
|
||||
enum g1m_main_id {
|
||||
/* "USBPower": the most common one */
|
||||
g1m_mid_usbpower,
|
||||
|
||||
/* "Ly755 ": fx-CG specific types */
|
||||
g1m_mid_ly755,
|
||||
|
||||
/* "CASIO\0\0\0": some other types */
|
||||
g1m_mid_casio,
|
||||
};
|
||||
|
||||
/* Each main ID have their own types. Here are the USBPower types: */
|
||||
|
||||
enum g1m_usbpower_type {
|
||||
/* fx language file */
|
||||
g1m_usbpower_type_lang = 0x12,
|
||||
|
||||
/* fx-CG add-in */
|
||||
g1m_usbpower_type_addin_cg = 0x2c,
|
||||
|
||||
/* mcs (main memory) save */
|
||||
g1m_usbpower_type_mcs = 0x31,
|
||||
|
||||
/* e-activity (document) */
|
||||
g1m_usbpower_type_eact = 0x49,
|
||||
|
||||
/* g1r equivalent */
|
||||
g1m_usbpower_type_g2r = 0x62,
|
||||
|
||||
/* g3m (fx-CG program) */
|
||||
g1m_usbpower_type_g3m = 0x75,
|
||||
|
||||
/* g3p (fx-CG picture) */
|
||||
g1m_usbpower_type_g3p = 0x7d,
|
||||
|
||||
/* add-in (compiled program) */
|
||||
g1m_usbpower_type_addin = 0xf3,
|
||||
};
|
||||
|
||||
/* Here are Ly755 types: */
|
||||
|
||||
enum g1m_ly755_type {
|
||||
/* language file */
|
||||
g1m_ly755_type_lang = 0x2c
|
||||
};
|
||||
|
||||
/* And here are the CASIO types: */
|
||||
|
||||
enum g1m_casio_type {
|
||||
/* c2p */
|
||||
g1m_casio_type_c2p = 0x63
|
||||
};
|
||||
* 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. */
|
||||
|
||||
# pragma pack()
|
||||
|
||||
/* After the Standard Header is read and the G1M type is read, we have parts,
|
||||
/* After the Standard Header is read and the type is read, we have parts,
|
||||
* each with their own subheaders and their own subtilities.
|
||||
*
|
||||
* Where do you want to start? Pick your poison. */
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/10/31 00:14:27 |___/ */
|
||||
/* Last updated: 2016/12/01 13:33:58 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#ifndef LIBG1M_INTERNALS_H
|
||||
|
@ -54,18 +54,27 @@
|
|||
/* skipping utility */
|
||||
int g1m_parse_skip(FILE *stream, size_t size, uint_fast32_t *checksum);
|
||||
|
||||
/* type getting utility */
|
||||
int g1m_get_type_info(unsigned char *main_id, unsigned char *subtype,
|
||||
const char **info, int (**rd)(g1m_t*, FILE*, struct standard_header*));
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Specific parsing functions */
|
||||
/* ************************************************************************** */
|
||||
int g1m_parse_g3p(g1m_t *handle, FILE *stream,
|
||||
struct standard_header *std);
|
||||
int g1m_parse_c2p(g1m_t *handle, FILE *stream);
|
||||
int g1m_parse_mcs(g1m_t *handle, FILE *stream, uint_fast16_t num);
|
||||
int g1m_parse_eact(g1m_t * handle, FILE *stream);
|
||||
int g1m_parse_addin(g1m_t *handle, FILE *stream);
|
||||
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);
|
||||
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);
|
||||
|
||||
|
|
|
@ -127,35 +127,6 @@ void g1m_log_mem(const char *prefx, void *m, size_t n)
|
|||
/* ************************************************************************** */
|
||||
/* Enumerations strings */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_get_type_string:
|
||||
* Get string description of a type of a G1M file.
|
||||
*
|
||||
* @arg code the code.
|
||||
* @return the string.
|
||||
*/
|
||||
|
||||
const char *g1m_get_type_string(int main_id, int type)
|
||||
{
|
||||
switch (main_id) {
|
||||
case g1m_mid_usbpower:
|
||||
switch (type) {
|
||||
case g1m_usbpower_type_addin_cg: return ("fx-CG addin");
|
||||
case g1m_usbpower_type_mcs: return ("mcs");
|
||||
case g1m_usbpower_type_eact: return ("e-activity");
|
||||
case g1m_usbpower_type_g2r: return ("mcs (g2r)");
|
||||
case g1m_usbpower_type_g3p: return ("g3p");
|
||||
case g1m_usbpower_type_addin: return ("addin");
|
||||
}
|
||||
break;
|
||||
case g1m_mid_ly755:
|
||||
switch (type) {
|
||||
case g1m_ly755_type_lang: return ("fx-CG language file");
|
||||
}
|
||||
}
|
||||
return ("unknown");
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_get_mcs_ftype_string:
|
||||
* Get string description of a type of a G1M part directory.
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/02 14:47:49 |___/ */
|
||||
/* Last updated: 2016/12/01 13:33:45 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
@ -66,8 +66,13 @@ static void set_data(g1m_t *handle,
|
|||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_parse_addin(g1m_t *handle, FILE *stream)
|
||||
int g1m_parse_addin(g1m_t *handle, FILE *stream,
|
||||
struct standard_header *std)
|
||||
{
|
||||
(void)std;
|
||||
/* set handle vars */
|
||||
handle->type = g1m_type_addin;
|
||||
|
||||
/* get the subheader */
|
||||
DREAD(hd, g1a_subheader)
|
||||
|
||||
|
@ -115,6 +120,10 @@ int g1m_parse_addin(g1m_t *handle, FILE *stream)
|
|||
int g1m_parse_addin_cg(g1m_t *handle, FILE *stream,
|
||||
struct standard_header *std)
|
||||
{
|
||||
/* set handle vars */
|
||||
handle->type = g1m_type_addin;
|
||||
handle->is_cg = 1;
|
||||
|
||||
/* get the subheader */
|
||||
DREAD(hd, g3a_subheader)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/02 14:47:49 |___/ */
|
||||
/* Last updated: 2016/12/01 13:33:45 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
@ -137,15 +137,20 @@ static int g1m_parse_eact_cont(g1m_t *handle, uint8_t *buf, size_t bufsize,
|
|||
* g1m_parse_eact:
|
||||
* Parse an EACT.
|
||||
*
|
||||
* Thanks to Julese50/CoiledSpring for his help on e-acts parsing.
|
||||
* Thanks to Julese50 for his help on e-acts parsing.
|
||||
*
|
||||
* @arg handle the handle.
|
||||
* @arg stream the stream to parse from.
|
||||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_parse_eact(g1m_t * handle, FILE *stream)
|
||||
int g1m_parse_eact(g1m_t * handle, FILE *stream,
|
||||
struct standard_header *std)
|
||||
{
|
||||
(void)std;
|
||||
/* set handle type */
|
||||
handle->type = g1m_type_eact;
|
||||
|
||||
/* parse the header */
|
||||
DREAD(hd, eact_header)
|
||||
|
||||
|
@ -162,6 +167,10 @@ int g1m_parse_eact(g1m_t * handle, FILE *stream)
|
|||
log_info("Setup area size is 0x%x bytes long.",
|
||||
hd.setup_area_size);
|
||||
|
||||
/* check if is CG */
|
||||
if (hd.eact_version == EACT_G3E)
|
||||
handle->is_cg = 1;
|
||||
|
||||
/* skip the setup area */
|
||||
SKIP(hd.setup_area_size)
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/24 18:00:21 |___/ */
|
||||
/* Last updated: 2016/12/01 13:33:45 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
@ -18,10 +18,16 @@
|
|||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_parse_lang(g1m_t *handle, FILE *stream)
|
||||
int g1m_parse_lang(g1m_t *handle, FILE *stream,
|
||||
struct standard_header *std)
|
||||
{
|
||||
(void)std;
|
||||
/* set handle type */
|
||||
//handle->type = g1m_type_lang;
|
||||
|
||||
(void)handle;
|
||||
(void)stream;
|
||||
/* TODO */
|
||||
log_info("Language type isn't managed yet.");
|
||||
return (0);
|
||||
}
|
||||
|
@ -40,6 +46,10 @@ int g1m_parse_lang_cg(g1m_t *handle, FILE *stream,
|
|||
struct standard_header *std)
|
||||
{
|
||||
(void)handle;
|
||||
/* set handle type */
|
||||
//handle->type = g1m_type_lang;
|
||||
//handle->is_cg = 1;
|
||||
|
||||
/* read the subheader */
|
||||
DREAD(hd, g3l_subheader)
|
||||
|
||||
|
|
|
@ -4,30 +4,11 @@
|
|||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/02 14:47:49 |___/ */
|
||||
/* Last updated: 2016/12/01 13:33:45 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
||||
/**
|
||||
* get_main_id:
|
||||
* Get numerical main ID based on the main ID string.
|
||||
*
|
||||
* @arg s the 8-bytes buffer containing the ID.
|
||||
* @return the main ID or -1 if the main ID is unknown.
|
||||
*/
|
||||
|
||||
static int get_main_id(unsigned char *s)
|
||||
{
|
||||
if (!memcmp(s, "USBPower", 8))
|
||||
return (g1m_mid_usbpower);
|
||||
if (!memcmp(s, "Ly755 ", 8))
|
||||
return (g1m_mid_ly755);
|
||||
if (!memcmp(s, "CASIO\0\0\0", 8))
|
||||
return (g1m_mid_casio);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* g1m_parse:
|
||||
* Parse a G1M file.
|
||||
|
@ -53,7 +34,7 @@ int g1m_parse(g1m_t *handle, FILE *stream)
|
|||
for (size_t i = 0; i < sizeof(struct standard_header); i++) u[i] = ~u[i];
|
||||
|
||||
/* print header */
|
||||
log_info("Raw standard header is:");
|
||||
log_info("Raw inverted standard header is:");
|
||||
logm_info(&hd, sizeof(struct standard_header));
|
||||
|
||||
/* correct standard header endianess */
|
||||
|
@ -69,68 +50,19 @@ int g1m_parse(g1m_t *handle, FILE *stream)
|
|||
return (g1m_error_magic);
|
||||
}
|
||||
|
||||
/* get the main ID */
|
||||
int main_id = get_main_id(hd.main_id);
|
||||
if (main_id < 0) {
|
||||
log_fatal("Main ID is unknown: '%.8s'", hd.main_id);
|
||||
/* get main ID */
|
||||
int (*read_func)(g1m_t*, FILE*, struct standard_header*);
|
||||
const char *type_string;
|
||||
if (g1m_get_type_info(hd.main_id, hd.subtype, &type_string, &read_func))
|
||||
return (g1m_error_magic);
|
||||
}
|
||||
|
||||
/* log some data */
|
||||
log_info("Standard Header Main ID is '%.8s'", hd.main_id);
|
||||
log_info("Standard Header Type is '%s' (0x%02x)",
|
||||
g1m_get_type_string(main_id, hd.type), hd.type);
|
||||
log_info("Standard Header filesize is %uo", hd.filesize);
|
||||
log_info("Standard Header type is '%s'.", type_string);
|
||||
log_info("Standard Header filesize is %uo.", hd.filesize);
|
||||
log_info("Standard Header num is %d.", hd.number);
|
||||
|
||||
/* subparse. */
|
||||
handle->type = 0;
|
||||
handle->is_cg = 0;
|
||||
switch (main_id) {
|
||||
case g1m_mid_usbpower: switch (hd.type) {
|
||||
case g1m_usbpower_type_lang:
|
||||
handle->type = g1m_type_lang;
|
||||
return (g1m_parse_lang(handle, stream));
|
||||
case g1m_usbpower_type_addin:
|
||||
handle->type = g1m_type_addin;
|
||||
return (g1m_parse_addin(handle, stream));
|
||||
case g1m_usbpower_type_addin_cg:
|
||||
handle->type = g1m_type_addin;
|
||||
handle->is_cg = 1;
|
||||
return (g1m_parse_addin_cg(handle, stream, &hd));
|
||||
case g1m_usbpower_type_g2r:
|
||||
case g1m_usbpower_type_mcs:
|
||||
handle->type = g1m_type_mcs;
|
||||
return (g1m_parse_mcs(handle, stream, hd.number));
|
||||
case g1m_usbpower_type_eact:
|
||||
handle->type = g1m_type_eact;
|
||||
return (g1m_parse_eact(handle, stream));
|
||||
case g1m_usbpower_type_g3p:
|
||||
handle->type = g1m_type_pict;
|
||||
handle->is_cg = 1;
|
||||
return (g1m_parse_g3p(handle, stream, &hd));
|
||||
default:
|
||||
log_info("Type not managed (yet?): 0x%02x", hd.type);
|
||||
} break;
|
||||
case g1m_mid_ly755: switch (hd.type) {
|
||||
case g1m_ly755_type_lang:
|
||||
handle->type = g1m_type_lang;
|
||||
handle->is_cg = 1;
|
||||
return (g1m_parse_lang_cg(handle, stream, &hd));
|
||||
break;
|
||||
default:
|
||||
log_info("Type not managed (yet?): 0x%02x", hd.type);
|
||||
} break;
|
||||
case g1m_mid_casio: switch (hd.type) {
|
||||
case g1m_casio_type_c2p:
|
||||
handle->type = g1m_type_pict;
|
||||
return (g1m_parse_c2p(handle, stream));
|
||||
break;
|
||||
default:
|
||||
log_info("Type not managed (yet?): 0x%02x", hd.type);
|
||||
} break;
|
||||
}
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
return ((*read_func)(handle, stream, &hd));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/02 14:47:49 |___/ */
|
||||
/* Last updated: 2016/12/01 13:33:45 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
@ -529,12 +529,16 @@ int g1m_parse_mcsfile_content(g1m_mcsfile_t **handle, FILE *stream,
|
|||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_parse_mcs(g1m_t *handle, FILE *stream, uint_fast16_t num)
|
||||
int g1m_parse_mcs(g1m_t *handle, FILE *stream,
|
||||
struct standard_header *std)
|
||||
{
|
||||
int err = g1m_error_alloc;
|
||||
|
||||
/* No "global" header for MCS parts, because this "global header"
|
||||
* was the standard header. */
|
||||
/* set handle vars */
|
||||
handle->type = g1m_type_mcs;
|
||||
|
||||
/* get number of subparts from the standard header */
|
||||
uint_fast16_t num = std->number;
|
||||
|
||||
/* allocate memory for the subparts */
|
||||
handle->mcs_count = 0;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* parse/picture_cg.c |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* parse/picture.c |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/02 14:47:49 |___/ */
|
||||
/* Last updated: 2016/12/01 13:33:45 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
@ -39,6 +39,9 @@ static void g3p_deobfuscate(uint8_t *buf, size_t n)
|
|||
int g1m_parse_g3p(g1m_t *handle, FILE *stream,
|
||||
struct standard_header *std)
|
||||
{
|
||||
/* set handle vars */
|
||||
handle->type = g1m_type_pict;
|
||||
|
||||
/* get the G3P global header */
|
||||
DREAD(hd, g3p_subheader)
|
||||
hd.g3p_size = be32toh(hd.g3p_size);
|
||||
|
@ -138,13 +141,17 @@ int g1m_parse_g3p(g1m_t *handle, FILE *stream,
|
|||
* @return the error code (0 if ok).
|
||||
*/
|
||||
|
||||
int g1m_parse_c2p(g1m_t *handle, FILE *stream)
|
||||
int g1m_parse_c2p(g1m_t *handle, FILE *stream,
|
||||
struct standard_header *std)
|
||||
{
|
||||
(void)std;
|
||||
/* set handle vars */
|
||||
//handle->type = g1m_type_pict;
|
||||
|
||||
(void)handle;
|
||||
(void)stream;
|
||||
handle->type = 0;
|
||||
log_info("C2P files are not managed yet.");
|
||||
/* TODO */
|
||||
log_info("C2P files are not managed yet.");
|
||||
|
||||
/* no error */
|
||||
return (0);
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* parse/skip.c |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* utils/skip.c |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/11/02 14:48:51 |___/ */
|
||||
/* Last updated: 2016/12/01 13:33:41 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
|
@ -0,0 +1,143 @@
|
|||
/* ************************************************************************** */
|
||||
/* _____ _ */
|
||||
/* utils/type.c |_ _|__ _ _| |__ ___ _ _ */
|
||||
/* | Project: libg1m | |/ _ \| | | | '_ \ / _ \ | | | */
|
||||
/* | | (_) | |_| | | | | __/ |_| | */
|
||||
/* By: thomas <thomas@touhey.fr> |_|\___/ \__,_|_| |_|\___|\__, |.fr */
|
||||
/* Last updated: 2016/12/01 13:33:41 |___/ */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
#include <libg1m/internals.h>
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Local types */
|
||||
/* ************************************************************************** */
|
||||
/* Subtype correspondance type */
|
||||
struct type_info {
|
||||
/* identification */
|
||||
const char *type;
|
||||
|
||||
/* info */
|
||||
const char *info;
|
||||
|
||||
/* actions */
|
||||
int (*read)(g1m_t*, FILE*, struct standard_header*);
|
||||
};
|
||||
|
||||
/* Main type correspondance type */
|
||||
struct main_info {
|
||||
/* identification */
|
||||
const char *type;
|
||||
|
||||
/* subtypes */
|
||||
struct type_info *subtypes;
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Correspondances */
|
||||
/* ************************************************************************** */
|
||||
/* Common magic types */
|
||||
#define magic_common "\x00\x10\x00\x10\x00"
|
||||
#define cp_magic "\x00\x01\x00\x01\x00"
|
||||
|
||||
/* USBPower subtypes */
|
||||
static struct type_info usbpower_types[] = {
|
||||
/* add-ins */
|
||||
{"\xf3" magic_common,
|
||||
"add-in", g1m_parse_addin},
|
||||
{"\x2c" cp_magic,
|
||||
"fx-CG add-in", g1m_parse_addin_cg},
|
||||
|
||||
/* MCS */
|
||||
{"\x31" magic_common,
|
||||
"mcs", g1m_parse_mcs},
|
||||
{"\x62" magic_common,
|
||||
"mcs (g2r)", g1m_parse_mcs},
|
||||
{"\x75" magic_common,
|
||||
"mcs (fx-CG)", g1m_parse_mcs},
|
||||
|
||||
/* Language */
|
||||
{"\x12" magic_common,
|
||||
"fx language file", g1m_parse_lang},
|
||||
|
||||
/* E-Activities */
|
||||
{"\x49" magic_common,
|
||||
"e-activity (document)", g1m_parse_eact},
|
||||
|
||||
/* Pictures */
|
||||
{"\x7d" magic_common,
|
||||
"fx-CG picture", g1m_parse_g3p},
|
||||
|
||||
{}
|
||||
};
|
||||
|
||||
/* Ly755 subtypes */
|
||||
static struct type_info ly755_types[] = {
|
||||
{"\x2c" cp_magic,
|
||||
"fx-CG language file", g1m_parse_lang_cg},
|
||||
{}
|
||||
};
|
||||
|
||||
/* CASIO subtypes */
|
||||
static struct type_info casio_types[] = {
|
||||
{"c2p\0\0\0",
|
||||
"Classpad picture", g1m_parse_c2p},
|
||||
{}
|
||||
};
|
||||
|
||||
/* Main types */
|
||||
static struct main_info types[] = {
|
||||
{"USBPower", usbpower_types},
|
||||
{"Ly755 ", ly755_types},
|
||||
{"CASIO\0\0\0", casio_types},
|
||||
{}
|
||||
};
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Main functions */
|
||||
/* ************************************************************************** */
|
||||
/**
|
||||
* g1m_get_type_info:
|
||||
* Get type info.
|
||||
*
|
||||
* @arg main_id The main ID (at least 8 bytes).
|
||||
* @arg subtype The subtype (at least 6 bytes).
|
||||
* @arg info Pointer to the info string to set.
|
||||
* @arg read Pointer to the read callback to set.
|
||||
* @return If there was an error.
|
||||
*/
|
||||
|
||||
int g1m_get_type_info(unsigned char *main_id, unsigned char *subtype,
|
||||
const char **info, int (**rd)(g1m_t*, FILE*, struct standard_header*))
|
||||
{
|
||||
/* look for main_id */
|
||||
struct main_info *mt = types;
|
||||
while (mt->type) {
|
||||
if (!memcmp(mt->type, main_id, 8))
|
||||
break ;
|
||||
mt++;
|
||||
}
|
||||
if (!mt->type) {
|
||||
log_fatal("Main ID not recognized:");
|
||||
logm_info(main_id, 8);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* look for subtype */
|
||||
struct type_info *sub = mt->subtypes;
|
||||
while (sub->type) {
|
||||
if (!memcmp(sub->type, subtype, 6))
|
||||
break ;
|
||||
sub++;
|
||||
}
|
||||
if (!sub->type) {
|
||||
log_fatal("Type not managed (yet?):");
|
||||
logm_info(subtype, 6);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* fill in info and return */
|
||||
if (info) *info = sub->info;
|
||||
if (rd) *rd = sub->read;
|
||||
return (0);
|
||||
}
|
Reference in New Issue