Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Michael A. (Mike) Iovine
p1
Commits
a2f22dc5
Commit
a2f22dc5
authored
4 years ago
by
Mike Iovine
Browse files
Options
Download
Email Patches
Plain Diff
Implement myunzip
parent
ea230a0f
master
No related merge requests found
Pipeline
#30575
failed with stage
in 0 seconds
Changes
6
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
.gitignore
+1
-0
.gitignore
Makefile
+5
-2
Makefile
include/inflate.h
+4
-2
include/inflate.h
src/inflate/inflate.c
+6
-25
src/inflate/inflate.c
src/inflate/main.c
+23
-2
src/inflate/main.c
src/myunzip/myunzip.c
+89
-0
src/myunzip/myunzip.c
with
128 additions
and
31 deletions
+128
-31
.gitignore
View file @
a2f22dc5
...
...
@@ -2,3 +2,4 @@
/myunzip0
/inflate
/huffman
/myunzip
This diff is collapsed.
Click to expand it.
Makefile
View file @
a2f22dc5
all
:
myzip0 myunzip0 huffman inflate test_inflate
all
:
myzip0 myunzip0 huffman inflate test_inflate
myunzip
myzip0
:
myzip0.c
cc myzip0.c
-o
myzip0
...
...
@@ -12,9 +12,12 @@ huffman : huffman.c
inflate
:
include/inflate.h src/inflate/main.c src/inflate/inflate.c
gcc
-I
include src/inflate/main.c src/inflate/inflate.c
-o
inflate
myunzip
:
include/inflate.h src/inflate/inflate.c src/myunzip/myunzip.c
gcc
-I
include src/inflate/inflate.c src/myunzip/myunzip.c
-o
myunzip
test_inflate
:
src/inflate/inflate.c tests/inflate_test.cpp
g++
-I
include src/inflate/inflate.c tests/inflate_test.cpp
-o
test_inflate
-l
gtest
./test_inflate
clean
:
rm
myzip0 myunzip0 huffman inflate test_inflate
rm
myzip0 myunzip0 huffman inflate test_inflate
myunzip
This diff is collapsed.
Click to expand it.
include/inflate.h
View file @
a2f22dc5
#include <stdbool.h>
#ifndef _INFLATE_H_
#define _INFLATE_H_
...
...
@@ -67,11 +69,11 @@ int *read_lens(char *buf, huffman_t *hf_codes,
* Read a single block from the buffer, and write the deflated
* results to "out".
*/
void
read_block
(
char
*
buf
,
FILE
*
out
);
bool
read_block
(
char
*
buf
,
FILE
*
out
);
/*
* Inflate the file fp.
*/
void
inflate
(
FILE
*
fp
,
char
*
fname
);
void
inflate
(
FILE
*
fp
,
long
size
,
char
*
fname
);
#endif
This diff is collapsed.
Click to expand it.
src/inflate/inflate.c
View file @
a2f22dc5
...
...
@@ -283,7 +283,7 @@ int *read_lens(char *buf, huffman_t *hf_codes, int num_symbols, int num_codes) {
return
lens
;
}
void
read_block
(
char
*
buf
,
FILE
*
out
)
{
bool
read_block
(
char
*
buf
,
FILE
*
out
)
{
/* First bit is the BFINAL flag */
bool
bfinal
=
get_next_bit
(
buf
);
...
...
@@ -346,7 +346,6 @@ void read_block(char *buf, FILE *out) {
{
/* Match a huffman code */
chunk_val
=
read_chunk
(
buf
,
*
hf
);
printf
(
"%d
\n
"
,
chunk_val
);
/* Literal, just write to output buffer */
if
(
chunk_val
<
256
)
{
fwrite
(
&
chunk_val
,
1
,
sizeof
(
char
),
out
);
...
...
@@ -381,32 +380,15 @@ void read_block(char *buf, FILE *out) {
destroy_huffman
(
hf
);
destroy_huffman
(
hf_dist
);
}
}
void
truncate_suffix
(
char
*
fname
)
{
char
*
dot
=
strrchr
(
fname
,
'.'
);
const
char
*
suffix
=
".deflate"
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
if
(
dot
==
NULL
||
*
(
dot
+
i
)
!=
suffix
[
i
])
{
fprintf
(
stderr
,
"error: must be a .deflate file"
);
exit
(
1
);
}
}
*
dot
=
'\0'
;
return
bfinal
;
}
void
inflate
(
FILE
*
fp
,
char
*
fname
)
{
truncate_suffix
(
fname
);
void
inflate
(
FILE
*
fp
,
long
size
,
char
*
fname
)
{
/* Create output file */
FILE
*
out
=
fopen
(
fname
,
"wb+"
);
/* Read the file into a buffer */
fseek
(
fp
,
0
,
SEEK_END
);
long
size
=
ftell
(
fp
);
rewind
(
fp
);
char
*
buf
=
(
char
*
)
malloc
(
size
);
if
(
!
buf
)
{
fprintf
(
stderr
,
"error: memory error
\n
"
);
...
...
@@ -414,9 +396,8 @@ void inflate(FILE *fp, char *fname) {
}
fread
(
buf
,
1
,
size
,
fp
);
while
(
_CUR_BIT
<
8
*
size
)
{
read_block
(
buf
,
out
);
}
/* Read until last block */
while
(
!
read_block
(
buf
,
out
))
{}
fclose
(
out
);
free
(
buf
);
...
...
This diff is collapsed.
Click to expand it.
src/inflate/main.c
View file @
a2f22dc5
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <inflate.h>
void
truncate_suffix
(
char
*
fname
)
{
char
*
dot
=
strrchr
(
fname
,
'.'
);
const
char
*
suffix
=
".deflate"
;
for
(
int
i
=
0
;
i
<
8
;
i
++
)
{
if
(
dot
==
NULL
||
*
(
dot
+
i
)
!=
suffix
[
i
])
{
fprintf
(
stderr
,
"error: must be a .deflate file
\n
"
);
exit
(
1
);
}
}
*
dot
=
'\0'
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
!=
2
)
{
fprintf
(
stderr
,
"usage: inflate [file]
\n
"
);
...
...
@@ -18,7 +34,12 @@ int main(int argc, char *argv[]) {
return
1
;
}
inflate
(
fp
,
fname
);
fseek
(
fp
,
0
,
SEEK_END
);
long
size
=
ftell
(
fp
);
rewind
(
fp
);
truncate_suffix
(
fname
);
inflate
(
fp
,
size
,
fname
);
fclose
(
fp
);
return
0
;
...
...
This diff is collapsed.
Click to expand it.
src/myunzip/myunzip.c
0 → 100644
View file @
a2f22dc5
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <inflate.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
)
{
FILE
*
out
=
fopen
(
fname
,
"wb"
);
size
=
record
->
uncompressed_size
;
char
*
buf
=
(
char
*
)
malloc
(
size
*
sizeof
(
char
));
fread
(
buf
,
1
,
size
,
fp
);
fwrite
(
buf
,
1
,
size
,
out
);
fclose
(
out
);
}
else
if
(
record
->
compression
==
DEFLATE
)
{
inflate
(
fp
,
record
->
compressed_size
,
fname
);
}
else
{
fprintf
(
stderr
,
"error: invalid compression
\n
"
);
exit
(
1
);
}
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
;
}
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment
Menu
Projects
Groups
Snippets
Help