Click here to Skip to main content
15,892,809 members
Articles / Programming Languages / C++

A Namespace Extension Toolkit

Rate me:
Please Sign up or sign in to vote.
4.78/5 (10 votes)
21 Mar 2006CPOL12 min read 84.9K   1.7K   42  
This article shows you how to build your own Windows Explorer interfaces to custom data.
/*
 Copyright 2005 Chad Yoshikawa
 http://www.ececs.uc.edu/~yoshikco
 yoshikco@ececs.uc.edu

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/
using System;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

using System.Diagnostics;
using System.IO;
using System.Net.Sockets;
using System.Net;

namespace CSharpFileSystem
{
	/// <summary>
	/// Handles reading and writing of basic types (string, buffers, ints, etc) to and from a socket connection
	/// </summary>
	public class IOLibrary
	{


		/// <summary>
		/// The maximum size of a read or write call in bytes
		/// </summary>
		public static int MAX_BUFFER_SIZE=1024*1024;
		/// <summary>
		/// The code representing failure (communicated between this and the NSE)
		/// </summary>
		public static int FAILURE_CODE = 0x00;
		/// <summary>
		/// Code indicating success 
		/// </summary>
		public static int SUCCESS_CODE = 0x01;

		/// <summary>
		/// Cannot create one of these -- use the static methods instead
		/// </summary>
		private IOLibrary()
		{
		} 

		/// <summary>
		/// Write a buffer to the output stream.
		/// This method writes the length of the buffer, then the buffer bytes.
		/// NOTE:  The buffer must be less than MAX_BUFFER_SIZE which is currently 1MB
		/// </summary>
		/// <param name="os">The output stream to write to</param>
		/// <param name="array">The array of bytes to write</param>
		public static void WriteBuffer(BinaryWriter os, byte[] array) {
			if ((array!=null) && (array.Length > 0) && (array.Length < MAX_BUFFER_SIZE)) {
				WriteInt(os,array.Length);
				os.Write(array);
			} else {
				WriteEmptyBuffer(os);
			}
		}

		/// <summary>
		/// Write an empty buffer is one with 0 length field and no bytes following it.
		/// </summary>
		/// <param name="os">The output stream to write to</param>
		public static void WriteEmptyBuffer(BinaryWriter os) {
			WriteInt(os,0);
		}

		/// <summary>
		/// Read a buffer from the wire.
		/// Buffers are represented by the buffer length (little-endian int) followed by that many bytes
		/// </summary>
		/// <param name="input_stream">The input stream to read from</param>
		/// <returns>An array representing the bytes read</returns>
		public static byte[] ReadBuffer(BinaryReader input_stream)  {
			byte[] buffer=null;

			int len = ReadInt(input_stream);
			if ((len!=0) && (len < MAX_BUFFER_SIZE)) {
				buffer = input_stream.ReadBytes(len);
			}
			return (buffer);
		}

	

		/// <summary>
		/// Write a string to the wire.  String values are converted to buffers (byte arrays) and then written
		/// using WriteBuffer.
		/// </summary>
		/// <param name="os">The wire</param>
		/// <param name="value">The string value.</param>
		public static void WriteString(BinaryWriter os, string value)  {
			if (value!=null) {
				byte[] array = System.Text.Encoding.Unicode.GetBytes(value);
				WriteBuffer(os,array);
			} else {
				WriteEmptyBuffer(os);
			}
		}


		/// <summary>
		/// Read a string from the wire.  Strings are represented by
		/// a length first, then a sequence of Unicode bytes.
		/// </summary>
		/// <param name="input_stream">The wire</param>
		/// <returns>A string</returns>
		public static String ReadString(BinaryReader input_stream)  {
			String ret=null;
			int len = ReadInt(input_stream);
			if ((len == 0) || (len > MAX_BUFFER_SIZE)) {
				ret = "";
			} else {
				byte[] buffer = input_stream.ReadBytes(len);
				ret = System.Text.UnicodeEncoding.Unicode.GetString(buffer);
			}
			return (ret);
		}


		/// <summary>
		/// Write a long value to the wire.  Longs are converted to byte arrays then written using WriteBuffer.
		/// </summary>
		/// <param name="os">the wire</param>
		/// <param name="value">the long value</param>
		public static void WriteLong(BinaryWriter os, long value)  {
			byte[] buffer = BitConverter.GetBytes(value);
			// only if wrong-endian
			// Array.Reverse(buffer);
			os.Write(buffer);
		}

		/// <summary>
		/// Read a long value from the wire.
		/// </summary>
		/// <param name="input_stream">the wire</param>
		/// <returns>a long value</returns>
		public static long ReadLong(BinaryReader input_stream)  {
			long ret = 0;
			byte[] buffer = input_stream.ReadBytes(8);
			// Array.Reverse(buffer);
			ret = BitConverter.ToInt64(buffer,0);
			return (ret);
		}

   
	
		/// <summary>
		/// Convert a serializable object to its byte array equivalent
		/// </summary>
		/// <param name="o">the obj</param>
		/// <returns>the bytes equivalent</returns>
		public static byte[] ConvertObjectToBytes(object o) {
			Debug.Assert(o!=null && o.GetType().IsSerializable); // make sure we can convert the object to bytes
			byte[] ret =null;
			try {
				MemoryStream stream = new MemoryStream();
				IFormatter formatter = new BinaryFormatter();
				formatter.Serialize(stream, o);
				stream.Flush();
				ret = stream.GetBuffer();
			} catch (Exception e) {
				Debug.WriteLine("Error convering object to bytes:"+e);
			}
			return (ret);
		}


		/// <summary>
		/// Read an object from the wire.
		/// An object is represented by a length followed by that many bytes.
		/// </summary>
		/// <param name="input_stream"></param>
		/// <returns></returns>
		public static object ReadObject(BinaryReader input_stream)  {
			object ret=null;
			try {
				byte[] buffer = ReadBuffer(input_stream);
				// now we have the buffer of bytes
				IFormatter formatter = new BinaryFormatter();
				Stream stream = new MemoryStream(buffer);
				ret = formatter.Deserialize(stream);
			} catch (Exception ex) {
				Debug.WriteLine("Error: "+ex);
				Debug.WriteLine(ex.StackTrace);
			}
			return (ret);
		}
	
		/// <summary>
		/// Convert bytes to the object
		/// </summary>
		/// <param name="buffer">the bytes</param>
		/// <returns>the object</returns>
		public static object ConvertBytesToObject(byte[] buffer) {
			Object ret = null;
			if (buffer == null) {
				return null;
			} 

			try {
				IFormatter formatter = new BinaryFormatter();
				Stream stream = new MemoryStream(buffer);
				ret = formatter.Deserialize(stream);
			} catch (Exception e) {
				Debug.WriteLine("Error converting bytes to object:"+e);
				Debug.WriteLine(e.StackTrace);
			}
			return (ret);
		}


		/// <summary>
		/// Read a result from the wire
		/// </summary>
		/// <param name="input_stream">wire</param>
		/// <returns>an int representing the result code</returns>
		public static int ReadResult(BinaryReader input_stream)  {
			int ret = FAILURE_CODE;
			// read the result code -- just an integer for now.
			ret = ReadInt(input_stream);
			return (ret);
		}

		/// <summary>
		/// Write a result (int) to the wire
		/// </summary>
		/// <param name="os">the wire</param>
		/// <param name="result">the value to write</param>
		public static void WriteResult(BinaryWriter os, int result)  {
			WriteInt(os,result);
		}

		/// <summary>
		/// Read an array of bytes from the wire
		/// </summary>
		/// <param name="input_stream">the wire</param>
		/// <param name="len">number of bytes to read</param>
		/// <returns>an array of size less than or equal to len</returns>
		public static byte[] ReadBytes(BinaryReader input_stream, int len) {
			if (len > MAX_BUFFER_SIZE) {
				return null;
			} else {
				byte[] ret = null;
				try {
					ret = input_stream.ReadBytes(len);
				} catch (Exception ex) {
					Debug.WriteLine("Error reading content:"+ex);
				}
				return (ret);
			}
		}

		/// <summary>
		/// Write an integer to the wire
		/// </summary>
		/// <param name="os">the wire</param>
		/// <param name="value">the integer to write</param>
		public static void WriteInt(BinaryWriter os, int value)  {
			byte[] buffer = BitConverter.GetBytes(value);
			//	Array.Reverse(buffer);
			os.Write(buffer);
		}

		/// <summary>
		/// Write a short value to the wire
		/// </summary>
		/// <param name="os">the wire</param>
		/// <param name="value">the value to write</param>
		public static void WriteShort(BinaryWriter os, short value)  {
			byte[] buffer = BitConverter.GetBytes(value);
			// Array.Reverse(buffer); // big endian
			os.Write(buffer);
		}


		/// <summary>
		/// Read an integer from the wire
		/// </summary>
		/// <param name="input_stream">the wire</param>
		/// <returns>the integer value read</returns>
		public static int ReadInt(BinaryReader input_stream)  {
			int ret=0;
			byte[] intAsBytes = input_stream.ReadBytes(4);
			// Array.Reverse(intAsBytes);
			ret = BitConverter.ToInt32(intAsBytes,0);
			return (ret);
		}

	} // end class
} // end namespace

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions