beta-0.89.2
[luatex.git] / source / libs / zziplib / zziplib-0.13.62 / zzipwrap / wrap.c
blob2bea0c39e5b6b59c5a15dc9fdde3340851f14436
2 /* Wrapper interface for zziplib's file IO functions.
4 * -- In memory-access IO function --
5 * Provides default fileio functions open/read/lseek/close and functions
6 * that enable blocked, memory buffered IO.
8 * (c) A. Schiffler, aschiffler@home.com
9 * Released under same license as zziplib (LGPL), Oct 2001
11 * modified 2002 to use new plugin_io interface by Guido Draheim
14 #include <zzip/conf.h>
15 #include <zzip/plugin.h>
16 /* #incl <zzip/wrap.h> */
17 #include "wrap.h"
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
23 #ifdef ZZIP_HAVE_UNISTD_H
24 #include <unistd.h>
25 #endif
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
30 /* Some globals that we use for operation */
32 static int zzip_memory_blocksize=0;
33 static zzipwrap_pfn_t zzip_memory_callback=NULL;
34 static void *zzip_memory_callbackdata=NULL;
35 static char *zzip_memory_buffer=NULL;
36 static int zzip_memory_bufferblock=0;
37 static int zzip_memory_fd=-1;
38 static int zzip_memory_pos=0;
39 static int zzip_memory_size=0;
41 /* at the moment, we do not export the five handlers of zzip_memry plugin_io */
42 #define ZZIP_memory static
44 ZZIP_memory void zzip_memory_reset(void)
46 zzip_memory_buffer=NULL;
47 zzip_memory_bufferblock=0;
48 zzip_memory_pos=0;
49 zzip_memory_size=0;
50 zzip_memory_fd=-1;
53 ZZIP_memory int zzip_memory_read(int fd, char *buf, size_t count)
55 int requested_block;
56 int transfer_start;
57 int transfer_bytes;
58 int bytes_read;
59 int bytes_to_write;
60 int bytes_written;
62 /* Check file descriptor */
63 if (fd!=zzip_memory_fd) {
64 return(-1);
67 if ((int)count<0)
68 return -1;
70 /* Work out how many bytes we have to read based */
71 /* on filepos and requested buffersize. */
72 bytes_to_write=zzip_memory_size-zzip_memory_pos;
73 if (bytes_to_write>=(int)count) {
74 bytes_to_write=(int)count;
77 /* Read/transfer loop */
78 bytes_written=0;
79 while (bytes_to_write>0) {
80 /* Check which block we are reading from */
81 requested_block=zzip_memory_pos/zzip_memory_blocksize;
82 /* Check if we have this block available */
83 if (zzip_memory_bufferblock!=requested_block) {
84 /* Read this block */
85 lseek(fd,requested_block*zzip_memory_blocksize,SEEK_SET);
86 bytes_read=read(fd,zzip_memory_buffer,zzip_memory_blocksize);
87 /* Clear unused bytes */
88 if ((bytes_read>=0) && (bytes_read<zzip_memory_blocksize)) {
89 memset(&zzip_memory_buffer[bytes_read],0,zzip_memory_blocksize-bytes_read);
91 /* Set current block pos */
92 zzip_memory_bufferblock=requested_block;
93 /* Process buffer if callback is set */
94 if (zzip_memory_callback) {
95 zzip_memory_callback(zzip_memory_buffer,zzip_memory_blocksize,zzip_memory_callbackdata);
97 } else {
98 bytes_read=zzip_memory_blocksize;
100 /* Check if we have read any data */
101 if (bytes_read > 0) {
102 /* Copy data to output buffer */
103 transfer_start=zzip_memory_pos-zzip_memory_bufferblock*zzip_memory_blocksize;
104 transfer_bytes=zzip_memory_blocksize-transfer_start;
105 if (transfer_bytes>bytes_to_write) {
106 transfer_bytes=bytes_to_write;
108 memcpy (&buf[bytes_written], &zzip_memory_buffer[transfer_start],transfer_bytes);
109 zzip_memory_pos += transfer_bytes;
110 bytes_written += transfer_bytes;
111 bytes_to_write -= transfer_bytes;
112 } else {
113 /* Exit on error during read */
114 bytes_to_write=0;
117 return(bytes_written);
120 ZZIP_memory int zzip_memory_open(const char *pathname, int flags)
122 int fd;
123 struct stat stat_buffer;
125 /* Deallocate any memory buffer laying around */
126 if (zzip_memory_buffer) {
127 free(zzip_memory_buffer);
129 /* Reset variables */
130 zzip_memory_reset();
131 /* Open file */
132 fd=open(pathname, flags);
133 if (fd<0) {
134 return(-1);
135 } else {
136 /* Get filesize */
137 if (fstat(fd, &stat_buffer)<0) {
138 return(-1);
140 if (stat_buffer.st_size<1) {
141 return(-1);
143 /* Store filesize */
144 zzip_memory_size = stat_buffer.st_size;
145 /* Allocate readbuffer */
146 zzip_memory_buffer = malloc(zzip_memory_blocksize);
147 /* Invalidate buffer block */
148 zzip_memory_bufferblock = -1;
149 /* Store file descriptor */
150 zzip_memory_fd=fd;
151 /* Return file descriptor */
152 return(fd);
156 ZZIP_memory int zzip_memory_close(int fd)
158 /* Check file descriptor */
159 if (fd!=zzip_memory_fd) {
160 return(-1);
162 /* Clear any memory buffer that might be laying around */
163 if (zzip_memory_buffer) {
164 free(zzip_memory_buffer);
166 /* Reset variables */
167 zzip_memory_reset();
168 /* Close file */
169 return(close(fd));
172 ZZIP_memory off_t zzip_memory_lseek(int fildes, off_t offset, int whence)
174 /* Check file descriptor */
175 if (fildes!=zzip_memory_fd) {
176 return(-1);
178 /* Change position pointer */
179 switch (whence) {
180 case SEEK_SET:
181 zzip_memory_pos=offset;
182 break;
183 case SEEK_CUR:
184 zzip_memory_pos += offset;
185 break;
186 case SEEK_END:
187 zzip_memory_pos = zzip_memory_size-1;
188 break;
190 /* Limit position to the last byte of the file */
191 if (zzip_memory_pos>(zzip_memory_size-1)) {
192 zzip_memory_pos=zzip_memory_size-1;
194 /* Return current position */
195 return(zzip_memory_pos);
198 /* -------- Control wrapper usage */
201 zzip_plugin_io_t
202 zzipwrap_use_memory_io(int blocksize,
203 zzipwrap_pfn_t callback, void *callbackdata)
205 static const struct zzip_plugin_io zzip_memory_io =
207 (void *) zzip_memory_open,
208 (void *) zzip_memory_close,
209 (void *) zzip_memory_read,
210 (void *) zzip_memory_lseek,
211 (void *) zzip_filesize,
215 /* Store blocksize and block-processing callback data */
217 zzip_memory_blocksize = blocksize;
218 zzip_memory_callback = callback;
219 zzip_memory_callbackdata = callbackdata;
221 return (zzip_plugin_io_t) &zzip_memory_io;