blob: 9cb076ff3ac586eedd648edf0a5d88d2d1afa27c [file] [log] [blame]
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -07001/* ioapi_buf.h -- IO base function header for compress/uncompress .zip
2 files using zlib + zip or unzip API
3
4 This version of ioapi is designed to buffer IO.
5
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -07006 Copyright (C) 1998-2003 Gilles Vollant
Nathan Moinvaziric680ad32014-01-12 14:04:54 -07007 (C) 2012-2014 Nathan Moinvaziri
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -07008
Nathan Moinvaziric680ad32014-01-12 14:04:54 -07009 This program is distributed under the terms of the same license as zlib.
10 See the accompanying LICENSE file for the full text of the license.
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -070011*/
12
13
14#include <stdio.h>
15#include <stdlib.h>
16#include <string.h>
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -070017#include <stdarg.h>
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -070018
19#include "zlib.h"
20#include "ioapi.h"
21
22#include "ioapi_buf.h"
23
24#if defined(_WIN32)
Nathan Moinvaziri8e5eb692014-01-07 19:55:59 -070025# include <conio.h>
26# define PRINTF _cprintf
27# define VPRINTF _vcprintf
Nathan Moinvaziri0200b0a2012-08-06 17:53:01 -070028#else
Nathan Moinvaziri8e5eb692014-01-07 19:55:59 -070029# define PRINTF printf
30# define VPRINTF vprintf
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -070031#endif
32
Nathan Moinvaziri1e00f0e2012-06-29 00:00:50 -070033//#define IOBUF_VERBOSE
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -070034
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -070035#ifdef __GNUC__
36#ifndef max
37#define max(x,y) ({ \
38const typeof(x) _x = (x); \
39const typeof(y) _y = (y); \
40(void) (&_x == &_y); \
41_x > _y ? _x : _y; })
42#endif /* __GNUC__ */
43
44#ifndef min
45#define min(x,y) ({ \
46const typeof(x) _x = (x); \
47const typeof(y) _y = (y); \
48(void) (&_x == &_y); \
49_x < _y ? _x : _y; })
50#endif
51#endif
52
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -070053typedef struct ourstream_s {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -070054 char readbuf[IOBUF_BUFFERSIZE];
55 uint32_t readbuf_len;
56 uint32_t readbuf_pos;
57 uint32_t readbuf_hits;
58 uint32_t readbuf_misses;
59 char writebuf[IOBUF_BUFFERSIZE];
60 uint32_t writebuf_len;
61 uint32_t writebuf_pos;
62 uint32_t writebuf_hits;
63 uint32_t writebuf_misses;
64 uint64_t position;
65 voidpf stream;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -070066} ourstream_t;
67
Nathan Moinvaziri1e00f0e2012-06-29 00:00:50 -070068#if defined(IOBUF_VERBOSE)
Nathan Moinvaziri8e5eb692014-01-07 19:55:59 -070069# define print_buf(o,s,f,...) print_buf_internal(o,s,f,__VA_ARGS__);
Nathan Moinvaziri1e00f0e2012-06-29 00:00:50 -070070#else
Nathan Moinvaziri8e5eb692014-01-07 19:55:59 -070071# define print_buf(o,s,f,...)
Nathan Moinvaziri1e00f0e2012-06-29 00:00:50 -070072#endif
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -070073
74void print_buf_internal(voidpf opaque, voidpf stream, char *format, ...)
75{
76 ourstream_t *streamio = (ourstream_t *)stream;
77 va_list arglist;
Nathan Moinvazirif427edb2012-10-21 15:20:13 -070078 PRINTF("Buf stream %p - ", streamio);
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -070079 va_start(arglist, format);
80 VPRINTF(format, arglist);
81 va_end(arglist);
82}
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -070083
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -070084voidpf fopen_buf_internal_func(voidpf opaque, voidpf stream, uint32_t number_disk, int mode)
Nathan Moinvaziri76d61312012-06-25 23:42:27 -070085{
Nathan Moinvazirif9a81c72012-07-09 01:13:40 -070086 ourstream_t *streamio = NULL;
87 if (stream == NULL)
88 return NULL;
89 streamio = (ourstream_t *)malloc(sizeof(ourstream_t));
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -070090 if (streamio == NULL)
91 return NULL;
92 memset(streamio, 0, sizeof(ourstream_t));
93 streamio->stream = stream;
94 print_buf(opaque, streamio, "open [num %d mode %d]\n", number_disk, mode);
95 return streamio;
Nathan Moinvaziri76d61312012-06-25 23:42:27 -070096}
97
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -070098voidpf ZCALLBACK fopen_buf_func(voidpf opaque, const char *filename, int mode)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -070099{
100 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700101 voidpf stream = bufio->filefunc.zopen_file(bufio->filefunc.opaque, filename, mode);
102 return fopen_buf_internal_func(opaque, stream, 0, mode);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700103}
104
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700105voidpf ZCALLBACK fopen64_buf_func(voidpf opaque, const char *filename, int mode)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700106{
107 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700108 voidpf stream = bufio->filefunc64.zopen64_file(bufio->filefunc64.opaque, filename, mode);
109 return fopen_buf_internal_func(opaque, stream, 0, mode);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700110}
111
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700112voidpf ZCALLBACK fopendisk_buf_func(voidpf opaque, voidpf stream_cd, uint32_t number_disk, int mode)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700113{
114 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700115 ourstream_t *streamio = (ourstream_t *)stream_cd;
116 voidpf *stream = bufio->filefunc.zopendisk_file(bufio->filefunc.opaque, streamio->stream, number_disk, mode);
117 return fopen_buf_internal_func(opaque, stream, number_disk, mode);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700118}
119
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700120voidpf ZCALLBACK fopendisk64_buf_func(voidpf opaque, voidpf stream_cd, uint32_t number_disk, int mode)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700121{
122 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700123 ourstream_t *streamio = (ourstream_t *)stream_cd;
124 voidpf stream = bufio->filefunc64.zopendisk64_file(bufio->filefunc64.opaque, streamio->stream, number_disk, mode);
125 return fopen_buf_internal_func(opaque, stream, number_disk, mode);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700126}
127
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700128long fflush_buf(voidpf opaque, voidpf stream)
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700129{
130 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
131 ourstream_t *streamio = (ourstream_t *)stream;
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700132 uint32_t total_bytes_to_write = 0;
133 uint32_t bytes_to_write = streamio->writebuf_len;
134 uint32_t bytes_left_to_write = streamio->writebuf_len;
135 long bytes_written = 0;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700136
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700137 while (bytes_left_to_write > 0)
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700138 {
139 if (bufio->filefunc64.zwrite_file != NULL)
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700140 bytes_written = bufio->filefunc64.zwrite_file(bufio->filefunc64.opaque, streamio->stream, streamio->writebuf + (bytes_to_write - bytes_left_to_write), bytes_left_to_write);
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700141 else
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700142 bytes_written = bufio->filefunc.zwrite_file(bufio->filefunc.opaque, streamio->stream, streamio->writebuf + (bytes_to_write - bytes_left_to_write), bytes_left_to_write);
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700143
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700144 streamio->writebuf_misses += 1;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700145
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700146 print_buf(opaque, stream, "write flush [%d:%d len %d]\n", bytes_to_write, bytes_left_to_write, streamio->writebuf_len);
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700147
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700148 if (bytes_written < 0)
149 return bytes_written;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700150
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700151 total_bytes_to_write += bytes_written;
152 bytes_left_to_write -= bytes_written;
153 streamio->position += bytes_written;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700154 }
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700155 streamio->writebuf_len = 0;
156 streamio->writebuf_pos = 0;
157 return total_bytes_to_write;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700158}
159
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700160uint32_t ZCALLBACK fread_buf_func(voidpf opaque, voidpf stream, void *buf, uint32_t size)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700161{
162 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700163 ourstream_t *streamio = (ourstream_t *)stream;
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700164 uint32_t buf_len = 0;
165 uint32_t bytes_to_read = 0;
166 uint32_t bytes_to_copy = 0;
167 uint32_t bytes_left_to_read = size;
168 uint32_t bytes_read = 0;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700169
Nathan Moinvaziri1e00f0e2012-06-29 00:00:50 -0700170 print_buf(opaque, stream, "read [size %ld pos %lld]\n", size, streamio->position);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700171
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700172 if (streamio->writebuf_len > 0)
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700173 {
174 print_buf(opaque, stream, "switch from write to read, not yet supported [%lld]\n", streamio->position);
175 }
176
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700177 while (bytes_left_to_read > 0)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700178 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700179 if ((streamio->readbuf_len == 0) || (streamio->readbuf_pos == streamio->readbuf_len))
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700180 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700181 if (streamio->readbuf_len == IOBUF_BUFFERSIZE)
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700182 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700183 streamio->readbuf_pos = 0;
184 streamio->readbuf_len = 0;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700185 }
186
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700187 bytes_to_read = IOBUF_BUFFERSIZE - (streamio->readbuf_len - streamio->readbuf_pos);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700188
189 if (bufio->filefunc64.zread_file != NULL)
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700190 bytes_read = bufio->filefunc64.zread_file(bufio->filefunc64.opaque, streamio->stream, streamio->readbuf + streamio->readbuf_pos, bytes_to_read);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700191 else
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700192 bytes_read = bufio->filefunc.zread_file(bufio->filefunc.opaque, streamio->stream, streamio->readbuf + streamio->readbuf_pos, bytes_to_read);
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700193
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700194 streamio->readbuf_misses += 1;
195 streamio->readbuf_len += bytes_read;
196 streamio->position += bytes_read;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700197
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700198 print_buf(opaque, stream, "filled [read %d/%d buf %d:%d pos %lld]\n", bytes_read, bytes_to_read, streamio->readbuf_pos, streamio->readbuf_len, streamio->position);
Nathan Moinvaziri76d61312012-06-25 23:42:27 -0700199
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700200 if (bytes_read == 0)
Nathan Moinvaziri5cdf2ca2012-05-10 15:59:36 -0700201 break;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700202 }
Nathan Moinvaziri1e00f0e2012-06-29 00:00:50 -0700203
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700204 if ((streamio->readbuf_len - streamio->readbuf_pos) > 0)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700205 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700206 bytes_to_copy = min(bytes_left_to_read, (uint32_t)(streamio->readbuf_len - streamio->readbuf_pos));
207 memcpy((char *)buf + buf_len, streamio->readbuf + streamio->readbuf_pos, bytes_to_copy);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700208
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700209 buf_len += bytes_to_copy;
210 bytes_left_to_read -= bytes_to_copy;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700211
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700212 streamio->readbuf_hits += 1;
213 streamio->readbuf_pos += bytes_to_copy;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700214
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700215 print_buf(opaque, stream, "emptied [copied %d remaining %d buf %d:%d pos %lld]\n", bytes_to_copy, bytes_left_to_read, streamio->readbuf_pos, streamio->readbuf_len, streamio->position);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700216 }
217 }
218
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700219 return size - bytes_left_to_read;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700220}
221
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700222uint32_t ZCALLBACK fwrite_buf_func(voidpf opaque, voidpf stream, const void *buf, uint32_t size)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700223{
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700224 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700225 ourstream_t *streamio = (ourstream_t *)stream;
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700226 uint32_t bytes_to_write = size;
227 uint32_t bytes_left_to_write = size;
228 uint32_t bytes_to_copy = 0;
229 uint32_t ret = 0;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700230
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700231 print_buf(opaque, stream, "write [size %ld len %d pos %lld]\n", size, streamio->writebuf_len, streamio->position);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700232
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700233 if (streamio->readbuf_len > 0)
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700234 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700235 streamio->position -= streamio->readbuf_len;
236 streamio->position += streamio->readbuf_pos;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700237
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700238 streamio->readbuf_len = 0;
239 streamio->readbuf_pos = 0;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700240
241 print_buf(opaque, stream, "switch from read to write [%lld]\n", streamio->position);
242
243 if (bufio->filefunc64.zseek64_file != NULL)
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700244 ret = bufio->filefunc64.zseek64_file(bufio->filefunc64.opaque, streamio->stream, streamio->position, ZLIB_FILEFUNC_SEEK_SET);
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700245 else
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700246 ret = bufio->filefunc.zseek_file(bufio->filefunc.opaque, streamio->stream, (uint32_t)streamio->position, ZLIB_FILEFUNC_SEEK_SET);
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700247
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700248 if (ret != 0)
249 return (uint32_t)-1;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700250 }
251
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700252 while (bytes_left_to_write > 0)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700253 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700254 bytes_to_copy = min(bytes_left_to_write, (uint32_t)(IOBUF_BUFFERSIZE - min(streamio->writebuf_len, streamio->writebuf_pos)));
Nathan Moinvaziri472fc132013-06-20 12:31:59 -0700255
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700256 if (bytes_to_copy == 0)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700257 {
Nathan Moinvaziri472fc132013-06-20 12:31:59 -0700258 if (fflush_buf(opaque, stream) <= 0)
Nathan Moinvaziri5cdf2ca2012-05-10 15:59:36 -0700259 return 0;
Nathan Moinvaziri472fc132013-06-20 12:31:59 -0700260
261 continue;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700262 }
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700263
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700264 memcpy(streamio->writebuf + streamio->writebuf_pos, (char *)buf + (bytes_to_write - bytes_left_to_write), bytes_to_copy);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700265
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700266 print_buf(opaque, stream, "write copy [remaining %d write %d:%d len %d]\n", bytes_to_copy, bytes_to_write, bytes_left_to_write, streamio->writebuf_len);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700267
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700268 bytes_left_to_write -= bytes_to_copy;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700269
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700270 streamio->writebuf_pos += bytes_to_copy;
271 streamio->writebuf_hits += 1;
272 if (streamio->writebuf_pos > streamio->writebuf_len)
273 streamio->writebuf_len += streamio->writebuf_pos - streamio->writebuf_len;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700274 }
275
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700276 return size - bytes_left_to_write;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700277}
278
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700279uint64_t ftell_buf_internal_func(voidpf opaque, voidpf stream, uint64_t position)
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700280{
281 ourstream_t *streamio = (ourstream_t *)stream;
282 streamio->position = position;
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700283 print_buf(opaque, stream, "tell [pos %llu readpos %d writepos %d err %d]\n", streamio->position, streamio->readbuf_pos, streamio->writebuf_pos, errno);
284 if (streamio->readbuf_len > 0)
285 position -= (streamio->readbuf_len - streamio->readbuf_pos);
286 if (streamio->writebuf_len > 0)
287 position += streamio->writebuf_pos;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700288 return position;
289}
290
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700291long ZCALLBACK ftell_buf_func(voidpf opaque, voidpf stream)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700292{
293 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700294 ourstream_t *streamio = (ourstream_t *)stream;
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700295 uint64_t position = bufio->filefunc.ztell_file(bufio->filefunc.opaque, streamio->stream);
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700296 return (long)ftell_buf_internal_func(opaque, stream, position);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700297}
298
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700299uint64_t ZCALLBACK ftell64_buf_func(voidpf opaque, voidpf stream)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700300{
301 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700302 ourstream_t *streamio = (ourstream_t *)stream;
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700303 uint64_t position = bufio->filefunc64.ztell64_file(bufio->filefunc64.opaque, streamio->stream);
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700304 return ftell_buf_internal_func(opaque, stream, position);
305}
306
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700307int fseek_buf_internal_func(voidpf opaque, voidpf stream, uint64_t offset, int origin)
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700308{
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700309 ourstream_t *streamio = (ourstream_t *)stream;
310
311 print_buf(opaque, stream, "seek [origin %d offset %llu pos %lld]\n", origin, offset, streamio->position);
312
313 switch (origin)
314 {
315 case ZLIB_FILEFUNC_SEEK_SET:
316
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700317 if (streamio->writebuf_len > 0)
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700318 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700319 if ((offset >= streamio->position) && (offset <= streamio->position + streamio->writebuf_len))
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700320 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700321 streamio->writebuf_pos = (uint32_t)(offset - streamio->position);
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700322 return 0;
323 }
324 }
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700325 if ((streamio->readbuf_len > 0) && (offset < streamio->position) && (offset >= streamio->position - streamio->readbuf_len))
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700326 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700327 streamio->readbuf_pos = (uint32_t)(offset - (streamio->position - streamio->readbuf_len));
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700328 return 0;
329 }
330 if (fflush_buf(opaque, stream) < 0)
331 return -1;
332 streamio->position = offset;
333 break;
334
335 case ZLIB_FILEFUNC_SEEK_CUR:
336
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700337 if (streamio->readbuf_len > 0)
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700338 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700339 if (offset <= (streamio->readbuf_len - streamio->readbuf_pos))
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700340 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700341 streamio->readbuf_pos += (uint32_t)offset;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700342 return 0;
343 }
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700344 offset -= (streamio->readbuf_len - streamio->readbuf_pos);
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700345 streamio->position += offset;
346 }
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700347 if (streamio->writebuf_len > 0)
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700348 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700349 if (offset <= (streamio->writebuf_len - streamio->writebuf_pos))
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700350 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700351 streamio->writebuf_pos += (uint32_t)offset;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700352 return 0;
353 }
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700354 offset -= (streamio->writebuf_len - streamio->writebuf_pos);
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700355 }
356
357 if (fflush_buf(opaque, stream) < 0)
358 return -1;
359
360 break;
361
362 case ZLIB_FILEFUNC_SEEK_END:
363
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700364 if (streamio->writebuf_len > 0)
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700365 {
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700366 streamio->writebuf_pos = streamio->writebuf_len;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700367 return 0;
368 }
369 break;
370 }
371
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700372 streamio->readbuf_len = 0;
373 streamio->readbuf_pos = 0;
374 streamio->writebuf_len = 0;
375 streamio->writebuf_pos = 0;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700376 return 1;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700377}
378
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700379long ZCALLBACK fseek_buf_func(voidpf opaque, voidpf stream, uint32_t offset, int origin)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700380{
381 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700382 ourstream_t *streamio = (ourstream_t *)stream;
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700383 long ret = -1;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700384 if (bufio->filefunc.zseek_file == NULL)
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700385 return ret;
386 ret = fseek_buf_internal_func(opaque, stream, offset, origin);
387 if (ret == 1)
388 ret = bufio->filefunc.zseek_file(bufio->filefunc.opaque, streamio->stream, offset, origin);
389 return ret;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700390}
391
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700392long ZCALLBACK fseek64_buf_func(voidpf opaque, voidpf stream, uint64_t offset, int origin)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700393{
394 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700395 ourstream_t *streamio = (ourstream_t *)stream;
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700396 long ret = -1;
Nathan Moinvaziri3a2005c2012-07-14 16:30:48 -0700397 if (bufio->filefunc64.zseek64_file == NULL)
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700398 return ret;
399 ret = fseek_buf_internal_func(opaque, stream, offset, origin);
400 if (ret == 1)
401 ret = bufio->filefunc64.zseek64_file(bufio->filefunc64.opaque, streamio->stream, offset, origin);
402 return ret;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700403}
404
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700405int ZCALLBACK fclose_buf_func(voidpf opaque, voidpf stream)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700406{
407 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700408 ourstream_t *streamio = (ourstream_t *)stream;
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700409 int ret = 0;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700410 fflush_buf(opaque, stream);
411 print_buf(opaque, stream, "close\n");
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700412 if (streamio->readbuf_hits + streamio->readbuf_misses > 0)
413 print_buf(opaque, stream, "read efficency %.02f%%\n", (streamio->readbuf_hits / ((float)streamio->readbuf_hits + streamio->readbuf_misses)) * 100);
414 if (streamio->writebuf_hits + streamio->writebuf_misses > 0)
415 print_buf(opaque, stream, "write efficency %.02f%%\n", (streamio->writebuf_hits / ((float)streamio->writebuf_hits + streamio->writebuf_misses)) * 100);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700416 if (bufio->filefunc64.zclose_file != NULL)
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700417 ret = bufio->filefunc64.zclose_file(bufio->filefunc64.opaque, streamio->stream);
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700418 else
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700419 ret = bufio->filefunc.zclose_file(bufio->filefunc.opaque, streamio->stream);
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700420 free(streamio);
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700421 return ret;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700422}
423
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700424int ZCALLBACK ferror_buf_func(voidpf opaque, voidpf stream)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700425{
426 ourbuffer_t *bufio = (ourbuffer_t *)opaque;
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700427 ourstream_t *streamio = (ourstream_t *)stream;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700428 if (bufio->filefunc64.zerror_file != NULL)
Nathan Moinvaziri6cae70f2012-06-28 02:02:57 -0700429 return bufio->filefunc64.zerror_file(bufio->filefunc64.opaque, streamio->stream);
430 return bufio->filefunc.zerror_file(bufio->filefunc.opaque, streamio->stream);
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700431}
432
433
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700434void fill_buffer_filefunc(zlib_filefunc_def *pzlib_filefunc_def, ourbuffer_t *ourbuf)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700435{
436 pzlib_filefunc_def->zopen_file = fopen_buf_func;
437 pzlib_filefunc_def->zopendisk_file = fopendisk_buf_func;
438 pzlib_filefunc_def->zread_file = fread_buf_func;
439 pzlib_filefunc_def->zwrite_file = fwrite_buf_func;
440 pzlib_filefunc_def->ztell_file = ftell_buf_func;
441 pzlib_filefunc_def->zseek_file = fseek_buf_func;
442 pzlib_filefunc_def->zclose_file = fclose_buf_func;
443 pzlib_filefunc_def->zerror_file = ferror_buf_func;
444 pzlib_filefunc_def->opaque = ourbuf;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700445}
446
Nathan Moinvaziriaa4758b2016-10-09 20:09:50 -0700447void fill_buffer_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def, ourbuffer_t *ourbuf)
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700448{
449 pzlib_filefunc_def->zopen64_file = fopen64_buf_func;
450 pzlib_filefunc_def->zopendisk64_file = fopendisk64_buf_func;
451 pzlib_filefunc_def->zread_file = fread_buf_func;
452 pzlib_filefunc_def->zwrite_file = fwrite_buf_func;
453 pzlib_filefunc_def->ztell64_file = ftell64_buf_func;
454 pzlib_filefunc_def->zseek64_file = fseek64_buf_func;
455 pzlib_filefunc_def->zclose_file = fclose_buf_func;
456 pzlib_filefunc_def->zerror_file = ferror_buf_func;
457 pzlib_filefunc_def->opaque = ourbuf;
Nathan Moinvaziri6aaab732012-05-06 13:04:17 -0700458}