pack serial

原创 2012年03月26日 10:33:26
#ifndef __pack_h__
#define __pack_h__
#include <string>

static bool is_big_endian()
{
	static unsigned short test_number = 0x1234;
	static bool fIsBigEndian = ( *( (char*)(&test_number) ) == 0x12 );
	return fIsBigEndian;
}

static int limit_max(int input, int max)
{
	return ( input > max && max > 0 )?max:input;
}

template<class T>
T exchange_value(T val)
{
	T retval = val;
	if( !is_big_endian() )
	{
		int ibytes = (int) sizeof( T );
		for( int i = 0; i < ibytes; i++ )
		{
			*( ( (char*)&retval )+i ) = *( ( (char*)&val ) + ibytes - 1 - i );
		}
	}
	return retval;
}

class TPack
{
public:
	typedef enum{PACK=0, UNPACK} PACK_CODE;
	static int		MAX_PACK_SIZE;
public:
	TPack( PACK_CODE code, int cbmax = MAX_PACK_SIZE )
	{
		m_ctlCode = code;
		m_pdata = 0;
		m_cbdata = 0;
		m_offset = 0;
		allocbuffer( cbmax );
	}
	virtual ~TPack()
	{
		destroy();
	}
private:
	void destroy()
	{
		free( m_pdata );
		m_pdata = 0;
		m_cbdata = 0;
		m_offset = 0;
	}

protected:
	TPack& operator<<(__int8 ch1)
	{
		pack_data( &ch1, 1 );
		return *this;
	}
	TPack& operator<<(__int16 ch2)
	{
		__int16 val = exchange_value<__int16>(ch2);
		pack_data( (char*)&val, 2 );
		return *this;
	}
	TPack& operator<<(__int32 ch4)
	{
		__int32 val = exchange_value<__int32>(ch4);
		pack_data( (char*)&val, 4 );
		return *this;
	}
	TPack& operator<<(__int64 ch8)
	{
		__int64 val = exchange_value<__int64>(ch8);
		pack_data( (char*)&val, 8 );
		return *this;
	}
	TPack& operator<<(bool b)
	{
		__int8 ch1 = b?1:0;
		(*this)<<ch1;
		return *this;
	}
	TPack& operator<<(float f)
	{
		__int32 ch4 = 0;
		memcpy(&ch4, &f, 4);
		(*this)<<ch4;
		return *this;
	}
	TPack& operator<<(double dbl)
	{
		__int64 ch8 = 0;
		memcpy(&ch8, &dbl, 8);
		(*this)<<ch8;
		return *this;
	}

	TPack& operator>>(__int8& ch1)
	{
		unpack_data( &ch1, 1 );
		return *this;
	}
	TPack& operator>>(__int16& ch2)
	{
		__int16 val = 0;
		unpack_data( (char*)&val, 2 );
		ch2 = exchange_value<__int16>(val);
		return *this;
	}
	TPack& operator>>(__int32& ch4)
	{
		__int32 val = 0;
		unpack_data( (char*)&val, 4 );
		ch4 = exchange_value<__int32>(val);
		return *this;
	}
	TPack& operator>>(__int64& ch8)
	{
		__int64 val = 0;
		unpack_data( (char*)&val, 8 );
		ch8 = exchange_value<__int64>(val);
		return *this;
	}
	TPack& operator>>(bool& b)
	{
		__int8 ch1 = 0;
		(*this)>>ch1;
		b = ( ch1 != 0 );
		return *this;
	}
	TPack& operator>>(float& f)
	{
		__int32 ch4 = 0;
		(*this)>>ch4;
		memcpy(&f, &ch4, 4);
		return *this;
	}
	TPack& operator>>(double& dbl)
	{
		__int64 ch8 = 0;
		(*this)>>ch8;
		memcpy(&dbl, &ch8, 8);
		return *this;
	}

	void pack_data( const char* pdata, int cbdata )
	{
		if( m_ctlCode == UNPACK || pdata == 0 || cbdata <=0 || ( m_cbdata+cbdata ) > m_cbmax )
			throw "pack data error!";
		memcpy( m_pdata+m_offset, pdata, cbdata );
		m_offset += cbdata;
		m_cbdata = m_offset;
	}
	void unpack_data( char* pdata, int cbdata )
	{
		if( m_ctlCode == PACK || pdata == 0 || cbdata <=0 || ( m_offset+cbdata ) > m_cbmax )
			throw "unpack data error!";
		memcpy( pdata, m_pdata+m_offset, cbdata );
		m_offset += cbdata;
	}

	bool ispacking()
	{
		return ( m_ctlCode == PACK ) ;
	}

public:
	bool allocbuffer( int size )
	{
		if( m_pdata == 0 )
		{
			m_pdata = (char*) malloc ( size );
			m_cbmax = size;
		}
		else if( size > m_cbmax )
		{
			m_pdata = (char*) realloc ( m_pdata, size );
			m_cbmax = size;
		}
		return ( m_pdata != 0 );
	}

	bool copydata( char* pdata, int cbdata )
	{
		if( allocbuffer( cbdata ) && ( pdata != 0 ) )
		{
			return serial( pdata, cbdata );
		}
		return false;
	}

	template<class T>
	bool serial( T& val )
	{
		try
		{
			if( ispacking() )
			{
				(*this)<<val;
			}
			else
			{
				(*this)>>val;
			}
			return true;
		}
		catch(char* strerr)
		{
			printf( "%s\n", strerr );
		}
		return false;
	}

