cake
/
libg1m
Archived
1
0
Fork 0

Cleaned e-activities and MCS gestion, added support placeholders in MCS

This commit is contained in:
Thomas Touhey 2016-12-10 14:16:28 +01:00
parent afd4aeebfd
commit 6a0a54c71c
3 changed files with 296 additions and 45 deletions

View File

@ -44,6 +44,7 @@ struct mcs_subheader {
enum mcs_filetype {
mcs_ftype_alphamem = 0x00,
mcs_ftype_program = 0x1,
mcs_ftype_string = 0x4,
mcs_ftype_list = 0x5,
mcs_ftype_mat = 0x6,
mcs_ftype_picture = 0x7,
@ -93,17 +94,28 @@ struct mcs_programheader {
};
/* And, well, spreadsheets are more complicated than that.
* There is a header, a column directory and a column definition table.
*
* The header mainly contains the column count: */
* There are different types of spreadsheets: */
enum mcs_spreadsheet_type {
mcs_spstype_normal = 0x01
};
/* And for all of them, there is a header: */
struct mcs_spreadsheetheader {
/* magic number? */
uint8_t magic;
/* spreadsheet type */
uint8_t type;
/* column count (max: 26), on 24 bits and non-aligned */
uint32_t column_count : 24;
};
/* Then, if it is a normal spreadsheet, there is a subheader,
* a column directory and a column definition table.
*
* Here's the subheader: */
struct mcs_spreadsheet_subheader {
/* alignment or magic? {0, 0, 0, 0} */
uint8_t align[4];

View File

@ -9,23 +9,34 @@
/* ************************************************************************** */
#include <libg1m/internals.h>
/* prototype for content parsing */
static int g1m_parse_eact_cont(g1m_t *handle, uint8_t *buf, size_t bufsize,
int depth);
/* ************************************************************************** */
/* Line correspondance type and prototype */
/* ************************************************************************** */
/* Correspondance type */
struct eact_line_type_corresp {
int rawtype;
int (*parse)(g1m_t*, uint8_t*, size_t);
char *info;
};
/* Correspondances tab prototype */
static struct eact_line_type_corresp eact_line_types[];
/* ************************************************************************** */
/* Content parsing */
/* ************************************************************************** */
/**
* g1m_parse_eact_eact:
* eact_parse_content_eact:
* Parse an EACT in an EACT, from the subheader.
*
* @arg handle the handle.
* @arg buf the buffer.
* @arg bufsize the buffer size.
* @arg depth the current depth.
* @return the error code (0 if ok).
*/
static int g1m_parse_eact_eact(g1m_t *handle, uint8_t *buf, size_t bufsize,
int depth)
static int eact_parse_content_eact(g1m_t *handle, uint8_t *buf, size_t bufsize)
{
int err;
@ -46,7 +57,7 @@ static int g1m_parse_eact_eact(g1m_t *handle, uint8_t *buf, size_t bufsize,
struct line_descriptor *lds = (void*)&buf[sizeof(struct eact_eactheader)];
/* browse the lines */
log_info("[>%d] %d lines to browse", depth, ehd.line_count);
log_info("%d lines to browse", ehd.line_count);
if (ehd.line_count)
lds[0].entry_offset = be32toh(lds[0].entry_offset << 8);
for (uint_fast32_t i = 0; i < ehd.line_count; i++) {
@ -72,20 +83,21 @@ static int g1m_parse_eact_eact(g1m_t *handle, uint8_t *buf, size_t bufsize,
if (entry_offset + linesize > bufsize)
return (g1m_error_eof);
/* log data */
log_info("[>%d][%ld] Is '%s' (0x%02x)", depth, i + 1,
g1m_get_eact_ltype_string(entry_type), entry_type);
#if LOGLEVEL <= ll_info
if (entry_type != eact_ltype_content) {
log_info("[>%d][%ld] Buffer (0x%zxo) is:", depth, i + 1, linesize);
logm_info(&buf[entry_offset], linesize);
/* look for the line type */
struct eact_line_type_corresp *ltype = eact_line_types;
while (ltype->parse) {
if (ltype->rawtype == entry_type)
break;
ltype++;
}
if (!ltype->parse) {
log_error("[%ld] unknown line type: %02x", i + 1, entry_type);
continue;
}
#endif
/* go recursive */
if (entry_type == eact_ltype_content
&& (err = g1m_parse_eact_cont(handle, &buf[entry_offset], linesize,
depth + 1)))
/* act */
log_info("[%ld] is '%s' (0x%02x)", i + 1, ltype->info, entry_type);
if ((err = (*ltype->parse)(handle, &buf[entry_offset], linesize)))
return (err);
}
@ -93,46 +105,225 @@ static int g1m_parse_eact_eact(g1m_t *handle, uint8_t *buf, size_t bufsize,
return (0);
}
/* ************************************************************************** */
/* Content Type correspondance list */
/* ************************************************************************** */
/* Correspondance type */
struct eact_content_type_corresp {
char *type;
int (*parse)(g1m_t*, uint8_t*, size_t);
};
/* Correspondance list */
static struct eact_content_type_corresp eact_content_types[] = {
{"@EACT\0\0", eact_parse_content_eact},
{}
};
/* ************************************************************************** */
/* Line parsing */
/* ************************************************************************** */
/**
* g1m_parse_eact_cont:
* eact_parse_line_calculation:
* Parse a calculation.
*
* @arg handle the handle.
* @arg buf the buffer.
* @arg size the buffer size.
* @return the error code (0 if ok).
*/
static int eact_parse_line_calculation(g1m_t *handle, uint8_t *buf, size_t size)
{
(void)handle;
(void)buf;
(void)size;
/* TODO */
log_info("Calculation raw data is:");
logm_info(buf, size);
return (0);
}
/**
* eact_parse_line_result:
* Parse a calculation result.
*
* @arg handle the handle.
* @arg buf the buffer.
* @arg size the buffer size.
* @return the error code (0 if ok).
*/
static int eact_parse_line_result(g1m_t *handle, uint8_t *buf, size_t size)
{
(void)handle;
(void)buf;
(void)size;
/* TODO */
log_info("Calculation result raw data is:");
logm_info(buf, size);
return (0);
}
/**
* eact_parse_line_content:
* Parse an E-Activity content.
*
* @arg handle the handle.
* @arg buf the buffer.
* @arg bufsize the buffer length.
* @arg depth the current depth.
* @arg size the buffer size.
* @return the error code (0 if ok).
*/
static int g1m_parse_eact_cont(g1m_t *handle, uint8_t *buf, size_t bufsize,
int depth)
static int eact_parse_line_content(g1m_t *handle, uint8_t *buf, size_t size)
{
(void)depth;
/* read content header */
size_t could_read = min(bufsize, sizeof(struct eact_contentheader));
size_t could_read = min(size, sizeof(struct eact_contentheader));
if (could_read < 9) return (g1m_error_eof);
struct eact_contentheader hd = {};
memcpy(&hd, buf, could_read);
/* log info */
log_info("[>%d] Type is '%.8s'", depth, hd.type);
log_info("[>%d] Name is '%.16s'", depth, hd.name);
log_info("Type is '%.8s'", hd.type);
log_info("Name is '%.16s'", hd.name);
/* prepare for next */
if (bufsize == could_read)
if (size == could_read)
return (0);
buf += could_read;
bufsize -= could_read;
size -= could_read;
/* if type eact, parse eact */
if (!strcmp((char*)hd.type, "@EACT"))
return (g1m_parse_eact_eact(handle, buf, bufsize, depth));
/* check for content type */
struct eact_content_type_corresp *ctype = eact_content_types;
while (ctype->parse) {
if (!memcmp(hd.type, ctype->type, 8))
break ;
ctype++;
}
if (!ctype->parse) {
log_error("Unknown content type: '%.8s'", hd.type);
return (0);
}
/* then parse */
int err;
if ((err = (*ctype->parse)(handle, buf, size)))
return (err);
/* otherwise, no error. */
return (0);
}
/**
* eact_parse_line_stdheading:
* Parse standard heading line.
*
* @arg handle the handle.
* @arg buf the buffer.
* @arg size the buffer size.
* @return the error code (0 if ok).
*/
static int eact_parse_line_stdheading(g1m_t *handle, uint8_t *buf, size_t size)
{
(void)handle;
(void)buf;
(void)size;
/* TODO */
log_info("Standard heading raw data is:");
logm_info(buf, size);
return (0);
}
/**
* eact_parse_line_picture:
* Parse picture line.
*
* @arg handle the handle.
* @arg buf the buffer.
* @arg size the buffer size.
* @return the error code (0 if ok).
*/
static int eact_parse_line_picture(g1m_t *handle, uint8_t *buf, size_t size)
{
(void)handle;
(void)buf;
(void)size;
/* TODO */
log_info("Picture raw data is:");
logm_info(buf, size);
return (0);
}
/**
* eact_parse_line_text:
* Parse text line.
*
* @arg handle the handle.
* @arg buf the buffer.
* @arg size the buffer size.
* @return the error code (0 if ok).
*/
static int eact_parse_line_text(g1m_t *handle, uint8_t *buf, size_t size)
{
(void)handle;
(void)buf;
(void)size;
/* TODO */
log_info("Text raw data is:");
logm_info(buf, size);
return (0);
}
/**
* eact_parse_line_code:
* Parse code line.
*
* @arg handle the handle.
* @arg buf the buffer.
* @arg size the buffer size.
* @return the error code (0 if ok).
*/
static int eact_parse_line_code(g1m_t *handle, uint8_t *buf, size_t size)
{
(void)handle;
(void)buf;
(void)size;
/* TODO */
log_info("Code raw data is:");
logm_info(buf, size);
return (0);
}
/* ************************************************************************** */
/* Line Type correspondance list */
/* ************************************************************************** */
/* All correspondances */
static struct eact_line_type_corresp eact_line_types[] = {
{eact_ltype_calc, eact_parse_line_calculation,
"calculation"},
{eact_ltype_calc_result, eact_parse_line_result,
"calculation result"},
{eact_ltype_content, eact_parse_line_content,
"content"},
{eact_ltype_stdheading, eact_parse_line_stdheading,
"standard heading"},
{eact_ltype_picture, eact_parse_line_picture,
"picture"},
{eact_ltype_text, eact_parse_line_text,
"pure text"},
{eact_ltype_code, eact_parse_line_code,
"text mixed with functions"},
{}
};
/* ************************************************************************** */
/* Main parsing functions */
/* ************************************************************************** */
/**
* g1m_parse_eact:
* Parse an EACT.
@ -181,5 +372,5 @@ int g1m_parse_eact(g1m_t * handle, FILE *stream,
READ(&buf, bufsize)
/* parse content */
return (g1m_parse_eact_cont(handle, buf, bufsize, 0));
return (eact_parse_line_content(handle, buf, bufsize));
}

View File

@ -116,13 +116,36 @@ static int g1m_parse_mcs_spreadsheet(g1m_mcsfile_t *handle, FILE *stream,
{
/* read header */
DREAD(hd, mcs_spreadsheetheader)
log_info("First raw 4 bytes of the header: ");
logm_info(&hd, 4);
logm_info(&hd, sizeof(struct mcs_spreadsheetheader));
/* check if the spreadsheet type is known */
if (hd.type != mcs_spstype_normal) {
log_info("Spreadsheet type is unknown. (0x%02x)", hd.type);
size_t leftsize = length - sizeof(struct mcs_spreadsheetheader);
if (leftsize) {
#if LOGLEVEL <= ll_info
uint8_t tmp[leftsize];
READ(tmp, leftsize)
log_info("Raw content is:");
logm_info(&hd, sizeof(struct mcs_spreadsheetheader));
logm_info(tmp, leftsize);
#else
SKIP(lengthsize)
#endif
}
return (0);
}
/* read subheader */
DREAD(shd, mcs_spreadsheet_subheader)
/* correct endianess */
uint_fast32_t colcount = hd.column_count;
colcount = be32toh(colcount << 8);
hd.defs_size = be32toh(hd.defs_size);
shd.defs_size = be32toh(shd.defs_size);
/* log some info */
log_info("%ld columns to parse!", colcount);
@ -449,6 +472,28 @@ static int g1m_parse_mcs_picture(g1m_mcsfile_t *handle, FILE *stream,
return (0);
}
/**
* g1m_parse_mcs_string:
* Parse string.
*
* @arg handle the handle.
* @arg stream the stream to parse from.
* @arg length the data length.
* @return the error code (0 if ok).
*/
static int g1m_parse_mcs_string(g1m_mcsfile_t *handle, FILE *stream,
uint_fast32_t length)
{
(void)handle;
log_info("String MCS file is not managed yet. Content:");
uint8_t str[length];
READ(str, length);
logm_info(str, length);
/* TODO */
return (0);
}
/**
* g1m_parse_mcs_setup:
* Parse settings.
@ -492,7 +537,7 @@ static int g1m_parse_mcs_alphamem(g1m_mcsfile_t *handle, FILE *stream,
/* ************************************************************************** */
/* Type correspondance list */
/* ************************************************************************** */
/* Correspondance list */
/* Correspondance type */
struct mcs_type_corresp {
int rawtype;
@ -521,6 +566,9 @@ static struct mcs_type_corresp mcs_types[] = {
{mcs_ftype_capture, g1m_mcstype_capt,
&g1m_parse_mcs_capture,
"capture"},
{mcs_ftype_string, 0x00, /* TODO */
&g1m_parse_mcs_string,
"string"},
{mcs_ftype_setup, 0x00, /* TODO */
&g1m_parse_mcs_setup,
"setup"},