Merge branch 'calli-3'

This commit is contained in:
David Anderson 2014-08-22 09:59:11 -07:00
commit 50f3ec8da2
3 changed files with 579 additions and 665 deletions

File diff suppressed because it is too large Load Diff

View File

@ -13,183 +13,161 @@ int mf_setpos(void *handle, size_t pos);
sp_writefuncs_t cstd_funcs = sp_writefuncs_t cstd_funcs =
{ {
mf_open, mf_open,
mf_close, mf_close,
mf_write, mf_write,
mf_read, mf_read,
mf_getpos, mf_getpos,
mf_setpos mf_setpos
}; };
sp_file_t *spfw_create(const char *name, sp_writefuncs_t *optfuncs) sp_file_t *spfw_create(const char *name, sp_writefuncs_t *optfuncs)
{ {
sp_file_t file; sp_file_t file;
sp_file_t *pFile; sp_file_t *pFile;
if (!optfuncs) if (!optfuncs)
{ optfuncs = &cstd_funcs;
optfuncs = &cstd_funcs;
}
file.handle = optfuncs->fnOpen(name); file.handle = optfuncs->fnOpen(name);
if (!file.handle) if (!file.handle)
{ return NULL;
return NULL;
}
pFile = (sp_file_t *)malloc(sizeof(sp_file_t)); pFile = (sp_file_t *)malloc(sizeof(sp_file_t));
pFile->handle = file.handle; pFile->handle = file.handle;
memcpy(&pFile->funcs, optfuncs, sizeof(sp_writefuncs_t)); memcpy(&pFile->funcs, optfuncs, sizeof(sp_writefuncs_t));
pFile->curoffs = 0; pFile->curoffs = 0;
pFile->header.magic = SPFILE_MAGIC; pFile->header.magic = SPFILE_MAGIC;
pFile->header.sections = 0; pFile->header.sections = 0;
pFile->header.stringtab = 0; pFile->header.stringtab = 0;
pFile->header.version = SPFILE_VERSION; pFile->header.version = SPFILE_VERSION;
pFile->header.imagesize = 0; pFile->header.imagesize = 0;
pFile->header.disksize = 0; pFile->header.disksize = 0;
pFile->header.compression = SPFILE_COMPRESSION_NONE; pFile->header.compression = SPFILE_COMPRESSION_NONE;
pFile->header.dataoffs = 0; pFile->header.dataoffs = 0;
pFile->lastsection = 0; pFile->lastsection = 0;
pFile->offsets = NULL; pFile->offsets = NULL;
pFile->sections = NULL; pFile->sections = NULL;
pFile->state = -1; pFile->state = -1;
pFile->nametab = NULL; pFile->nametab = NULL;
pFile->nametab_idx = 0; pFile->nametab_idx = 0;
return pFile; return pFile;
} }
void spfw_destroy(sp_file_t *spf) void spfw_destroy(sp_file_t *spf)
{ {
free(spf->sections); free(spf->sections);
free(spf->nametab); free(spf->nametab);
free(spf->offsets); free(spf->offsets);
spf->funcs.fnClose(spf->handle); spf->funcs.fnClose(spf->handle);
free(spf); free(spf);
} }
uint8_t spfw_add_section(sp_file_t *spf, const char *name) uint8_t spfw_add_section(sp_file_t *spf, const char *name)
{ {
size_t namelen; size_t namelen;
uint8_t s; uint8_t s;
if (spf->state != -1) if (spf->state != -1)
{ return 0;
return 0;
}
namelen = strlen(name) + 1; namelen = strlen(name) + 1;
if (spf->header.sections == 0) if (spf->header.sections == 0)
{ {
/** allocate for first section */ /** allocate for first section */
spf->sections = (sp_file_section_t *)malloc(sizeof(sp_file_section_t)); spf->sections = (sp_file_section_t *)malloc(sizeof(sp_file_section_t));
spf->offsets = (size_t *)malloc(sizeof(size_t)); spf->offsets = (size_t *)malloc(sizeof(size_t));
spf->nametab = (char *)malloc(namelen); spf->nametab = (char *)malloc(namelen);
} else { } else {
uint16_t num = spf->header.sections + 1; uint16_t num = spf->header.sections + 1;
spf->sections = (sp_file_section_t *)realloc(spf->sections, sizeof(sp_file_section_t) * num); spf->sections = (sp_file_section_t *)realloc(spf->sections, sizeof(sp_file_section_t) * num);
spf->offsets = (size_t *)realloc(spf->offsets, sizeof(size_t) * num); spf->offsets = (size_t *)realloc(spf->offsets, sizeof(size_t) * num);
spf->nametab = (char *)realloc(spf->nametab, spf->nametab_idx + namelen); spf->nametab = (char *)realloc(spf->nametab, spf->nametab_idx + namelen);
} }
s = spf->header.sections; s = spf->header.sections;
spf->sections[s].nameoffs = spf->nametab_idx; spf->sections[s].nameoffs = spf->nametab_idx;
/** /**
* "fix" offset will be the second uint2 slot, which is after the previous sections after the header. * "fix" offset will be the second uint2 slot, which is after the previous sections after the header.
*/ */
spf->offsets[s] = sizeof(spf->header) + (sizeof(sp_file_section_t) * spf->header.sections) + sizeof(uint32_t); spf->offsets[s] = sizeof(spf->header) + (sizeof(sp_file_section_t) * spf->header.sections) + sizeof(uint32_t);
strcpy(&spf->nametab[spf->nametab_idx], name); strcpy(&spf->nametab[spf->nametab_idx], name);
spf->nametab_idx += namelen; spf->nametab_idx += namelen;
return ++spf->header.sections; return ++spf->header.sections;
} }
int spfw_finalize_header(sp_file_t *spf) int spfw_finalize_header(sp_file_t *spf)
{ {
uint32_t size; uint32_t size;
if (spf->state != -1) if (spf->state != -1)
{ return -1;
return -1;
}
size = sizeof(sp_file_section_t) * spf->header.sections; size = sizeof(sp_file_section_t) * spf->header.sections;
spf->header.stringtab = sizeof(spf->header) + size; spf->header.stringtab = sizeof(spf->header) + size;
spf->header.dataoffs = spf->header.stringtab + spf->nametab_idx; spf->header.dataoffs = spf->header.stringtab + spf->nametab_idx;
if (spf->funcs.fnWrite(&spf->header, sizeof(spf->header), 1, spf->handle) != 1) if (spf->funcs.fnWrite(&spf->header, sizeof(spf->header), 1, spf->handle) != 1)
{ return -1;
return -1; if (spf->funcs.fnWrite(spf->sections, sizeof(sp_file_section_t), spf->header.sections, spf->handle) !=
} spf->header.sections)
if (spf->funcs.fnWrite(spf->sections, sizeof(sp_file_section_t), spf->header.sections, spf->handle) != return -1;
spf->header.sections) if (spf->funcs.fnWrite(spf->nametab, sizeof(char), spf->nametab_idx, spf->handle) != spf->nametab_idx)
{ return -1;
return -1; spf->curoffs = spf->funcs.fnGetPos(spf->handle);
} spf->lastsection = spf->curoffs;
if (spf->funcs.fnWrite(spf->nametab, sizeof(char), spf->nametab_idx, spf->handle) != spf->nametab_idx) spf->state++;
{
return -1;
}
spf->curoffs = spf->funcs.fnGetPos(spf->handle);
spf->lastsection = spf->curoffs;
spf->state++;
return 0; return 0;
} }
int spfw_next_section(sp_file_t *spf) int spfw_next_section(sp_file_t *spf)
{ {
uint8_t s; uint8_t s;
uint32_t rest[2]; uint32_t rest[2];
if (spf->state < 0 || spf->state > spf->header.sections) if (spf->state < 0 || spf->state > spf->header.sections)
{ return -1;
return -1;
}
if (spf->state == (int)spf->header.sections) if (spf->state == (int)spf->header.sections)
{ return 0;
return 0;
}
s = (uint8_t)spf->state; s = (uint8_t)spf->state;
spf->curoffs = spf->funcs.fnGetPos(spf->handle); spf->curoffs = spf->funcs.fnGetPos(spf->handle);
spf->funcs.fnSetPos(spf->handle, spf->offsets[s]); spf->funcs.fnSetPos(spf->handle, spf->offsets[s]);
rest[0] = spf->lastsection; rest[0] = spf->lastsection;
rest[1] = spf->curoffs - spf->lastsection; rest[1] = spf->curoffs - spf->lastsection;
if (spf->funcs.fnWrite(rest, sizeof(uint32_t), 2, spf->handle) != 2) if (spf->funcs.fnWrite(rest, sizeof(uint32_t), 2, spf->handle) != 2)
{ return -1;
return -1;
}
spf->funcs.fnSetPos(spf->handle, spf->curoffs); spf->funcs.fnSetPos(spf->handle, spf->curoffs);
spf->lastsection = spf->curoffs; spf->lastsection = spf->curoffs;
spf->state++; spf->state++;
return 1; return 1;
} }
int spfw_finalize_all(sp_file_t *spf) int spfw_finalize_all(sp_file_t *spf)
{ {
uint8_t offs; uint8_t offs;
if (spf->state < spf->header.sections) if (spf->state < spf->header.sections)
{ return -1;
return -1;
}
offs = offsetof(sp_file_hdr_t, imagesize); offs = offsetof(sp_file_hdr_t, imagesize);
spf->header.disksize = spf->funcs.fnGetPos(spf->handle); spf->header.disksize = spf->funcs.fnGetPos(spf->handle);
spf->header.imagesize = spf->funcs.fnGetPos(spf->handle); spf->header.imagesize = spf->funcs.fnGetPos(spf->handle);
spf->funcs.fnSetPos(spf->handle, offs); spf->funcs.fnSetPos(spf->handle, offs);
spf->funcs.fnWrite(&spf->header.imagesize, sizeof(uint32_t), 1, spf->handle); spf->funcs.fnWrite(&spf->header.imagesize, sizeof(uint32_t), 1, spf->handle);
spf->funcs.fnSetPos(spf->handle, spf->header.imagesize); spf->funcs.fnSetPos(spf->handle, spf->header.imagesize);
return 1; return 1;
} }
/** /**
@ -198,43 +176,39 @@ int spfw_finalize_all(sp_file_t *spf)
void *mf_open(const char *name) void *mf_open(const char *name)
{ {
return memfile_creat(name, 1024); return memfile_creat(name, 1024);
} }
void mf_close(void *handle) void mf_close(void *handle)
{ {
memfile_destroy((memfile_t *)handle); memfile_destroy((memfile_t *)handle);
} }
size_t mf_write(const void *buf, size_t size, size_t count, void *handle) size_t mf_write(const void *buf, size_t size, size_t count, void *handle)
{ {
if (!count) if (!count)
{ return 0;
return 0;
}
if (memfile_write((memfile_t *)handle, buf, size*count)) if (memfile_write((memfile_t *)handle, buf, size*count))
{ return count;
return count;
}
return 0; return 0;
} }
size_t mf_read(void *buf, size_t size, size_t count, void *handle) size_t mf_read(void *buf, size_t size, size_t count, void *handle)
{ {
return memfile_read((memfile_t *)handle, buf, size*count) / count; return memfile_read((memfile_t *)handle, buf, size*count) / count;
} }
size_t mf_getpos(void *handle) size_t mf_getpos(void *handle)
{ {
return (long)memfile_tell((memfile_t *)handle); return (long)memfile_tell((memfile_t *)handle);
} }
int mf_setpos(void *handle, size_t pos) int mf_setpos(void *handle, size_t pos)
{ {
memfile_seek((memfile_t *)handle, (long)pos); memfile_seek((memfile_t *)handle, (long)pos);
return 1; return 1;
} }
@ -246,31 +220,31 @@ int mf_setpos(void *handle, size_t pos)
void *fp_open(const char *name) void *fp_open(const char *name)
{ {
return fopen(name, "wb"); return fopen(name, "wb");
} }
void fp_close(void *handle) void fp_close(void *handle)
{ {
fclose((FILE *)handle); fclose((FILE *)handle);
} }
size_t fp_write(const void *buf, size_t size, size_t count, void *handle) size_t fp_write(const void *buf, size_t size, size_t count, void *handle)
{ {
return fwrite(buf, size, count, (FILE *)handle); return fwrite(buf, size, count, (FILE *)handle);
} }
size_t fp_read(void *buf, size_t size, size_t count, void *handle) size_t fp_read(void *buf, size_t size, size_t count, void *handle)
{ {
return fread(buf, size, count, (FILE *)handle); return fread(buf, size, count, (FILE *)handle);
} }
size_t fp_getpos(void *handle) size_t fp_getpos(void *handle)
{ {
return (size_t)ftell((FILE *)handle); return (size_t)ftell((FILE *)handle);
} }
int fp_setpos(void *handle, size_t pos) int fp_setpos(void *handle, size_t pos)
{ {
return fseek((FILE *)handle, (long)pos, SEEK_SET); return fseek((FILE *)handle, (long)pos, SEEK_SET);
} }
#endif #endif

View File

@ -8,30 +8,30 @@
*/ */
typedef struct sp_writefuncs_s typedef struct sp_writefuncs_s
{ {
void *(*fnOpen)(const char *); /* filename, returns handle */ void *(*fnOpen)(const char *); /* filename, returns handle */
void (*fnClose)(void *); /* handle */ void (*fnClose)(void *); /* handle */
/* buffer, size, count, handle, returns count written */ /* buffer, size, count, handle, returns count written */
size_t (*fnWrite)(const void *, size_t, size_t, void *); size_t (*fnWrite)(const void *, size_t, size_t, void *);
/* buffer, size, count, handle, returns count read */ /* buffer, size, count, handle, returns count read */
size_t (*fnRead)(void *, size_t, size_t, void *); size_t (*fnRead)(void *, size_t, size_t, void *);
/* returns current position from start */ /* returns current position from start */
size_t (*fnGetPos)(void *); size_t (*fnGetPos)(void *);
/* sets current position from start, return 0 for success, nonzero for error */ /* sets current position from start, return 0 for success, nonzero for error */
int (*fnSetPos)(void *, size_t); int (*fnSetPos)(void *, size_t);
} sp_writefuncs_t; } sp_writefuncs_t;
typedef struct sp_file_s typedef struct sp_file_s
{ {
sp_file_hdr_t header; sp_file_hdr_t header;
sp_file_section_t *sections; sp_file_section_t *sections;
size_t *offsets; size_t *offsets;
sp_writefuncs_t funcs; sp_writefuncs_t funcs;
size_t lastsection; size_t lastsection;
size_t curoffs; size_t curoffs;
void *handle; void *handle;
int state; int state;
char *nametab; char *nametab;
size_t nametab_idx; size_t nametab_idx;
} sp_file_t; } sp_file_t;
/** /**