cake
/
libg1m
Archived
1
0
Fork 0

Should have integrated Caspro variable exchange. :D

This commit is contained in:
Thomas Touhey 2017-03-06 13:03:54 +01:00
parent 6f52a704de
commit b26d860aeb
7 changed files with 119 additions and 14 deletions

View File

@ -88,7 +88,7 @@ typedef struct g1m_bcd_s {
# define g1m_casbcd_special 0x80
# define g1m_casbcd_negative 0x50
# define g1m_casbcd_pow_neg 0x01
typedef struct {
typedef struct cas_bcd {
unsigned char mantissa[8];
unsigned char signinfo;
unsigned char exponent;

View File

@ -118,7 +118,6 @@ G1M_STDFUNC(storage)
/* others */
int g1m_decode_fkey_cg_content(g1m_t *handle, g1m_buffer_t *buffer,
uint_fast32_t zonesize, uint32_t *pchecksum);
/* ************************************************************************** */
/* MCS-specific decoding functions */
/* ************************************************************************** */
@ -135,7 +134,13 @@ G1M_MCSFUNC(program)
G1M_MCSFUNC(setup)
G1M_MCSFUNC(spreadsheet)
G1M_MCSFUNC(string)
/* ************************************************************************** */
/* CASPRO-specific decoding functions */
/* ************************************************************************** */
# define G1M_CASPROFUNC(NAME) \
int g1m_decode_caspro_##NAME(g1m_mcsfile_t *handle, g1m_buffer_t *buffer);
G1M_CASPROFUNC(var)
/* ************************************************************************** */
/* Picture utilities */
/* ************************************************************************** */

View File

@ -20,6 +20,48 @@
* https://casetta.tuxfamily.org/formats/cas
* ************************************************************************** */
#include <libg1m/internals.h>
#define FUNC(NAME) g1m_decode_caspro_##NAME
/* ************************************************************************** */
/* Type correspondance list */
/* ************************************************************************** */
/* Part parsing function type */
typedef int (*caspro_decode_function)(g1m_mcsfile_t*, g1m_buffer_t*);
/* Correspondance type */
struct caspro_corresp {
unsigned int type;
caspro_decode_function decode;
};
/* All correspondances */
#define TTERM {0, NULL}
static struct caspro_corresp caspro_types[] = {
{g1m_mcstype_var, FUNC(var)},
TTERM
};
/**
* lookup_caspro_decode:
* Lookup for a parsing function for the Caspro part.
*
* @arg type the libg1m MCS file type.
* @return the function (NULL if not found).
*/
static caspro_decode_function lookup_caspro_decode(g1m_mcstype_t type)
{
/* lookup for the type */
struct caspro_corresp *c = caspro_types;
while (c->decode) {
if (type == c->type)
break;
c++;
}
/* return the function */
return (c->decode);
}
/* ************************************************************************** */
/* Head decoding function */
@ -42,12 +84,20 @@ int g1m_decode_caspro_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
return (g1m_error_unknown);
/* read specific data */
if (head->type == g1m_mcstype_program) {
switch (head->type) {
case g1m_mcstype_program:;
/* copy password */
char *endp = memchr(hd.aux, 0xFF, 8);
size_t plen = endp ? (size_t)(endp - (char*)hd.aux) : 8;
memcpy(head->password, hd.aux, plen);
head->password[plen] = 0;
break;
case g1m_mcstype_variable:
/* TODO: id */
head->count = 1;
if (hd.used)
head->flags |= g1m_mcsflag_unfinished;
break;
}
/* TODO */
@ -61,15 +111,23 @@ int g1m_decode_caspro_head(g1m_mcshead_t *head, g1m_buffer_t *buffer)
* g1m_decode_caspro_part:
* Decode a CASIOLINK Protocol content part.
*
* @arg file the file to make
* (or double pointer to the one to contribute to).
* @arg head the head to fill.
* @arg file the file to contribute to.
* @arg buffer the buffer to read from.
* @return if there was an error, or not.
*/
int g1m_decode_caspro_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer)
{
/* TODO */
return (g1m_error_unknown);
/* checks */
if (!file) return (g1m_error_op);
/* look for the decoding function */
caspro_decode_function decode = lookup_caspro_decode(file->head.type);
if (!decode) {
log_error("No dedicated decoding function was found for this type!");
return (g1m_error_unknown);
}
/* decode the part */
return ((*decode)(file, buffer));
}

View File

@ -53,3 +53,42 @@ int g1m_decode_mcs_var(g1m_mcsfile_t **handle, g1m_buffer_t *buffer,
/* no problem, woop woop */
return (0);
}
/**
* g1m_decode_caspro_var:
* Decode variable.
*
* @arg handle the handle to contribute to.
* @arg buffer the buffer to read from.
* @return the error code (0 if ok).
*/
int g1m_decode_caspro_var(g1m_mcsfile_t *handle, g1m_buffer_t *buffer)
{
/* read the magic and real part */
uint8_t magic[4]; READ(magic, 4)
DREAD(rawreal, cas_bcd)
uint8_t csum = g1m_checksum8(magic, 4)
+ g1m_checksum8(&rawreal, sizeof(cas_bcd_t));
/* read the imaginary part */
g1m_bcd_t real, imgn = {};
if (g1m_bcd_fromcas(&rawreal, &real)) {
DREAD(rawimgn, cas_bcd)
csum += g1m_checksum8(&rawimgn, sizeof(cas_bcd_t));
g1m_bcd_fromcas(&rawimgn, &imgn);
}
/* check the checksum */
uint8_t checksum; READ(&checksum, 1)
if (csum != checksum)
return (g1m_error_checksum);
if (memcmp(magic, "\0\1\0\1", 4))
return (g1m_error_magic);
/* set the values and return */
handle->var.real = real;
handle->var.imgn = imgn;
handle->head.flags &= ~g1m_mcsflag_unfinished;
return (0);
}

View File

@ -34,6 +34,7 @@ struct mcs_corresp {
};
/* All correspondances */
#define TTERM {0, NULL}
static struct mcs_corresp mcs_types[] = {
{g1m_mcstype_program, FUNC(program)},
{g1m_mcstype_list, FUNC(list)},
@ -45,7 +46,8 @@ static struct mcs_corresp mcs_types[] = {
{g1m_mcstype_string, FUNC(string)},
{g1m_mcstype_setup, FUNC(setup)},
{g1m_mcstype_alphamem, FUNC(var)},
{}
{g1m_mcstype_variable, FUNC(var)},
TTERM
};
/**
@ -56,7 +58,7 @@ static struct mcs_corresp mcs_types[] = {
* @return the function (NULL if not found).
*/
static mcs_decode_func_t lookup_mcsfile_decode(unsigned int type)
static mcs_decode_func_t lookup_mcsfile_decode(g1m_mcstype_t type)
{
/* lookup for the type */
struct mcs_corresp *c = mcs_types;
@ -135,10 +137,10 @@ int g1m_decode_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *head,
if (!head) return (g1m_error_op);
g1m_mcshead_t h = *head;
/* look for the parsing function */
/* look for the decoding function */
mcs_decode_func_t decode = lookup_mcsfile_decode(head->type);
if (!decode) {
log_error("No dedicated parsing function for this type was found!");
log_error("No dedicated decoding function for this type was found!");
goto notparsing;
}

View File

@ -58,7 +58,7 @@ int g1m_make_mcsfile(g1m_mcsfile_t **handle, const g1m_mcshead_t *rawhead)
h->cells[0] = malloc(sizeof(g1m_mcs_cell_t) * wd * ht);
if (!h->cells[0]) { free(h->cells); goto fail; }
for (int y = 1; y < ht; y++)
for (unsigned int y = 1; y < ht; y++)
h->cells[y] = &h->cells[0][h->head.width * y];
}
break;

View File

@ -41,7 +41,8 @@ struct type_corresp {
#define TTERM {NULL, NULL, 0}
static struct type_corresp cas_types[] = {
{"TXT", "PG", g1m_mcstype_program},
{"VAL", "MT", g1m_mcstype_variable},
{"VAL", "VM", g1m_mcstype_variable},
//{"VAL", "MT", g1m_mcstype_matrix},
/* terminating entry */
TTERM