C# Streaming Decompression Example (from System.IO.Stream –> System.IO.Stream)

// Streaming decompression from System.IO.Stream --> System.IO.Stream

// In this example, the source and sink streams are files.
// However, they can be any type of System.IO.Stream, such as a System.Net.Sockets.NetworkStream
System.IO.FileStream fsSource = File.OpenRead("qa_data/image.compressed");
Chilkat.StreamConnector scSource = new Chilkat.StreamConnector();

System.IO.FileStream fsSink = File.OpenWrite("qa_data/image.bmp");
Chilkat.StreamConnector scSink = new Chilkat.StreamConnector();

Chilkat.Compression compress = new Chilkat.Compression();
compress.Algorithm = "deflate";

// Create a Chilkat.Stream object, and set the source/sink to the System.IO.Stream objects.
Chilkat.Stream stream = new Chilkat.Stream();
scSource.SetAsSource(fsSource, stream);
scSink.SetAsSink(fsSink, stream);

// Do the streaming decompress -- reading from fsSource and writing to fsSink
bool success = compress.DecompressStream(stream);

C# SFTP Upload from Byte[]

This example demonstrates how to open a remote file on an SSH/SFTP server,
write to the file, and then close it.  This is analogous to opening a local file,
writing to it, and closing it.  The SFTP protocol (i.e. Secure File Transfer over SSH),
follows the same concepts as typical file I/O programming -- i.e. open a file,
read, write, close, etc.).

// Assume at this point we already have a Chilkat.SFtp object
// connected to a server, authenticated, and InitializeSftp has
// already been called..


// To upload a binary file from Byte[], the procedure is to open the remote file,
// write the data, and then close the file.

// Open a remote file, returning a handle to the open file.
string handle = sftp.OpenFile("test.dat", "readWrite", "createTruncate");
if (!sftp.LastMethodSuccess)
    {
    textBox2.Text = sftp.LastErrorText;
    return;
    }

string text = "To live is the rarest thing in the world. Most people exist, that is all. -- Oscar Wilde\r\n";
byte[] bytes= System.Text.Encoding.UTF8.GetBytes(text);

// Write some data to the file.
bool success;
for (int i = 0; i < 20; i++)
    {
    // It is possible to write bytes:
    success = sftp.WriteFileBytes(handle, bytes);
    // It is also possible to write the string:
    if (success) success = sftp.WriteFileText(handle, "utf-8", text);

    if (!success)
        {
        textBox2.Text = sftp.LastErrorText;
        return;
        }
    }

// Close the remote file.
if (!sftp.CloseHandle(handle))
    {
    textBox2.Text = sftp.LastErrorText;
    return;
    }
 

C# TaskCompleted Event — Updating the UI from a Background Thread

This sample C# snippet demonstrates how to use the TaskCompleted event to be notified when an asynchronous method completes. Given that the event callback is in the background thread, any UI updates must occur on the main thread. This example demonstrates how to do it:

	private void taskCompletedToolStripMenuItem_Click(object sender, EventArgs e)
	    {
	    // Demonstrate an asynchronous Chilkat method call with a TaskCompleted event.
	    Chilkat.Http http = new Chilkat.Http();

	    http.OnTaskCompleted += http_OnTaskCompleted;

	    Chilkat.Task task = http.QuickGetStrAsync("http://www.chilkatsoft.com/");

	    // We can set the task.UserData property to identify this particular asynchronous call in the callback.
	    task.UserData = "chilkatHomePage";

	    // Runs the HTTP GET asynchronously on a background thread..
	    task.Run();
	    }

	// This event fires in the background thread. 
	// 
	void http_OnTaskCompleted(object sender, Chilkat.TaskCompletedEventArgs args)
	    {
	    Chilkat.Task task = args.Task;

	    // This event callback is running in the background thread.
	    // To update a UI element, we must be on the UI thread..
	    this.Invoke((MethodInvoker)delegate
		{
		    // The task.UserData can be used to identify the particular asynchronous method call
		    // that this callback belongs to.
		    if (task.UserData.Equals("chilkatHomePage"))
			{
			// An asychronous method is simply calling the corresponding synchronous method
			// in a background thread.  In this case, it is a call to QuickGetStr,
			// which returned a string, or it returned Nothing for failure.  This result is available
			// via task.GetResultString.  The LastErrorText for the background call 
			// is available in task.ResultErrorText
			string htmlPage = task.GetResultString();
			if (htmlPage == null)
			    {
			    textBox2.Text = task.ResultErrorText;
			    }
			else
			    {
			    textBox2.Text = htmlPage;
			    }
			}
		});
	    }
	}

Is Calling .Dispose() Recommended for C# and VB.NET?

Question:

