diff --git a/include/libg1m.h b/include/libg1m.h index 4cc310b..63e60fd 100644 --- a/include/libg1m.h +++ b/include/libg1m.h @@ -129,13 +129,9 @@ extern int g1m_decode_casfile_part(g1m_mcsfile_t *file, g1m_buffer_t *buffer); /* ************************************************************************** */ /* MCS archive management */ /* ************************************************************************** */ -/* add MCS files */ -extern int g1m_putmcs_program(g1m_t *handle, g1m_mcsfile_t **pfile, - char *name, char *password, char *content); -extern int g1m_putmcs_capture(g1m_t *handle, g1m_mcsfile_t **pfile, - int id, int width, int height, uint32_t **pixels); -extern int g1m_putmcs_picture(g1m_t *handle, g1m_mcsfile_t **pfile, - int id, uint32_t **pixels_one, uint32_t **pixels_two); +/* create and insert an MCS file into a MCS archive */ +extern int g1m_mcs_insert(g1m_t *handle, const g1m_mcshead_t *head, + g1m_mcsfile_t **tofile); # ifdef __cplusplus } diff --git a/src/decode/cas.c b/src/decode/cas.c index 5722e96..5ecb8bc 100644 --- a/src/decode/cas.c +++ b/src/decode/cas.c @@ -275,37 +275,13 @@ int g1m_decode_cas(g1m_t *handle, g1m_buffer_t *buffer) err = g1m_decode_casfiles_part(&head, heads, buffer); if (err) goto fail; } - } else - heads[0] = head; - - /* prepare space in the index */ - int required_size = handle->count - + (head.flags & g1m_mcsflag_multiple) ? head.count : 1; - if (required_size > handle->_size) { - int newsize = required_size + 2; - log_info("index not big enough, allocating from %d to %d slots", - handle->_size, newsize); - - /* allocate new index */ - err = g1m_error_alloc; - g1m_mcsfile_t **index = calloc(sizeof(g1m_mcsfile_t*), newsize); - if (!index) goto fail; - - /* copy old data */ - memcpy(index, handle->files, - sizeof(g1m_mcsfile_t*) * handle->_size); - memset(&index[handle->_size], 0, - sizeof(g1m_mcsfile_t*) * (newsize - handle->_size)); - handle->files = index; - handle->_size = newsize; - } + } else heads[0] = head; for (int i = 0; i < numheads; i++) { /* prepare the file */ log_info("Preparing the group file #%d", i); - err = g1m_make_mcsfile(&handle->files[handle->count], &heads[i]); + g1m_mcsfile_t *file; err = g1m_mcs_insert(handle, &heads[i], &file); if (err) goto fail; - g1m_mcsfile_t *file = handle->files[handle->count]; handle->count++; /* read each part */ #if LOGLEVEL <= ll_info diff --git a/src/manage/mcs.c b/src/manage/mcs.c index 6aa44c4..0456570 100644 --- a/src/manage/mcs.c +++ b/src/manage/mcs.c @@ -20,20 +20,22 @@ #define MCS_CHUNK_SIZE 16 /* ************************************************************************** */ -/* Internal functions */ +/* General function for inserting files */ /* ************************************************************************** */ /** - * find_space_for_file: - * Find space for some element function. + * g1m_mcs_insert: + * Find space for a file and allocate. * * @arg handle the handle. * @arg head the head. + * @arg tofile the file pointer for the user. * @return the mcs file (NULL if allocation error). */ -static g1m_mcsfile_t *find_space_for_file(g1m_t *handle, g1m_mcshead_t *head) +int g1m_mcs_insert(g1m_t *handle, const g1m_mcshead_t *head, + g1m_mcsfile_t **tofile) { - g1m_mcsfile_t **pfile = NULL; + g1m_mcsfile_t **pfile = NULL; *tofile = NULL; /* look if this file isn't already in the tab */ int istyp = g1m_mcshead_uses_id(head); @@ -44,21 +46,57 @@ static g1m_mcsfile_t *find_space_for_file(g1m_t *handle, g1m_mcshead_t *head) continue; } - if ((file->head.type == head->type) && (istyp ? - file->head.id == head->id : !strcmp(file->head.name, head->name))) { - g1m_free_mcsfile(file); - pfile = &handle->files[i]; - goto found; + /* loop assertions */ + if (file->head.type != head->type) + continue; + if (head->type) { + if (istyp) { + if (head->id != file->head.id) + continue; + } else if (strcmp(file->head.name, head->name)) + continue; + } else switch (g1m_mcsinfo(head)) { + case g1m_mcsinfo_mcs: + if (strncmp((char*)head->_group, (char*)file->head._group, 16)) + continue; + if (strncmp((char*)head->_dirname, (char*)file->head._dirname, 8)) + continue; + if (strncmp((char*)head->name, (char*)file->head.name, 8)) + continue; + break; + case g1m_mcsinfo_cas: + case g1m_mcsinfo_caspro: + if (strncmp((char*)head->_datatype, + (char*)file->head._datatype, 2)) + continue; + break; + default: continue; } + + /* slot was found! */ + g1m_free_mcsfile(file); + pfile = &handle->files[i]; + goto found; } /* if no empty space was found, take one at the end (allocate if needed) */ if (!pfile) { if (handle->count >= handle->_size) { - handle->_size = handle->count + MCS_CHUNK_SIZE; - handle->files = realloc(handle->files, - handle->_size * sizeof(g1m_mcsfile_t**)); - if (!handle->files) return (NULL); + /* allocate new index */ + int newsize = handle->count + MCS_CHUNK_SIZE; + g1m_mcsfile_t **newindex = malloc(newsize * sizeof(g1m_mcsfile_t*)); + if (!newindex) return (g1m_error_alloc); + + /* copy the data from the old index */ + memcpy(newindex, handle->files, + handle->_size * sizeof(g1m_mcsfile_t*)); + memset(&newindex[handle->_size], 0, + (newsize - handle->_size) * sizeof(g1m_mcsfile_t*)); + + /* free old, assign new */ + free(handle->files); + handle->files = newindex; + handle->_size = newsize; } pfile = &handle->files[handle->count++]; } @@ -66,132 +104,9 @@ static g1m_mcsfile_t *find_space_for_file(g1m_t *handle, g1m_mcshead_t *head) found:; /* make the file */ int err = g1m_make_mcsfile(pfile, head); - if (err) return (NULL); + if (err) return (err); /* return it */ - return (*pfile); -} - -/* ************************************************************************** */ -/* Create files in archive */ -/* ************************************************************************** */ -/** - * g1m_putmcs_program: - * Put a program in a MCS handle. - * - * @arg handle the handle. - * @arg pfile pointer to the file pointer to set. - * @arg name the name of the program. - * @arg password the password (NULL if none). - * @return the error code (0 if ok). - */ - -int g1m_putmcs_program(g1m_t *handle, g1m_mcsfile_t **pfile, - char *name, char *password, char *content) -{ - /* check if the operation is supported */ - if (~handle->type & g1m_type_mcs) return (g1m_error_op); - - /* find the file */ - g1m_mcshead_t head = { - .type = g1m_mcstype_program, - .size = strlen(content) - }; - strncpy(head.name, name, 8); head.name[8] = 0; - if (password) strncpy(head.password, password, 8); - else head.password[0] = 0; - g1m_mcsfile_t *file = find_space_for_file(handle, &head); - if (!file) return (g1m_error_alloc); - - /* set content */ - memcpy(file->content, content, file->head.size); - - /* no error */ - if (pfile) *pfile = file; - return (0); -} - -/** - * g1m_putmcs_capture: - * Put a capture in an MCS handle. - * - * @arg handle the handle. - * @arg pfile the file pointer to get file. - * @arg id the capture ID (1 to 20). - * @arg width the capture width. - * @arg height the capture height. - * @arg pic the pixels to copy. - * @return the error code (0 if ok). - */ - -int g1m_putmcs_capture(g1m_t *handle, g1m_mcsfile_t **pfile, - int id, int width, int height, uint32_t **pic) -{ - /* check if the operation is supported */ - if (~handle->type & g1m_type_mcs || id < 1 || id > 20) - return (g1m_error_op); - - /* find the file */ - g1m_mcshead_t head = { - .type = g1m_mcstype_capture, .id = id, - .width = width, .height = height - }; - g1m_mcsfile_t *file = find_space_for_file(handle, &head); - if (!file) return (g1m_error_alloc); - - /* copy pixels */ - uint32_t *pix = &file->pic[0][0]; - for (int y = 0; y < height; y++) { - uint32_t *line = *pic++; - for (int x = 0; x < width; x++) - *pix++ = *line++; - } - - /* no error */ - if (pfile) *pfile = file; - return (0); -} - -/** - * g1m_putmcs_picture: - * Put a picture in an MCS handle. - * - * @arg handle the handle. - * @arg pfile the file pointer to get. - * @arg id the picture ID (1 to 20). - * @arg pic_one pixels of the first 128x64 image to copy. - * @arg pic_two pixels of the second 128x64 image to copy. - * @return the error code (0 if ok). - */ - -int g1m_putmcs_picture(g1m_t *handle, g1m_mcsfile_t **pfile, - int id, uint32_t **pic_one, uint32_t **pic_two) -{ - /* check if the operation is supported */ - if (~handle->type & g1m_type_mcs || id < 1 || id > 20) - return (g1m_error_op); - - /* find the file */ - g1m_mcshead_t head = { - .type = g1m_mcstype_picture, .id = id, - .width = 128, .height = 64 - }; - g1m_mcsfile_t *file = find_space_for_file(handle, &head); - if (!file) return (g1m_error_alloc); - - /* copy pixels */ - uint32_t *one = &file->pics[0][0][0]; - uint32_t *two = &file->pics[1][0][0]; - for (int y = 0; y < 64; y++) { - uint32_t *line_one = *pic_one++; - uint32_t *line_two = *pic_two++; - for (int x = 0; x < 128; x++) { - *one++ = *line_one++; - *two++ = *line_two++; - } - } - - /* no error */ - if (pfile) *pfile = file; + *tofile = *pfile; return (0); }