libopc
opc_zipwrite.c

Demonstrates low level ZIP write functionality as needed by the high level opcContainer API.

#include <opc/opc.h>
#include <stdio.h>
#include <time.h>
#ifdef WIN32
#include <crtdbg.h>
#endif
/*
This example shows how to use the low level zip functions.
Ussage:
opc_zipread FILENAME [--import] [--delete] [--add] [--commit] [--trim]
* --import existing streams
* --delete all streams
* --add sample streams
* --commit streams
* --trim commit and trim streams
Sample:
opc_zipread out.zip --delete --import --add --commit
*/
static opc_error_t addSegment(void *iocontext,
void *userctx,
opcZip *zip=(opcZip *)userctx;
OPC_ENSURE(0==skip(iocontext));
OPC_ENSURE(-1!=opcZipLoadSegment(zip, xmlStrdup(info->name), info->rels_segment, info));
return OPC_ERROR_NONE;
}
static opc_error_t releaseSegment(opcZip *zip, opc_uint32_t segment_id) {
const xmlChar *name=NULL;
OPC_ENSURE(OPC_ERROR_NONE==opcZipGetSegmentInfo(zip, segment_id, &name, NULL, NULL));
OPC_ASSERT(NULL!=name);
xmlFree((void*)name);
return OPC_ERROR_NONE;
}
int main( int argc, const char* argv[] )
{
#ifdef WIN32
_CrtSetDbgFlag (_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
time_t start_time=time(NULL);
opc_error_t err=OPC_ERROR_NONE;
if (OPC_ERROR_NONE==(err=opcInitLibrary())) {
if (argc>0) {
opcIO_t io;
if (OPC_ERROR_NONE==opcFileInitIOFile(&io, _X(argv[1]), OPC_FILE_READ | OPC_FILE_WRITE)) {
opcZip *zip=opcZipCreate(&io);
if (NULL!=zip) {
for(int i=2;i<argc;i++) {
if (0==strcmp(argv[i], "--import")) { // import existing segments
OPC_ENSURE(OPC_ERROR_NONE==opcZipLoader(&io, zip, addSegment));
} else if (0==strcmp(argv[i], "--delete")) { // delete all segments
opc_uint32_t first_segment=i;
opc_uint32_t last_segment=i;
OPC_ENSURE(opcZipSegmentDelete(zip, &first_segment, &last_segment, releaseSegment));
}
} else if (0==strcmp(argv[i], "--add")) { // add sample streams
static char txt[]="Hello World!";
opc_uint32_t segment1_id=opcZipCreateSegment(zip, xmlStrdup(_X("hello.txt")), OPC_FALSE, 47+5, 0, 0, 0);
opc_uint32_t segment2_id=opcZipCreateSegment(zip, xmlStrdup(_X("stream.txt")), OPC_FALSE, 47+5, 0, 8, 6);
if (-1!=segment1_id) {
opcZipOutputStream *out=opcZipOpenOutputStream(zip, &segment1_id);
OPC_ENSURE(opcZipWriteOutputStream(zip, out, _X(txt), strlen(txt))==strlen(txt));
OPC_ENSURE(OPC_ERROR_NONE==opcZipCloseOutputStream(zip, out, &segment1_id));
}
if (-1!=segment2_id) {
opcZipOutputStream *out=opcZipOpenOutputStream(zip, &segment2_id);
OPC_ENSURE(opcZipWriteOutputStream(zip, out, _X(txt), strlen(txt))==strlen(txt));
OPC_ENSURE(OPC_ERROR_NONE==opcZipCloseOutputStream(zip, out, &segment2_id));
}
} else if (0==strcmp(argv[i], "--commit")) { // commit
OPC_ENSURE(OPC_ERROR_NONE==opcZipCommit(zip, OPC_FALSE));
} else if (0==strcmp(argv[i], "--trim")) { // commit and trim
OPC_ENSURE(OPC_ERROR_NONE==opcZipCommit(zip, OPC_TRUE));
}
}
opcZipClose(zip, releaseSegment);
} else {
OPC_ENSURE(OPC_ERROR_NONE==opcFileCleanupIO(&io));
}
}
}
if (OPC_ERROR_NONE==err) err=opcFreeLibrary();
}
time_t end_time=time(NULL);
fprintf(stdout, "time %.2lfsec\n", difftime(end_time, start_time));
#ifdef WIN32
OPC_ASSERT(!_CrtDumpMemoryLeaks());
#endif
return (OPC_ERROR_NONE==err?0:3);
}