In your examples online, we have noticed that .Dispose() is never
called after using Chilkat classes (we are writing in C#).

Is calling .Dispose() recommended?  Does your code not need to destroy
any native resources or handles that would normally be cleaned up in
the Dispose method (the IDisposeable interface) ?

Answer:

For objects that manage a TCP/IP socket connection with a server (FTP2, SSH, SFTP, POP3, SMTP, IMAP, HTTP, etc.) then calling Dispose will close the connection.  Aside from memory-usage and socket connections, there are no other resources used by Chilkat classes.  Dispose may also deallocate some internal memory.

The important thing to realize is that once Dispose is called, your code should not use that particular instance of the object again.  I always prefer a more explicit approach.  For example, instead of calling Chilkat.MailMan.Dispose to ensure that a connection to the SMTP server is closed, call Chilkat.MailMan.CloseSmtpConnection.  (If the mailman is not actually connected, calling CloseSmtpConnection does NOT result in an error.  It is harmless.)

Also, when an Chilkat object’s finalizer is called (i.e. when it is garbage-collected), any existing socket connections are closed and internal memory is (of course) deallocated.   You may force garbage collection by doing this (in C#)

 GC.Collect();
 GC.WaitForPendingFinalizers();

BASE64 Decode with Charset GB2312

Question:
I have a Base64 decode error, as follows:

CkString str;
str.setString("16q");
str.base64Decode("gb2312");
const char *strResult = str.getString();

convert result is { cb f2 }
But the correct result should be { d7 aa}

What’s wrong?

The platform is WinCE 6.0, use Chilkat_PPC_M5.lib

Answer:

The following code shows how to do it correctly:

    CkString str;
    str.setString("16q");

    // The following line of code tells the CkString object to 
    // decode the base64 to raw bytes, then interpret those bytes as
    // GB2312 encoded characters and store them within the string.
    // Internally, the string is stored as utf-8.
    str.base64Decode("gb2312");

    // This is an implicit conversion to ANSI, because
    // getString returns either ANSI or utf-8,
    // depending on the setting of get_Utf8/put_Utf8
    const char *strAnsi = str.getString();

    // Instead, fetch the string as GB2312 bytes:
    const char *strGb2312 = str.getEnc("gb2312");

    const unsigned char *c = (const unsigned char *) strGb2312;
    while (*c != '\0') {  printf("%02x ",*c); c++; }
    printf("\n");

    // The output is "d7 aa "


    // Another way to decode using CkByteData...
    CkByteData data;
    data.appendEncoded("16q","base64");
    c = data.getData();
    unsigned long i;
    unsigned long sz = data.getSize();
    for (i=0; i<sz; i++) { printf("%02x ",*c); c++; }
    printf("\n");

    // The output is "d7 aa "

SFTP Progress Monitoring and Abort (C#)

Here is an example for monitoring the progress of an SFTP file transfer:

        void sftp_OnPercentDone(object sender, Chilkat.PercentDoneEventArgs args)
        {
            progressBar1.Value = args.PercentDone;

            // To abort at any point, you may set args.Abort = true  
            // args.Abort = true;
        }

        void sftp_OnAbortCheck(object sender, Chilkat.AbortCheckEventArgs args)
        {
            // See http://cknotes.com/?p=149  for more information about 
            // using the AbortCheck event...
           
        }

private void button2_Click(object sender, EventArgs e)
{
	// SFTP upload with progress monitoring.
	Chilkat.SFtp sftp = new Chilkat.SFtp();

	// IMPORTANT: Enable event callbacks:
	sftp.EnableEvents = true;

	// Unlock the component.
	bool success = sftp.UnlockComponent("Anything for 30-day trial");
	if (!success)
	{
	textBox1.Text = sftp.LastErrorText;
	return;
	}

	// Connect to the SSH/SFTP server. (use a domain name or IP address)
	success = sftp.Connect("192.168.1.117", 22);
	if (!success)
	{
	textBox1.Text = sftp.LastErrorText;
	return;
	}

	// Authenticate..
	success = sftp.AuthenticatePw("chilkat", "myPassword");
	if (!success)
	{
	textBox1.Text = sftp.LastErrorText;
	return;
	}

	success = sftp.InitializeSftp();
	if (!success)
	{
	textBox1.Text = sftp.LastErrorText;
	return;
	}

	// Establish some event handlers:
	sftp.OnAbortCheck += new Chilkat.SFtp.AbortCheckEventHandler(sftp_OnAbortCheck);
	sftp.OnPercentDone += new Chilkat.SFtp.PercentDoneEventHandler(sftp_OnPercentDone);

	// See http://cknotes.com/?p=149  for more information about 
	// using the AbortCheck event...

	// Do an upload.
	// Note: If the file to be uploaded or downloaded is too small, 
	// the PercentDone callback will not be called for each 1%.
	// It's possible if the file is so small relative to the speed
	// of the connection that you may get a single 100% callback if
	// the data transfer happens almost instantaneously.
	string localFilepath = "c:/temp/hamlet.xml";
	string remoteFilepath = "hamlet.xml";
	progressBar1.Value = 0;
	success = sftp.UploadFileByName(remoteFilepath, localFilepath);
	if (!success)
	{
	textBox1.Text = sftp.LastErrorText;
	return;
	}
	MessageBox.Show("OK!");
}

C# Encrypting/Decrypting with Stream

This C# example demonstrates how to use Chilkat.Crypt2 to encrypt and decrypting using the .NET FileStream class:

    Chilkat.Crypt2 crypt = new Chilkat.Crypt2();
    bool success = crypt.UnlockComponent("Anything for 30-day trial");
    if (!success)
    {
        MessageBox.Show(crypt.LastErrorText);
        return;
    }

    crypt.CryptAlgorithm = "aes";
    crypt.CipherMode = "cbc";
    crypt.KeyLength = 128;

    crypt.SetEncodedIV("0000000000000000", "hex");
    crypt.SetEncodedKey("abcdefghijklmnop", "ascii");

    // Open input and output files as file streams...
    FileStream fsIn = File.OpenRead("hamlet.xml");
    FileStream fsOut = File.Create("encrypted.dat");

    crypt.FirstChunk = true;
    crypt.LastChunk = false;
    byte [] encryptedChunk;

    // Encrypt the stream in 1024 byte chunks.
    byte[] b = new byte[1024];

    int n;
    while ((n = fsIn.Read(b, 0, b.Length)) > 0)
    {
        if (n < b.Length)
        {
            // Don't encrypt the full 1024 bytes, only the amount read...
            byte[] tmp = new byte[n];
            int i;
            for (i = 0; i < n; i++) tmp[i] = b[i];
            encryptedChunk = crypt.EncryptBytes(tmp);
        }
        else
        {
            encryptedChunk = crypt.EncryptBytes(b);
        }

        fsOut.Write(encryptedChunk, 0, encryptedChunk.Length);
        crypt.FirstChunk = false;
    }
    fsIn.Close();

    // Flush any remaining encrypted data.
    crypt.LastChunk = true;
    byte[] empty = { };
    encryptedChunk = crypt.EncryptBytes(empty);
    if (encryptedChunk.Length > 0)
    {
        fsOut.Write(encryptedChunk, 0, encryptedChunk.Length);
    }
    fsOut.Close();


    // Now decrypt in chunks.  The decryptor must know when the last
    // block is being processed so it may unpad it correctly.

    System.IO.FileInfo fi = new System.IO.FileInfo("encrypted.dat");
    long fileSize = fi.Length;
    int numChunks = (int)fileSize / b.Length;

    fsIn = File.OpenRead("encrypted.dat");
    fsOut = File.Create("decrypted.xml");

    crypt.FirstChunk = true;
    crypt.LastChunk = false;
    byte[] decryptedChunk;

    int idx;
    for (idx = 0; idx <= numChunks; idx++)
    {
        n = fsIn.Read(b, 0, b.Length);

        // Is this the last chunk?
        if (idx == numChunks)
        {
            // Decrypt only the amount read...
            byte[] lastBlock = new byte[n];
            int i;
            for (i = 0; i < n; i++) lastBlock[i] = b[i];
            crypt.LastChunk = true;
            decryptedChunk = crypt.DecryptBytes(lastBlock);
        }
        else
        {
            decryptedChunk = crypt.DecryptBytes(b);
        }

        fsOut.Write(decryptedChunk, 0, decryptedChunk.Length);
        crypt.FirstChunk = false;
    }
    fsIn.Close();
    fsOut.Close();

    MessageBox.Show("Finished!");

C# 3DES (Triple-DES) Test Vector

This post provides C# sample code for matching a test vector (known answer test).

3DES Settings:

  • ECB Mode
  • 192-bit key (i.e. 3 8-bit keys)
  • ASCII Key Bytes: 1234567890123456ABCDEFGH
  • ASCII Text to Encrypt: The quick brown fox jumped over the lazy dog
  • Pads with zero bytes
  • Hexadecimalized Encrypted Result:
    13d4d3549493d2870f93c3e0812a06de467e1f9c0bfb16c0
    70ede5cabbd3ca62f217a7ae8d47f2c7bf62eb309323b58b


C# Code:

    string keyAscii = "1234567890123456ABCDEFGH";
    byte[] key = ASCIIEncoding.ASCII.GetBytes(keyAscii);

    byte[] clearText = ASCIIEncoding.ASCII.GetBytes("The quick brown fox jumped over the lazy dog");

    TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
    des.KeySize = 192;
    des.Key = key;
    des.Mode = CipherMode.ECB;
    des.Padding = PaddingMode.Zeros;
    byte[] cipherText = des.CreateEncryptor().TransformFinalBlock(clearText, 0, clearText.Length);

3DES Code to match this test vector in other languages:
ASP: 3DES Test Vector
SQL Server: 3DES Test Vector
C#: 3DES Test Vector
C++: 3DES Test Vector
MFC: 3DES Test Vector
C: 3DES Test Vector
Delphi: 3DES Test Vector
Visual FoxPro: 3DES Test Vector
Java: 3DES Test Vector
Perl: 3DES Test Vector
PHP: 3DES Test Vector
Python: 3DES Test Vector
Ruby: 3DES Test Vector
VB.NET: 3DES Test Vector
Visual Basic: 3DES Test Vector
VBScript: 3DES Test Vector