A portable, simple zip library written in C

Overview

A portable (OSX/Linux/Windows), simple zip library written in C

This is done by hacking awesome miniz library and layering functions on top of the miniz v1.15 API.

Build

The Idea

... 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. 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.

Examples

  • Create a new zip archive with default compression level.
struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
{
    zip_entry_open(zip, "foo-1.txt");
    {
        const char *buf = "Some data here...\0";
        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);
}
zip_close(zip);
  • Append to the existing zip archive.
struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
{
    zip_entry_open(zip, "foo-3.txt");
    {
        const char *buf = "Append some data here...\0";
        zip_entry_write(zip, buf, strlen(buf));
    }
    zip_entry_close(zip);
}
zip_close(zip);
  • Extract a zip archive into a folder.
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);

    return 0;
}

int arg = 2;
zip_extract("foo.zip", "/tmp", on_extract_entry, &arg);
  • Extract a zip entry into memory.
void *buf = NULL;
size_t bufsize;

struct zip_t *zip = zip_open("foo.zip", 0, 'r');
{
    zip_entry_open(zip, "foo-1.txt");
    {
        zip_entry_read(zip, &buf, &bufsize);
    }
    zip_entry_close(zip);
}
zip_close(zip);

free(buf);
  • Extract a zip entry into memory (no internal allocation).
unsigned char *buf;
size_t bufsize;

struct zip_t *zip = zip_open("foo.zip", 0, 'r');
{
    zip_entry_open(zip, "foo-1.txt");
    {
        bufsize = zip_entry_size(zip);
        buf = calloc(sizeof(unsigned char), bufsize);

        zip_entry_noallocread(zip, (void *)buf, bufsize);
    }
    zip_entry_close(zip);
}
zip_close(zip);

free(buf);
  • Extract a zip entry into memory using callback.
struct buffer_t {
    char *data;
    size_t size;
};

static size_t on_extract(void *arg, unsigned long long offset, const void *data, size_t size) {
    struct buffer_t *buf = (struct buffer_t *)arg;
    buf->data = realloc(buf->data, buf->size + size + 1);
    assert(NULL != buf->data);

    memcpy(&(buf->data[buf->size]), data, size);
    buf->size += size;
    buf->data[buf->size] = 0;

    return size;
}

struct buffer_t buf = {0};
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
{
    zip_entry_open(zip, "foo-1.txt");
    {
        zip_entry_extract(zip, on_extract, &buf);
    }
    zip_entry_close(zip);
}
zip_close(zip);

free(buf.data);
  • Extract a zip entry into a file.
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
{
    zip_entry_open(zip, "foo-2.txt");
    {
        zip_entry_fread(zip, "foo-2.txt");
    }
    zip_entry_close(zip);
}
zip_close(zip);
  • List of all zip entries
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
int i, n = zip_total_entries(zip);
for (i = 0; i < n; ++i) {
    zip_entry_openbyindex(zip, i);
    {
        const char *name = zip_entry_name(zip);
        int isdir = zip_entry_isdir(zip);
        unsigned long long size = zip_entry_size(zip);
        unsigned int crc32 = zip_entry_crc32(zip);
    }
    zip_entry_close(zip);
}
zip_close(zip);
  • Compress folder (recursively)
void zip_walk(struct zip_t *zip, const char *path) {
    DIR *dir;
    struct dirent *entry;
    char fullpath[MAX_PATH];
    struct stat s;

    memset(fullpath, 0, MAX_PATH);
    dir = opendir(path);
    assert(dir);

    while ((entry = readdir(dir))) {
      // skip "." and ".."
      if (!strcmp(entry->d_name, ".\0") || !strcmp(entry->d_name, "..\0"))
        continue;

      snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
      stat(fullpath, &s);
      if (S_ISDIR(s.st_mode))
        zip_walk(zip, fullpath);
      else {
        zip_entry_open(zip, fullpath);
        zip_entry_fwrite(zip, fullpath);
        zip_entry_close(zip);
      }
    }

    closedir(dir);
}

Bindings

Compile zip library as a dynamic library.

$ mkdir build
$ cd build
$ cmake -DBUILD_SHARED_LIBS=true ..
$ make

Go (cgo)

package main

/*
#cgo CFLAGS: -I../src
#cgo LDFLAGS: -L. -lzip
#include <zip.h>
*/
import "C"
import "unsafe"

func main() {
	path := C.CString("/tmp/go.zip")
	zip := C.zip_open(path, 6, 'w')

	entryname := C.CString("test")
	C.zip_entry_open(zip, entryname)

	content := "test content"
	buf := unsafe.Pointer(C.CString(content))
	bufsize := C.size_t(len(content))
	C.zip_entry_write(zip, buf, bufsize)

	C.zip_entry_close(zip)

	C.zip_close(zip)
}

Rust (ffi)

extern crate libc;
use std::ffi::CString;

#[repr(C)]
pub struct Zip {
    _private: [u8; 0],
}

#[link(name = "zip")]
extern "C" {
    fn zip_open(path: *const libc::c_char, level: libc::c_int, mode: libc::c_char) -> *mut Zip;
    fn zip_close(zip: *mut Zip) -> libc::c_void;

    fn zip_entry_open(zip: *mut Zip, entryname: *const libc::c_char) -> libc::c_int;
    fn zip_entry_close(zip: *mut Zip) -> libc::c_int;
    fn zip_entry_write(
        zip: *mut Zip,
        buf: *const libc::c_void,
        bufsize: libc::size_t,
    ) -> libc::c_int;
}

fn main() {
    let path = CString::new("/tmp/rust.zip").unwrap();
    let mode: libc::c_char = 'w' as libc::c_char;

    let entryname = CString::new("test.txt").unwrap();
    let content = "test content\0";

    unsafe {
        let zip: *mut Zip = zip_open(path.as_ptr(), 5, mode);
        {
            zip_entry_open(zip, entryname.as_ptr());
            {
                let buf = content.as_ptr() as *const libc::c_void;
                let bufsize = content.len() as libc::size_t;
                zip_entry_write(zip, buf, bufsize);
            }
            zip_entry_close(zip);
        }
        zip_close(zip);
    }
}

