cake
/
libg1m
Archived
1
0
Fork 0

Corrected some things, able to re-decode MCS files now.

This commit is contained in:
Thomas Touhey 2017-02-26 13:04:01 +01:00
parent e558ab19d4
commit 81822777de
12 changed files with 67 additions and 76 deletions

View File

@ -35,7 +35,7 @@ int g1m_get_type_info(const char *path,
unsigned int *platform, unsigned int *type);
/* get mcs type data */
int g1m_mcstype_getlib(const char *groupname, const char *filename,
int g1m_mcstype_get(const char *groupname, const char *filename,
unsigned int rawtype, unsigned int *type, int *id);
int g1m_mcstype_toraw(unsigned int type, int id,
char *name, char *dirname, char *groupname);

View File

@ -56,11 +56,10 @@
/* read with EOF check */
#define READ(TO, SZ) { \
int READ_err = (*buffer->read)(buffer->cookie, (void*)(TO), (SZ)); \
if (READ_err) return (READ_err); \
}
#define GREAD(TO, SZ) \
if (READ_err) return (READ_err); }
#define GREAD(TO, SZ) { \
if ((err = (*buffer->read)(buffer->cookie, (void*)(TO), (SZ)))) \
goto fail;
goto fail; }
/* read with EOF check, declare var before */
#define DREAD(NAM, STRUCT) \
struct STRUCT NAM; \

View File

@ -40,6 +40,7 @@ typedef unsigned int g1m_mcstype_t;
# define g1m_mcstype_setup 0x0080
# define g1m_mcstype_alphamem 0x0100
# define g1m_mcstype_vct 0x0200
# define g1m_mcstype_variable 0x0400
/* MCS file type aliases */
# define g1m_mcstype_picture g1m_mcstype_pict

View File

@ -1,5 +1,5 @@
/* *****************************************************************************
* user/free.c -- free elements of a handle.
* core/free.c -- free elements of a handle.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libg1m.

View File

@ -1,25 +0,0 @@
/* *****************************************************************************
* decode/ctf.c -- decode the calculator text format
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libg1m.
* libg1m is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 3.0 of the License,
* or (at your option) any later version.
*
* libg1m is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libg1m; if not, see <http://www.gnu.org/licenses/>.
*
* This format is a community-made, open and documented format. The
* description of it is on CASPRO's website:
* http://www.spiderpixel.co.uk/caspro/ctfindex.html
* ************************************************************************** */
#include <libg1m/internals.h>
/* TODO */

View File

