Click here to Skip to main content
15,881,424 members
Articles / Desktop Programming / MFC

Network Development Kit 2.0

Rate me:
Please Sign up or sign in to vote.
4.88/5 (114 votes)
29 Dec 2006CPOL 2.9M   25.7K   495  
Network Development Kit is a set of simple classes for a client-server architecture.
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// NDK 2.0 - Network Development Kit                                          //
//                                                                            //
// Authors: Sebastien Lachance                                                //
//                                                                            //
// E-mail:  netblitz@rocler.qc.ca                                             //
//                                                                            //
// -------------------------------------------------------------------------- //
//                                                                            //
// Permission to use, copy, modify, and distribute this software for any      //
// purpose and without fee is hereby granted. This is no guarantee about the  //
// use of this software. For any comments, bugs or thanks, please email us.   //
//                                                                            //
// -------------------------------------------------------------------------- //
//                                                                            //
// Targeted Platform: Any Windows version                                     //
//                                                                            //
// Last modification: December 2006                                           //
//                                                                            //
// History:                                                                   //
//                                                                            //
// 1- First release of this file.                                             //
// 2- The class is renamed and some optimizations are applied. Hungarian      //
//    notation is used.                                                       //
// 3- When serializing a message, the class scheme is serialized. When a      //
//    message is read, a verification is done to make sure it's a valid       //
//    message.                                                                //
// 4- Fix a bug concerning the parameter unLength in GetAt and GetNext.       //
//    A reference is now used.                                                //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Includes                                                                   //
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "NDKMessage.h"


////////////////////////////////////////////////////////////////////////////////
// Constructors / Destructor                                                  //
////////////////////////////////////////////////////////////////////////////////

// Constructor.
CNDKMessage::CNDKMessage()
{
	m_lCurrentIndex = 0;
}


// Constructor with a unique Id.
CNDKMessage::CNDKMessage(long lId)
{
	m_lId = lId;
	m_lCurrentIndex = 0;
}


// Copy-Constructor.
CNDKMessage::CNDKMessage(const CNDKMessage& message)
{
	m_lId = message.m_lId;
	m_lCurrentIndex = message.m_lCurrentIndex;
	m_elements.RemoveAll();

	m_elements.Append(message.m_elements);
}


// Destructor.
CNDKMessage::~CNDKMessage()
{
}


////////////////////////////////////////////////////////////////////////////////
// Attributes                                                                 //
////////////////////////////////////////////////////////////////////////////////
 
// Sets a unique identifier to each message.
void CNDKMessage::SetId(long lId)
{ 
	m_lId = lId;
}


// Gets the identifier of this message.
long CNDKMessage::GetId() const
{ 
	return m_lId; 
}


// Gets the number of elements in the array of this message.
int CNDKMessage::GetNbElements() const
{
	return (int)m_elements.GetSize();
}


////////////////////////////////////////////////////////////////////////////////
// Operations                                                                 //
////////////////////////////////////////////////////////////////////////////////

// The following methods are used to add at the end an element in the 
// internal array of the CNDKMessage to any value.

void CNDKMessage::Add(UCHAR ucData)
{
	m_elements.Add(CNDKMessageData(ucData));
}


void CNDKMessage::Add(char cData)
{
	m_elements.Add(CNDKMessageData(cData));
}


void CNDKMessage::Add(USHORT usData)
{
	m_elements.Add(CNDKMessageData(usData));
}


void CNDKMessage::Add(short sData)
{
	m_elements.Add(CNDKMessageData(sData));
}


void CNDKMessage::Add(UINT unData)
{
	m_elements.Add(CNDKMessageData(unData));
}


void CNDKMessage::Add(int nData)
{
	m_elements.Add(CNDKMessageData(nData));
}


void CNDKMessage::Add(ULONG ulData)
{
	m_elements.Add(CNDKMessageData(ulData));
}


void CNDKMessage::Add(long lData)
{
	m_elements.Add(CNDKMessageData(lData));
}


void CNDKMessage::Add(float fData)
{
	m_elements.Add(CNDKMessageData(fData));
}


void CNDKMessage::Add(double dData)
{
	m_elements.Add(CNDKMessageData(dData));
}


void CNDKMessage::Add(const CString& strData)
{
	m_elements.Add(CNDKMessageData(strData));
}


void CNDKMessage::Add(LPVOID pData, UINT unLength)
{
	m_elements.Add(CNDKMessageData(pData, unLength));
}


// The following methods are used to set an element at the specified index
// in the internal array of the CNDKMessage to any value. Index is 
// zero-indexed.

void CNDKMessage::SetAt(long lIndex, unsigned char ucData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(ucData));
}


void CNDKMessage::SetAt(long lIndex, char cData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(cData));
}


void CNDKMessage::SetAt(long lIndex, unsigned short usData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(usData));
}


void CNDKMessage::SetAt(long lIndex, short sData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(sData));
}


void CNDKMessage::SetAt(long lIndex, unsigned int unData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(unData));
}


void CNDKMessage::SetAt(long lIndex, int nData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(nData));
}


void CNDKMessage::SetAt(long lIndex, unsigned long ulData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(ulData));
}


void CNDKMessage::SetAt(long lIndex, long lData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(lData));
}


void CNDKMessage::SetAt(long lIndex, float fData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(fData));
}


void CNDKMessage::SetAt(long lIndex, double dData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(dData));
}


void CNDKMessage::SetAt(long lIndex, const CString& strData)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(strData));
}


void CNDKMessage::SetAt(long lIndex, LPVOID pData, UINT unLength)
{
	if (IsValidSetIndex(lIndex))
		m_elements.SetAtGrow(lIndex, CNDKMessageData(pData, unLength));
}


// Gets the data type at the specified index.
NDKDataType CNDKMessage::GetDataTypeAt(long lIndex) const
{
	NDKDataType dataType = NDKDataString;

	if (IsValidGetIndex(lIndex))
		dataType = m_elements.GetAt(lIndex).GetDataType();
	
	return  dataType;
}


// The following methods are used to get an element at the specified index
// in the internal array of the CNDKMessage. The parameter passed by 
// reference will be filled with the appropriate data. The type of data 
// extracted must match the type of data set with a previous call to 
// SetAt or Add. Index is zero-indexed.

void CNDKMessage::GetAt(long lIndex, UCHAR& ucData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(ucData));
}


void CNDKMessage::GetAt(long lIndex, char& cData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(cData));
}


void CNDKMessage::GetAt(long lIndex, USHORT& usData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(usData));
}


void CNDKMessage::GetAt(long lIndex, short& sData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(sData));
}


void CNDKMessage::GetAt(long lIndex, UINT& unData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(unData));
}


void CNDKMessage::GetAt(long lIndex, int& nData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(nData));
}


void CNDKMessage::GetAt(long lIndex, ULONG& ulData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(ulData));
}


void CNDKMessage::GetAt(long lIndex, long& lData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(lData));
}


void CNDKMessage::GetAt(long lIndex, float& fData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(fData));
}


void CNDKMessage::GetAt(long lIndex, double& dData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(dData));
}


void CNDKMessage::GetAt(long lIndex, CString& strData) const
{
	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(strData));
}


void CNDKMessage::GetAt(long lIndex, LPVOID pData, UINT& unLength) const
{
	ASSERT(pData != NULL);

	if (IsValidGetIndex(lIndex))
		VERIFY(m_elements.GetAt(lIndex).Get(pData, unLength));
}


// Resets the current index. The current index is used by GetNext method.
void CNDKMessage::ResetCurrentIndex()
{
	m_lCurrentIndex = 0;
}


// Gets the current index.
long CNDKMessage::GetCurrentIndex() const
{
	return m_lCurrentIndex;
}


// Returns if the current index is the last.
BOOL CNDKMessage::IsLastCurrentIndex()
{
	return m_lCurrentIndex >= m_elements.GetSize();	
}


// The following methods are used to get an element in the internal array of 
// the CNDKMessage using the current index. The parameter passed by 
// reference will be filled with the appropriate data. The type of data 
// extracted must match the type of data set with a previous call to 
// SetAt or Add. 
void CNDKMessage::GetNext(UCHAR& ucData)
{
	GetAt(m_lCurrentIndex++, ucData);
}