	bool serial( char* pdata, int size )
	{
		try
		{
			if( ispacking() )
			{
				pack_data( pdata, size );
			}
			else
			{
				unpack_data( pdata, size );
			}
			return true;
		}
		catch(char* strerr)
		{
			printf( "%s\n", strerr );
		}
		return false;
	}

	bool serial( std::string& str, int maxsize = -1 )
	{
		try
		{
			if( ispacking() )
			{
				int ilen = limit_max( str.length(), maxsize );
				(*this) << ilen;
				if( ilen > 0 )
					serial( (char*)str.c_str(), ilen );
			}
			else
			{
				int ilen = 0;
				str.empty();
				(*this) >> ilen;
				ilen = limit_max( ilen, maxsize );
				if( ilen > 0 )
				{
					char* pdata = (char*) malloc ( ilen+1 );
					*( pdata + ilen ) = 0;
					serial( pdata, ilen );
					str.assign(pdata, ilen+1);
				}
			}
			return true;
		}
		catch(char* strerr)
		{
			printf( "%s\n", strerr );
		}
		return false;
	}

	bool serial( std::wstring& str, int maxsize = -1 )
	{
		try
		{
			if( ispacking() )
			{
				int ilen = limit_max( str.length(), maxsize ) * 2;
				(*this) << ilen;
				if( ilen > 0 )
					serial( (char*)str.c_str(), ilen );
			}
			else
			{
				int ilen = 0;
				str.empty();
				(*this) >> ilen;
				ilen = limit_max( ilen, maxsize );
				if( ilen > 0 )
				{
					char* pdata = (char*) malloc ( ilen+2 );
					*( pdata + ilen ) = 0;
					*( pdata + ilen + 1 ) = 0;
					serial( pdata, ilen );
					str.assign((wchar_t*)pdata, ilen/2);
				}
			}
			return true;
		}
		catch(char* strerr)
		{
			printf( "%s\n", strerr );
		}
		return false;
	}

	void reset(PACK_CODE code)
	{
		m_ctlCode = code;
		m_offset = 0;
	}
	char* data() const
	{
		return m_pdata;
	}
	char* wdata()
	{
		return m_pdata;
	}
	int size() const
	{
		return m_cbdata;
	}
private:
	PACK_CODE	m_ctlCode;
	char*			m_pdata;
	int				m_cbdata;
	int				m_offset;
	int				m_cbmax;
};

int TPack::MAX_PACK_SIZE = 102400;

#endif

C++ boost::asio::serial_port 串口通信类 使用 封装 [大三四八九月实习]

串口一旦存在后,C++ boost::asio就当串口为一种流(文件流 )来使用。 C++的BOOST库中,通信库都在asio下,串口类结构为boost::asio::serial_port。串...

linux下TTY驱动(serial)

之前因为是刚入门所以看了串口有关的东西,一开始看了stm32f407上的串口编程(Keil MDK),那算是裸的驱动了。   linux下的串口如果要正常工作的话,就必须通过TTY这个子系统,TTY子...

Ubutun Linux下如何安装 USB-Serial的转换驱动?

Ubutun Linux下如何安装 USB-Serial的转换驱动

简介JVM的Serial及ParNew收集器

Serial: 串行收集器,JVM client模式下的默认收集器,使用复制算法,在进行垃圾回收时会暂停其他所有的工作线程(stop the world,简称STW)直至回收结束,因此会影响用户的正常...

usb serial驱动流程分析

说明:usb serial驱动在主机侧(一般是PC侧)枚举成USB串口,在从设备侧(一般是手机侧)提供tty接口,提供一个主机和从设备通信的机制。本文档主要描述设备侧驱动从主机侧接收到数据后如何通知应...

linux serial构架分析及驱动开发(3)

转载: 这一节我们将介绍一个serial驱动的实例,后面各节中也将以这个例子来分析串口各种操作的实际情景(例子是at91sam9260板子的串口驱动)。    该驱动将串口看作平...

Serial模式下的GC测试

环境: windows7 64bit JDK1.7.0_07 测试1:没有手动分配任何对象时的内存状况 VM参数:-XX:+UseSerialGC -Xmx20m -Xms20m -verbo...
  • fanwu72
  • fanwu72
  • 2013年05月18日 20:29
  • 400

路由的Serial,BRI,AUX,AUI等端口的区别是什么?都有什么作用?

      各种交换机的数据接口类型作为局域网的主要连接设备,以太网交换机成为应用普及最快的网络设备之一,同时,也是随着这种快速的发展,交换机的功能不断增强,随之而来则是交换机端口的更新换代以及各种特...

Arduino代码机制-Serial下

真正开始讲串口了。串口是流的具体实现。串口在类HardwareSerial中描述。类HardwareSerial在Stream的基础上,添加了发送和接收数据缓冲区,实际上是个队列,添加了构造函数和其他...

linux serial构架分析及驱动开发

前面介绍了tty核心分析及tty驱动开发的方法,tty设备包括串口、终端、伪终端三大类,其中终端和伪终端驱动内核都帮我们实现好了,很少需要改动。因此我们主要介绍串口驱动的开发及其在内核中的构架(其核心...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:pack serial
举报原因:
原因补充:

(最多只允许输入30个字)