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> */
23 #ifdef ZZIP_HAVE_UNISTD_H
26 #include <sys/types.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;
53 ZZIP_memory
int zzip_memory_read(int fd
, char *buf
, size_t count
)
62 /* Check file descriptor */
63 if (fd
!=zzip_memory_fd
) {
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 */
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
) {
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
);
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
;
113 /* Exit on error during read */
117 return(bytes_written
);
120 ZZIP_memory
int zzip_memory_open(const char *pathname
, int flags
)
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 */
132 fd
=open(pathname
, flags
);
137 if (fstat(fd
, &stat_buffer
)<0) {
140 if (stat_buffer
.st_size
<1) {
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 */
151 /* Return file descriptor */
156 ZZIP_memory
int zzip_memory_close(int fd
)
158 /* Check file descriptor */
159 if (fd
!=zzip_memory_fd
) {
162 /* Clear any memory buffer that might be laying around */
163 if (zzip_memory_buffer
) {
164 free(zzip_memory_buffer
);
166 /* Reset variables */
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
) {
178 /* Change position pointer */
181 zzip_memory_pos
=offset
;
184 zzip_memory_pos
+= offset
;
187 zzip_memory_pos
= zzip_memory_size
-1;
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 */
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
;