summaryrefslogtreecommitdiff
path: root/rbutil/rbutilqt/mspack/system-mspack.c
diff options
context:
space:
mode:
Diffstat (limited to 'rbutil/rbutilqt/mspack/system-mspack.c')
-rw-r--r--rbutil/rbutilqt/mspack/system-mspack.c237
1 files changed, 237 insertions, 0 deletions
diff --git a/rbutil/rbutilqt/mspack/system-mspack.c b/rbutil/rbutilqt/mspack/system-mspack.c
new file mode 100644
index 0000000000..a7f4a5c218
--- /dev/null
+++ b/rbutil/rbutilqt/mspack/system-mspack.c
@@ -0,0 +1,237 @@
1/* This file is part of libmspack.
2 * (C) 2003-2004 Stuart Caie.
3 *
4 * libmspack is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU Lesser General Public License (LGPL) version 2.1
6 *
7 * For further details, see the file COPYING.LIB distributed with libmspack
8 */
9
10#ifdef HAVE_CONFIG_H
11# include <config.h>
12#endif
13
14#include "system-mspack.h"
15
16#ifndef LARGEFILE_SUPPORT
17const char *largefile_msg = "library not compiled to support large files.";
18#endif
19
20
21int mspack_version(int entity) {
22 switch (entity) {
23 /* CHM decoder version 1 -> 2 changes:
24 * - added mschmd_sec_mscompressed::spaninfo
25 * - added mschmd_header::first_pmgl
26 * - added mschmd_header::last_pmgl
27 * - added mschmd_header::chunk_cache;
28 */
29 case MSPACK_VER_MSCHMD:
30 return 2;
31 case MSPACK_VER_LIBRARY:
32 case MSPACK_VER_SYSTEM:
33 case MSPACK_VER_MSCABD:
34 case MSPACK_VER_MSSZDDD:
35 case MSPACK_VER_MSKWAJD:
36 return 1;
37 case MSPACK_VER_MSCABC:
38 case MSPACK_VER_MSCHMC:
39 case MSPACK_VER_MSLITD:
40 case MSPACK_VER_MSLITC:
41 case MSPACK_VER_MSHLPD:
42 case MSPACK_VER_MSHLPC:
43 case MSPACK_VER_MSSZDDC:
44 case MSPACK_VER_MSKWAJC:
45 return 0;
46 }
47 return -1;
48}
49
50int mspack_sys_selftest_internal(int offt_size) {
51 return (sizeof(off_t) == offt_size) ? MSPACK_ERR_OK : MSPACK_ERR_SEEK;
52}
53
54/* validates a system structure */
55int mspack_valid_system(struct mspack_system *sys) {
56 return (sys != NULL) && (sys->open != NULL) && (sys->close != NULL) &&
57 (sys->read != NULL) && (sys->write != NULL) && (sys->seek != NULL) &&
58 (sys->tell != NULL) && (sys->message != NULL) && (sys->alloc != NULL) &&
59 (sys->free != NULL) && (sys->copy != NULL) && (sys->null_ptr == NULL);
60}
61
62/* returns the length of a file opened for reading */
63int mspack_sys_filelen(struct mspack_system *system,
64 struct mspack_file *file, off_t *length)
65{
66 off_t current;
67
68 if (!system || !file || !length) return MSPACK_ERR_OPEN;
69
70 /* get current offset */
71 current = system->tell(file);
72
73 /* seek to end of file */
74 if (system->seek(file, (off_t) 0, MSPACK_SYS_SEEK_END)) {
75 return MSPACK_ERR_SEEK;
76 }
77
78 /* get offset of end of file */
79 *length = system->tell(file);
80
81 /* seek back to original offset */
82 if (system->seek(file, current, MSPACK_SYS_SEEK_START)) {
83 return MSPACK_ERR_SEEK;
84 }
85
86 return MSPACK_ERR_OK;
87}
88
89
90
91/* definition of mspack_default_system -- if the library is compiled with
92 * MSPACK_NO_DEFAULT_SYSTEM, no default system will be provided. Otherwise,
93 * an appropriate default system (e.g. the standard C library, or some native
94 * API calls)
95 */
96
97#ifdef MSPACK_NO_DEFAULT_SYSTEM
98struct mspack_system *mspack_default_system = NULL;
99#else
100
101/* implementation of mspack_default_system for standard C library */
102
103#include <stdio.h>
104#include <stdlib.h>
105#include <string.h>
106#include <stdarg.h>
107
108struct mspack_file_p {
109 FILE *fh;
110 const char *name;
111};
112
113static struct mspack_file *msp_open(struct mspack_system *self,
114 const char *filename, int mode)
115{
116 struct mspack_file_p *fh;
117 const char *fmode;
118
119 switch (mode) {
120 case MSPACK_SYS_OPEN_READ: fmode = "rb"; break;
121 case MSPACK_SYS_OPEN_WRITE: fmode = "wb"; break;
122 case MSPACK_SYS_OPEN_UPDATE: fmode = "r+b"; break;
123 case MSPACK_SYS_OPEN_APPEND: fmode = "ab"; break;
124 default: return NULL;
125 }
126
127 if ((fh = (struct mspack_file_p *) malloc(sizeof(struct mspack_file_p)))) {
128 fh->name = filename;
129 if ((fh->fh = fopen(filename, fmode))) return (struct mspack_file *) fh;
130 free(fh);
131 }
132 return NULL;
133}
134
135static void msp_close(struct mspack_file *file) {
136 struct mspack_file_p *self = (struct mspack_file_p *) file;
137 if (self) {
138 fclose(self->fh);
139 free(self);
140 }
141}
142
143static int msp_read(struct mspack_file *file, void *buffer, int bytes) {
144 struct mspack_file_p *self = (struct mspack_file_p *) file;
145 if (self && buffer && bytes >= 0) {
146 size_t count = fread(buffer, 1, (size_t) bytes, self->fh);
147 if (!ferror(self->fh)) return (int) count;
148 }
149 return -1;
150}
151
152static int msp_write(struct mspack_file *file, void *buffer, int bytes) {
153 struct mspack_file_p *self = (struct mspack_file_p *) file;
154 if (self && buffer && bytes >= 0) {
155 size_t count = fwrite(buffer, 1, (size_t) bytes, self->fh);
156 if (!ferror(self->fh)) return (int) count;
157 }
158 return -1;
159}
160
161static int msp_seek(struct mspack_file *file, off_t offset, int mode) {
162 struct mspack_file_p *self = (struct mspack_file_p *) file;
163 if (self) {
164 switch (mode) {
165 case MSPACK_SYS_SEEK_START: mode = SEEK_SET; break;
166 case MSPACK_SYS_SEEK_CUR: mode = SEEK_CUR; break;
167 case MSPACK_SYS_SEEK_END: mode = SEEK_END; break;
168 default: return -1;
169 }
170#ifdef HAVE_FSEEKO
171 return fseeko(self->fh, offset, mode);
172#else
173 return fseek(self->fh, offset, mode);
174#endif
175 }
176 return -1;
177}
178
179static off_t msp_tell(struct mspack_file *file) {
180 struct mspack_file_p *self = (struct mspack_file_p *) file;
181#ifdef HAVE_FSEEKO
182 return (self) ? (off_t) ftello(self->fh) : 0;
183#else
184 return (self) ? (off_t) ftell(self->fh) : 0;
185#endif
186}
187
188static void msp_msg(struct mspack_file *file, const char *format, ...) {
189 va_list ap;
190 if (file) fprintf(stderr, "%s: ", ((struct mspack_file_p *) file)->name);
191 va_start(ap, format);
192 vfprintf(stderr, format, ap);
193 va_end(ap);
194 fputc((int) '\n', stderr);
195 fflush(stderr);
196}
197
198static void *msp_alloc(struct mspack_system *self, size_t bytes) {
199#ifdef DEBUG
200 /* make uninitialised data obvious */
201 char *buf = malloc(bytes + 8);
202 if (buf) memset(buf, 0xDC, bytes);
203 *((size_t *)buf) = bytes;
204 return &buf[8];
205#else
206 return malloc(bytes);
207#endif
208}
209
210static void msp_free(void *buffer) {
211#ifdef DEBUG
212 char *buf = buffer;
213 size_t bytes;
214 if (buf) {
215 buf -= 8;
216 bytes = *((size_t *)buf);
217 /* make freed data obvious */
218 memset(buf, 0xED, bytes);
219 free(buf);
220 }
221#else
222 free(buffer);
223#endif
224}
225
226static void msp_copy(void *src, void *dest, size_t bytes) {
227 memcpy(dest, src, bytes);
228}
229
230static struct mspack_system msp_system = {
231 &msp_open, &msp_close, &msp_read, &msp_write, &msp_seek,
232 &msp_tell, &msp_msg, &msp_alloc, &msp_free, &msp_copy, NULL
233};
234
235struct mspack_system *mspack_default_system = &msp_system;
236
237#endif