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