| 1 | #include "libtraceio.h" |
|---|
| 2 | #include <zlib.h> |
|---|
| 3 | #include <stdlib.h> |
|---|
| 4 | #include <errno.h> |
|---|
| 5 | |
|---|
| 6 | struct libtrace_io_t { |
|---|
| 7 | gzFile file; |
|---|
| 8 | }; |
|---|
| 9 | |
|---|
| 10 | ssize_t libtrace_io_read(libtrace_io_t *io, void *buf, size_t len) |
|---|
| 11 | { |
|---|
| 12 | int err=gzread(io->file,buf,(unsigned) len); |
|---|
| 13 | int err2=errno; |
|---|
| 14 | if (err>=0) { |
|---|
| 15 | /* successfully read <x> bytes */ |
|---|
| 16 | return (ssize_t)err; |
|---|
| 17 | } |
|---|
| 18 | switch(err) { |
|---|
| 19 | case Z_STREAM_END: |
|---|
| 20 | return 0; |
|---|
| 21 | case Z_ERRNO: |
|---|
| 22 | if (err2==0) |
|---|
| 23 | return 0; /* EOF */ |
|---|
| 24 | return -1; |
|---|
| 25 | case Z_MEM_ERROR: |
|---|
| 26 | errno=ENOMEM; |
|---|
| 27 | return -1; |
|---|
| 28 | default: |
|---|
| 29 | /* Some decompression error or something */ |
|---|
| 30 | errno=EINVAL; |
|---|
| 31 | return -1; |
|---|
| 32 | } |
|---|
| 33 | } |
|---|
| 34 | |
|---|
| 35 | libtrace_io_t *libtrace_io_fdopen(int fd, const char *mode) |
|---|
| 36 | { |
|---|
| 37 | libtrace_io_t *io = (libtrace_io_t*)malloc(sizeof(libtrace_io_t)); |
|---|
| 38 | if (io == NULL) |
|---|
| 39 | return NULL; |
|---|
| 40 | io->file = gzdopen(fd,mode); |
|---|
| 41 | if (!io->file) { |
|---|
| 42 | free(io); |
|---|
| 43 | return NULL; |
|---|
| 44 | } |
|---|
| 45 | return io; |
|---|
| 46 | } |
|---|
| 47 | |
|---|
| 48 | libtrace_io_t *libtrace_io_open(const char *path, const char *mode) |
|---|
| 49 | { |
|---|
| 50 | libtrace_io_t *io = (libtrace_io_t*)malloc(sizeof(libtrace_io_t)); |
|---|
| 51 | if (io == NULL) |
|---|
| 52 | return NULL; |
|---|
| 53 | io->file = gzopen(path,mode); |
|---|
| 54 | return io; |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | /* Technically close returns -1 on failure, but if the close fails, really |
|---|
| 58 | * what are you going to do about it? |
|---|
| 59 | */ |
|---|
| 60 | void libtrace_io_close(libtrace_io_t *io) |
|---|
| 61 | { |
|---|
| 62 | (void)gzclose(io->file); |
|---|
| 63 | io->file=NULL; |
|---|
| 64 | free(io); |
|---|
| 65 | } |
|---|
| 66 | |
|---|
| 67 | ssize_t libtrace_io_write(libtrace_io_t *io, const void *buf, size_t len) |
|---|
| 68 | { |
|---|
| 69 | /* gzip doesn't like writing 0 bytes - tends to break the |
|---|
| 70 | * crc calculations */ |
|---|
| 71 | if (len == 0) |
|---|
| 72 | return 0; |
|---|
| 73 | return (ssize_t)gzwrite(io->file,buf,(unsigned)len); |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | off_t libtrace_io_seek(libtrace_io_t *io, off_t offset, int whence) |
|---|
| 77 | { |
|---|
| 78 | return gzseek(io->file,offset,whence); |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | ssize_t libtrace_io_tell(libtrace_io_t *io) |
|---|
| 82 | { |
|---|
| 83 | return (ssize_t)gztell(io->file); |
|---|
| 84 | } |
|---|