Exemplo n.º 1
0
bool DoIO (CTCPIPUnixDrvr* pTCPIPSystem, IDL_char* wbuffer, IDL_long write_count, IDL_char*& rbuffer, IDL_long& read_count,CConnect *pConnection, CStmt *pStatement)
{
	bool bok = true;

// write count, read count and temporary count
	long wcount;
	long rcount = 0;
	int tcount = 0;

	char* buffer;
	rbuffer = NULL;
// should the header specify swap
#ifdef BIGE
	HEADER wheader = {0,0,0,0,'N',COMP_12,WRITE_REQUEST_FIRST,SIGNATURE,CLIENT_HEADER_VERSION_BE,PC,TCPIP,SWAP_NO,0,0};
	HEADER rheader = {0,0,0,0,'N',COMP_12,READ_RESPONSE_FIRST,SIGNATURE,CLIENT_HEADER_VERSION_BE,PC,TCPIP,SWAP_NO,0,0};
#else
	HEADER wheader = {0,0,0,0,'N',COMP_12,WRITE_REQUEST_FIRST,SIGNATURE,CLIENT_HEADER_VERSION_LE,PC,TCPIP,SWAP_YES,0,0};
	HEADER rheader = {0,0,0,0,'N',COMP_12,READ_RESPONSE_FIRST,SIGNATURE,CLIENT_HEADER_VERSION_LE,PC,TCPIP,SWAP_YES,0,0};
#endif
	HEADER* prheader,*pwheader;

	if(pTCPIPSystem->odbcAPI == AS_API_GETOBJREF)
	{
		;
	}
	else
	{
		if(pTCPIPSystem->swap() == SWAP_YES)
		{
			wheader.swap = SWAP_YES;
			rheader.swap = SWAP_YES;
		}
		else
		{
			wheader.swap = SWAP_NO;
			rheader.swap = SWAP_NO;
		}
	}

	wheader.operation_id	= pTCPIPSystem->odbcAPI;
	rheader.operation_id	= pTCPIPSystem->odbcAPI;
	wheader.dialogueId		= pTCPIPSystem->dialogueId;
	rheader.dialogueId		= pTCPIPSystem->dialogueId;
	unsigned int timeout	= pTCPIPSystem->dwTimeout;
	memset(&pTCPIPSystem->m_rheader, 0, sizeof(HEADER));

	RESET_ERRORS((long)pTCPIPSystem);

	if (pTCPIPSystem->m_IOCompression > 0 &&
	    pTCPIPSystem->m_IOCompression == 1)
	{
		wheader.compress_ind = COMP_YES;
		//wheader.compress_type = COMP_14; // this should be set in the ::Compress method, based on what compression type the application chooses (right now there is only one COMP_14
		rheader.compress_ind = COMP_YES;
		rheader.compress_type = COMP_14;  // the driver requests that the server use this compression type. this should also be set based on what compression type the application chooses
	}
	else
	{
		wheader.compress_ind = COMP_NO;
		wheader.compress_type = 0;
		rheader.compress_ind = COMP_NO;
		rheader.compress_type = 0;
	}

// send to the server

	wheader.total_length = write_count;
	wheader.hdr_type = WRITE_REQUEST_FIRST;
		wheader.compress_type = 0;

#ifdef TRACE_COMPRESSION
	if(gDrvrGlobal.gTraceCompression)
	{
		printf("sending bytes number: %d\n",write_count);
	}
#endif
	wcount = write_count;

	while (wcount > 0)
	{
		if (wheader.hdr_type == WRITE_REQUEST_FIRST)
		{
			if (wcount > MAX_TCP_BUFFER_LENGTH - sizeof(HEADER))
				tcount = MAX_TCP_BUFFER_LENGTH - sizeof(HEADER);
			else
				tcount = wcount;
		}
		else
		{
			if (wcount > MAX_TCP_BUFFER_LENGTH)
				tcount = MAX_TCP_BUFFER_LENGTH;
			else
				tcount = wcount;
		}

		pwheader = &wheader;
		bok = (gDrvrGlobal.fpTCPIPDoWriteRead)((void*)pTCPIPSystem, pwheader, wbuffer, tcount, timeout);
		if (bok == false)
			goto out;
		wheader.hdr_type = WRITE_REQUEST_NEXT;
		wcount  -= tcount;
		wbuffer += tcount;
	}
// receive from the server

	pTCPIPSystem->cleanup(); //release all temp memory

// read for READ_RESPONSE_FIRST

	tcount = 0;
	rbuffer = NULL;
	rheader.hdr_type = READ_RESPONSE_FIRST;

	prheader = &rheader;
	bok = (gDrvrGlobal.fpTCPIPDoWriteRead)((void*)pTCPIPSystem, prheader, rbuffer, tcount, timeout);

	if(bok == false && pConnection != NULL)
	{
		if(MAP_SRVR_ERRORS(pConnection) == TIMEOUT_EXCEPTION)
		{
			if( pTCPIPSystem->odbcAPI != AS_API_GETOBJREF &&
				pTCPIPSystem->odbcAPI != AS_API_STOPSRVR &&
				pTCPIPSystem->odbcAPI != SRVR_API_SQLCONNECT &&
				pTCPIPSystem->odbcAPI != SRVR_API_SQLDISCONNECT)
			{
			    	odbcas_ASSvc_StopSrvr_exc_ stopSrvrException;
				stopSrvrException.exception_nr=SQL_ERROR;
				if(pStatement != NULL)
				   pStatement->setDiagRec(DRIVER_ERROR, IDS_S1_T00, TIMEOUT_EXCEPTION, FORMAT_ERROR((long)pStatement->getSrvrTCPIPSystem()));
				pConnection->sendStopServer(&stopSrvrException);
				bok = (gDrvrGlobal.fpTCPIPDoWriteRead)((void*)pTCPIPSystem, prheader, rbuffer, tcount, timeout);
			}
		}
	}

	if (bok == false)
		goto out;
		
	if(pTCPIPSystem->odbcAPI == AS_API_GETOBJREF)
	{
		if(prheader->version == SERVER_HEADER_VERSION_LE)
			// we're connected to a Seaquest system
			#if defined(BIGE)
			pTCPIPSystem->setSwap(SWAP_YES);
			#else
			pTCPIPSystem->setSwap(SWAP_NO);
			#endif
		else if(prheader->version == SERVER_HEADER_VERSION_BE)
			// we're connected to a older system
			#if defined(BIGE)
			pTCPIPSystem->setSwap(SWAP_NO);
			#else
			pTCPIPSystem->setSwap(SWAP_YES);
			#endif
		else
bool DoIO (CTCPIPSystemDrvr* pTCPIPSystem, char* wbuffer, long write_count, char*& rbuffer, long& read_count, CConnect *pConnection, CStmt *pStatement)
{
	bool bok = true;

// write count, read count and temporary count
	long wcount;
	long rcount = 0;
	long tcount = 0;

	char* buffer;
	rbuffer = NULL;
//
	HEADER wheader = {0,0,0,0,'N',COMP_12,WRITE_REQUEST_FIRST,SIGNATURE,CLIENT_HEADER_VERSION_LE,PC,TCPIP,SWAP_YES,0,0};
	HEADER rheader = {0,0,0,0,'N',COMP_12,READ_RESPONSE_FIRST,SIGNATURE,CLIENT_HEADER_VERSION_LE,PC,TCPIP,SWAP_YES,0,0};
	HEADER* prheader,*pwheader;

	if(pTCPIPSystem->odbcAPI == AS_API_GETOBJREF)
	{
		// For GetObjRef, the header is always sent in BigEndian form since when establishing a new connection
		// we won't know the system type
		;
	}
	else
	{
		if(pTCPIPSystem->swap() == SWAP_NO)
		{
			// We're connected from a Little Endian Client to a Little Endian Server
			wheader.swap = SWAP_NO;
			rheader.swap = SWAP_NO;
		}
		else
		{
			// We're connected from a Little Endian Client to a Big Endian Server
			;
		}
	}

	wheader.operation_id	= pTCPIPSystem->odbcAPI;
	rheader.operation_id	= pTCPIPSystem->odbcAPI;
	wheader.dialogueId		= pTCPIPSystem->dialogueId;
	rheader.dialogueId		= pTCPIPSystem->dialogueId;
	unsigned int timeout	= pTCPIPSystem->dwTimeout;
	memset(&pTCPIPSystem->m_rheader, 0, sizeof(HEADER));

	RESET_ERRORS((long)pTCPIPSystem);

	if (pTCPIPSystem->m_IOCompression > 0 &&
	    pTCPIPSystem->m_IOCompression == 1)
	{
		wheader.compress_ind = COMP_YES;
		//wheader.compress_type = COMP_14; // this should be set in the ::Compress method, based on what compression type the application chooses (right now there is only one COMP_14
		rheader.compress_ind = COMP_YES;
		rheader.compress_type = COMP_14;  // the driver requests that the server use this compression type. this should also be set based on what compression type the application chooses
	}
	else
	{
		wheader.compress_ind = COMP_NO;
		wheader.compress_type = 0;
		rheader.compress_ind = COMP_NO;
		rheader.compress_type = 0;
	}

// send to the server

	wheader.total_length = write_count;
	wheader.hdr_type = WRITE_REQUEST_FIRST;
		wheader.compress_type = 0;
#if (defined(WIN32)||defined(_WIN64))&&defined(TRACE_COMPRESSION)
	if(gDrvrGlobal.gTraceCompression)
	{
		printf("sending bytes number: %d\n",write_count);
	}
#endif
	wcount = write_count;

	while (wcount > 0)
	{
		if (wheader.hdr_type == WRITE_REQUEST_FIRST)
		{
			if (wcount > MAX_TCP_BUFFER_LENGTH - sizeof(HEADER))
				tcount = MAX_TCP_BUFFER_LENGTH - sizeof(HEADER);
			else
				tcount = wcount;
		}
		else
		{
			if (wcount > MAX_TCP_BUFFER_LENGTH)
				tcount = MAX_TCP_BUFFER_LENGTH;
			else
				tcount = wcount;
		}

		pwheader = &wheader;
		TRACE_TRANSPORT_OUT(wheader.hdr_type, pTCPIPSystem->m_object_ref, pwheader, wbuffer, tcount, timeout);
		bok = (gDrvrGlobal.fpTCPIPDoWriteRead)((void*)pTCPIPSystem, pwheader, wbuffer, tcount, timeout);
		if (bok == false)
			goto out;
		wheader.hdr_type = WRITE_REQUEST_NEXT;
		wcount  -= tcount;
		wbuffer += tcount;
	}
// receive from the server

	pTCPIPSystem->cleanup(); //release all temp memory

// read for READ_RESPONSE_FIRST

	tcount = 0;
	rbuffer = NULL;
	rheader.hdr_type = READ_RESPONSE_FIRST;

	prheader = &rheader;
	bok = (gDrvrGlobal.fpTCPIPDoWriteRead)((void*)pTCPIPSystem, prheader, rbuffer, tcount, timeout);

	if(bok == false)
	{
		if(MAP_SRVR_ERRORS(pConnection) == TIMEOUT_EXCEPTION)
		{
			if( pTCPIPSystem->odbcAPI != AS_API_GETOBJREF &&
				pTCPIPSystem->odbcAPI != AS_API_STOPSRVR &&
				pTCPIPSystem->odbcAPI != SRVR_API_SQLCONNECT &&
				pTCPIPSystem->odbcAPI != SRVR_API_SQLDISCONNECT)
			{
				if(pStatement != NULL)
					pStatement->setDiagRec(DRIVER_ERROR, IDS_S1_T00, TIMEOUT_EXCEPTION, FORMAT_ERROR((long)pStatement->getSrvrTCPIPSystem()));
				pConnection->sendStopServer();
				bok = (gDrvrGlobal.fpTCPIPDoWriteRead)((void*)pTCPIPSystem, prheader, rbuffer, tcount, timeout);
			}
		}
	}

	if (bok == false)
		goto out;

	TRACE_TRANSPORT_IN(READ_RESPONSE_FIRST, pTCPIPSystem->m_object_ref, prheader, rbuffer, tcount, timeout);

	if(pTCPIPSystem->odbcAPI == AS_API_GETOBJREF)
	{
		if(prheader->version == SERVER_HEADER_VERSION_LE)
			pTCPIPSystem->setSwap(SWAP_NO);
		else if(prheader->version == SERVER_HEADER_VERSION_BE)
			pTCPIPSystem->setSwap(SWAP_YES);
		else
			// we're connected to an older system (which will just echo back the version we send)
			pTCPIPSystem->setSwap(SWAP_YES);
	}



// the server returns total length in the header

	memcpy(&pTCPIPSystem->m_rheader, prheader, sizeof(HEADER));
	if (prheader->compress_ind == COMP_YES && prheader->compress_type != 0)
	{
		SET_ERROR((long)pTCPIPSystem, PC, TCPIP, pTCPIPSystem->odbcAPI, E_DRIVER, pTCPIPSystem->m_object_ref, O_DO_WRITE_READ, F_DO_IO, DRVR_ERR_COMPRESS_OPERATION, rcount);
		bok = false;
		goto out;
	}
	else
		rcount = prheader->total_length;

	read_count = rcount;

	buffer = (char*)pTCPIPSystem->r_allocate(rcount);
	if (buffer == NULL)
	{
		SET_ERROR((long)pTCPIPSystem, PC, TCPIP, pTCPIPSystem->odbcAPI, E_DRIVER, pTCPIPSystem->m_object_ref, O_DO_OPERATOR_NEW, F_DO_IO, DRVR_ERR_MEMORY_ALLOCATE, rcount);
		bok = false;
		goto out;
	}

// if there is something beside the header in the IO buffer

	if (tcount > 0)
	{
		memcpy(buffer, rbuffer, tcount);
		rcount -= tcount;
	}

	rbuffer = buffer+ tcount;

// read for READ_RESPONSE_NEXT

	while (rcount > 0){
// we send only a header
		tcount = 0;
		rheader.hdr_type = READ_RESPONSE_NEXT;
		prheader = &rheader;
		bok = (gDrvrGlobal.fpTCPIPDoWriteRead)((void*)pTCPIPSystem, prheader, rbuffer, tcount, timeout);
		if (bok == false)
			goto out;
		TRACE_TRANSPORT_IN(READ_RESPONSE_NEXT, pTCPIPSystem->m_object_ref, prheader, rbuffer, tcount, timeout);
		rcount  -= tcount;
		rbuffer += tcount;
	}

	rbuffer = buffer;
#if (defined(WIN32)||defined(_WIN64))&&defined(TRACE_COMPRESSION)
	if(gDrvrGlobal.gTraceCompression)
	{
		printf("receiving bytes number: %d\n",read_count);
	}
#endif
out:
	return bok;
}