void CNDKMessage::GetNext(char& cData)
{
	GetAt(m_lCurrentIndex++, cData);
}


void CNDKMessage::GetNext(USHORT& usData)
{
	GetAt(m_lCurrentIndex++, usData);
}


void CNDKMessage::GetNext(short& sData)
{
	GetAt(m_lCurrentIndex++, sData);
}


void CNDKMessage::GetNext(UINT& unData)
{
	GetAt(m_lCurrentIndex++, unData);
}


void CNDKMessage::GetNext(int& nData)
{
	GetAt(m_lCurrentIndex++, nData);
}


void CNDKMessage::GetNext(ULONG& ulData)
{
	GetAt(m_lCurrentIndex++, ulData);
}


void CNDKMessage::GetNext(long& lData)
{
	GetAt(m_lCurrentIndex++, lData);
}


void CNDKMessage::GetNext(float& fData)
{
	GetAt(m_lCurrentIndex++, fData);
}


void CNDKMessage::GetNext(double& dData)
{
	GetAt(m_lCurrentIndex++, dData);
}


void CNDKMessage::GetNext(CString& strData)
{
	GetAt(m_lCurrentIndex++, strData);
}


void CNDKMessage::GetNext(LPVOID pData, UINT& unLength)
{
	GetAt(m_lCurrentIndex++, pData, unLength);
}


// Serializes a CNDKMessage object to a CArchive
IMPLEMENT_SERIAL(CNDKMessage, CObject, VERSIONABLE_SCHEMA | 1)
void CNDKMessage::Serialize(CArchive& archive)
{	
	TRY
	{
		archive.SerializeClass(RUNTIME_CLASS(CNDKMessage));
	
		if (archive.IsStoring())
		{
			archive << m_lId;
			archive << (int)m_elements.GetSize();

			for (int nIndex = 0; nIndex < m_elements.GetSize(); nIndex++)
				m_elements.GetAt(nIndex).Serialize(archive);
		}
		else
		{
			if (archive.GetObjectSchema() == 1)
			{
				int nNbElements = 0;

				archive >> m_lId;
				archive >> nNbElements;

				if (nNbElements > 0)
				{
					m_elements.SetSize(nNbElements);

					for (int nIndex = 0; nIndex < nNbElements; nIndex++)
					{
						CNDKMessageData	messageData;

						messageData.Serialize(archive);
					
						m_elements.SetAt(nIndex, messageData);
					}
				}
			}
		}

		ResetCurrentIndex();
	}
	CATCH(CArchiveException, e)
	{
		AfxThrowArchiveException(e->m_cause);
	}
	END_CATCH
}


////////////////////////////////////////////////////////////////////////////////
// Operators                                                                  //
////////////////////////////////////////////////////////////////////////////////

// Assignment operator.
const CNDKMessage& CNDKMessage::operator=(const CNDKMessage& message)
{
	if (&message != this)
	{
		m_lId = message.m_lId;
		m_lCurrentIndex = message.m_lCurrentIndex;
		m_elements.RemoveAll();

		m_elements.Append(message.m_elements);
	}

	return *this;
}


////////////////////////////////////////////////////////////////////////////////
// Private Attributes                                                         //
////////////////////////////////////////////////////////////////////////////////

// Returns if the index is valid for the array of elements when setting a
// value.
BOOL CNDKMessage::IsValidSetIndex(long lIndex) const
{
	ASSERT(lIndex >= 0);

	return lIndex >= 0;
}


// Returns if the index is valid for the array of elements when getting a
// value.
BOOL CNDKMessage::IsValidGetIndex(long lIndex) const
{
	ASSERT((lIndex >= 0) && (lIndex < m_elements.GetSize()));

	return (lIndex >= 0) && (lIndex < m_elements.GetSize());
}

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
Software Developer (Senior) Mirego
Canada Canada
My name is Sébastien Lachance.

I love C# developing Windows Phone and Windows 8 applications.

When I’m not in front of a computer, my hobbies include playing bridge, poker and other card games, biking, reading technology news.

Comments and Discussions