sourcepawn/compiler/sp_file.c
author David Anderson <danderson@mozilla.com>
Thu Aug 08 09:40:23 2013 -0700 (2013-08-08)
changeset 3976 bc77cfde7c5c
parent 2471 194be299b700
permissions -rw-r--r--
Add -Wno-narrowing to support building on GCC-4.7 (no bug, r=me).
     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <stdlib.h>
     4 #include "sp_file.h"
     5 #include "memfile.h"
     6 
     7 void *mf_open(const char *name);
     8 void mf_close(void *handle);
     9 size_t mf_write(const void *buf, size_t size, size_t count, void *handle);
    10 size_t mf_read(void *buf, size_t size, size_t count, void *handle);
    11 size_t mf_getpos(void *handle);
    12 int mf_setpos(void *handle, size_t pos);
    13 
    14 sp_writefuncs_t cstd_funcs = 
    15 {
    16 	mf_open,
    17 	mf_close,
    18 	mf_write,
    19 	mf_read,
    20 	mf_getpos,
    21 	mf_setpos
    22 };
    23 
    24 sp_file_t *spfw_create(const char *name, sp_writefuncs_t *optfuncs)
    25 {
    26 	sp_file_t file;
    27 	sp_file_t *pFile;
    28 
    29 	if (!optfuncs)
    30 	{
    31 		optfuncs = &cstd_funcs;
    32 	}
    33 
    34 	file.handle = optfuncs->fnOpen(name);
    35 	if (!file.handle)
    36 	{
    37 		return NULL;
    38 	}
    39 
    40 	pFile = (sp_file_t *)malloc(sizeof(sp_file_t));
    41 
    42 	pFile->handle = file.handle;
    43 	memcpy(&pFile->funcs, optfuncs, sizeof(sp_writefuncs_t));
    44 	pFile->curoffs = 0;
    45 	pFile->header.magic = SPFILE_MAGIC;
    46 	pFile->header.sections = 0;
    47 	pFile->header.stringtab = 0;
    48 	pFile->header.version = SPFILE_VERSION;
    49 	pFile->header.imagesize = 0;
    50 	pFile->header.disksize = 0;
    51 	pFile->header.compression = SPFILE_COMPRESSION_NONE;
    52 	pFile->header.dataoffs = 0;
    53 	pFile->lastsection = 0;
    54 	pFile->offsets = NULL;
    55 	pFile->sections = NULL;
    56 	pFile->state = -1;
    57 	pFile->nametab = NULL;
    58 	pFile->nametab_idx = 0;
    59 
    60 	return pFile;
    61 }
    62 
    63 void spfw_destroy(sp_file_t *spf)
    64 {
    65 	free(spf->sections);
    66 	free(spf->nametab);
    67 	free(spf->offsets);
    68 	spf->funcs.fnClose(spf->handle);
    69 	free(spf);
    70 }
    71 
    72 uint8_t spfw_add_section(sp_file_t *spf, const char *name)
    73 {
    74 	size_t namelen;
    75 	uint8_t s;
    76 	if (spf->state != -1)
    77 	{
    78 		return 0;
    79 	}
    80 
    81 	namelen = strlen(name) + 1;
    82 
    83 	if (spf->header.sections == 0)
    84 	{
    85 		/** allocate for first section */
    86 		spf->sections = (sp_file_section_t *)malloc(sizeof(sp_file_section_t));
    87 		spf->offsets = (size_t *)malloc(sizeof(size_t));
    88 		spf->nametab = (char *)malloc(namelen);
    89 	} else {
    90 		uint16_t num = spf->header.sections + 1;
    91 		spf->sections = (sp_file_section_t *)realloc(spf->sections, sizeof(sp_file_section_t) * num);
    92 		spf->offsets = (size_t *)realloc(spf->offsets, sizeof(size_t) * num);
    93 		spf->nametab = (char *)realloc(spf->nametab, spf->nametab_idx + namelen);
    94 	}
    95 
    96 	s = spf->header.sections;
    97 
    98 	spf->sections[s].nameoffs = spf->nametab_idx;
    99 	/** 
   100 	 * "fix" offset will be the second uint2 slot, which is after the previous sections after the header.
   101 	 */
   102 	spf->offsets[s] = sizeof(spf->header) + (sizeof(sp_file_section_t) * spf->header.sections) + sizeof(uint32_t);
   103 	strcpy(&spf->nametab[spf->nametab_idx], name);
   104 	spf->nametab_idx += namelen;
   105 
   106 	return ++spf->header.sections;
   107 }
   108 
   109 int spfw_finalize_header(sp_file_t *spf)
   110 {
   111 	uint32_t size;
   112 	if (spf->state != -1)
   113 	{
   114 		return -1;
   115 	}
   116 
   117 	size = sizeof(sp_file_section_t) * spf->header.sections;
   118 
   119 	spf->header.stringtab = sizeof(spf->header) + size;
   120 	spf->header.dataoffs = spf->header.stringtab + spf->nametab_idx;
   121 	if (spf->funcs.fnWrite(&spf->header, sizeof(spf->header), 1, spf->handle) != 1)
   122 	{
   123 		return -1;
   124 	}
   125 	if (spf->funcs.fnWrite(spf->sections, sizeof(sp_file_section_t), spf->header.sections, spf->handle) != 
   126 		spf->header.sections)
   127 	{
   128 		return -1;
   129 	}
   130 	if (spf->funcs.fnWrite(spf->nametab, sizeof(char), spf->nametab_idx, spf->handle) != spf->nametab_idx)
   131 	{
   132 		return -1;
   133 	}
   134 	spf->curoffs = spf->funcs.fnGetPos(spf->handle);
   135 	spf->lastsection = spf->curoffs;
   136 	spf->state++;
   137 
   138 	return 0;
   139 }
   140 
   141 int spfw_next_section(sp_file_t *spf)
   142 {
   143 	uint8_t s;
   144 	uint32_t rest[2];
   145 
   146 	if (spf->state < 0 || spf->state > spf->header.sections)
   147 	{
   148 		return -1;
   149 	}
   150 
   151 	if (spf->state == (int)spf->header.sections)
   152 	{
   153 		return 0;
   154 	}
   155 
   156 	s = (uint8_t)spf->state;
   157 
   158 	spf->curoffs = spf->funcs.fnGetPos(spf->handle);
   159 	spf->funcs.fnSetPos(spf->handle, spf->offsets[s]);
   160 	
   161 	rest[0] = spf->lastsection;
   162 	rest[1] = spf->curoffs - spf->lastsection;
   163 	if (spf->funcs.fnWrite(rest, sizeof(uint32_t), 2, spf->handle) != 2)
   164 	{
   165 		return -1;
   166 	}
   167 
   168 	spf->funcs.fnSetPos(spf->handle, spf->curoffs);
   169 	spf->lastsection = spf->curoffs;
   170 
   171 	spf->state++;
   172 
   173 	return 1;
   174 }
   175 
   176 int spfw_finalize_all(sp_file_t *spf)
   177 {
   178 	uint8_t offs;
   179 
   180 	if (spf->state < spf->header.sections)
   181 	{
   182 		return -1;
   183 	}
   184 
   185 	offs = offsetof(sp_file_hdr_t, imagesize);
   186 	spf->header.disksize = spf->funcs.fnGetPos(spf->handle);
   187 	spf->header.imagesize = spf->funcs.fnGetPos(spf->handle);
   188 	spf->funcs.fnSetPos(spf->handle, offs);
   189 	spf->funcs.fnWrite(&spf->header.imagesize, sizeof(uint32_t), 1, spf->handle);
   190 	spf->funcs.fnSetPos(spf->handle, spf->header.imagesize);
   191 
   192 	return 1;
   193 }
   194 
   195 /**
   196  * More memory file operations
   197  */
   198 
   199 void *mf_open(const char *name)
   200 {
   201 	return memfile_creat(name, 1024);
   202 }
   203 
   204 void mf_close(void *handle)
   205 {
   206 	memfile_destroy((memfile_t *)handle);
   207 }
   208 
   209 size_t mf_write(const void *buf, size_t size, size_t count, void *handle)
   210 {
   211 	if (!count)
   212 	{
   213 		return 0;
   214 	}
   215 
   216 	if (memfile_write((memfile_t *)handle, buf, size*count))
   217 	{
   218 		return count;
   219 	}
   220 
   221 	return 0;
   222 }
   223 
   224 size_t mf_read(void *buf, size_t size, size_t count, void *handle)
   225 {
   226 	return memfile_read((memfile_t *)handle, buf, size*count) / count;
   227 }
   228 
   229 size_t mf_getpos(void *handle)
   230 {
   231 	return (long)memfile_tell((memfile_t *)handle);
   232 }
   233 
   234 int mf_setpos(void *handle, size_t pos)
   235 {
   236 	memfile_seek((memfile_t *)handle, (long)pos);
   237 	return 1;
   238 }
   239 
   240 
   241 #if UNUSED_FOR_NOW
   242 /**
   243  * Default file operations...
   244  * Based on C standard library calls.
   245  */
   246 
   247 void *fp_open(const char *name)
   248 {
   249 	return fopen(name, "wb");
   250 }
   251 
   252 void fp_close(void *handle)
   253 {
   254 	fclose((FILE *)handle);
   255 }
   256 
   257 size_t fp_write(const void *buf, size_t size, size_t count, void *handle)
   258 {
   259 	return fwrite(buf, size, count, (FILE *)handle);
   260 }
   261 
   262 size_t fp_read(void *buf, size_t size, size_t count, void *handle)
   263 {
   264 	return fread(buf, size, count, (FILE *)handle);
   265 }
   266 
   267 size_t fp_getpos(void *handle)
   268 {
   269 	return (size_t)ftell((FILE *)handle);
   270 }
   271 
   272 int fp_setpos(void *handle, size_t pos)
   273 {
   274 	return fseek((FILE *)handle, (long)pos, SEEK_SET);
   275 }
   276 #endif