void qa_create_zip_from_data(void)
{
CkZip zip;

zip.NewZip("qa_output/test.zip");

// This is the content of the files to be added to the .zip
const char *fileContents = "The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog. The quick brown fox jumped over the lazy dog.";

// AppendString2 returns a CkZipEntry, so make sure to get it and delete it if not needed..
// If NULL is returned, then the AppendString2 failed.
CkZipEntry *ent = zip.AppendString2("quickBrownFox1.txt",fileContents,"ansi");
if (ent) { delete ent; ent = 0; }

// Another way of adding in-memory data to a .zip is by calling AppendData. This is good for binary (non-text) data.
// In this case, we'll use the bytes of fileContents.
size_t szContent = strlen(fileContents);

CkByteData binaryContent;
// It is possible to let the CkByteData "borrow" data.  This avoid copying the bytes, which is good if the amount
// of data is large.
binaryContent.borrowData(fileContents,szContent);

// Add the binaryContent to the zip.
ent = zip.AppendData("quickBrownFox2.txt",binaryContent);
if (ent) { delete ent; ent = 0; }

// We now have a zip object (not yet a file on disk) that contains 2 entries: quickBrownFox1.txt and quickBrownFox2.txt
// Write the .zip to a file  (this is where the actual compression occurs)
// This writes the .zip to "qa_output/test.zip"
bool success = zip.WriteZipAndClose();
if (!success)
    {
    printf("%s\n",zip.lastErrorText());
    }
else
    {
    printf("success.\n");
    }
}