C++ Zip Example to Append In-Memory Binary and String Data


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");
    }
}

Chilkat C++ API Lowercase Methods Returning “const char *”

In any Chilkat C++ class, there are two alternatives for methods that return a string, and for string properties. The first alternative is to return the string in an output-only “CkString &” in the final argument. The second alternative is to return a “const char *” directly. For example, the CkSFtp class has the following:

	// A property named "HostKeyFingerprint"
	void get_HostKeyFingerprint(CkString &str);
	const char *hostKeyFingerprint(void);

	// The "ReadFileText" method
	bool ReadFileText(const char *sftpHandle, int numBytes, const char *charset, CkString &outStr);
	const char *readFileText(const char *sftpHandle, int numBytes, const char *charset);

The same convention is used for the Unicode (wchar_t) version of the API, as well as the “C” API’s

	// In the CkSFtpW class:

	void get_HostKeyFingerprint(CkString &str);
	const wchar_t *hostKeyFingerprint(void);

	bool ReadFileText(const wchar_t *sftpHandle, int numBytes, const wchar_t *charset, CkString &outStr);  
	const wchar_t *readFileText(const wchar_t *sftpHandle, int numBytes, const wchar_t *charset);

	// In the "C" API

	void CkSFtp_getHostKeyFingerprint(HCkSFtp cHandle, HCkString retval);  
	const char *CkSFtp_hostKeyFingerprint(HCkSFtp cHandle);

	BOOL CkSFtp_ReadFileText(HCkSFtp cHandle, const char *sftpHandle, int numBytes, const char *charset, HCkString outStr);  
	const char *CkSFtp_readFileText(HCkSFtp cHandle, const char *sftpHandle, int numBytes, const char *charset);

Important: The lowercase alternative that returns a “const char *” is returning a pointer to internal memory that is not permanent. Your application should make use of it immediately and then discard the pointer. If the string is needed for a longer amount of time, then it should be copied to memory owned and controlled by the application, or the upper-case alternative using CkString should be used instead. If an application keeps a “const char *” pointer and continues to make additional calls on the same Chilkat object instance, the memory pointed to by the “const char *” could change.

(C++) Return Email Headers as iso-8859-15? (or any other charset)

Question:

In C++, is it somehow possible to specify a desired charset (like ISO-8859-15) when getting mail headers with POP3?

Answer:

Instead of calling the method that returns a “const char *” — which can return either utf-8 or ANSI (see this Chilkat blog post about the Utf8 property common to all Chilkat C++ classes), call the alternate method that returns the string in a CkString object.  You can then get the iso-8859-15 string from the CkString object.

Each Chilkat C++ method that returns a string has two versions — an upper-case version that returns the string in a CkString (always the last argument), and a lower-case version that returns a “const char *”.

For example, in the CkEmail class:

bool GetHeaderField(const char *fieldName, CkString &outFieldValue);
const char *getHeaderField(const char *fieldName);

The lower-case method returning a “const char *” returns a pointer to memory that may be overwritten in subsequent calls.  Therefore, make sure to copy the string to a safe place immediately before making additional calls on the same Chilkat object instance.  (Only methods that also return “const char *” would overwrite the memory from a previous call.)

The upper-case version of the method returns the string in a CkString object.  It is an output-only argument, meaning that the CkString contents are replaced, not appended.  To get the iso-8859-15 string from the CkString, call the getEnc method.  For example:

const char  *str_iso_8859_15 = outFieldValue.getEnc("iso-8859-15");

This returns a NULL-terminated string where each character is represented as a single byte using the iso-8859-15 encoding.