@ -148,6 +148,11 @@ static int find_decode_function(g1m_t *handle, const char *path,
static int decode_std(g1m_t *handle, const char *path, g1m_buffer_t *buffer,
struct standard_header *std, g1m_type_t expected_types)
{
/* reverse the standard header */
uint8_t *u = (uint8_t*)std;
for (size_t i = 0; i < sizeof(struct standard_header); i++)
u[i] = ~u[i];
/* print header */
log_info("Raw inverted standard header is:");
logm_info(std, sizeof(struct standard_header));
@ -201,11 +206,9 @@ int g1m_decode(g1m_t *handle, const char *path, g1m_buffer_t *buffer,
if (buf[0] == ':')
return (g1m_decode_cas(handle, buffer, expected_types));
/* identify a standard header */
READ(&buffer[1], 0x1F)
struct standard_header std;
uint8_t *u = (uint8_t*)&std;
for (size_t i = 0; i < sizeof(struct standard_header); i++)
u[i] = ~buf[i];
return (decode_std(handle, path, buffer, &std, expected_types));
/* identify a standard header (send a _copy_) */
READ(&buf[1], 0x1F)
uint8_t altbuf[0x20]; memcpy(altbuf, buf, 0x20);
return (decode_std(handle, path, buffer, (struct standard_header*)altbuf,
expected_types));
}

View File

@ -668,7 +668,7 @@ int g1m_decode_mcsfile_head(g1m_mcshead_t *head,
if (!head) return (-1);
/* look for the raw type */
if (g1m_mcstype_getlib((char*)groupname, (char*)filename, raw_type,
if (g1m_mcstype_get((char*)groupname, (char*)filename, raw_type,
&head->type, &head->id))
head->type = g1m_mcstype_unknown;
log_info("libg1m file type is 0x%04X", head->type);
@ -805,7 +805,7 @@ int g1m_decode_mcs(g1m_t *handle, g1m_buffer_t *buffer,
/* get number of subparts from the standard header */
uint_fast16_t num = std->number;
/* allocate memory for the files */
/* allocate memory for the files index */
handle->count = 0;
handle->_size = num;
if (num) {
@ -850,7 +850,7 @@ int g1m_decode_mcs(g1m_t *handle, g1m_buffer_t *buffer,
handle->files[handle->count] = NULL;
err = g1m_decode_mcsfile(&handle->files[handle->count],
&head, buffer);
if (err) return (err);
if (err) goto fail;
handle->count++;
}
}

View File

@ -1,5 +1,5 @@
/* *****************************************************************************
* user/make.c -- create a handle.
* manage/create.c -- create a handle.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libg1m.

View File

@ -1,5 +1,5 @@
/* *****************************************************************************
* user/mcs.c -- manage an MCS archive.
* manage/mcs.c -- manage an MCS archive handle.
* Copyright (C) 2017 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
*
* This file is part of libg1m.

View File

@ -32,11 +32,17 @@
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);
size_t orig = size;
while (size) {
size_t read = fread(buf, 1, size, file);
size -= read;
if (!read || read == (size_t)-1) {
log_error("READING failed: read %" PRIuSIZE "/%" PRIuSIZE
" bytes, %" PRIuSIZE " missing.", orig - size, orig, size);
return (g1m_error_eof);
}
}
/* no error */

View File

@ -74,8 +74,10 @@ static struct group_corresp mcs_groups[] = {
TTERM
}},
{"ALPHA MEM", noarg, (struct type_corresp[]){
{0x00, NULL /* "ALPHA MEM" */, 0, "$GLOBAL",
{0x00, "ALPHA MEM", 0, "$GLOBAL",
"alpha memory", g1m_mcstype_alphamem},
{0x00, "", arg | arg_is_let, "$GLOBAL",
"alpha memory", g1m_mcstype_variable},
TTERM
}},
{"STRING ", arg | arg_is_num, (struct type_corresp[]){
@ -204,7 +206,11 @@ static struct group_corresp mcs_groups[] = {
static int get_number(const char *s, int *num, int isnum)
{
if (!strcmp(s, "Ans"))
*num = 27;
*num = g1m_ans;
else if (!strcmp(s, "\xCE"))
*num = g1m_theta;
else if (!strcmp(s, "\xCD"))
*num = g1m_r;
else if (isnum) {
if (!(*num = atoi(s))) return (1);
} else {
@ -217,7 +223,7 @@ static int get_number(const char *s, int *num, int isnum)
/**
* g1m_mcstype_getlib:
* g1m_mcstype_get:
* Get libg1m type from rawtype.
*
* @arg gname the MCS group name.
@ -228,12 +234,12 @@ static int get_number(const char *s, int *num, int isnum)
* @return if the type was not found (0 if yes).
*/
int g1m_mcstype_getlib(const char *gname, const char *fname,
int g1m_mcstype_get(const char *gname, const char *fname,
unsigned int rawtype, unsigned int *type, int *id)
{
/* log what we're looking for */
log_info("Looking for type with '%s' group, '%s' name and 0x%02x raw type",
gname, fname, rawtype);
log_info("Looking for type with '%.8s' group, '%.8s' name and "
"0x%02X raw type", gname, fname, rawtype);
/* look for group correspondance */
int gid = 0;
@ -327,19 +333,23 @@ int g1m_mcstype_toraw(unsigned int type, int id,
found:
/* put the group name */
strcpy(groupname, g->name);
if (g->flags & arg) {
int grid = g1m_get_id_major(id);
if ((t->flags & arg) && ~t->flags & weight_by_gid)
grid = g1m_get_id_minor(id);
if (grid == 27)
if (grid == g1m_ans)
sprintf(groupname, "%sAns", g->name);
else if (grid == g1m_theta)
sprintf(groupname, "%s\xCE", g->name);
else if (grid == g1m_r)
sprintf(groupname, "%s\xCD", g->name);
else if (g->flags & arg_is_num)
sprintf(groupname, "%s%d", g->name, grid);
else
sprintf(groupname, "%s%c", g->name, grid + 'A' - 1);
} else
strcpy(groupname, g->name);
}
/* put the directory name */
strcpy(dirname, t->dirname);
@ -348,8 +358,12 @@ found:
if (t->flags & arg) {
int namid = g1m_get_id_minor(id);
if (namid == 27)
if (namid == g1m_ans)
sprintf(name, "%sAns", t->name);
else if (namid == g1m_theta)
sprintf(name, "%s\xCE", t->name);
else if (namid == g1m_r)
sprintf(name, "%s\xCD", t->name);
else if (t->flags & arg_is_num)
sprintf(name, "%s%d", t->name, namid);
else

View File

@ -22,9 +22,6 @@
* g1m_skip:
* Skip some bytes.
*
* I've made two loops to avoid conditions in each loop iteration
* when checksum is not calculated. Yeah, I know. #YOLO.
*
* @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.
@ -33,24 +30,20 @@
int g1m_skip(g1m_buffer_t *buffer, size_t size, uint_fast32_t *checksum)
{
uint8_t buf[1024]; int err;
size_t rd = 0; uint_fast32_t add = 0;
while (1) {
/* if no size left, exit */
if (!size) break;
uint_fast32_t add = 0;
size_t orig = size;
while (size) {
/* 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);
}
rd += curlen;
/* feed the checksum */
add = g1m_checksum32(buf, curlen, add);
size_t curlen = min(size, 1024);
size -= curlen;
if ((err = (*buffer->read)(buffer->cookie, buf, curlen))) {
log_error("Skipping has failed after %zu bytes", size);
return (err);
}
/* feed the checksum */
add = g1m_checksum32(buf, curlen, add);
}
/* add to checksum */