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