رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران
  • 1
فرهاد شیری

کلاس کمکی Byte Helper


سوال

در خیلی از پروژه هایی تجاری که برای سخت افزارهای مشخصی نرم افزار ویا Frame Ware تولید میکنید.(مثال درایور نویسی ویا ماژولهای کنترلی سخت افزار و...  ) 

اغلب اوقات به دستوراتی ازقبیل memcpy , memset ,std::copy ,... جهت جایگذاری بیت ها وبایت های لازم به طور قطع به یقین از دستورات فوق استفاده میکنیم، لذا کلاس فوق اغلب این توابع را در اختیارتان قرار میدهد که برای برنامه نویسی شی گرا بهینه شده است.

در صورتی که پیشنهادی جهت بهبود این کلاس داشتید لطفا دریغ نفرمایید.

#ifndef BYTEHELPER_H_
#define BYTEHELPER_H_

/*#define WRITE_BYTE(type,arg1,arg2) \
	ByteHelper::getInstance()->write_Byte<type>(arg1,arg2)
 #define WRITE_BYTES(arg1,arg2)     \
	ByteHelper::getInstance()->write_Bytes(arg1,arg2)
 #define WRITE_BYTES2(arg1,arg2,arg3)     \
	ByteHelper::getInstance()->write_Bytes(arg1,arg2,arg3)
 #define WRITE_BYTES_COPY(type,arg1,arg2,arg3,arg4) \
	ByteHelper::getInstance()->write_Bytes_Copy<type>(arg1,arg2,arg3,arg4)
 #define WRITE_BYTES_COPY2(type,arg1,arg2) \
	ByteHelper::getInstance()->write_Bytes_Copy<type>(arg1,arg2)
 #define CLEAR_BYTES(arg1)          \
	ByteHelper::getInstance()->clear_Bytes(arg1)*/

#include "MyException.h"
#include "unique_ptr.h"
#include <string.h>
#include <iterator>
#include <algorithm>
#include <sstream>

#include "test_template.h"
#include "const.h"

class ByteHelper
{
private:
	//defined private ctor! because can not create object.
	//must be create object calling static factory method getInstance();

	ByteHelper(ByteHelper&);//Copy ctor
	ByteHelper& operator=(ByteHelper&);//Copy Assignment operator

	static void deletePointer(ByteHelper* tp)
	{
		if (tp != NULL)
		{
			delete tp;
			tp = NULL;
		}
	}

public:
	ByteHelper() :
		pBinaryHelper(new binaryFormatHelper)
	{
	} //Default ctor

	~ByteHelper()
	{
	}

	//static ctor
	inline static const uniqueptr<ByteHelper>& getInstance()
	{
		static const uniqueptr<ByteHelper> pByteHelper(new ByteHelper,
				&deletePointer);
		return pByteHelper;
	}

	template<typename _R, size_t N>
	inline void*
	clear_Bytes(_R(&sourceData)[N])
	{
		return memset(sourceData,0,N);
	}
    /*
     * clear_bytes because overloaded if sourcedata
     * is C style Array sending into class must be sending array size into function
     * and if sourcedata is pointer to array no needed array size.!
     */
	template<typename _R>
	inline void*
	clear_Bytes(_R* sourceData, size_t size)
	{
		return memset(sourceData, 0, size > 0 ? size : sizeof(sourceData));
	}

	template<typename _CAST_TYPE, typename _R, typename _T>
	inline bool write_Byte(_R* restrict_to, const _T& restrict_from)
	{
		try
		{
			*((_CAST_TYPE) restrict_to) = restrict_from;
		} catch (MyException& E)
		{
			return false;
		}
		return true;
	}

	template<typename _R, typename _T>
	inline bool convert_Byte(_R* restrict_to, _T* restrict_from)
	{
		try
		{
			restrict_to = *(reinterpret_cast<_R> (restrict_from[0]));
		} catch (MyException& E)
		{
			return false;
		}
		return true;
	}

	template<typename _R, typename _T>
	inline _R* write_Bytes(_R* restrict_to,
			const _T* restrict_from, size_t size = 0)
	{
		try
		{
			memcpy(restrict_to, restrict_from, size > 0 ? size : sizeof(restrict_from));
		} catch (MyException& E)
		{
			return 0;
		}
		return restrict_to;
	}
	template<typename _R, typename _T>
	inline _R* copy_Bytes(_R* restrict_to, const _T* restrict_from,
			int beginOffset = 0, int writeSizeToDest = 0)
	{
		try
		{
			int tmp_size = writeSizeToDest > 0 ? writeSizeToDest
					: sizeof(restrict_to);
			std::copy(restrict_from + beginOffset, restrict_from + tmp_size,reinterpret_cast<_R*>(restrict_to));
		} catch (MyException& E)
		{
			return 0;
		}
		return restrict_to;
	}

	template<typename _R, typename _T>
	_R* xChangeBuffer(_R* const restrict_to , const _T* const restrict_from) const
	{
		if (restrict_from != NULL)
		{
			getInstance()->clear_Bytes(restrict_to, sizeof(restrict_to));
			getInstance()->write_Bytes(restrict_to, restrict_from, sizeof(restrict_from));
		}

		return restrict_to;
	}

