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

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

数据分包处理

#ifndef __DIVPACK_H__ #define __DIVPACK_H__ #pragma once typedef int (*pfnProcessPackCallback)(co...

@SuppressWarnings("serial")在Java中有什么作用?

简介:java.lang.SuppressWarnings是J2SE 5.0中标准的Annotation之一。可以标注在类、字段、方法、参数、构造方法,以及局部变量上。 作用:告诉编译器忽略指定的警...

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

//原文地址:http://blog.csdn.net/sirzjp/article/details/6170596 uart_close主要在tty_release和do_tty_hundu...

show interface Serial5/1/0.1/1/4/1:16的接口 解析含义

PE#show interface Serial5/1/0.1/1/4/1:16 其中接口标识Serial5/1/0.1/1/4/1:16中“.”之前的表示一个155M的SONET口,“.”之后的1...

Raspberry Raspbian turning off the UART functioning as a serial console

Raspberry Raspbian turning off the UART functioning as a serial console

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

转载:http://blog.csdn.net/sirzjp/article/details/6169984 在uart_register_driver函数中有这样的一个函数:tty_s...

Android/JAVA下基于java-simple-serial-connector串口开发完整教程

列个纲: 1.根据.cpp文件和.h文件制作so库; 2.基础API认识; 3.代码示例; 以下正文: 1. 笔者android studio版本为:2.1.1    1.1将项目...

串行 Flash 通用驱动库 SFUD (Serial Flash Universal Driver)

SFUD (Serial Flash Universal Driver) 串行 Flash 通用驱动库0、SFUD 是什么SFUD 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行...

Serial的基本使用和ArduinoIDE的串口工具——人人都能玩硬件

Serial类和ArduinoIDE的串口工具方便了我们在Arduino没有外接显示设备的情况下获取Arduino当前的状态。本文不对Serial作深入讲解,仅对这两者的使用作基本介绍,目的在于方便后...

关于USB-Serial、USB转串口、USB-UART、PL2303、CH340等的理解

USB-Serial、USB转串口、USB-UART、PL2303、CH340
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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