Commit af20c8c87ba9b1c80ba02190393be183cf454719

Authored by Imanol-Mikel Barba Sabariego
1 parent 3f906bc9

Moved decompression function outside and changed it to work with buffers. Added compression function

compression.c 0 → 100644
  1 +#include "compression.h"
  2 +
  3 +ssize_t inflateGzip(void* compData, size_t compDataLen, void** unCompData) {
  4 + unsigned int increase = compDataLen/2;
  5 + unsigned int uncompLength = compDataLen; // Later to be increased
  6 +
  7 + char* uncomp = (char*)calloc(uncompLength, sizeof(char));
  8 +
  9 + z_stream strm;
  10 + strm.next_in = (Bytef*) compData;
  11 + strm.avail_in = compDataLen;
  12 + strm.total_out = 0;
  13 + strm.zalloc = Z_NULL;
  14 + strm.zfree = Z_NULL;
  15 +
  16 + if (inflateInit2(&strm, (16+MAX_WBITS)) != Z_OK) {
  17 + fprintf(stderr, "Unable to initialize zlib zstream for decompression\n");
  18 + free(uncomp);
  19 + return -1;
  20 + }
  21 +
  22 + int err = Z_OK;
  23 + do {
  24 + // If our output buffer is too small
  25 + if(strm.total_out >= uncompLength ) {
  26 + // Increase size of output buffer
  27 + void* newptr = realloc(uncomp,uncompLength + increase);
  28 + if(newptr == NULL) {
  29 + fprintf(stderr,"Unable to request memory realloc\n");
  30 + inflateEnd(&strm);
  31 + free(uncomp);
  32 + return -2;
  33 + }
  34 + uncomp = newptr;
  35 + uncompLength += increase;
  36 + }
  37 +
  38 + strm.next_out = (Bytef *) (uncomp + strm.total_out);
  39 + strm.avail_out = uncompLength - strm.total_out;
  40 +
  41 + // Inflate another chunk.
  42 + err = inflate (&strm, Z_SYNC_FLUSH);
  43 + if(err != Z_OK && err != Z_STREAM_END) {
  44 + fprintf(stderr, "zlib error: %d.\n", err);
  45 + inflateEnd(&strm);
  46 + free(uncomp);
  47 + return -3;
  48 + }
  49 + } while(err != Z_STREAM_END);
  50 + uncompLength = strm.total_out;
  51 +
  52 + if(inflateEnd(&strm) != Z_OK) {
  53 + fprintf(stderr,"Error while deallocating libz zstream\n");
  54 + free(uncomp);
  55 + return -4;
  56 + }
  57 +
  58 + *unCompData = uncomp;
  59 + return uncompLength;
  60 +}
  61 +
  62 +ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData) {
  63 + unsigned int compLength = unCompDataLen;
  64 + unsigned int increase = compLength/4;
  65 + char* comp = (char*)calloc(compLength, sizeof(char));
  66 +
  67 + z_stream strm;
  68 + strm.next_in = (Bytef*) unCompData;
  69 + strm.avail_in = unCompDataLen;
  70 + strm.total_out = 0;
  71 + strm.zalloc = Z_NULL;
  72 + strm.zfree = Z_NULL;
  73 +
  74 + if(deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, (16+MAX_WBITS),8 , Z_DEFAULT_STRATEGY) != Z_OK) {
  75 + fprintf(stderr, "Unable to initialize zlib zstream for compression\n");
  76 + free(comp);
  77 + return -1;
  78 + }
  79 +
  80 + int err = Z_OK;
  81 + do {
  82 + // If our output buffer is too small
  83 + if (strm.total_out >= compLength) {
  84 + // Increase size of output buffer
  85 + void* newptr = realloc(comp, compLength + increase);
  86 + if(newptr == NULL) {
  87 + fprintf(stderr,"Unable to request memory realloc\n");
  88 + deflateEnd(&strm);
  89 + free(comp);
  90 + return -2;
  91 + }
  92 + comp = newptr;
  93 + compLength += increase;
  94 + }
  95 +
  96 + strm.next_out = (Bytef*) (comp + strm.total_out);
  97 + strm.avail_out = compLength - strm.total_out;
  98 +
  99 + // deflate another chunk
  100 + err = deflate(&strm, Z_FINISH);
  101 + if(err != Z_OK && err != Z_STREAM_END) {
  102 + fprintf(stderr, "Error while deflating buffer\n");
  103 + deflateEnd(&strm);
  104 + free(comp);
  105 + return -3;
  106 + }
  107 + } while(err != Z_STREAM_END);
  108 + compLength = strm.total_out;
  109 +
  110 + if(deflateEnd(&strm) != Z_OK) {
  111 + fprintf(stderr,"Error while deallocating libz zstream\n");
  112 + free(comp);
  113 + return -4;
  114 + }
  115 +
  116 + // Set OS Flag to 0x00: "FAT filesystem (MS-DOS, OS/2, NT/Win32)"
  117 + comp[OS_FLAG_OFFSET] = 0x00;
  118 +
  119 + *compData = comp;
  120 + return compLength;
  121 +}
