summaryrefslogtreecommitdiff
path: root/Build/source/libs/zziplib/zziplib-0.13.62/zzipwrap/wrap.c
blob: 2bea0c39e5b6b59c5a15dc9fdde3340851f14436 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223

/* Wrapper interface for zziplib's file IO functions. 
 *
 * -- In memory-access IO function --
 *  Provides default fileio functions open/read/lseek/close and functions 
 *  that enable blocked, memory buffered IO. 
 *
 *  (c) A. Schiffler, aschiffler@home.com                         
 *  Released under same license as zziplib (LGPL), Oct 2001 
 *
 *  modified 2002 to use new plugin_io interface by Guido Draheim
 */

#include <zzip/conf.h>
#include <zzip/plugin.h>
/* #incl <zzip/wrap.h> */
#include      "wrap.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifdef ZZIP_HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

/* Some globals that we use for operation */

static int zzip_memory_blocksize=0;
static zzipwrap_pfn_t zzip_memory_callback=NULL;
static void *zzip_memory_callbackdata=NULL;
static char *zzip_memory_buffer=NULL;
static int zzip_memory_bufferblock=0;
static int zzip_memory_fd=-1;
static int zzip_memory_pos=0;
static int zzip_memory_size=0;

/* at the moment, we do not export the five handlers of zzip_memry plugin_io */
#define ZZIP_memory static

ZZIP_memory void zzip_memory_reset(void)
{
 zzip_memory_buffer=NULL;
 zzip_memory_bufferblock=0;
 zzip_memory_pos=0;
 zzip_memory_size=0;
 zzip_memory_fd=-1;
}

ZZIP_memory int zzip_memory_read(int fd, char *buf, size_t count)
{
 int requested_block;
 int transfer_start;
 int transfer_bytes;
 int bytes_read;
 int bytes_to_write;
 int bytes_written;
 
 /* Check file descriptor */
 if (fd!=zzip_memory_fd) {
  return(-1);
 }

 if ((int)count<0) 
     return -1;

 /* Work out how many bytes we have to read based */
 /*  on filepos and requested buffersize. */
 bytes_to_write=zzip_memory_size-zzip_memory_pos;
 if (bytes_to_write>=(int)count) {
  bytes_to_write=(int)count;
 }

 /* Read/transfer loop */
 bytes_written=0;
 while (bytes_to_write>0) {
  /* Check which block we are reading from */
  requested_block=zzip_memory_pos/zzip_memory_blocksize;
  /* Check if we have this block available */
  if (zzip_memory_bufferblock!=requested_block) {
   /* Read this block */
   lseek(fd,requested_block*zzip_memory_blocksize,SEEK_SET);
   bytes_read=read(fd,zzip_memory_buffer,zzip_memory_blocksize);
   /* Clear unused bytes */
   if ((bytes_read>=0) && (bytes_read<zzip_memory_blocksize)) {
    memset(&zzip_memory_buffer[bytes_read],0,zzip_memory_blocksize-bytes_read);
   }
   /* Set current block pos */
   zzip_memory_bufferblock=requested_block;
   /* Process buffer if callback is set */
   if (zzip_memory_callback) {
    zzip_memory_callback(zzip_memory_buffer,zzip_memory_blocksize,zzip_memory_callbackdata);
   }
  } else {
   bytes_read=zzip_memory_blocksize;
  }
  /* Check if we have read any data */ 
  if (bytes_read > 0) {
   /* Copy data to output buffer */
   transfer_start=zzip_memory_pos-zzip_memory_bufferblock*zzip_memory_blocksize;
   transfer_bytes=zzip_memory_blocksize-transfer_start;
   if (transfer_bytes>bytes_to_write) {
    transfer_bytes=bytes_to_write;
   }
   memcpy (&buf[bytes_written], &zzip_memory_buffer[transfer_start],transfer_bytes);
   zzip_memory_pos += transfer_bytes;
   bytes_written += transfer_bytes;
   bytes_to_write -= transfer_bytes;
  } else {
   /* Exit on error during read */
   bytes_to_write=0;
  }
 }
 return(bytes_written);
}

ZZIP_memory int zzip_memory_open(const char *pathname, int flags)
{
 int fd;
 struct stat stat_buffer;
 
 /* Deallocate any memory buffer laying around */
 if (zzip_memory_buffer) {
  free(zzip_memory_buffer);
 }
 /* Reset variables */
 zzip_memory_reset();
 /* Open file */
 fd=open(pathname, flags);
 if (fd<0) { 
  return(-1);
 } else { 
  /* Get filesize */
  if (fstat(fd, &stat_buffer)<0) {
   return(-1);
  } 
  if (stat_buffer.st_size<1) {
   return(-1);
  }
  /* Store filesize */
  zzip_memory_size = stat_buffer.st_size;
  /* Allocate readbuffer */
  zzip_memory_buffer = malloc(zzip_memory_blocksize);
  /* Invalidate buffer block */
  zzip_memory_bufferblock = -1;
  /* Store file descriptor */
  zzip_memory_fd=fd;
  /* Return file descriptor */
  return(fd);
 } 
}

ZZIP_memory int zzip_memory_close(int fd)
{
 /* Check file descriptor */
 if (fd!=zzip_memory_fd) {
  return(-1);
 }
 /* Clear any memory buffer that might be laying around */
 if (zzip_memory_buffer) {
  free(zzip_memory_buffer);
 }
 /* Reset variables */
 zzip_memory_reset();
 /* Close file */
 return(close(fd));
}

ZZIP_memory off_t zzip_memory_lseek(int fildes, off_t offset, int whence)
{
 /* Check file descriptor */
 if (fildes!=zzip_memory_fd) {
  return(-1);
 }
 /* Change position pointer */
 switch (whence) {
  case SEEK_SET:
   zzip_memory_pos=offset;
   break;
  case SEEK_CUR:
   zzip_memory_pos += offset;
   break;
  case SEEK_END:
   zzip_memory_pos = zzip_memory_size-1;
   break;
 }
 /* Limit position to the last byte of the file */
 if (zzip_memory_pos>(zzip_memory_size-1)) {
  zzip_memory_pos=zzip_memory_size-1;
 }
 /* Return current position */ 
 return(zzip_memory_pos);
}

/* -------- Control wrapper usage */


zzip_plugin_io_t
zzipwrap_use_memory_io(int blocksize, 
		       zzipwrap_pfn_t callback, void *callbackdata)
{
 static const struct zzip_plugin_io zzip_memory_io =
 {
  (void *) zzip_memory_open,
  (void *) zzip_memory_close,
  (void *) zzip_memory_read,
  (void *) zzip_memory_lseek,
  (void *) zzip_filesize,
  0
 };

 /* Store blocksize and block-processing callback data */

 zzip_memory_blocksize = blocksize;
 zzip_memory_callback = callback;
 zzip_memory_callbackdata = callbackdata;

 return (zzip_plugin_io_t) &zzip_memory_io;
}