summaryrefslogtreecommitdiff
path: root/utils/rbutilqt/mspack/system-mspack.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/rbutilqt/mspack/system-mspack.c')
-rw-r--r--utils/rbutilqt/mspack/system-mspack.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/utils/rbutilqt/mspack/system-mspack.c b/utils/rbutilqt/mspack/system-mspack.c
new file mode 100644
index 0000000000..9d4886a8db
--- /dev/null
+++ b/utils/rbutilqt/mspack/system-mspack.c
@@ -0,0 +1,240 @@
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 (void)self;
119
120 switch (mode) {
121 case MSPACK_SYS_OPEN_READ: fmode = "rb"; break;
122 case MSPACK_SYS_OPEN_WRITE: fmode = "wb"; break;
123 case MSPACK_SYS_OPEN_UPDATE: fmode = "r+b"; break;
124 case MSPACK_SYS_OPEN_APPEND: fmode = "ab"; break;
125 default: return NULL;
126 }
127
128 if ((fh = (struct mspack_file_p *) malloc(sizeof(struct mspack_file_p)))) {
129 fh->name = filename;
130 if ((fh->fh = fopen(filename, fmode))) return (struct mspack_file *) fh;
131 free(fh);
132 }
133 return NULL;
134}
135
136static void msp_close(struct mspack_file *file) {
137 struct mspack_file_p *self = (struct mspack_file_p *) file;
138 if (self) {
139 fclose(self->fh);
140 free(self);
141 }
142}
143
144static int msp_read(struct mspack_file *file, void *buffer, int bytes) {
145 struct mspack_file_p *self = (struct mspack_file_p *) file;
146 if (self && buffer && bytes >= 0) {
147 size_t count = fread(buffer, 1, (size_t) bytes, self->fh);
148 if (!ferror(self->fh)) return (int) count;
149 }
150 return -1;
151}
152
153static int msp_write(struct mspack_file *file, void *buffer, int bytes) {
154 struct mspack_file_p *self = (struct mspack_file_p *) file;
155 if (self && buffer && bytes >= 0) {
156 size_t count = fwrite(buffer, 1, (size_t) bytes, self->fh);
157 if (!ferror(self->fh)) return (int) count;
158 }
159 return -1;
160}
161
162static int msp_seek(struct mspack_file *file, off_t offset, int mode) {
163 struct mspack_file_p *self = (struct mspack_file_p *) file;
164 if (self) {
165 switch (mode) {
166 case MSPACK_SYS_SEEK_START: mode = SEEK_SET; break;
167 case MSPACK_SYS_SEEK_CUR: mode = SEEK_CUR; break;
168 case MSPACK_SYS_SEEK_END: mode = SEEK_END; break;
169 default: return -1;
170 }
171#ifdef HAVE_FSEEKO
172 return fseeko(self->fh, offset, mode);
173#else
174 return fseek(self->fh, offset, mode);
175#endif
176 }
177 return -1;
178}
179
180static off_t msp_tell(struct mspack_file *file) {
181 struct mspack_file_p *self = (struct mspack_file_p *) file;
182#ifdef HAVE_FSEEKO
183 return (self) ? (off_t) ftello(self->fh) : 0;
184#else
185 return (self) ? (off_t) ftell(self->fh) : 0;
186#endif
187}
188
189static void msp_msg(struct mspack_file *file, const char *format, ...) {
190 va_list ap;
191 if (file) fprintf(stderr, "%s: ", ((struct mspack_file_p *) file)->name);
192 va_start(ap, format);
193 vfprintf(stderr, format, ap);
194 va_end(ap);
195 fputc((int) '\n', stderr);
196 fflush(stderr);
197}
198
199static void *msp_alloc(struct mspack_system *self, size_t bytes) {
200#ifdef DEBUG
201 /* make uninitialised data obvious */
202 char *buf = malloc(bytes + 8);
203 (void)self;
204 if (buf) memset(buf, 0xDC, bytes);
205 *((size_t *)buf) = bytes;
206 return &buf[8];
207#else
208 (void)self;
209 return malloc(bytes);
210#endif
211}
212
213static void msp_free(void *buffer) {
214#ifdef DEBUG
215 char *buf = buffer;
216 size_t bytes;
217 if (buf) {
218 buf -= 8;
219 bytes = *((size_t *)buf);
220 /* make freed data obvious */
221 memset(buf, 0xED, bytes);
222 free(buf);
223 }
224#else
225 free(buffer);
226#endif
227}
228
229static void msp_copy(void *src, void *dest, size_t bytes) {
230 memcpy(dest, src, bytes);
231}
232
233static struct mspack_system msp_system = {
234 &msp_open, &msp_close, &msp_read, &msp_write, &msp_seek,
235 &msp_tell, &msp_msg, &msp_alloc, &msp_free, &msp_copy, NULL
236};
237
238struct mspack_system *mspack_default_system = &msp_system;
239
240#endif