Ruby (ffi)

Install ffi gem.

$ gem install ffi

Bind in your module.

require 'ffi'

module Zip
  extend FFI::Library
  ffi_lib "./libzip.#{::FFI::Platform::LIBSUFFIX}"

  attach_function :zip_open, [:string, :int, :char], :pointer
  attach_function :zip_close, [:pointer], :void

  attach_function :zip_entry_open, [:pointer, :string], :int
  attach_function :zip_entry_close, [:pointer], :void
  attach_function :zip_entry_write, [:pointer, :string, :int], :int
end

ptr = Zip.zip_open("/tmp/ruby.zip", 6, "w".bytes()[0])

status = Zip.zip_entry_open(ptr, "test")

content = "test content"
status = Zip.zip_entry_write(ptr, content, content.size())

Zip.zip_entry_close(ptr)
Zip.zip_close(ptr)

Python (cffi)

Install cffi package

$ pip install cffi

Bind in your package.

import ctypes.util
from cffi import FFI

ffi = FFI()
ffi.cdef("""
    struct zip_t *zip_open(const char *zipname, int level, char mode);
    void zip_close(struct zip_t *zip);

    int zip_entry_open(struct zip_t *zip, const char *entryname);
    int zip_entry_close(struct zip_t *zip);
    int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize);
""")

Zip = ffi.dlopen(ctypes.util.find_library("zip"))

ptr = Zip.zip_open("/tmp/python.zip", 6, 'w')

status = Zip.zip_entry_open(ptr, "test")

content = "test content"
status = Zip.zip_entry_write(ptr, content, len(content))

Zip.zip_entry_close(ptr)
Zip.zip_close(ptr)

Never (ffi)

extern "libzip.so" func zip_open(zipname: string, level: int, mode: char) -> c_ptr
extern "libzip.so" func zip_close(zip: c_ptr) -> void

extern "libzip.so" func zip_entry_open(zip: c_ptr, entryname: string) -> int
extern "libzip.so" func zip_entry_close(zip: c_ptr) -> int
extern "libzip.so" func zip_entry_write(zip: c_ptr, buf: string, bufsize: int) -> int
extern "libzip.so" func zip_entry_fwrite(zip: c_ptr, filename: string) -> int

func main() -> int
{
    let content = "Test content"

    let zip = zip_open("/tmp/never.zip", 6, 'w');

    zip_entry_open(zip, "test.file");
    zip_entry_fwrite(zip, "/tmp/test.txt");
    zip_entry_close(zip);

    zip_entry_open(zip, "test.content");
    zip_entry_write(zip, content, length(content));
    zip_entry_close(zip);

    zip_close(zip);
    0
}

Ring

The language comes with RingZip based on this library

load "ziplib.ring"

new Zip {
    setFileName("myfile.zip")
    open("w")
    newEntry() {
        open("test.c")
        writefile("test.c")
        close()
    }
    close()
}

Check out more cool projects which use this library:

  • Filament: Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows, and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
  • Hermes JS Engine: Hermes is a JavaScript engine optimized for fast start-up of React Native apps on Android. It features ahead-of-time static optimization and compact bytecode.
  • Open Asset Import Library: A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
  • PowerToys: Set of utilities for power users to tune and streamline their Windows 10 experience for greater productivity.
  • The Ring Programming Language: Innovative and practical general-purpose multi-paradigm language.
  • The V Programming Language: Simple, fast, safe, compiled. For developing maintainable software.
  • TIC-80: TIC-80 is a FREE and OPEN SOURCE fantasy computer for making, playing and sharing tiny games.
  • Urho3D: Urho3D is a free lightweight, cross-platform 2D and 3D game engine implemented in C++ and released under the MIT license. Greatly inspired by OGRE and Horde3D.
  • Vcpkg: Vcpkg helps you manage C and C++ libraries on Windows, Linux and MacOS.
  • and more...