0 122 \ No newline at end of file
... ...
compression.h 0 → 100644
  1 +#ifndef _COMPRESSION_H
  2 +#define _COMPRESSION_H
  3 +
  4 +#include <stdlib.h>
  5 +#include <zlib.h>
  6 +#include <stdio.h>
  7 +
  8 +#define OS_FLAG_OFFSET 0x9
  9 +
  10 +ssize_t deflateGzip(void* unCompData, size_t unCompDataLen, void** compData);
  11 +ssize_t inflateGzip(void* compData, size_t compDataLen, void** unCompData);
  12 +
  13 +#endif
0 14 \ No newline at end of file
... ...
1 1 #include "nbt.h"
  2 +#include "compression.h"
  3 +#include "chunk.h"
2 4  
3 5 ssize_t loadDB(const char* filename, void** data);
4 6 void destroyTag(Tag* t);
... ... @@ -26,67 +28,31 @@ ssize_t loadDB(const char* filename, void** data) {
26 28 }
27 29 fstat(fd, &sb);
28 30  
29   - uint16_t header = 0;
30   - if(pread(fd,&header,sizeof(uint16_t),0) == -1) {
31   - perror("Unable to read header");
32   - close(fd);
33   - return -3;
34   - }
35   -
36 31 void* filedata;
37 32 ssize_t filesize = sb.st_size;
38 33  
39   - if(header == GZIP_MAGIC) {
40   - close(fd);
41   - filedata = calloc(GZIP_BUFFER,sizeof(char));
42   - gzFile file = gzopen(filename,"r");
43   - if(!file) {
44   - perror("Failed to gzopen() file");
45   - free(filedata);
46   - return -4;
47   - }
48   - int err;
49   - int nRead;
50   - size_t totalBytes = 0;
51   - while((nRead = gzread(file, filedata+totalBytes, GZIP_BUFFER)) != 0) {
52   - totalBytes += nRead;
53   - if(!(totalBytes % GZIP_BUFFER)) {
54   - void* newptr = realloc(filedata,totalBytes + GZIP_BUFFER);
55   - if(newptr == NULL) {
56   - perror("Unable to realloc for decompression");
57   - gzclose(file);
58   - free(filedata);
59   - return -6;
60   - }
61   - filedata = newptr;
62   - }
63   - }
64   - if(!gzeof(file)) {
65   - const char * errorStr;
66   - errorStr = gzerror(file, &err);
67   - fprintf(stderr, "libz error: %s.\n", errorStr);
68   - gzclose(file);
69   - free(filedata);
70   - return -5;
71   - }
72   - filesize = totalBytes;
73   - gzclose (file);
74   - } else {
75   - filedata = malloc(filesize);
76   - ssize_t nRead = 0;
77   - size_t totalRead = 0;
78   -
79   - while((nRead = read(fd,filedata+totalRead,filesize-totalRead))) {
80   - if(nRead == -1) {
81   - if(errno == EINTR) {
82   - continue;
83   - }
84   - perror("Error reading file");
85   - return -7;
  34 + filedata = malloc(filesize);
  35 + ssize_t nRead = 0;
  36 + size_t totalRead = 0;
  37 +
  38 + while((nRead = read(fd,filedata+totalRead,filesize-totalRead))) {
  39 + if(nRead == -1) {
  40 + if(errno == EINTR) {
  41 + continue;
86 42 }
87   - totalRead += nRead;
  43 + perror("Error reading file");
  44 + return -7;
88 45 }
  46 + totalRead += nRead;
89 47 }
  48 +
  49 + if(*(uint16_t*)filedata == GZIP_MAGIC) {
  50 + void* decompressedFileData;
  51 + filesize = inflateGzip(filedata,filesize,&decompressedFileData);
  52 + free(filedata);
  53 + filedata = decompressedFileData;
  54 + }
  55 +
90 56 *data = filedata;
91 57 return filesize;
92 58 }
... ... @@ -190,6 +156,12 @@ unsigned int parseCompound(void* addr, TagCompound* tc) {
190 156 pos += parseTag(pos,&list[numTags]);
191 157 } while(list[numTags++].type != TAG_END);
192 158  
  159 + void* newptr = reallocarray(list, numTags, sizeof(Tag));
  160 + if(!newptr) {
  161 + fprintf(stderr,"Unable to request memory realloc\n");
  162 + }
  163 + list = newptr;
  164 +
193 165 tc->list = list;
194 166 tc->numTags = numTags-1;
195 167 return pos - addr;
... ...