Click here to Skip to main content
15,886,519 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.5K   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, and other source files, were derived from two GPL'd sources:
 "An Almost Complete Namespace Extension Sample"
 http://www.codeproject.com/shell/NamespaceExtImpl.asp
 Copyright 2005 Pascal Hurni

 AdfView
 http://www.viksoe.dk/code/adfview.htm
 Written by Bjarke Viksoe
 Copyright (c) 2001-2002 Bjarke Viksoe.

 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

*/
#pragma once

#include <Winsock2.h>
#include <string>

/// This is a set of helper functions that enable us to send/receive data types over-the-wire
class IOLibrary {

public:

	/// Write a buffer to a socket
	/// @param mySocket the socket to write to
	/// @param buf the buffer to write
	/// @param length the number of bytes to write
	static void WriteBuffer(SOCKET mySocket, char* buf, int length) {
		int num_written = 0;
		int ret_value;
		//char BUFFER[1024];
		while (num_written < length) {
			ret_value = send(mySocket,buf+num_written,length-num_written,NULL);
			if (ret_value == SOCKET_ERROR) {
				// error
				CGalaxyUtils::TraceTime("Error when writing to socket");
			}
			num_written+=ret_value;
		} // END WHILE
	} // END WRITEBUFFER

	/// Read a buffer from a socket
	/// @param mySocket the socket to read from
	/// @param buf the buffer to read into
	/// @param length the number of bytes to read
	static void ReadBuffer(SOCKET mySocket, char* buf, int length) {
		int num_read = 0;
		while (num_read < length) {
			num_read+= recv(mySocket,buf+num_read,length-num_read,NULL);
		}
	}
 
	/// A templated method to convert a primitive type to an array of bytes
	/// @param arg the object to convert
	/// @return a buffer of bytes representing the primivive type, to be freed by the caller
	template <class T>
		static char* ConvertToByteArray(T arg) {
			char * ret = new char[sizeof(T)];
			for (int i=0;i<sizeof(arg); i++) {
				int offset = i*8;
				ret[i] = (arg& (0xff << offset)) >> offset;
			} // end for
			return (ret);
		} // end ConvertToByteArray


		/// A templated method to convert an array of bytes back to a primitive type
		/// @param buf the buffer to convert
		/// @return the primitive type, reconstituted.
		template <class T>
			static T ConvertBytesTo(byte *buf) {
				T ret = 0x0;
				for (int i=0;i<sizeof(T); i++) {
					int offset = i*8;
					ret |= buf[i] << offset;
				} // end for
				return (ret);
			}


	/// Convert a bunch of bytes to a wide string
	/// @param buf the pointer to the byte buffer
	/// @param num_bytes the number of bytes (not characters)
	/// @return the new wide string
	static std::wstring ConvertBytesToString(byte* buf, int num_bytes) {
		std::wstring ret;
		ret.reserve(num_bytes/sizeof(wchar_t));
		wchar_t c;
		for (unsigned int i=0;i<num_bytes/sizeof(wchar_t);i++) {
			c = buf[i*2] | buf[i*2+1] << 8;
			ret +=c;
		}
		return (ret);
	} // end ConvertToByteArray

	
	/// A templated method to write a primitive value to the socket
	/// @param mySocket the socket to write to
	/// @param arg the value to write
	template <class T>
	static void Write(SOCKET mySocket,T arg) {
		char* buf= ConvertToByteArray<T>(arg);
		WriteBuffer(mySocket,buf,sizeof(arg));
		delete[] buf;
	}

	/// Write a unicode string to a socket
	/// @param mySocket the socket
	/// @param str the string to write
	static void WriteString(SOCKET mySocket,std::wstring str) {
		int num_bytes = (int)(str.length()*sizeof(wchar_t));
		IOLibrary::Write<int>(mySocket,num_bytes);
		IOLibrary::WriteBuffer(mySocket, (char*)(str.c_str()),num_bytes);
	}

	/// Templated method to read a primitive type from a socket
	/// @param mySocket the socket
	/// @return the primitive type
	template <class T>
	static T Read(SOCKET mySocket) {
		byte buf[sizeof(T)];
		ReadBuffer(mySocket,(char*)buf,sizeof(T));
		T ret = ConvertBytesTo<T>(buf);
		return (ret);
	}

	/// Read a string from a socket
	/// @param mySocket the socket
	/// @return the unicode string
	static std::wstring ReadString(SOCKET mySocket) {
		int num_bytes = Read<int>(mySocket);
		byte *buf = new byte[num_bytes];
		ReadBuffer(mySocket,(char*)buf,num_bytes);
		std::wstring ret = ConvertBytesToString(buf,num_bytes);
		delete[] buf;
		return (ret);

	}

	

};

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