There was a problem fetching linked pipelines.
Commit 46617ce3 authored by Mike Iovine's avatar Mike Iovine
Browse files

Implement task 1.2 myunzip0

parent 804e1e19
No related merge requests found
Pipeline #29968 failed with stage
in 0 seconds
Showing with 89 additions and 0 deletions
+89 -0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
struct file_record {
uint32_t signature;
uint16_t version;
uint16_t flag;
uint16_t compression;
uint16_t mod_time;
uint16_t mod_date;
uint32_t crc32;
uint32_t compressed_size;
uint32_t uncompressed_size;
uint16_t file_name_len;
uint16_t extra_len;
}
/* Don't pad this struct, i.e. guaranteed that sizeof(struct file_record) =
* sum of the sizes of its elements. This makes the code a bit nicer;
* we can just fread() the first sizeof(struct file_record) bytes in the
* file directly into the struct.
*/
__attribute__((packed));
typedef struct file_record file_record_t;
const int UNCOMPRESSED = 0;
const int DEFLATE = 8;
void unzip(FILE *fp) {
file_record_t *record = (file_record_t *) malloc(sizeof(file_record_t));
if (!record) {
fprintf(stderr, "error: memory error\n");
exit(1);
}
/* Read metadata */
fread(record, 1, sizeof(file_record_t), fp);
char *fname = (char *) malloc(record->file_name_len);
fread(fname, 1, record->file_name_len, fp);
/* Move pointer to start of file data */
fseek(fp, record->extra_len, SEEK_CUR);
int size;
if (record->compression == UNCOMPRESSED) {
size = record->uncompressed_size;
} else if (record->compression == DEFLATE) {
size = record->compressed_size;
strcat(fname, ".deflate");
} else {
fprintf(stderr, "error: invalid compression\n");
exit(1);
}
FILE *out = fopen(fname, "wb");
/* TODO is there a better way to do this?
* worried about storing a huge buffer for large files... */
char *buf = (char *) malloc(size * sizeof(char));
fread(buf, 1, size, fp);
fwrite(buf, 1, size, out);
fclose(out);
free(record);
}
int main(int argc, char *argv[]) {
FILE *fp;
if (argc != 2) {
fprintf(stderr, "usage: myunzip0 [filename]\n");
return 1;
}
fp = fopen(argv[1], "rb");
if (!fp) {
fprintf(stderr, "error: no such file\n");
return 1;
}
unzip(fp);
fclose(fp);
return 0;
}
File added
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment