⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httppipe.h

📁 封装的http和文件存取的c++类例子
💻 H
字号:
#ifndef _httppipe_h_
#define _httppipe_h_



#include "BrewString.h"
#include "AEEStdlib.h"
#include "AEENet.h"
#include "AEEAppGen.h"
#include "AEE.h"
#include "CbkDispatcher.h"

//Port address to connect to.
#define  TIMESERVER_PORT      80
#define  TIMESERVER_HOST      "216.18.119.195"   // IP address in a.b.c.d dot-notation

#define WEB_ERROR_PROTOCOL AEE_NET_EBADAPP
// Invalid Address
#define DOTADDR_NONE  0xFFFFFFFF


typedef enum {NO_DATA_TYPE, TEXT_DATA_TYPE, IMAGE_DATA_TYPE} DATA_TYPE;


//A few utility macros; We shall eventually move this into the AEE Services.
#define ISDIGIT(c)  ( (unsigned) ((c) - '0') < 10)
#define ISALPHA(c)  ( (unsigned) ( ((c)|32) - 'a') < 26 )
#define ISALNUM(c)  ( ISDIGIT(c) || ISALPHA(c) )


#define HTTP_REQUEST_TAIL " HTTP/1.0 \r\n\r\n"
#define HTTP_HEADER_TAIL "\r\n\r\n"


struct HDS: public IRelease
{
	static void createHTTPDataStruct(HDS*& ds)
	{
		if (ds==0)
			ds = new HDS();
	}

	virtual void releaseResource( ) 
	{
		delete this;
	}

	virtual int getUID( ) 
	{
		return 100;
	}

	
	static int getID()
	{
		return 100;
	}
	template <class R>
	static HDS* initDataStruct(R* rr, char* address, const String& params )
	{
		HDS* ds=static_cast<HDS*>(rr->getRegistered(HDS::getID()));
		HDS::createHTTPDataStruct(ds);
		ds->address = address;
		ds->parameters = params;
		if (!ds->data.isEmpty())
			ds->data="";
		rr->registerResource(ds);
		return ds;
	}

	char* address;
	String parameters;
	String data;
	int error;
	DATA_TYPE dataType;
	UINT bufSize;

private:
	HDS() :  bufSize(128)
	{}
	HDS( const HDS &Value );
	const HDS &operator = ( const HDS &Rhs );
};

template <class Y, class F>
struct pkCBK;



class HTTPpipe 
{
public:
	
	HTTPpipe(IShell* shell,  IExecute* pp, HDS* ds) :	
							shell_(shell),
							processPolicy_(pp), 
							piSock_(0),
							piNet_(0),
							isHeaderProcessed_(false),
							buf_(new char[ds->bufSize+1]),
							ds_(ds)
	{
	}
	
	~HTTPpipe();

	int	init();
	int	initConnection();
	void reset();
private:
	void connect( int err);
	static void connectStatic(HTTPpipe* app, int err);
	void write();
	void read();
	int readHeader();
	void onError( int errorCode) ;
	void onData( ) ;
	void releaseResources();
	void releaseResource();
private:
	IShell* shell_;
	INetMgr *piNet_;
	ISocket *piSock_;
	IExecute* processPolicy_; 
	String 	command_;
	bool isHeaderProcessed_;
	char* buf_;
	typedef pkCBK0<HTTPpipe, void (HTTPpipe::*)()> P;
	P p_;
	typedef pkCBK1<HTTPpipe, void (HTTPpipe::*)(int)> PI;
	PI pi_;
	HDS* ds_;
private:	
	HTTPpipe( const HTTPpipe &Value );
	const HTTPpipe &operator = ( const HTTPpipe &Rhs );

	

};


static INAddr xConvertToINAddr(char *psz)
{
	INAddr ul = 0;
	int nByte = 0;
	char c;
	
	if(!psz)
		return 0;
	
	while (ISDIGIT(*psz)) {
		int n = 0;
		while ( ISDIGIT(c=*psz)) {
			n = n*10 + (c - '0');
			++psz;
		}
		((char*)&ul)[nByte++] = n;
		
		if (nByte == 4 || *psz != '.')
			break;
		
		++psz;
	}
	
	if (nByte < 4 || ISALNUM(*psz))
		ul = DOTADDR_NONE;
	
	return ul;
}


HTTPpipe::~HTTPpipe()
{
	releaseResources();
}

void HTTPpipe::releaseResource()
{
	if (piSock_) 
	{
		ISOCKET_Cancel(piSock_, 0, 0);
		ISOCKET_Release(piSock_);
		piSock_ = 0;
	}
}

void HTTPpipe::reset()
{
	releaseResource();
	isHeaderProcessed_ = false;
	command_ = "";
}


void HTTPpipe::releaseResources()
{
	releaseResource();
	if (piNet_)
	{
		INETMGR_Release(piNet_);
		piNet_ = 0;
	}
	delete[] buf_;
	buf_ = 0;
}