	template<typename _R, typename _T>
	_R* xChangeBuffer(_R* const restrict_to , const _T* const restrict_from)
	{
		if (restrict_from != NULL)
		{
			clear_Bytes(restrict_to, sizeof(restrict_to));
			write_Bytes(restrict_to, restrict_from, sizeof(restrict_from));
		}

		return restrict_to;
	}
	template<class Tp>
	class OutputStream: std::ostream_iterator<Tp>
	{
	public:
		~OutputStream()
		{
		}
		typedef std::ostream_iterator<Tp> ostream_ptr;
		OutputStream(const byte* format, std::ostream& os_type) :
			std::ostream_iterator<Tp>(os_type, format)
		{
		}

		template<typename T>
		void operator()(T container)
		{
			std::copy(container.begin(), container.end(), *this->get());
		}

	private:
		const ostream_ptr* get() const
		{
			return static_cast<const ostream_ptr*> (this);
		}
	};

	template<class T>
	inline static const ByteHelper::OutputStream<T>& getOutPutStreamInstance(
			const byte* format)
	{
		static ByteHelper::OutputStream<T> m_outPutStream(format, std::cout);
		return m_outPutStream;
	}

	class binaryFormatHelper
	{

	private:
		/* Consent */
		static const udword INT_SIZE = sizeof(dword) * BYTE_BIT_SIZE; //32
		static const word CHAR_SIZE = sizeof(byte) * BYTE_BIT_SIZE; // 8

	public:

		const byte* bytesToHex(const PBYTE const source_hex, word qtyByte)
		{
			Ostream ss;
			for (word i = qtyByte ; i >= 0; i--)
			{
				if (source_hex + i)
					ss << std::hex << (dword) *(source_hex + i );
			}
			if (ss.str().c_str())
			{
				return ss.str().c_str();
			}
			else
			{
               static const byte emptyStream[]={'-' , '\0'};
               return emptyStream;
			}
		}

		udword evaluateNumFromString(const PBYTE const str, const dword len)
		{
			udword number = 0;
			word bitShift = INT_SIZE;
			if (len > 1)
			{
				for (dword i = 0; i < len; i++)
				{
					bitShift -= CHAR_SIZE;
					number += (BYTE) *(str + i) << bitShift;
				}
			}
			else if (len == 1)
			{
				number = (BYTE) *(str + 0);
			}
			return number;
		}

		void printBinary32(udword srcNum, byte* const destBuffer)
		{
			register udword bit;
			udword cnt = 0;
			dword index = 0;
			size_t sz = sizeof(dword) * 8;
			for (bit = 1 << (sz - 1); bit > 0; bit >>= 1 /*i/=2*/)
			{
				if (++cnt == 5)
				{
					*(destBuffer + index++) = '-';
					cnt = 1;
				}
				*(destBuffer + index++) = (srcNum & bit) ? '1' : '0';
			}
		}

		template<class T, size_t N>
		void writeBinary(const PBYTE const src_data, T(&dest_data)[N],
				dword src_index, dword beginOffset, dword endOffset)
		{

			//1- evaluation of the numerical value of a byte array.
			udword eval_num = evaluateNumFromString(reinterpret_cast<const PBYTE> (&src_data[src_index]) , 1);

			//2- write the binary values into temporary byte array.
			byte tmpBuf[BINARY_PATTERN_SIZE];
			getInstance()->clear_Bytes(tmpBuf);
			printBinary32(eval_num, tmpBuf);

			//3- copy needed byte from temporary byte array into destination byte array.
			getInstance()->clear_Bytes(dest_data);
			getInstance()->copy_Bytes(dest_data, tmpBuf, beginOffset,endOffset);
		}

	};
	const uniqueptr<binaryFormatHelper> pBinaryHelper;

};

#endif /* BYTEHELPER_H_ */
class MyException: public std::exception {

public:

	MyException(std::string errMsg)  {
		printStackTrace(errMsg.c_str());
	}
	MyException(const MyException &);

	static void destory(MyException *my) {
		delete my;
	}

	const char* what() {
		return std::exception::what();
	}

	void printStackTrace(const char* cError) const {
        std::cout <<"Error ->" << cError;  
	}
private:
	CoutPrinter printer;

};

فقط بجای کلاس unique_ptr از کلاسهای std::unique_ptr در memory.h استفاده نمایید.

تابع ()getInstance جهت استفاده از توابع کلاس فوق نیازی به ایجاد یک شی جدید از کلاس فوق ندارید با استفاده از متد فوق می توانید یک سازنده استاتیک داشته باشید.

در صورتی که مفید بود! بفرمایید متدهای الباقی راهم توضیح بدم.

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

0 پاسخ به این سوال تا کنون داده شده است

پست های پیشنهاد شده

هنوز برای این سوال پاسخی ارسال نشده است

مهمان
این موضوع برای عدم ارسال قفل گردیده است.

  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

×
×
  • جدید...