1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/sourcepawn/compiler/sp_file.c Sun Mar 30 07:00:22 2008 +0000
1.3 @@ -0,0 +1,276 @@
1.4 +#include <stdio.h>
1.5 +#include <string.h>
1.6 +#include <malloc.h>
1.7 +#include "sp_file.h"
1.8 +#include "memfile.h"
1.9 +
1.10 +void *mf_open(const char *name);
1.11 +void mf_close(void *handle);
1.12 +size_t mf_write(const void *buf, size_t size, size_t count, void *handle);
1.13 +size_t mf_read(void *buf, size_t size, size_t count, void *handle);
1.14 +size_t mf_getpos(void *handle);
1.15 +int mf_setpos(void *handle, size_t pos);
1.16 +
1.17 +sp_writefuncs_t cstd_funcs =
1.18 +{
1.19 + mf_open,
1.20 + mf_close,
1.21 + mf_write,
1.22 + mf_read,
1.23 + mf_getpos,
1.24 + mf_setpos
1.25 +};
1.26 +
1.27 +sp_file_t *spfw_create(const char *name, sp_writefuncs_t *optfuncs)
1.28 +{
1.29 + sp_file_t file;
1.30 + sp_file_t *pFile;
1.31 +
1.32 + if (!optfuncs)
1.33 + {
1.34 + optfuncs = &cstd_funcs;
1.35 + }
1.36 +
1.37 + file.handle = optfuncs->fnOpen(name);
1.38 + if (!file.handle)
1.39 + {
1.40 + return NULL;
1.41 + }
1.42 +
1.43 + pFile = (sp_file_t *)malloc(sizeof(sp_file_t));
1.44 +
1.45 + pFile->handle = file.handle;
1.46 + memcpy(&pFile->funcs, optfuncs, sizeof(sp_writefuncs_t));
1.47 + pFile->curoffs = 0;
1.48 + pFile->header.magic = SPFILE_MAGIC;
1.49 + pFile->header.sections = 0;
1.50 + pFile->header.stringtab = 0;
1.51 + pFile->header.version = SPFILE_VERSION;
1.52 + pFile->header.imagesize = 0;
1.53 + pFile->header.disksize = 0;
1.54 + pFile->header.compression = SPFILE_COMPRESSION_NONE;
1.55 + pFile->header.dataoffs = 0;
1.56 + pFile->lastsection = 0;
1.57 + pFile->offsets = NULL;
1.58 + pFile->sections = NULL;
1.59 + pFile->state = -1;
1.60 + pFile->nametab = NULL;
1.61 + pFile->nametab_idx = 0;
1.62 +
1.63 + return pFile;
1.64 +}
1.65 +
1.66 +void spfw_destroy(sp_file_t *spf)
1.67 +{
1.68 + free(spf->sections);
1.69 + free(spf->nametab);
1.70 + free(spf->offsets);
1.71 + spf->funcs.fnClose(spf->handle);
1.72 + free(spf);
1.73 +}
1.74 +
1.75 +uint8_t spfw_add_section(sp_file_t *spf, const char *name)
1.76 +{
1.77 + size_t namelen;
1.78 + uint8_t s;
1.79 + if (spf->state != -1)
1.80 + {
1.81 + return 0;
1.82 + }
1.83 +
1.84 + namelen = strlen(name) + 1;
1.85 +
1.86 + if (spf->header.sections == 0)
1.87 + {
1.88 + /** allocate for first section */
1.89 + spf->sections = (sp_file_section_t *)malloc(sizeof(sp_file_section_t));
1.90 + spf->offsets = (size_t *)malloc(sizeof(size_t));
1.91 + spf->nametab = (char *)malloc(namelen);
1.92 + } else {
1.93 + uint16_t num = spf->header.sections + 1;
1.94 + spf->sections = (sp_file_section_t *)realloc(spf->sections, sizeof(sp_file_section_t) * num);
1.95 + spf->offsets = (size_t *)realloc(spf->offsets, sizeof(size_t) * num);
1.96 + spf->nametab = (char *)realloc(spf->nametab, spf->nametab_idx + namelen);
1.97 + }
1.98 +
1.99 + s = spf->header.sections;
1.100 +
1.101 + spf->sections[s].nameoffs = spf->nametab_idx;
1.102 + /**
1.103 + * "fix" offset will be the second uint2 slot, which is after the previous sections after the header.
1.104 + */
1.105 + spf->offsets[s] = sizeof(spf->header) + (sizeof(sp_file_section_t) * spf->header.sections) + sizeof(uint32_t);
1.106 + strcpy(&spf->nametab[spf->nametab_idx], name);
1.107 + spf->nametab_idx += namelen;
1.108 +
1.109 + return ++spf->header.sections;
1.110 +}
1.111 +
1.112 +int spfw_finalize_header(sp_file_t *spf)
1.113 +{
1.114 + uint32_t size;
1.115 + if (spf->state != -1)
1.116 + {
1.117 + return -1;
1.118 + }
1.119 +
1.120 + size = sizeof(sp_file_section_t) * spf->header.sections;
1.121 +
1.122 + spf->header.stringtab = sizeof(spf->header) + size;
1.123 + spf->header.dataoffs = spf->header.stringtab + spf->nametab_idx;
1.124 + if (spf->funcs.fnWrite(&spf->header, sizeof(spf->header), 1, spf->handle) != 1)
1.125 + {
1.126 + return -1;
1.127 + }
1.128 + if (spf->funcs.fnWrite(spf->sections, sizeof(sp_file_section_t), spf->header.sections, spf->handle) !=
1.129 + spf->header.sections)
1.130 + {
1.131 + return -1;
1.132 + }
1.133 + if (spf->funcs.fnWrite(spf->nametab, sizeof(char), spf->nametab_idx, spf->handle) != spf->nametab_idx)
1.134 + {
1.135 + return -1;
1.136 + }
1.137 + spf->curoffs = spf->funcs.fnGetPos(spf->handle);
1.138 + spf->lastsection = spf->curoffs;
1.139 + spf->state++;
1.140 +
1.141 + return 0;
1.142 +}
1.143 +
1.144 +int spfw_next_section(sp_file_t *spf)
1.145 +{
1.146 + uint8_t s;
1.147 + uint32_t rest[2];
1.148 +
1.149 + if (spf->state < 0 || spf->state > spf->header.sections)
1.150 + {
1.151 + return -1;
1.152 + }
1.153 +
1.154 + if (spf->state == (int)spf->header.sections)
1.155 + {
1.156 + return 0;
1.157 + }
1.158 +
1.159 + s = (uint8_t)spf->state;
1.160 +
1.161 + spf->curoffs = spf->funcs.fnGetPos(spf->handle);
1.162 + spf->funcs.fnSetPos(spf->handle, spf->offsets[s]);
1.163 +
1.164 + rest[0] = spf->lastsection;
1.165 + rest[1] = spf->curoffs - spf->lastsection;
1.166 + if (spf->funcs.fnWrite(rest, sizeof(uint32_t), 2, spf->handle) != 2)
1.167 + {
1.168 + return -1;
1.169 + }
1.170 +
1.171 + spf->funcs.fnSetPos(spf->handle, spf->curoffs);
1.172 + spf->lastsection = spf->curoffs;
1.173 +
1.174 + spf->state++;
1.175 +
1.176 + return 1;
1.177 +}
1.178 +
1.179 +int spfw_finalize_all(sp_file_t *spf)
1.180 +{
1.181 + uint8_t offs;
1.182 +
1.183 + if (spf->state < spf->header.sections)
1.184 + {
1.185 + return -1;
1.186 + }
1.187 +
1.188 + offs = offsetof(sp_file_hdr_t, imagesize);
1.189 + spf->header.disksize = spf->funcs.fnGetPos(spf->handle);
1.190 + spf->header.imagesize = spf->funcs.fnGetPos(spf->handle);
1.191 + spf->funcs.fnSetPos(spf->handle, offs);
1.192 + spf->funcs.fnWrite(&spf->header.imagesize, sizeof(uint32_t), 1, spf->handle);
1.193 + spf->funcs.fnSetPos(spf->handle, spf->header.imagesize);
1.194 +
1.195 + return 1;
1.196 +}
1.197 +
1.198 +/**
1.199 + * More memory file operations
1.200 + */
1.201 +
1.202 +void *mf_open(const char *name)
1.203 +{
1.204 + return memfile_creat(name, 1024);
1.205 +}
1.206 +
1.207 +void mf_close(void *handle)
1.208 +{
1.209 + memfile_destroy((memfile_t *)handle);
1.210 +}
1.211 +
1.212 +size_t mf_write(const void *buf, size_t size, size_t count, void *handle)
1.213 +{
1.214 + if (!count)
1.215 + {
1.216 + return 0;
1.217 + }
1.218 +
1.219 + if (memfile_write((memfile_t *)handle, buf, size*count))
1.220 + {
1.221 + return count;
1.222 + }
1.223 +
1.224 + return 0;
1.225 +}
1.226 +
1.227 +size_t mf_read(void *buf, size_t size, size_t count, void *handle)
1.228 +{
1.229 + return memfile_read((memfile_t *)handle, buf, size*count) / count;
1.230 +}
1.231 +
1.232 +size_t mf_getpos(void *handle)
1.233 +{
1.234 + return (long)memfile_tell((memfile_t *)handle);
1.235 +}
1.236 +
1.237 +int mf_setpos(void *handle, size_t pos)
1.238 +{
1.239 + memfile_seek((memfile_t *)handle, (long)pos);
1.240 + return 1;
1.241 +}
1.242 +
1.243 +
1.244 +#if UNUSED_FOR_NOW
1.245 +/**
1.246 + * Default file operations...
1.247 + * Based on C standard library calls.
1.248 + */
1.249 +
1.250 +void *fp_open(const char *name)
1.251 +{
1.252 + return fopen(name, "wb");
1.253 +}
1.254 +
1.255 +void fp_close(void *handle)
1.256 +{
1.257 + fclose((FILE *)handle);
1.258 +}
1.259 +
1.260 +size_t fp_write(const void *buf, size_t size, size_t count, void *handle)
1.261 +{
1.262 + return fwrite(buf, size, count, (FILE *)handle);
1.263 +}
1.264 +
1.265 +size_t fp_read(void *buf, size_t size, size_t count, void *handle)
1.266 +{
1.267 + return fread(buf, size, count, (FILE *)handle);
1.268 +}
1.269 +
1.270 +size_t fp_getpos(void *handle)
1.271 +{
1.272 + return (size_t)ftell((FILE *)handle);
1.273 +}
1.274 +
1.275 +int fp_setpos(void *handle, size_t pos)
1.276 +{
1.277 + return fseek((FILE *)handle, (long)pos, SEEK_SET);
1.278 +}
1.279 +#endif