Overview

The RoseOutputZipMember class is a subclass of RoseOutputStream used to write compressed data to a member in a Zip archive. This stream requires additional setup C code to initialize and open the archive, then create the new member.

The code below provides an outline that you can customize. Be sure to fopen() the zipfile in binary mode on Windows.

#include <rose.h>
#include <rose_zip.h>

int write_zipped_file (
    FILE * dstfile,
    const char * member_name
    )
{
    // Set up the hook functions for zip
    zlib_filefunc_def io_funcs;

    fill_fopen_filefunc (&io_funcs);
    io_funcs.opaque = dstfile;
    io_funcs.zopen_file = rose_iozip_open_stub;
    io_funcs.zclose_file = rose_iozip_close_stub;

    zipFile zf = zipOpen2(0, APPEND_STATUS_CREATE, 0, &io_funcs);
    if (!zf) {
	printf ("Could not open zip file");
	return 1;
    }

    time_t now;
    time(&now);
    
    struct tm * ltm = localtime(&now);
    
    zip_fileinfo info;
    info.dosDate = 0;
    info.internal_fa = 0;
    info.external_fa = 0;
    info.tmz_date.tm_sec = ltm->tm_sec;
    info.tmz_date.tm_min = ltm->tm_min;
    info.tmz_date.tm_hour = ltm->tm_hour;
    info.tmz_date.tm_mday = ltm->tm_mday;
    info.tmz_date.tm_mon = ltm->tm_mon;
    info.tmz_date.tm_year = ltm->tm_year;
    
    int zerr = zipOpenNewFileInZip(
	zf, member_name, &info,
	0, 0, // no extrafield local
	0, 0, // no extrafield global
	0,    // no comment
	Z_DEFLATED,
	Z_DEFAULT_COMPRESSION
	);
    

    if (zerr != ZIP_OK) {
	printf ("Could not add %s to zip file", member_name);
	return 1;
    }

    // new zip destination
    RoseOutputZipMember dstmem (zf, "output file");

    dstmem.put("write your file contents here");
    dstmem.flush();

    // also zipCloseFileInZip(zf); if writing many files
    //
    if (zipClose(zf, 0 /*no global comment*/)) {
	printf ("Problems closing zip file");
	return 1;
    }

    return 0;
}

ctor()

RoseOutputZipMember();
RoseOutputZipMember(
	void * f,
	const char * nm = 0
	);

The RoseOutputFile() constructor has two versions. The default contructor leaves the name and zfile() zip handle fields unset, while the second constructor initializes both fields.

The zip file handle is typed as void*, but should be an zipFile value returned from an zipOpen function.

zfile()

void * zfile();
void zfile (void* f);

The zfile() function gets and sets the underlying zip file handle that stream data will be read from. This handle is typed as void*, but should be an zipFile value returned from an zipOpen function and then set to a particular member by zipOpenNewFileInZip().

flush()

virtual int flush();	

The flush() function writes the contents of the I/O memory buffer to the compressed zip member and returns the error_state(). This is called automatically by put() when the buffer is full. You must also call it manually when you are done to write the last partial buffer of data out to the destination.