sdasgup3
9/28/2016 - 5:57 PM

How to use libzip

How to use libzip

// Compile: 
// g++  libzipplayground.cpp  -I<path to libzip include> libarchive-rw.a   -lz 
#include<iostream>
#include<string>
#include <zip.h>
#include <cstdlib>
using namespace std;

char *readfile(string filename, size_t *size) {
  char * buffer;
  size_t result;

  FILE* pFile = fopen (filename.c_str(), "rb" );
  if (pFile==NULL) {fputs ("File error",stderr); exit (1);}

  // obtain file size:
  fseek (pFile , 0 , SEEK_END);
  unsigned int lSize = ftell (pFile);
  rewind (pFile);

  // allocate memory to contain the whole file:
  buffer = (char*) malloc (sizeof(char)*lSize);
  if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}

  // copy the file into the buffer:
  result = fread (buffer,1,lSize,pFile);
  if (result != lSize) {fputs ("Reading error",stderr); exit (3);}

  /* the whole file is now loaded in the memory buffer. */

  // terminate
  fclose (pFile);
  *size = lSize;
  return buffer;

}

void dump(zip *archive) {
  int files_total = zip_get_num_entries(archive, 0);
  printf("Note: we have only %d files in ZIP\n",files_total);


  struct zip_stat sb;
  int r, len;
  long long sum; 
  char buffer[10000];

  for (int i = 0; i < zip_get_num_entries(archive, 0); i++) {
    if (zip_stat_index(archive, i, 0, &sb) == 0) {
      printf("==================\n");
      printf("Name: [%s], ", sb.name);
      printf("Size: [%llu], ", sb.size);
      printf("Index: [%llu], ", sb.index);
      printf("Valid: [%llu], ", sb.valid);
      printf("mtime: [%u]\n", (unsigned int)sb.mtime);

      zip_file *zf = zip_fopen_index(archive, i, 0);
      if (!zf) {
        fprintf(stderr, "boese, boese\n");
        cout << "failed to opne  entry of archive. " << zip_strerror(archive) << endl;
        zip_close(archive);
      }

      sum = 0;
      while (sum != sb.size) {
        len = zip_fread(zf, buffer, 100);
        if (len < 0) {
          fprintf(stderr, "boese, boese\n");
          exit(102);
        }
        printf("%s",buffer, len);
        sum += len;
      }
      zip_fclose(zf);
      printf("==================\n");
    }
  }
  printf("\n\n");
}

zip * get_archive(string path, int flags) {
  int error = 0;
  zip *archive = zip_open(path.c_str(), flags , &error);

  if(!archive) {
    cout << "could not open or create archive" <<  path << endl;
    exit(1) ;
  }
  cout << "Done : creating archieve" << path <<  endl;
  return archive;
}

void add(zip *archive, string file) {
  int index;
  size_t len;
  char *data      = readfile(file, &len);
  cout << "File content \n" << "Name "  << file << "\nSize " << len << "\n" << data  << "\n";

  zip_source *source = zip_source_buffer(archive, data, len, 0);
  if(source == NULL) {
    cout << "failed to create source buffer. " << zip_strerror(archive) << endl;
    return ;
  }

  //index = (int)zip_file_add(archive, file.c_str(), source, ZIP_FL_ENC_UTF_8);
  index = (int)zip_add(archive, file.c_str(), source);
  if(index < 0) {
    zip_source_free(source);
    cout << "failed to add file to archive. " << zip_strerror(archive) << endl;
    return ;
  }

}

void 
createfromexisting(string path) {
  zip *oldarchive = get_archive(path, ZIP_CREATE);
  dump(oldarchive);

  std::string new_path  = "/home/sdasgup3/Junk/LIBZIP/ref_new.zip";
  int err;
  int flags = ZIP_CREATE;
  zip_t *archive = zip_open(new_path.c_str(), flags, &err);
  char buffer[10000];

  for (int i = 0; i < zip_get_num_entries(oldarchive, 0); i++) {
    zip_stat_t sb;;
    if (zip_stat_index(oldarchive, i, 0, &sb) == 0) {
      size_t s = sb.size;
      const char* name  =  sb.name;

      zip_file *zf = zip_fopen_index(oldarchive, i, 0);
      if (!zf) {
        fprintf(stderr, "boese, boese\n");
        cout << "failed to open  entry of archive. " << zip_strerror(archive) << endl;
        zip_close(archive);
      }

      size_t len = zip_fread(zf, buffer, s);
      if (len < 0) {
        fprintf(stderr, "boese, boese\n");
        exit(102);
      }
      zip_fclose(zf);

      zip_source *zipBuffer = zip_source_buffer(archive, buffer, s, 0 /*don't free*/);
      if(zip_file_add(archive, name, zipBuffer, ZIP_FL_ENC_UTF_8) < 0 ) {
        cout << "zip_file_add problem " << zip_strerror(archive) << endl;
      }
    }
  }

  dump(archive);


  zip_close(oldarchive);
  zip_close(archive);
}

int main () {

  std::string path1  = "/home/sdasgup3/Junk/LIBZIP/archive.zip";
  std::string path2  = "/home/sdasgup3/Junk/LIBZIP/ref.zip";

  std::string file1     = "message1.txt";
  std::string file2     = "Makefile.rules";
  //std::string file1     = "/home/sdasgup3/Junk/LIBZIP/message1.txt";
  //std::string file2     = "/home/sdasgup3/Junk/LIBZIP/Makefile.rules";

  //Read
  zip *archive1 = get_archive(path2, ZIP_CREATE);
  dump(archive1);
  zip_close(archive1);

  //create from existing
  createfromexisting(path2);


  return 0;
}