Skip to content

Commit

Permalink
Add zip_entry_(f)read (madler#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
kuba-- authored Feb 18, 2017
1 parent c02431f commit 5f6e4a8
Show file tree
Hide file tree
Showing 7 changed files with 471 additions and 142 deletions.
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/build/
/xcodeproj/

# Object files
*.o
*.ko
Expand Down Expand Up @@ -29,6 +32,6 @@
*.x86_64
*.hex

/build/

# Temporary
*.swp
.DS_Store
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ compiler:
script:
- mkdir build
- cd build
- cmake .. && make
- cmake .. && make && make test
10 changes: 9 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ if (MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
endif (MSVC)

# libzip
set(SRC src/miniz.h src/zip.h src/zip.c)

add_library(${CMAKE_PROJECT_NAME} ${SRC})

# zip_test
add_executable(zip_test test/main.c)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
target_link_libraries(zip_test ${CMAKE_PROJECT_NAME})

enable_testing()
add_test(NAME zip_test COMMAND zip_test)
155 changes: 108 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
### A portable (OSX/Linux/Windows), simple zip library written in C
### A portable (OSX/Linux/Windows), simple zip library written in C
This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library and layering functions on top of the miniz v1.15 API.

[![Codacy Badge](https://api.codacy.com/project/badge/Grade/d70fb0b050b74ef7aed70087e377e7d7)](https://www.codacy.com/app/kuba--/zip?utm_source=github.com&utm_medium=referral&utm_content=kuba--/zip&utm_campaign=Badge_Grade)
Expand All @@ -10,67 +10,128 @@ This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library
[osx-linux-badge]: https://img.shields.io/travis/kuba--/zip/master.svg?label=linux/osx "Travis CI build status"
[osx-linux-link]: https://travis-ci.org/kuba--/zip "Travis CI build status"

# The Idea
<img src="zip.png" name="zip" />
# The Idea
<img src="zip.png" name="zip" />
... Some day, I was looking for zip library written in C for my project, but I could not find anything simple enough and lightweight.
Everything what I tried required 'crazy mental gymnastics' to integrate or had some limitations or was too heavy.
I hate frameworks, factories and adding new dependencies. If I must to install all those dependencies and link new library, I'm getting almost sick.
I wanted something powerfull and small enough, so I could add just a few files and compile them into my project.
And finally I found miniz.
Everything what I tried required 'crazy mental gymnastics' to integrate or had some limitations or was too heavy.
I hate frameworks, factories and adding new dependencies. If I must to install all those dependencies and link new library, I'm getting almost sick.
I wanted something powerfull and small enough, so I could add just a few files and compile them into my project.
And finally I found miniz.
Miniz is a lossless, high performance data compression library in a single source file. I only needed simple interface to append buffers or files to the current zip-entry. Thanks to this feature I'm able to merge many files/buffers and compress them on-the-fly.

It was the reason, why I decided to write zip module on top of the miniz. It required a little bit hacking and wrapping some functions, but I kept simplicity. So, you can grab these 3 files and compile them into your project. I hope that interface is also extremely simple, so you will not have any problems to understand it.

# Example
### Example (compress)

```c
#include <stdio.h>
#include <string.h>

#include "zip.h"
#include <zip.h>

int main() {
/*
Create a new zip archive with default compression level (6)
*/
struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
// we should check if zip is NULL and if any other function returned < 0
{
zip_entry_open(zip, "foo-1.txt");
{
char *buf = "Some data here...";
zip_entry_write(zip, buf, strlen(buf));
}
zip_entry_close(zip);

zip_entry_open(zip, "foo-2.txt");
{
// merge 3 files into one entry and compress them on-the-fly.
zip_entry_fwrite(zip, "foo-2.1.txt");
zip_entry_fwrite(zip, "foo-2.2.txt");
zip_entry_fwrite(zip, "foo-2.3.txt");
}
zip_entry_close(zip);
}
// always remember to close and release resources
zip_close(zip);

/*
Append to existing zip archive
*/
zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
// we should check if zip is NULL
{
zip_entry_open(zip, "foo-3.txt");
{
char *buf = "Append some data here...";
zip_entry_write(zip, buf, strlen(buf));
}
zip_entry_close(zip);
}
// always remember to close and release resources
zip_close(zip);

return 0;
}
```

### Example (decompress)

```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <zip.h>

// callback function
int on_extract_entry(const char *filename, void *arg) {
static int i = 0;
int n = *(int *)arg;
printf("Extracted: %s (%d of %d)\n", filename, ++i, n);
static int i = 0;
int n = *(int *)arg;
printf("Extracted: %s (%d of %d)\n", filename, ++i, n);

return 0;
return 0;
}

int main() {
/*
Create a new zip archive with default compression level (6)
*/
struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 0);
// we should check if zip is NULL
{
zip_entry_open(zip, "foo-1.txt");
{
char *buf = "Some data here...";
zip_entry_write(zip, buf, strlen(buf));
}
zip_entry_close(zip);

zip_entry_open(zip, "foo-2.txt");
{
// merge 3 files into one entry and compress them on-the-fly.
zip_entry_fwrite(zip, "foo-2.1.txt");
zip_entry_fwrite(zip, "foo-2.2.txt");
zip_entry_fwrite(zip, "foo-2.3.txt");
}
zip_entry_close(zip);
}
// always remember to close and release resources
zip_close(zip);

/*
Extract a zip archive into /tmp folder
*/
int arg = 2;
zip_extract("foo.zip", "/tmp", on_extract_entry, &arg);

return 0;
/*
Extract the zip archive into /tmp folder
*/
int arg = 2;
zip_extract("foo.zip", "/tmp", on_extract_entry, &arg);

/*
...or open the zip archive with only read access
*/
void *buf = NULL;
size_t bufsize;

struct zip_t *zip = zip_open("foo.zip", 0, 'r');
// we should check if zip is NULL and if any other function returned < 0
{
zip_entry_open(zip, "foo-1.txt");
{
// extract into memory
zip_entry_read(zip, &buf, &bufsize);
printf("Read(foo-1.txt): %zu bytes: %.*s\n", bufsize, (int)bufsize,
buf);
}
zip_entry_close(zip);

zip_entry_open(zip, "foo-2.txt");
{
// extract into a file
zip_entry_fread(zip, "foo-2.txt");
}
zip_entry_close(zip);
}
// always remember to close and release resources
zip_close(zip);

// do something with buffer... and remember to free memory
free(buf);

return 0;
}
```
Loading

0 comments on commit 5f6e4a8

Please sign in to comment.