2017-06-05 13:36:52 +08:00
|
|
|
/* ioapi_buf.c -- IO base function header for compress/uncompress .zip
|
2012-05-06 13:04:17 -07:00
|
|
|
files using zlib + zip or unzip API
|
|
|
|
|
|
|
|
This version of ioapi is designed to buffer IO.
|
|
|
|
|
2017-09-17 16:52:02 -07:00
|
|
|
Copyright (C) 2012-2017 Nathan Moinvaziri
|
|
|
|
https://github.com/nmoinvaz/minizip
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2014-01-12 14:04:54 -07:00
|
|
|
This program is distributed under the terms of the same license as zlib.
|
|
|
|
See the accompanying LICENSE file for the full text of the license.
|
2012-05-06 13:04:17 -07:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2012-06-28 02:02:57 -07:00
|
|
|
#include <stdarg.h>
|
2012-05-06 13:04:17 -07:00
|
|
|
|
|
|
|
#include "zlib.h"
|
|
|
|
#include "ioapi.h"
|
|
|
|
|
|
|
|
#include "ioapi_buf.h"
|
|
|
|
|
2017-03-04 10:06:24 -08:00
|
|
|
#ifndef IOBUF_BUFFERSIZE
|
|
|
|
# define IOBUF_BUFFERSIZE (UINT16_MAX)
|
2017-09-17 16:52:02 -07:00
|
|
|
#endif
|
2017-03-04 10:06:24 -08:00
|
|
|
|
2012-05-06 13:04:17 -07:00
|
|
|
#if defined(_WIN32)
|
2014-01-07 19:55:59 -07:00
|
|
|
# include <conio.h>
|
|
|
|
# define PRINTF _cprintf
|
|
|
|
# define VPRINTF _vcprintf
|
2012-08-06 17:53:01 -07:00
|
|
|
#else
|
2014-01-07 19:55:59 -07:00
|
|
|
# define PRINTF printf
|
|
|
|
# define VPRINTF vprintf
|
2012-05-06 13:04:17 -07:00
|
|
|
#endif
|
|
|
|
|
2012-06-29 00:00:50 -07:00
|
|
|
//#define IOBUF_VERBOSE
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2012-05-06 13:04:17 -07:00
|
|
|
#ifdef __GNUC__
|
|
|
|
#ifndef max
|
|
|
|
#define max(x,y) ({ \
|
|
|
|
const typeof(x) _x = (x); \
|
|
|
|
const typeof(y) _y = (y); \
|
|
|
|
(void) (&_x == &_y); \
|
|
|
|
_x > _y ? _x : _y; })
|
|
|
|
#endif /* __GNUC__ */
|
|
|
|
|
|
|
|
#ifndef min
|
|
|
|
#define min(x,y) ({ \
|
|
|
|
const typeof(x) _x = (x); \
|
|
|
|
const typeof(y) _y = (y); \
|
|
|
|
(void) (&_x == &_y); \
|
|
|
|
_x < _y ? _x : _y; })
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
typedef struct mz_stream_buffered_s {
|
|
|
|
mz_stream stream;
|
2016-10-09 20:09:50 -07:00
|
|
|
char readbuf[IOBUF_BUFFERSIZE];
|
|
|
|
uint32_t readbuf_len;
|
|
|
|
uint32_t readbuf_pos;
|
|
|
|
uint32_t readbuf_hits;
|
|
|
|
uint32_t readbuf_misses;
|
|
|
|
char writebuf[IOBUF_BUFFERSIZE];
|
|
|
|
uint32_t writebuf_len;
|
|
|
|
uint32_t writebuf_pos;
|
|
|
|
uint32_t writebuf_hits;
|
|
|
|
uint32_t writebuf_misses;
|
|
|
|
uint64_t position;
|
2017-09-29 21:02:09 -07:00
|
|
|
int32_t error;
|
2017-10-01 21:43:24 -07:00
|
|
|
} mz_stream_buffered;
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2012-06-29 00:00:50 -07:00
|
|
|
#if defined(IOBUF_VERBOSE)
|
2017-10-01 21:43:24 -07:00
|
|
|
# define mz_stream_buffered_print(o,s,f,...) mz_stream_buffered_print_internal(o,s,f,__VA_ARGS__);
|
2012-06-29 00:00:50 -07:00
|
|
|
#else
|
2017-10-01 21:43:24 -07:00
|
|
|
# define mz_stream_buffered_print(o,s,f,...)
|
2017-09-17 16:52:02 -07:00
|
|
|
#endif
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
void mz_stream_buffered_printinternal(voidpf stream, char *format, ...)
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
2012-06-28 02:02:57 -07:00
|
|
|
va_list arglist;
|
2017-09-29 21:02:09 -07:00
|
|
|
PRINTF("Buf stream %p - ", buffered);
|
2012-06-28 02:02:57 -07:00
|
|
|
va_start(arglist, format);
|
|
|
|
VPRINTF(format, arglist);
|
|
|
|
va_end(arglist);
|
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int32_t ZCALLBACK mz_stream_buffered_open(voidpf stream, const char *filename, int mode)
|
2012-06-25 23:42:27 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
|
|
mz_stream_buffered_print(opaque, buffered, "open [num %d mode %d]\n", number_disk, mode);
|
|
|
|
return mz_stream_open(stream, filename, mode);
|
2012-06-25 23:42:27 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int32_t mz_stream_buffered_flush(voidpf stream, uint32_t *written)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
2017-09-29 21:02:09 -07:00
|
|
|
uint32_t total_bytes_written = 0;
|
|
|
|
uint32_t bytes_to_write = buffered->writebuf_len;
|
|
|
|
uint32_t bytes_left_to_write = buffered->writebuf_len;
|
|
|
|
uint32_t bytes_written = 0;
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
*written = 0;
|
2017-09-17 16:52:02 -07:00
|
|
|
|
2016-10-09 20:09:50 -07:00
|
|
|
while (bytes_left_to_write > 0)
|
2012-07-14 16:30:48 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
bytes_written = mz_stream_write(buffered->stream.base, buffered->writebuf + (bytes_to_write - bytes_left_to_write), bytes_left_to_write);
|
2017-09-29 21:02:09 -07:00
|
|
|
if (bytes_written != bytes_left_to_write)
|
2017-10-01 21:43:24 -07:00
|
|
|
return MZ_STREAM_ERR;
|
2012-07-14 16:30:48 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->writebuf_misses += 1;
|
2012-07-14 16:30:48 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "write flush [%d:%d len %d]\n", bytes_to_write, bytes_left_to_write, buffered->writebuf_len);
|
2012-07-14 16:30:48 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
total_bytes_written += bytes_written;
|
2016-10-09 20:09:50 -07:00
|
|
|
bytes_left_to_write -= bytes_written;
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->position += bytes_written;
|
2012-07-14 16:30:48 -07:00
|
|
|
}
|
2017-09-29 21:02:09 -07:00
|
|
|
|
|
|
|
buffered->writebuf_len = 0;
|
|
|
|
buffered->writebuf_pos = 0;
|
|
|
|
|
|
|
|
*written = total_bytes_written;
|
2017-10-01 21:43:24 -07:00
|
|
|
return MZ_STREAM_OK;
|
2012-07-14 16:30:48 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int32_t ZCALLBACK mz_stream_buffered_read(voidpf stream, void *buf, uint32_t size)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
2016-10-09 20:09:50 -07:00
|
|
|
uint32_t buf_len = 0;
|
|
|
|
uint32_t bytes_to_read = 0;
|
|
|
|
uint32_t bytes_to_copy = 0;
|
|
|
|
uint32_t bytes_left_to_read = size;
|
|
|
|
uint32_t bytes_read = 0;
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "read [size %ld pos %lld]\n", size, buffered->position);
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->writebuf_len > 0)
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "switch from write to read, not yet supported [%lld]\n", buffered->position);
|
2012-07-14 16:30:48 -07:00
|
|
|
|
2016-10-09 20:09:50 -07:00
|
|
|
while (bytes_left_to_read > 0)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
if ((buffered->readbuf_len == 0) || (buffered->readbuf_pos == buffered->readbuf_len))
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->readbuf_len == IOBUF_BUFFERSIZE)
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->readbuf_pos = 0;
|
|
|
|
buffered->readbuf_len = 0;
|
2012-06-28 02:02:57 -07:00
|
|
|
}
|
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
bytes_to_read = IOBUF_BUFFERSIZE - (buffered->readbuf_len - buffered->readbuf_pos);
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
if (mz_stream_read(buffered->stream.base, buffered->readbuf + buffered->readbuf_pos, bytes_to_read) != bytes_to_read)
|
2017-09-29 21:02:09 -07:00
|
|
|
return 0;
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->readbuf_misses += 1;
|
|
|
|
buffered->readbuf_len += bytes_read;
|
|
|
|
buffered->position += bytes_read;
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "filled [read %d/%d buf %d:%d pos %lld]\n", bytes_read, bytes_to_read, buffered->readbuf_pos, buffered->readbuf_len, buffered->position);
|
2012-06-25 23:42:27 -07:00
|
|
|
|
2016-10-09 20:09:50 -07:00
|
|
|
if (bytes_read == 0)
|
2012-05-10 15:59:36 -07:00
|
|
|
break;
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
2012-06-29 00:00:50 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
if ((buffered->readbuf_len - buffered->readbuf_pos) > 0)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
bytes_to_copy = min(bytes_left_to_read, (uint32_t)(buffered->readbuf_len - buffered->readbuf_pos));
|
|
|
|
memcpy((char *)buf + buf_len, buffered->readbuf + buffered->readbuf_pos, bytes_to_copy);
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2016-10-09 20:09:50 -07:00
|
|
|
buf_len += bytes_to_copy;
|
|
|
|
bytes_left_to_read -= bytes_to_copy;
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->readbuf_hits += 1;
|
|
|
|
buffered->readbuf_pos += bytes_to_copy;
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "emptied [copied %d remaining %d buf %d:%d pos %lld]\n", bytes_to_copy, bytes_left_to_read, buffered->readbuf_pos, buffered->readbuf_len, buffered->position);
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-09 20:09:50 -07:00
|
|
|
return size - bytes_left_to_read;
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int32_t ZCALLBACK mz_stream_buffered_write(voidpf stream, const void *buf, uint32_t size)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
2016-10-09 20:09:50 -07:00
|
|
|
uint32_t bytes_to_write = size;
|
|
|
|
uint32_t bytes_left_to_write = size;
|
|
|
|
uint32_t bytes_to_copy = 0;
|
2017-09-29 21:02:09 -07:00
|
|
|
uint32_t bytes_flushed = 0;
|
2017-04-04 22:35:40 -07:00
|
|
|
int64_t ret = 0;
|
2012-05-06 13:04:17 -07:00
|
|
|
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "write [size %ld len %d pos %lld]\n", size, buffered->writebuf_len, buffered->position);
|
2012-07-14 16:30:48 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->readbuf_len > 0)
|
|
|
|
{
|
|
|
|
buffered->position -= buffered->readbuf_len;
|
|
|
|
buffered->position += buffered->readbuf_pos;
|
2012-07-14 16:30:48 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->readbuf_len = 0;
|
|
|
|
buffered->readbuf_pos = 0;
|
2012-07-14 16:30:48 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "switch from read to write [%lld]\n", buffered->position);
|
2012-07-14 16:30:48 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
if (mz_stream_seek(buffered->stream.base, buffered->position, MZ_STREAM_SEEK_SET) == MZ_STREAM_ERR)
|
|
|
|
return MZ_STREAM_ERR;
|
2012-07-14 16:30:48 -07:00
|
|
|
}
|
|
|
|
|
2016-10-09 20:09:50 -07:00
|
|
|
while (bytes_left_to_write > 0)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
bytes_to_copy = min(bytes_left_to_write, (uint32_t)(IOBUF_BUFFERSIZE - min(buffered->writebuf_len, buffered->writebuf_pos)));
|
2013-06-20 12:31:59 -07:00
|
|
|
|
2016-10-09 20:09:50 -07:00
|
|
|
if (bytes_to_copy == 0)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
if (mz_stream_buffered_flush(stream, &bytes_flushed) == MZ_STREAM_ERR)
|
|
|
|
return MZ_STREAM_ERR;
|
2017-09-29 21:02:09 -07:00
|
|
|
if (bytes_flushed == 0)
|
2012-05-10 15:59:36 -07:00
|
|
|
return 0;
|
2013-06-20 12:31:59 -07:00
|
|
|
|
|
|
|
continue;
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
2017-09-17 16:52:02 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
memcpy(buffered->writebuf + buffered->writebuf_pos, (char *)buf + (bytes_to_write - bytes_left_to_write), bytes_to_copy);
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "write copy [remaining %d write %d:%d len %d]\n", bytes_to_copy, bytes_to_write, bytes_left_to_write, buffered->writebuf_len);
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2016-10-09 20:09:50 -07:00
|
|
|
bytes_left_to_write -= bytes_to_copy;
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->writebuf_pos += bytes_to_copy;
|
|
|
|
buffered->writebuf_hits += 1;
|
|
|
|
if (buffered->writebuf_pos > buffered->writebuf_len)
|
|
|
|
buffered->writebuf_len += buffered->writebuf_pos - buffered->writebuf_len;
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
|
|
|
|
2016-10-09 20:09:50 -07:00
|
|
|
return size - bytes_left_to_write;
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int64_t mz_stream_buffered_tellinternal(voidpf stream, uint64_t position)
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->position = position;
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "tell [pos %llu readpos %d writepos %d err %d]\n", buffered->position, buffered->readbuf_pos, buffered->writebuf_pos, errno);
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->readbuf_len > 0)
|
|
|
|
position -= (buffered->readbuf_len - buffered->readbuf_pos);
|
|
|
|
if (buffered->writebuf_len > 0)
|
|
|
|
position += buffered->writebuf_pos;
|
2012-06-28 02:02:57 -07:00
|
|
|
return position;
|
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int64_t ZCALLBACK mz_stream_buffered_tell(voidpf stream)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
|
|
int64_t position = mz_stream_tell(buffered->stream.base);
|
|
|
|
return mz_stream_buffered_tellinternal(stream, position);
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int mz_stream_buffered_seekinternal(voidpf stream, uint64_t offset, int origin)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
2017-09-29 21:02:09 -07:00
|
|
|
uint32_t bytes_flushed = 0;
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "seek [origin %d offset %llu pos %lld]\n", origin, offset, buffered->position);
|
2012-06-28 02:02:57 -07:00
|
|
|
|
|
|
|
switch (origin)
|
2012-05-06 23:52:22 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
case MZ_STREAM_SEEK_SET:
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->writebuf_len > 0)
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
if ((offset >= buffered->position) && (offset <= buffered->position + buffered->writebuf_len))
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->writebuf_pos = (uint32_t)(offset - buffered->position);
|
2017-10-01 21:43:24 -07:00
|
|
|
return MZ_STREAM_OK;
|
2012-06-28 02:02:57 -07:00
|
|
|
}
|
|
|
|
}
|
2017-09-29 21:02:09 -07:00
|
|
|
if ((buffered->readbuf_len > 0) && (offset < buffered->position) && (offset >= buffered->position - buffered->readbuf_len))
|
2012-05-07 00:39:30 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->readbuf_pos = (uint32_t)(offset - (buffered->position - buffered->readbuf_len));
|
2017-10-01 21:43:24 -07:00
|
|
|
return MZ_STREAM_OK;
|
2012-05-07 00:39:30 -07:00
|
|
|
}
|
2017-09-29 21:02:09 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
if (mz_stream_buffered_flush(stream, &bytes_flushed) == MZ_STREAM_ERR)
|
|
|
|
return MZ_STREAM_ERR;
|
2017-09-29 21:02:09 -07:00
|
|
|
|
|
|
|
buffered->position = offset;
|
2012-06-28 02:02:57 -07:00
|
|
|
break;
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
case MZ_STREAM_SEEK_CUR:
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->readbuf_len > 0)
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
if (offset <= (buffered->readbuf_len - buffered->readbuf_pos))
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->readbuf_pos += (uint32_t)offset;
|
2017-10-01 21:43:24 -07:00
|
|
|
return MZ_STREAM_OK;
|
2017-09-17 16:52:02 -07:00
|
|
|
}
|
2017-09-29 21:02:09 -07:00
|
|
|
offset -= (buffered->readbuf_len - buffered->readbuf_pos);
|
|
|
|
buffered->position += offset;
|
2012-06-28 02:02:57 -07:00
|
|
|
}
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->writebuf_len > 0)
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
if (offset <= (buffered->writebuf_len - buffered->writebuf_pos))
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->writebuf_pos += (uint32_t)offset;
|
2017-10-01 21:43:24 -07:00
|
|
|
return MZ_STREAM_OK;
|
2012-06-28 02:02:57 -07:00
|
|
|
}
|
2017-09-29 21:02:09 -07:00
|
|
|
//offset -= (buffered->writebuf_len - buffered->writebuf_pos);
|
2012-06-28 02:02:57 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
if (mz_stream_buffered_flush(stream, &bytes_flushed) == MZ_STREAM_ERR)
|
|
|
|
return MZ_STREAM_ERR;
|
2012-06-28 02:02:57 -07:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
case MZ_STREAM_SEEK_END:
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->writebuf_len > 0)
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->writebuf_pos = buffered->writebuf_len;
|
2017-10-01 21:43:24 -07:00
|
|
|
return MZ_STREAM_OK;
|
2012-06-28 02:02:57 -07:00
|
|
|
}
|
|
|
|
break;
|
2012-05-06 23:52:22 -07:00
|
|
|
}
|
2012-06-28 02:02:57 -07:00
|
|
|
|
2017-09-29 21:02:09 -07:00
|
|
|
buffered->readbuf_len = 0;
|
|
|
|
buffered->readbuf_pos = 0;
|
|
|
|
buffered->writebuf_len = 0;
|
|
|
|
buffered->writebuf_pos = 0;
|
2017-10-01 21:43:24 -07:00
|
|
|
return MZ_STREAM_ERR;
|
2012-06-28 02:02:57 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int32_t ZCALLBACK mz_stream_buffered_seek(voidpf stream, uint64_t offset, int origin)
|
2012-06-28 02:02:57 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
|
|
if (mz_stream_buffered_seekinternal(stream, offset, origin) == MZ_STREAM_ERR)
|
|
|
|
return MZ_STREAM_ERR;
|
|
|
|
return mz_stream_seek(buffered->stream.base, offset, origin);
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int32_t ZCALLBACK mz_stream_buffered_close(voidpf stream)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
2017-09-29 21:02:09 -07:00
|
|
|
uint32_t bytes_flushed = 0;
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_flush(stream, &bytes_flushed);
|
|
|
|
mz_stream_buffered_print(opaque, stream, "close\n");
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->readbuf_hits + buffered->readbuf_misses > 0)
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "read efficency %.02f%%\n", (buffered->readbuf_hits / ((float)buffered->readbuf_hits + buffered->readbuf_misses)) * 100);
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered->writebuf_hits + buffered->writebuf_misses > 0)
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered_print(opaque, stream, "write efficency %.02f%%\n", (buffered->writebuf_hits / ((float)buffered->writebuf_hits + buffered->writebuf_misses)) * 100);
|
|
|
|
return mz_stream_close(&buffered->stream.base);
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
int32_t ZCALLBACK mz_stream_buffered_error(voidpf stream)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = (mz_stream_buffered *)stream;
|
|
|
|
return mz_stream_error(&buffered->stream.base);
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
voidpf mz_stream_buffered_create(voidpf *stream)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = NULL;
|
2012-05-06 13:04:17 -07:00
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
buffered = (mz_stream_buffered *)malloc(sizeof(mz_stream_buffered));
|
|
|
|
if (buffered != NULL)
|
|
|
|
{
|
|
|
|
memset(buffered, 0, sizeof(mz_stream_buffered));
|
|
|
|
|
|
|
|
buffered->stream.open = mz_stream_buffered_open;
|
|
|
|
buffered->stream.read = mz_stream_buffered_read;
|
|
|
|
buffered->stream.write = mz_stream_buffered_write;
|
|
|
|
buffered->stream.tell = mz_stream_buffered_tell;
|
|
|
|
buffered->stream.seek = mz_stream_buffered_seek;
|
|
|
|
buffered->stream.close = mz_stream_buffered_close;
|
|
|
|
buffered->stream.error = mz_stream_buffered_error;
|
|
|
|
buffered->stream.create = mz_stream_buffered_create;
|
|
|
|
buffered->stream.delete = mz_stream_buffered_delete;
|
|
|
|
}
|
|
|
|
if (stream == NULL)
|
|
|
|
*stream = buffered;
|
2017-09-29 21:02:09 -07:00
|
|
|
|
|
|
|
return (voidpf)buffered;
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|
|
|
|
|
2017-10-01 21:43:24 -07:00
|
|
|
void mz_stream_buffered_delete(voidpf *stream)
|
2012-05-06 13:04:17 -07:00
|
|
|
{
|
2017-10-01 21:43:24 -07:00
|
|
|
mz_stream_buffered *buffered = NULL;
|
|
|
|
if (stream == NULL)
|
|
|
|
return;
|
|
|
|
buffered = (mz_stream_buffered *)*stream;
|
2017-09-29 21:02:09 -07:00
|
|
|
if (buffered != NULL)
|
|
|
|
free(buffered);
|
2012-05-06 13:04:17 -07:00
|
|
|
}
|