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

perl中pack函数的用法

pack接收一个普通 Perl 数值的 LIST 并且根据 TEMPLATE 把它们转换成一个字节串并且返回 该字串。它的用法如下              pack TEMPLATE, LIST ...
  • jiangzhao526
  • jiangzhao526
  • 2013年12月17日 16:22
  • 1292

C++ #pragma pack()解析

我们知道计算机系统对基本数据类型在内存中的存放是有一定限制的,通常我们会要求这些数据的首地址的值是某个数的倍数(4或8),这就是所谓的内存对齐。       而每个平台上的编译器都有着自己的“默认对齐...
  • misayaaaaa
  • misayaaaaa
  • 2017年04月10日 09:08
  • 1040

#pragma pack()用法详解

1.什么是对齐?为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各...
  • lime1991
  • lime1991
  • 2015年03月22日 11:20
  • 2523

#pragma pack([n|push|pop]) 用法

#pragma pack(): 取消用户自定义的结构体成员(或类的数据成员)的对齐方式,恢复编译器默认的对齐方式(VC++和GCC编译器默认8个字节对齐,并且,我们可以在编译器的设置里更改编译器的默...
  • crazywdy
  • crazywdy
  • 2014年06月23日 14:15
  • 3839

#Pragma Pack(n)与内存分配 pragma pack(push,1)与#pragma pack(1)的区别

from:http://blog.csdn.net/mylinx/article/details/7007309  #pragma pack(n) 解释一: 每个特定平台上的...
  • aidem_brown
  • aidem_brown
  • 2017年08月24日 20:20
  • 932

Tkinter教程之Pack篇

Tkinter教程之Pack篇#Pack为一布局管理器,可将它视为一个弹性的容器1.一个空的widget#不使用pack# -*- coding: cp936 -*-from Tkinter impo...
  • jcodeer
  • jcodeer
  • 2007年10月06日 15:59
  • 11631

#pragram pack(0) pack(1) pack(2) pack(4) StructLayoutAttribute ::Pack 字段

StructLayoutAttribute ::Pack 字段 控制类或结构的数据字段在内存中的对齐方式。 命名空间:   System.R...
  • hezikui1987
  • hezikui1987
  • 2013年10月08日 10:58
  • 1130

记录#pragma pack()的问题

在Cortex M0平台上做开发的时候,遇到一个纠结了两三天的问题。 代码添加了PWM马达控制后,继续做USB复合设备。在做好USB复合设备,发现原来的PWM马达控制不起作用了,首先对比了模块的寄存...
  • dndxhej
  • dndxhej
  • 2014年01月28日 17:56
  • 8927

php 的pack方法

今天在弄这个pack方法,但是真不知道如何写下来,感觉很纷乱 pack--压缩资料到位字符串之中。 语法:string pack(string format, mixed [args]...); ...
  • zhuoxiong
  • zhuoxiong
  • 2012年03月16日 17:36
  • 13027

结构体拷贝内存 与 #parama pack (1)

结构体内存拷贝与#parama pack (1) 1. 发现问题: 串口在发送命令之前,需要利用结构体(易读,且容易定位)来填充发送命令的内存,发现了此问题: #include  // ---...
  • wangjianfeiwuhao
  • wangjianfeiwuhao
  • 2012年02月18日 21:53
  • 2337
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:pack serial
举报原因:
原因补充:

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