Issues
  • zip_extract doesn't work if not on main OS drive?

    zip_extract doesn't work if not on main OS drive?

    I'm using this lib in a Qt app and everything works as expected until I move the app to another drive. This line of code works as expected if the application resides on C (the main drive where the OS is installed). Moving it to somewhere like F and nothing gets extracted.

    zip_extract(input_filename, temporary_dir, nullptr, nullptr);
    

    In my test case, input_filename is also on C and temporary_dir is a folder created in the temp directory (also on C). I'm using MSVC 2017 on Windows 10. Even running as admin I get the same issue.

    bug help wanted windows 
    opened by iKlsR 22
  • MinGW fails compilation

    MinGW fails compilation

    Reproducing on windows 10:

    1. Install MinGW-get from https://osdn.net/projects/mingw/releases/p15522
    2. Add the mingw32-base-bin and mingw-gcc-g++-bin packages.
    3. Install cmake.
    4. Add C:\MinGW\bin to path.
    5. mkdir build, cmake .. -G "MinGW Makefiles", cmake --build . error.log

    Relevant MinGW header: (https://sourceforge.net/p/mingw/mingw-org-wsl/ci/21762bb4a1bd0c88c38eead03f59e8d994349e83/tree/include/sys/types.h)

    MinGW doesn't use any defines to indicate ssize_t has been declared. I suggest we detect MinGW directly. After adding a check for MINGW32 before the ssize_t typedef, it compiles and passes mingw32-make test. patch.txt I'll create a PR if this looks OK.

    windows 
    opened by nick-dumas 20
  •  zip_entry_fwrite(zip,

    zip_entry_fwrite(zip, "foo-2.1.txt") fails for big sizes

    Writing a zip archive fails when trying to zip big files.

    When running in Debug, i get this assertion: miniz.h:3025: tdefl_compress_lz_codes: Assertion `d->m_huff_code_sizes[1][sym]' failed.

    bug help wanted 
    opened by ForgottenTales 15
  • Properly handling files in use and zero-bytes files.

    Properly handling files in use and zero-bytes files.

    If a file is in use, the zip_entry_fwrite will return ZIP_EWRTDIR -15 In that case, the file is actually created in the zip archive but with 0 bytes in size. So how to handle this situation? I tried calling zip_entry_close then zip_entries_delete and I got return value of 1 which means the file with 0 bytes is deleted. However, the next call to zip_entry_open/zip_entry_fwrite/zip_entry_closewill crash the application. Precisely the call to zip_entry_closein the sequence above. zip_open is called with 'w' flag. Is this a bug?

    question 
    opened by RCECoder 14
  • Add delete entry function

    Add delete entry function

    @kuba-- I have implemented the entry deletion function. The idea is to obtain the offset and data length of every file data in the ZIP file first, then move the data behind the deleted entry forward to overwrite the deleted data, and in the end truncate the invalid data at the end of the ZIP file. The case of deleting one folder (multiple files) at a time is considered in the implementation.

    opened by jinfeihan57 14
  • Update CMake files with Config install and some cleanup

    Update CMake files with Config install and some cleanup

    I want to add this package to the Hunter package manager: https://github.com/ruslo/hunter

    To do so, we need to export the library target in the modern CMake fashion. No Hunter-specific changes need to be made since the library has no dependencies.

    This line install(FILES ${PROJECT_SOURCE_DIR}/src/zip.h DESTINATION ${INCLUDE_INSTALL_DIR}/zip) means that library consumers need to include #include <zip/zip.h> which avoids conflicts with other libraries that may use the same filename (zip.h).

    opened by rbsheth 13
  • Attempting to build from source. No Make file

    Attempting to build from source. No Make file

    This command seems to succeed. cmake -DBUILD_SHARED_LIBS=true ..

    Attempting to call make after results in make: *** No targets specified and no makefile found. Stop.

    opened by seitzcasey 12
  • zip doesn't compile on 32b system with GCC 9.2.0

    zip doesn't compile on 32b system with GCC 9.2.0

    Trying to compile assimp for Alpine Linux on 32bit platforms and there seems to be an issue with ssize_t decleration:

    [ 62%] Building CXX object code/CMakeFiles/assimp.dir/__/contrib/poly2tri/poly2tri/sweep/cdt.cc.o
    In file included from /home/buildozer/aports/testing/assimp/src/assimp-5.0.0/code/3MF/D3MFExporter.cpp:61:
    /home/buildozer/aports/testing/assimp/src/assimp-5.0.0/contrib/zip/src/zip.h:30:15: error: conflicting declaration 'typedef long int ssize_t'
       30 | typedef long  ssize_t;  /* byte count or error */
          |               ^~~~~~~
    In file included from /usr/include/stdio.h:26,
                     from /usr/include/fortify/stdio.h:22,
                     from /usr/include/c++/9.2.0/cstdio:42,
                     from /usr/include/c++/9.2.0/ext/string_conversions.h:43,
                     from /usr/include/c++/9.2.0/bits/basic_string.h:6493,
                     from /usr/include/c++/9.2.0/string:55,
                     from /usr/include/c++/9.2.0/stdexcept:39,
                     from /usr/include/c++/9.2.0/array:39,
                     from /usr/include/c++/9.2.0/tuple:39,
                     from /usr/include/c++/9.2.0/bits/unique_ptr.h:37,
                     from /usr/include/c++/9.2.0/memory:80,
                     from /home/buildozer/aports/testing/assimp/src/assimp-5.0.0/code/3MF/D3MFExporter.h:44,
                     from /home/buildozer/aports/testing/assimp/src/assimp-5.0.0/code/3MF/D3MFExporter.cpp:45:
    /usr/include/bits/alltypes.h:151:15: note: previous declaration as 'typedef int ssize_t'
      151 | typedef _Addr ssize_t;
          |               ^~~~~~~
    

    CI output might be of interest: https://cloud.drone.io/alpinelinux/aports/13069 and AL PR https://github.com/alpinelinux/aports/pull/11998

    I posted this to https://github.com/assimp/assimp/issues/2733 as well.

    bug 
    opened by russkel 12
  • supply buffer to read function

    supply buffer to read function

    I'm working with a memory managed system (Matlab) and was wondering if it would be possible to have the following functions:

    1. extern size_t *zip_entry_size(struct zip_t *zip) - return the # of bytes of the current entry
    2. extern int zip_entry_read2(struct zip_t *zip, void *buf, size_t bufsize) -User passes in the buffer, the bufsize here is the size of the input buffer ...

    The alternative, which is ok for now, is to memcpy after reading, but I'd prefer to avoid this.

    enhancement 
    opened by JimHokanson 12
  • Add support for wide characters.

    Add support for wide characters.

    There are potential issues while using this lib on localized versions of windows. That can happen if a path string has characters that do to fit into char. Anyway, is there a way to deal with it now?

    question windows 
    opened by mykhailopylyp 11
  • The archive loses its structure after unpacking

    The archive loses its structure after unpacking

    Hi. Faced a problem when unpacking an archive using OS utilities.

    I pack the Archive using the methods:

        struct zip_t *zip = zip_open(zipArr, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
        zip_entry_open(zip, file);
        zip_entry_write(zip, data.data(), data.size()) ;
        zip_entry_close(zip);
    

    After packing, I get an archive with a seemingly correct structure.

    image

    But after unpacking such an archive, I have a bunch of unstructured files.

    .
    ├── AbstractButton.qml
    ├── AbstractButtonSection.qml
    ├── ActionGroup.qml
    ├── Action.qml
    ├── ApplicationWindow.qml
    ├── Blend.qml
    ├── BoxShadow.qml
    ├── BrightnessContrast.qml
    ├── busyindicator-icon16.png
    ├── [email protected]
    ├── busyindicator-icon.png
    ├── BusyIndicator.qml
    ├── BusyIndicatorSpecifics.qml
    ├── ButtonGroup.qml
    ├── button-icon16.png
    ├── [email protected]
    ├── button-icon.png
    ├── ButtonPanel.qml
    ├── Button.qml
    ├── ButtonSection.qml
    ├── ButtonSpecifics.qml
    ├── checkbox-icon16.png
    ├── [email protected]
    ├── checkbox-icon.png
    ├── CheckBox.qml
    ├── CheckBoxSpecifics.qml
    ├── CheckDelegate.qml
    ├── CheckDelegateSpecifics.qml
    ├── CheckIndicator.qml
    ├── CheckSection.qml
    ├── Colorize.qml
    ├── ColorOverlay.qml
    ├── combobox-icon16.png
    ├── [email protected]
    ├── combobox-icon.png
    ├── ComboBox.qml
    ├── ComboBoxSpecifics.qml
    ├── ConicalGradient.qml
    ├── Container.qml
    ├── ContainerSection.qml
    ├── Control.qml
    ├── ControlSection.qml
    ├── ControlSpecifics.qml
    ├── CursorDelegate.qml
    ├── delaybutton-icon16.png
    ├── [email protected]
    ├── delaybutton-icon.png
    ├── DelayButton.qml
    ├── DelayButtonSpecifics.qml
    ├── Desaturate.qml
    ├── dial-icon16.png
    ├── [email protected]
    ├── dial-icon.png
    ├── DialogButtonBox.qml
    ├── Dialog.qml
    ├── Dial.qml
    ├── DialSpecifics.qml
    ├── DirectionalBlur.qml
    ├── Displace.qml
    ├── Drawer.qml
    ├── DropShadowBase.qml
    ├── DropShadowBase.qmlc
    ├── DropShadow.qml
    ├── ElevationEffect.qml
    ├── FastBlur.qml
    ├── FastGlow.qml
    ├── FastGlow.qmlc
    ├── FastInnerShadow.qml
    ├── FastInnerShadow.qmlc
    ├── FastMaskedBlur.qml
    ├── FastMaskedBlur.qmlc
    ├── frame-icon16.png
    ├── [email protected]
    ├── frame-icon.png
    ├── Frame.qml
    ├── FrameSpecifics.qml
    ├── GammaAdjust.qml
    ├── GaussianBlur.qml
    ├── GaussianDirectionalBlur.qml
    ├── GaussianDirectionalBlur.qmlc
    ├── GaussianGlow.qml
    ├── GaussianGlow.qmlc
    ├── GaussianInnerShadow.qml
    ├── GaussianInnerShadow.qmlc
    ├── GaussianMaskedBlur.qml
    ├── GaussianMaskedBlur.qmlc
    ├── Glow.qml
    ├── groupbox-icon16.png
    ├── [email protected]
    ├── groupbox-icon.png
    ├── GroupBox.qml
    ├── GroupBoxSpecifics.qml
    ├── HueSaturation.qml
    ├── InnerShadow.qml
    ├── itemdelegate-icon16.png
    ├── [email protected]
    ├── itemdelegate-icon.png
    ├── ItemDelegate.qml
    ├── ItemDelegateSection.qml
    ├── ItemDelegateSpecifics.qml
    ├── label-icon16.png
    ├── [email protected]
    ├── label-icon.png
    ├── Label.qml
    ├── LabelSpecifics.qml
    ├── LevelAdjust.qml
    ├── libbradient.so
    ├── libcomposeplatforminputcontextplugin.so
    ├── libdmabuf-server.so
    ├── libdrm-egl-server.so
    ├── libfullscreen-shell-v1.so
    ├── libibusplatforminputcontextplugin.so
    ├── libicudata.so.56
    ├── libicui18n.so.56
    ├── libicuuc.so.56
    ├── libivi-shell.so
    ├── liblinux-dmabuf-unstable-v1.so
    ├── libqconnmanbearer.so
    ├── libqeglfs.so
    ├── libqgenericbearer.so
    ├── libqgif.so
    ├── libqgtk3.so
    ├── libqicns.so
    ├── libqico.so
    ├── libqjpeg.so
    ├── libqlinuxfb.so
    ├── libqminimalegl.so
    ├── libqminimal.so
    ├── libqnmbearer.so
    ├── libqoffscreen.so
    ├── libqquicklayoutsplugin.so
    ├── libqsvgicon.so
    ├── libqsvg.so
    ├── libQt5Core.so.5
    ├── libQt5DBus.so.5
    ├── libQt5EglFSDeviceIntegration.so.5
    ├── libQt5Gui.so.5
    ├── libQt5Network.so.5
    ├── libQt5QmlModels.so.5
    ├── libQt5Qml.so.5
    ├── libQt5QmlWorkerScript.so.5
    ├── libQt5QuickControls2.so.5
    ├── libQt5Quick.so.5
    ├── libQt5QuickTemplates2.so.5
    ├── libQt5Svg.so.5
    ├── libQt5WaylandClient.so.5
    ├── libQt5WaylandCompositor.so.5
    ├── libQt5Widgets.so.5
    ├── libQt5XcbQpa.so.5
    ├── libqtga.so
    ├── libqtgraphicaleffectsplugin.so
    ├── libqtgraphicaleffectsprivate.so
    ├── libqtiff.so
    ├── libqt-plugin-wayland-egl.so
    ├── libqtquick2plugin.so
    ├── libqtquickcontrols2fusionstyleplugin.so
    ├── libqtquickcontrols2imaginestyleplugin.so
    ├── libqtquickcontrols2materialstyleplugin.so
    ├── libqtquickcontrols2plugin.so
    ├── libqtquickcontrols2universalstyleplugin.so
    ├── libqtquicktemplates2plugin.so
    ├── libqwayland-egl.so
    ├── libqwayland-generic.so
    ├── libqwayland-xcomposite-egl.so
    ├── libqwayland-xcomposite-glx.so
    ├── libqwbmp.so
    ├── libqwebp.so
    ├── libqxcb-egl-integration.so
    ├── libqxcb-glx-integration.so
    ├── libqxcb.so
    ├── libqxdgdesktopportal.so
    ├── libshm-emulation-server.so
    ├── libvulkan-server.so
    ├── libwayland-eglstream-controller.so
    ├── libwindowplugin.so
    ├── libwl-shell.so
    ├── libxcomposite-egl.so
    ├── libxcomposite-glx.so
    ├── libxdg-shell.so
    ├── libxdg-shell-v5.so
    ├── libxdg-shell-v6.so
    ├── LinearGradient.qml
    ├── MaskedBlur.qml
    ├── MenuBarItem.qml
    ├── MenuBar.qml
    ├── MenuItem.qml
    ├── Menu.qml
    ├── MenuSeparator.qml
    ├── OpacityMask.qml
    ├── PaddingSection.qml
    ├── page-icon16.png
    ├── [email protected]
    ├── page-icon.png
    ├── pageindicator-icon16.png
    ├── [email protected]
    ├── pageindicator-icon.png
    ├── PageIndicator.qml
    ├── PageIndicatorSpecifics.qml
    ├── Page.qml
    ├── PageSpecifics.qml
    ├── pane-icon16.png
    ├── [email protected]
    ├── pane-icon.png
    ├── Pane.qml
    ├── PaneSection.qml
    ├── PaneSpecifics.qml
    ├── plugins.qmltypes
    ├── Popup.qml
    ├── progressbar-icon16.png
    ├── [email protected]
    ├── progressbar-icon.png
    ├── ProgressBar.qml
    ├── ProgressBarSpecifics.qml
    ├── qmldir
    ├── qtbase_ar.qm
    ├── qtbase_bg.qm
    ├── qtbase_ca.qm
    ├── qtbase_cs.qm
    ├── qtbase_da.qm
    ├── qtbase_de.qm
    ├── qtbase_en.qm
    ├── qtbase_es.qm
    ├── qtbase_fi.qm
    ├── qtbase_fr.qm
    ├── qtbase_gd.qm
    ├── qtbase_he.qm
    ├── qtbase_hu.qm
    ├── qtbase_it.qm
    ├── qtbase_ja.qm
    ├── qtbase_ko.qm
    ├── qtbase_lv.qm
    ├── qtbase_pl.qm
    ├── qtbase_ru.qm
    ├── qtbase_sk.qm
    ├── qtbase_uk.qm
    ├── qtbase_zh_TW.qm
    ├── qt.conf
    ├── qtdeclarative_bg.qm
    ├── qtdeclarative_da.qm
    ├── qtdeclarative_de.qm
    ├── qtdeclarative_en.qm
    ├── qtdeclarative_es.qm
    ├── qtdeclarative_fi.qm
    ├── qtdeclarative_fr.qm
    ├── qtdeclarative_hu.qm
    ├── qtdeclarative_ja.qm
    ├── qtdeclarative_ko.qm
    ├── qtdeclarative_lv.qm
    ├── qtdeclarative_pl.qm
    ├── qtdeclarative_ru.qm
    ├── qtdeclarative_sk.qm
    ├── qtdeclarative_uk.qm
    ├── qtquickcontrols2.metainfo
    ├── RadialBlur.qml
    ├── RadialGradient.qml
    ├── radiobutton-icon16.png
    ├── [email protected]
    ├── radiobutton-icon.png
    ├── RadioButton.qml
    ├── RadioButtonSpecifics.qml
    ├── RadioDelegate.qml
    ├── RadioDelegateSpecifics.qml
    ├── RadioIndicator.qml
    ├── rangeslider-icon16.png
    ├── [email protected]
    ├── rangeslider-icon.png
    ├── RangeSlider.qml
    ├── RangeSliderSpecifics.qml
    ├── RectangularGlow.qml
    ├── RecursiveBlur.qml
    ├── roundbutton-icon16.png
    ├── [email protected]
    ├── roundbutton-icon.png
    ├── RoundButton.qml
    ├── RoundButtonSpecifics.qml
    ├── ScrollBar.qml
    ├── ScrollIndicator.qml
    ├── scrollview-icon16.png
    ├── [email protected]
    ├── scrollview-icon.png
    ├── ScrollView.qml
    ├── ScrollViewSpecifics.qml
    ├── SliderGroove.qml
    ├── SliderHandle.qml
    ├── slider-icon16.png
    ├── [email protected]
    ├── slider-icon.png
    ├── Slider.qml
    ├── SliderSpecifics.qml
    ├── spinbox-icon16.png
    ├── [email protected]
    ├── spinbox-icon.png
    ├── SpinBox.qml
    ├── SpinBoxSpecifics.qml
    ├── SplitView.qml
    ├── stackview-icon16.png
    ├── [email protected]
    ├── stackview-icon.png
    ├── StackView.qml
    ├── StackViewSpecifics.qml
    ├── SwipeDelegate.qml
    ├── SwipeDelegateSpecifics.qml
    ├── swipeview-icon16.png
    ├── [email protected]
    ├── swipeview-icon.png
    ├── SwipeView.qml
    ├── SwipeViewSpecifics.qml
    ├── SwitchDelegate.qml
    ├── SwitchDelegateSpecifics.qml
    ├── switch-icon16.png
    ├── [email protected]
    ├── switch-icon.png
    ├── SwitchIndicator.qml
    ├── Switch.qml
    ├── SwitchSpecifics.qml
    ├── TabBar.qml
    ├── TabBarSpecifics.qml
    ├── TabButton.qml
    ├── TabButtonSpecifics.qml
    ├── TestQMLWidgets
    ├── TestQMLWidgets.sh
    ├── textarea-icon16.png
    ├── [email protected]
    ├── textarea-icon.png
    ├── TextArea.qml
    ├── TextAreaSpecifics.qml
    ├── textfield-icon16.png
    ├── [email protected]
    ├── textfield-icon.png
    ├── TextField.qml
    ├── TextFieldSpecifics.qml
    ├── ThresholdMask.qml
    ├── toolbar-icon16.png
    ├── [email protected]
    ├── toolbar-icon.png
    ├── ToolBar.qml
    ├── ToolBarSpecifics.qml
    ├── toolbutton-icon16.png
    ├── [email protected]
    ├── toolbutton-icon.png
    ├── ToolButton.qml
    ├── ToolButtonSpecifics.qml
    ├── toolseparator-icon16.png
    ├── [email protected]
    ├── toolseparator-icon.png
    ├── ToolSeparator.qml
    ├── ToolSeparatorSpecifics.qml
    ├── ToolTip.qml
    ├── tumbler-icon16.png
    ├── [email protected]
    ├── tumbler-icon.png
    ├── Tumbler.qml
    ├── TumblerSpecifics.qml
    └── ZoomBlur.qml
    
    0 directories, 354 files
    
    

    what could be the problem?

    invalid 
    opened by EndrII 11
  • When writing file names in Cyrillic, the file is not written

    When writing file names in Cyrillic, the file is not written

    Hello! I trying to write file to zip with cyrillic symbols

    			zip_entry_open(zip, "тест.txt");
    			zip_entry_write(zip, content, size);
    			zip_entry_close(zip);
    

    Archive is empty..

    opened by HellsCoder 2
Releases(v0.2.4)
  • v0.2.4(Jul 9, 2022)

    What's Changed

    • fix delete entries fail by @HellsCoder in https://github.com/kuba--/zip/pull/267
    • Enable building tests only if the project is built as a standalone one by @zivke in https://github.com/kuba--/zip/pull/269

    New Contributors

    • @HellsCoder made their first contribution in https://github.com/kuba--/zip/pull/267
    • @zivke made their first contribution in https://github.com/kuba--/zip/pull/269

    Full Changelog: https://github.com/kuba--/zip/compare/v0.2.3...v0.2.4

    Source code(tar.gz)
    Source code(zip)
  • v0.2.3(Jun 6, 2022)

    What's Changed

    • For support shareable file open on windows by @appledragon in https://github.com/kuba--/zip/pull/220
    • MAX_PATH=1024 by @kuba-- in https://github.com/kuba--/zip/pull/222
    • No freopen for append by @kuba-- in https://github.com/kuba--/zip/pull/223
    • Permissions xattr. logic from zip info by @kuba-- in https://github.com/kuba--/zip/pull/227
    • Update zip.c by @kuba-- in https://github.com/kuba--/zip/pull/230
    • Fix compilation on MS-DOS/DJGPP by @kuba-- in https://github.com/kuba--/zip/pull/235
    • Wrap mz_zip_time_t_to_dos_time() call by @Dialga in https://github.com/kuba--/zip/pull/236
    • Add switch case for MZ_ZIP_TOTAL_ERRORS by @Dialga in https://github.com/kuba--/zip/pull/237
    • Do not jump over initialisation by @prissi in https://github.com/kuba--/zip/pull/238
    • Add ZIP_RAW_ENTRYNAME macro by @kuba-- in https://github.com/kuba--/zip/pull/240
    • Forward changes we use in ogre by @paroj in https://github.com/kuba--/zip/pull/242
    • Replace S_IWRITE by S_IWUSR by @kuba-- in https://github.com/kuba--/zip/pull/244
    • Update zip.c by @kuba-- in https://github.com/kuba--/zip/pull/245
    • Expose entry index as (s)size_t by @kuba-- in https://github.com/kuba--/zip/pull/249
    • Fix mkdir for tcc on Windows by @Dialga in https://github.com/kuba--/zip/pull/261
    • Fix ftruncate for tcc on Windows by @Dialga in https://github.com/kuba--/zip/pull/260
    • Fix unzip big files by @kuba-- in https://github.com/kuba--/zip/pull/262

    New Contributors

    • @appledragon made their first contribution in https://github.com/kuba--/zip/pull/220
    • @prissi made their first contribution in https://github.com/kuba--/zip/pull/238
    • @paroj made their first contribution in https://github.com/kuba--/zip/pull/242

    Full Changelog: https://github.com/kuba--/zip/compare/v0.2.2...v0.2.3

    Source code(tar.gz)
    Source code(zip)
  • v0.2.2(Dec 11, 2021)

    What's Changed

    • switch to ninja build by @kuba-- in https://github.com/kuba--/zip/pull/216
    • Port of features from miniz (creation of ZIP64 files and empty folders) by @javiserrano in https://github.com/kuba--/zip/pull/215

    New Contributors

    • @javiserrano made their first contribution in https://github.com/kuba--/zip/pull/215

    Full Changelog: https://github.com/kuba--/zip/compare/v0.2.1...v0.2.2

    Source code(tar.gz)
    Source code(zip)
  • v0.2.1(Dec 10, 2021)

    What's Changed

    • Fix - unsafe _wfopen and _wfreopen in Visual Studio by @kuba-- in https://github.com/kuba--/zip/pull/206
    • Fix defines by @kuba-- in https://github.com/kuba--/zip/pull/208
    • [CMakeLists.txt] Set C89; [src/zip.c] C89-compatibility by @SamuelMarks in https://github.com/kuba--/zip/pull/212
    • Add sanitizers for zip by @sdt27 in https://github.com/kuba--/zip/pull/213
    • pass MZ_ZIP_GENERAL_PURPOSE_BIT_FLAG_UTF8 by @kuba-- in https://github.com/kuba--/zip/pull/214

    New Contributors

    • @SamuelMarks made their first contribution in https://github.com/kuba--/zip/pull/212
    • @sdt27 made their first contribution in https://github.com/kuba--/zip/pull/213

    Full Changelog: https://github.com/kuba--/zip/compare/v0.2.0...v0.2.1

    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Aug 6, 2021)

  • v0.1.32(Jul 22, 2021)

    Change log:

    • Fix compiler (MSC) warnings (#186, #187, #196, #199)
    • API to set custom global CRC-32 function (#191)
    • Custom mz_stat for MSC (#194)
    • Custom mz_mkdir for MSC (#200)
    Source code(tar.gz)
    Source code(zip)
  • v0.1.22(Jan 21, 2021)

  • v0.1.21(Dec 18, 2020)

    • Open files with wide char names on Windows (#150)
    • Fix compilation with MINIZ_NO_TIME (#151)
    • Fix compilation error for msvs latest (#155)
    • Fix normalize entry path (#159)
    Source code(tar.gz)
    Source code(zip)
  • v0.1.20(Nov 19, 2020)

    • Fix tinfl_decompress
    • New API zip_extract_stream(), zip_open_stream(), zip_delete_entries
    • Remove -pedantic for tests in release mode.
    • Define ssize_t only for MSVC compiler which does not support POSIX
    Source code(tar.gz)
    Source code(zip)
  • v0.1.19(Apr 23, 2020)

    • Upgrade cmake to 3.4 (#122), to have support for WINDOWS_EXPORT_ALL_SYMBOLS.

    Note: cmake -DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=TRUE -DBUILD_SHARED_LIBS=TRUE creates dlls on Windows without declspec() using new CMake export all feature. More details here

    Source code(tar.gz)
    Source code(zip)
  • v0.1.18(Feb 4, 2020)

  • v0.1.17(Jan 22, 2020)

    • Check if the archive has a zip64 end of central directory headers.
    • Fix potential memory leak (if new entry does not exist).
    • Replace travis and appveyor by github actions.
    Source code(tar.gz)
    Source code(zip)
  • v0.1.16(Nov 12, 2019)

  • v0.1.15(May 24, 2019)

  • v0.1.14(Mar 28, 2019)

  • v0.1.13(Feb 25, 2019)

  • v0.1.12(Jan 14, 2019)

    • Extract zipped symlinks as symlinks on UNIX platforms.
    • Support for TDM-GCC compiler.
    • Rename function basename to base_name (to avoid conflicts with <string.h>).
    • Support for Android NDK <stdint.h>.
    Source code(tar.gz)
    Source code(zip)
  • v0.1.11(Oct 30, 2018)

    • Make read functions syscall compatible.
    • Improvements in build system (make install)

    Bugfixes:

    • "zip_extract doesn't work if not on main OS drive" (https://github.com/kuba--/zip/issues/85)
    Source code(tar.gz)
    Source code(zip)
  • v0.1.10(Sep 30, 2018)

  • v0.1.9(Aug 22, 2018)

  • v0.1.8(Aug 10, 2018)

  • v0.1.7(Aug 1, 2018)

    • Fix Issue generating zip windows MSYS": https://github.com/kuba--/zip/issues/46
    • Use target_include_directories to help dependents find the zip.h file: https://github.com/kuba--/zip/pull/45
    Source code(tar.gz)
    Source code(zip)
  • v0.1.6(Jul 24, 2018)

    • bug fixes
      • memset function will lead to underflow of the buffer
      • Lite fix about build in _MSC_VER (PS)
      • remove wrong if for MSC
    • clang-format
    • update cmake file
    Source code(tar.gz)
    Source code(zip)
  • v0.1.5(Mar 8, 2018)

    • minor bug fixes
    • new API functions:
    /*
      Returns an uncompressed size of the current zip entry.
    
      Args:
        zip: zip archive handler.
    
      Returns:
        The uncompressed size in bytes.
    */
    extern unsigned long long zip_entry_size(struct zip_t *zip);
    
    /*
      Returns CRC-32 checksum of the current zip entry.
    
      Args:
        zip: zip archive handler.
    
      Returns:
        The CRC-32 checksum.
    */
    extern unsigned int zip_entry_crc32(struct zip_t *zip);
    
    /*
      Extracts the current zip entry into a memory buffer using no memory allocation.
    
      Args:
        zip: zip archive handler.
        buf: preallocated output buffer.
        bufsize: output buffer size (in bytes).
    
      Note:
        - ensure supplied output buffer is large enough.
        - zip_entry_size function (returns uncompressed size for the current entry)
          can be handy to estimate how big buffer is needed.
        - for large entries, please take a look at zip_entry_extract function.
    
      Returns:
        The return code - 0 on success, negative number (< 0) on error (e.g. bufsize
        is not large enough).
    */
    extern int zip_entry_noallocread(struct zip_t *zip, void *buf, size_t bufsize);
    
    Source code(tar.gz)
    Source code(zip)
  • v0.1.4(Jan 9, 2018)

    • minor bug fixes
    • new API functions:
    /*
      Opens a new entry by index in the zip archive.
      This function is only valid if zip archive was opened in 'r' (readonly) mode.
    
      Args:
        zip: zip archive handler.
        index: index in local dictionary.
    
      Returns:
        The return code - 0 on success, negative number (< 0) on error.
    */
    extern int zip_entry_openbyindex(struct zip_t *zip, int index);
    
    /*
      Returns a local name of the current zip entry.
      The main difference between user's entry name and local entry name
      is optional relative path.
      Following .ZIP File Format Specification - the path stored MUST not contain
      a drive or device letter, or a leading slash.
      All slashes MUST be forward slashes '/' as opposed to backwards slashes '\'
      for compatibility with Amiga and UNIX file systems etc.
    
      Args:
        zip: zip archive handler.
    
      Returns:
        The pointer to the current zip entry name, or NULL on error.
    */
    extern const char *zip_entry_name(struct zip_t *zip);
    
    /*
      Returns an index of the current zip entry.
    
      Args:
        zip: zip archive handler.
    
      Returns:
        The index on success, negative number (< 0) on error.
    */
    extern int zip_entry_index(struct zip_t *zip);
    
    /*
      Determines if the current zip entry is a directory entry.
    
      Args:
        zip: zip archive handler.
    
      Returns:
        The return code - 1 (true), 0 (false), negative number (< 0) on error.
    */
    extern int zip_entry_isdir(struct zip_t *zip);
    
    /*
      Returns the number of all entries (files and directories) in the zip archive.
    
      Args:
        zip: zip archive handler.
    
      Returns:
        The return code - the number of entries on success,
        negative number (< 0) on error.
    */
    extern int zip_total_entries(struct zip_t *zip);
    
    Source code(tar.gz)
    Source code(zip)
  • v0.1.3(Nov 9, 2017)

  • v0.1.2(Jul 21, 2017)

  • v0.1.1(Mar 16, 2017)

Owner
Kuba Podgórski
Distributed storage systems, Optimization, Source code analysis
Kuba Podgórski
A simple C library for compressing lists of integers using binary packing

The SIMDComp library A simple C library for compressing lists of integers using binary packing and SIMD instructions. The assumption is either that yo

Daniel Lemire 391 Aug 7, 2022
Interpreter and miner for the LODA language written in C++

LODA Interpreter and Miner (C++) LODA is an assembly language, a computational model and a tool for mining integer sequences. You can use it to search

LODA Language 12 Jul 8, 2022
This is a compiler written from scratch in C

C Compiler This is a compiler written from scratch in C, with fully supporting C18 as a goal. It can currently compile itself, and most simple program

null 28 Jun 10, 2022
A compiler written in C++ to convert .hoi code to hoi4 code

What is HC4? HC4 is a compiler that converts .hoic filenames to Hearts of Iron IV's .txt. Usage Use hc4 in the terminal (./hc4 if on Unix) and it will

SaCode 1 Jul 31, 2022
A C compiler written in Zig.

Aro A C compiler with the goal of providing fast compilation and low memory usage with good diagnostics. Currently it can preprocess, parse and semant

Veikka Tuominen 374 Aug 6, 2022
Smaller C is a simple and small single-pass C compiler

Smaller C is a simple and small single-pass C compiler, currently supporting most of the C language common between C89/ANSI C and C99 (minus some C89 and plus some C99 features).

Alexey Frunze 1.1k Aug 9, 2022
An interpreter for a simple imperative language called IPL

For this project, I've implemented an interpreter for IPL, a small imperative language created for educational purposes in the Introduction to Programming course (k04), using some of the techniques I learned from the book Crafting Interpreters.

Jo 11 Aug 8, 2022
Superfast compression library

DENSITY Superfast compression library DENSITY is a free C99, open-source, BSD licensed compression library. It is focused on high-speed compression, a

Centaurean 979 Jul 27, 2022
data compression library for embedded/real-time systems

heatshrink A data compression/decompression library for embedded/real-time systems. Key Features: Low memory usage (as low as 50 bytes) It is useful f

Atomic Object 1.1k Jul 30, 2022
Small strings compression library

SMAZ - compression for very small strings ----------------------------------------- Smaz is a simple compression library suitable for compressing ver

Salvatore Sanfilippo 999 Aug 8, 2022
Compression abstraction library and utilities

Squash - Compresion Abstraction Library

null 364 Jul 31, 2022
Multi-format archive and compression library

Welcome to libarchive! The libarchive project develops a portable, efficient C library that can read and write streaming archives in a variety of form

null 1.8k Aug 9, 2022
is a c++20 compile and runtime Struct Reflections header only library.

is a c++20 compile and runtime Struct Reflections header only library. It allows you to iterate over aggregate type's member variables.

RedSkittleFox 4 Apr 18, 2022
A C++ static library offering a clean and simple interface to the 7-zip DLLs.

bit7z A C++ static library offering a clean and simple interface to the 7-zip DLLs Supported Features • Getting Started • Download • Requirements • Bu

Riccardo 279 Jul 29, 2022
Fork of the popular zip manipulation library found in the zlib distribution.

minizip-ng 3.0.0 minizip-ng is a zip manipulation library written in C that is supported on Windows, macOS, and Linux. Developed and maintained by Nat

zlib-ng 930 Aug 11, 2022
Fork of the popular zip manipulation library found in the zlib distribution.

minizip-ng 3.0.1 minizip-ng is a zip manipulation library written in C that is supported on Windows, macOS, and Linux. Developed and maintained by Nat

zlib-ng 929 Aug 5, 2022
An embedded-friendly library for decompressing files from zip archives

An 'embedded-friendly' (aka Arduino) library to extract and decompress files from ZIP archives

Larry Bank 25 Jul 17, 2022
Przemyslaw Skibinski 556 Aug 4, 2022
FCracker is a command line tool designed to brute force encrypted files like zip, 7z, rar, pdf etc.

FCrack is a command-line tool designed to brute force encrypted files like zip, 7z, rar, pdf, gpg etc.

null 18 Aug 4, 2022
FUSE file system for ZIP archives

title section header footer date MOUNT-ZIP 1 User Manual mount-zip 1.0 November 2021 NAME mount-zip - Mount a ZIP archive as a FUSE filesystem. SYNOPS

Google 34 Aug 4, 2022
gzip (GNU zip) is a compression utility designed to be a replacement for 'compress'

gzip (GNU zip) is a compression utility designed to be a replacement for 'compress'

ACM at UCLA 7 Apr 27, 2022
Runtime Archiver plugin for Unreal Engine. Cross-platform archiving and unarchiving directories and files. Currently supports ZIP format.

Runtime Archiver Archiving and dearchiving directories and files Explore the docs » Marketplace . Releases . Support Chat Features Fast speed Easy arc

Georgy Treshchev 18 Jul 27, 2022
LibreSSL Portable itself. This includes the build scaffold and compatibility layer that builds portable LibreSSL from the OpenBSD source code.

LibreSSL Portable itself. This includes the build scaffold and compatibility layer that builds portable LibreSSL from the OpenBSD source code.

OpenBSD LibreSSL Portable 1.1k Jul 29, 2022
LibTomMath is a free open source portable number theoretic multiple-precision integer library written entirely in C.

libtommath This is the git repository for LibTomMath, a free open source portable number theoretic multiple-precision integer (MPI) library written en

libtom 525 Aug 10, 2022
Cranium - 🤖 A portable, header-only, artificial neural network library written in C99

Cranium is a portable, header-only, feedforward artificial neural network library written in vanilla C99. It supports fully-connected networks of arbi

Devin Soni 532 Jul 31, 2022
A tiny, portable, immediate-mode UI library written in ANSI C

A tiny, portable, immediate-mode UI library written in ANSI C Features Tiny: around 1100 sloc of ANSI C Works within a fixed-sized memory region: no a

null 2.3k Aug 8, 2022
Simple and portable (but not inflexible) GUI library in C that uses the native GUI technologies of each platform it supports.

libui: a portable GUI library for C This README is being written. Status It has come to my attention that I have not been particularly clear about how

Pietro Gagliardi 10.3k Aug 2, 2022
Portable, simple and extensible C++ logging library

Plog - portable, simple and extensible C++ logging library Pretty powerful logging library in about 1000 lines of code Introduction Hello log! Feature

Sergey Podobry 1.5k Aug 11, 2022
Very low footprint JSON parser written in portable ANSI C

Very low footprint JSON parser written in portable ANSI C. BSD licensed with no dependencies (i.e. just drop the C file into your project) Never recur

James McLaughlin 1.2k Jul 28, 2022