Nox

Hello,

I want to use Nim on Windows to work with IDML files which contain bunch of zipped XML files packed in specific order (e.g. mimetype file comes as first and must be uncompressed).

I've tried “Wrapper for the zip library” but can't get it to work. It looks like libzip library is kinda hard to compile on Windows? I'm not sure how to make it compile with Nim. And libzip_all.c is supposed to be some old buggy code, right? Also, not sure how to use it instead of libzip.

Is there maybe some straightforward way to work with zip files? Maybe some easy alternative somewhere on Github?

2017-07-29 12:00:29
try out miniz: https://github.com/richgel999/miniz - it is single file C-library, which can read/write zip files... I'm not sure if there is a ready to use Nim bindings, but it should be easy to make one yourself...
2017-07-29 17:02:54
Nox

Thanks, I will check it out.

In meanwhile I've figured out how to use zipfiles. Just had to add: {.passl: "-lz".}

I've downloaded precompiled zlib binaries because zlib.dll supplied with Nim is 32 bit for some reason.

Also, right away I've found some problem in libzip.nim, it produced IO error while extracting whole archive:

 extractAll*(z: var ZipArchive, dest: string) =
  ## extracts all files from archive `z` to the destination directory.
  createDir(dest)
  for file in walkFiles(z):
    if file.contains("/"):
      createDir(dest / file[0..file.rfind("/")])
    extractFile(z, file, dest / file)

so I've changed it to:

 extractAll*(z: var ZipArchive, dest: string) =
  ## extracts all files from archive `z` to the destination directory.
  createDir(dest)
  for file in walkFiles(z):
    if file.endsWith("/"):
      createDir(dest / file[0..file.rfind("/")])
    else:
      extractFile(z, file, os.unixToNativePath(dest / file))

Need to test other parts as well

Now, I will look for a way to statically link zlib, but I'm really new to all this stuff with compiling/linking C/C++/GCC.

2017-07-29 19:20:04
Nox
Hmm... Looks like appending files with fmAppend or fmReadWriteExisting modes does not work, not sure why. 2017-07-29 21:23:21
There is a binding: https://github.com/h3rald/nim-miniz This is also part of the "min" language.
2017-08-03 22:53:17
Nox

Thanks, it seems to work fine, though I've already modified libzip wrapper to suit my needs It has one advantage over miniz that you can replace existing files in ZIP without unpacking everything.

Only downside of using libzip is that precompiled binary that I have is linked to zlib1.dll and I guess there is no way around it without recompiling libzip itself.

2017-08-06 12:44:25
Can we get these fixes/improvements as a PR please? 2017-08-06 12:49:31
Nox

Sure, but they would be incompatible with libzip_all.c that is supplied with current wrapper. Maybe consider removing it and adding newest zlib/libzip libraries to the current MinGW package from Nim website? Precompiled versions are available via Msys repo: http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-zlib-1.2.11-1-any.pkg.tar.xz http://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-libzip-1.2.0-2-any.pkg.tar.xz

Not sure how it will affect Mac OS/Linux fellows though.

Also, I'm using just these directives to link both libraries statically:

{.passl: "-static".}
{.passl: "-lzip".}
{.passl: "-lz".}

instead of

when defined(unix) and not defined(useLibzipSrc):
  when defined(macosx):
    {.pragma: dynlib: "libzip(|2|4).dylib".}
  else:
    {.pragma: dynlib: "libzip(|2).so(|.4|.2|.1|.0)".}
else:
  when defined(unix):
    {.passl: "-lz".}
  {.compile: "zip/private/libzip_all.c".}
  {.pragma: mydll.}
{.pragma: dynlib: "libzip-5.dll".}

not sure if this is correct/preferred.

2017-08-07 14:41:39