int HTTPpipe::init()
{ 
	int err;
	if ((err = ISHELL_CreateInstance(shell_, AEECLSID_NET, (void**)(&piNet_))) != SUCCESS) 
	{
		return err; 
	}	
	if (!piNet_)
	{
		return EFAILED;
	}	
   // INETMGR_SetLinger(piNet_, 0);
	return SUCCESS;

}



int HTTPpipe::initConnection()
{
	if (piSock_)
	{
		return SUCCESS; //safe approach if a connection is tried 
							//before ending the previous one - isReusable==true
	}
	int err;
	//	DBGPRINTF("initConnection");
	piSock_ = INETMGR_OpenSocket(piNet_, AEE_SOCK_STREAM);
	if (!piSock_) 
	{
		err = INETMGR_GetLastError(piNet_);
		return err;
	}
	INAddr nodeINAddr = xConvertToINAddr(ds_->address);
	command_ = "GET " + ds_->parameters + HTTP_REQUEST_TAIL;
	pi_.setCallback(this, &HTTPpipe::connect);
	if ((err = ISOCKET_Connect (piSock_, nodeINAddr, AEE_htons(TIMESERVER_PORT), 
		(PFNCONNECTCB)PI::callbackHandler, &pi_))  != AEE_NET_SUCCESS)
	{
		return ISOCKET_GetLastError(piSock_);
	}
	return SUCCESS;
}





void HTTPpipe::connectStatic(HTTPpipe* app, int err)
{
	app->connect(err);
}



void HTTPpipe::connect(int err)
{
	if (err) 
	{
		DBGPRINTF("error connect");
		onError(err) ;
		return;
	}

	p_.setCallback(this, &HTTPpipe::write);
	write();
	return;
}



void HTTPpipe::write ()
{
	const char *psz = command_.toCharArray();
	int  cbWrite = command_.length();


	while (cbWrite > 0) {
		int rv = ISOCKET_Write(piSock_, 
			(byte *)psz, (uint16)cbWrite);
		
		if (rv == AEE_NET_WOULDBLOCK) {
			command_.partialString(command_.length()- cbWrite, command_.length());
			ISOCKET_Writeable(piSock_, (PFNNOTIFY)P::callbackHandler, &p_);
			return;
		} 
		else if (rv == AEE_NET_ERROR) 
		{	
			onError(ISOCKET_GetLastError(piSock_)) ;
			return;
		}

		cbWrite -= rv;
		psz += rv;
	}
	p_.setCallback(this,&HTTPpipe::read);
	read();
	return;
}





void HTTPpipe::read ()
{
	if (!piSock_)
	{
		DBGPRINTF("piSock == 0 in read");
		onError(EFAILED);
		return;
	}
	int32 rv = ISOCKET_Read(piSock_, buf_, ds_->bufSize);
	if  (rv == AEE_NET_WOULDBLOCK) 
	{
		ISOCKET_Readable(piSock_, (PFNNOTIFY)P::callbackHandler, &p_);
		return;
	} 
	else if (rv == AEE_NET_ERROR)  
	{
		onError(ISOCKET_GetLastError(piSock_)) ;
		return;
	}
	else if (rv > 0) 
	{
		buf_[rv] = 0;
		ds_->data += buf_;
		if (!isHeaderProcessed_)
		{
			int err = readHeader();
			if (err == SUCCESS)
			{
				isHeaderProcessed_ = true;
			}
			else  if (err == WEB_ERROR_PROTOCOL)
			{
				onError(err) ;
				return;
			}
		}
		ISOCKET_Readable(piSock_, (PFNNOTIFY)P::callbackHandler, &p_);
		return;
	}
	else if (rv == 0) 
	{	
		onData();
		return;
	}
}



int HTTPpipe::readHeader() 
{
	int contentIndex = ds_->data.indexOf(HTTP_HEADER_TAIL);
	if (contentIndex == -1)
	{
		return EFAILED;
	}
	contentIndex += 4;

//	String content = "Content-Type:";
//	String cLength = "Content-Length:";
	int statusIndexStart = ds_->data.indexOf("HTTP/");
	statusIndexStart = ds_->data.indexOf(" ", statusIndexStart + 1);
	int statusIndexEnd = ds_->data.indexOf(" ", statusIndexStart + 1);
	int status = ATOI((ds_->data.substring(statusIndexStart, statusIndexEnd)).toCharArray())/100;
	if (status != 2) 
	{
		return WEB_ERROR_PROTOCOL;
	}
	ds_->dataType = (ds_->data.indexOf("image/") > -1) ? IMAGE_DATA_TYPE : TEXT_DATA_TYPE;
	ds_->data.partialString(contentIndex, ds_->data.length());
	return SUCCESS;
}


void HTTPpipe::onError( int errorCode) {
	ds_->error = errorCode;
	ds_->data = "";
	ds_->dataType = NO_DATA_TYPE;
	processPolicy_->onCbk() ;
}

void HTTPpipe::onData( ) {
	ds_->error = SUCCESS;
	processPolicy_->onCbk() ;
}




#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -