www.pudn.com > Ge_opc_Server_v1.rar > I_SIO.CPP


// i_sio.cpp 
// 
//  This file contains the implementation of 
//  the IOPCSyncIO interface for groups in the LHEpipeview server. 
// 
// 
//	(c) COPYRIGHT 1996,1997 INTELLUTION INC. 
// ALL RIGHTS RESERVED 
// 
// Original Author: Al Chisholm 
// 
// Modification Log: 
//  Vers    Date   By    Notes 
//  ----  -------- ---   ----- 
//  0.00  11/18/96 ACC 
//        12/27/96 acc   add more sample code 
//  0.01  02/05/97 acc   See 'acc001' 
//                       Fix memory leaks 
//                       Fix handle validation in Read and Write (missing 'continue') 
//                       Be sure to null all 'out' pointers in case of error 
//  0.02  03/01/97 acc   Add support for Variant Conversions (acc002) 
//                       (changes to read and write) 
//  0.90  04/02/97 acc   Changes to GetValue() 
// 
// 
 
#define WIN32_LEAN_AND_MEAN 
 
#include "OPCLHEpipeview.h" 
#include "OPCerror.h" 
 
 
///////////////////////////////////////////////////////////////////////////// 
// Constructor /Destructor functions 
// 
 
/////////////////////////////////////// 
// ILHEpipeviewSIO() 
//   Constructor for this Interface 
// 
/////////////////////////////////////// 
ILHEpipeviewSIO::ILHEpipeviewSIO( LPUNKNOWN parent ) 
{ 
	m_Parent = (LHEpipeviewGroup *)parent; 
} 
 
 
 
/////////////////////////////////////// 
// ~ILHEpipeviewSIO() 
//   Destructor for this Interface 
// 
/////////////////////////////////////// 
ILHEpipeviewSIO::~ILHEpipeviewSIO( void) 
{ 
	m_Parent->m_pILHEpipeviewSIO = 0; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// IUnknown functions Delegate to Parent 
// 
 
STDMETHODIMP_(ULONG) ILHEpipeviewSIO::AddRef( void) 
{ 
	return m_Parent->AddRef(); 
} 
 
STDMETHODIMP_(ULONG) ILHEpipeviewSIO::Release( void) 
{ 
	return m_Parent->Release(); 
} 
 
STDMETHODIMP ILHEpipeviewSIO::QueryInterface( REFIID iid, LPVOID* ppInterface) 
{ 
	return m_Parent->QueryInterface(iid, ppInterface); 
} 
 
 
 
///////////////////////////////////////////////////////////////////////////// 
// ILHEpipeviewSIO (IOPCSyncIO) interface functions 
// 
 
 
/////////////////////////////////////// 
// Read 
/////////////////////////////////////// 
STDMETHODIMP ILHEpipeviewSIO::Read( 
	OPCDATASOURCE   dwSource, 
	DWORD           dwNumItems, 
	OPCHANDLE     * phServer, 
	OPCITEMSTATE ** ppItemValues, 
	HRESULT      ** ppErrors 
    ) 
{ 
	LHEpipeviewGroup &g = *m_Parent; 
	DWORD	i; 
	HRESULT *hr; 
	OPCITEMSTATE *is; 
 
	// Defaults in case of error 
	// 
	*ppErrors = hr = NULL;			//acc001 
	*ppItemValues = is = NULL;		//acc001 
 
	// Allocate memory for the item values and hresults 
	// 
	*ppErrors = hr = (HRESULT*) pIMalloc->Alloc(sizeof(HRESULT) *dwNumItems);		//acc001 
	if(hr == NULL) return E_OUTOFMEMORY; 
	*ppItemValues = is = (OPCITEMSTATE*) pIMalloc->Alloc(sizeof(OPCITEMSTATE)*dwNumItems);		//acc001 
	if(is == NULL) 
	{ 
		pIMalloc->Free(hr);			//acc001 
		return E_OUTOFMEMORY; 
	} 
 
	// For each item 
	// 
	for (i=0; i< dwNumItems; i++) 
	{ 
		// Validate the handle 
		// 
		int j = phServer[i]; 
		if (!g.ItemValid(j)) 
		{ 
			hr[i] = OPC_E_INVALIDHANDLE; 
			continue;			//acc001 
		} 
 
		// Find the item that matches the server handle 
		// 
		LHEpipeviewItem &item = *g.ItemPtr(j); 
 
		// and extract the requested data... 
		// GetValue attempts the conversion from Canonical to Requested 
		// According the the OPC Spec, AddItems and/or SetDataTypes 
		// will have already verified that this is possible. 
		// 
		is[i].hClient = item.m_hClientItem; 
		VariantInit(&is[i].vDataValue); 
		hr[i] = item.GetValue(dwSource, &is[i].vDataValue, &is[i].wQuality, &is[i].ftTimeStamp);	// acc002 
 
		// For CACHE, If Group not active then quality is bad no matter what 
		// 
		if(( dwSource == OPC_DS_CACHE) && !g.m_bActive) 
			is[i].wQuality = QUAL_NOTACTIVE; 
 
		// Note that doing a read does not affect OnDataChange 
		// so we do NOT clear Changed flag 
		// 
 
	} 
	return S_OK; 
} 
 
/////////////////////////////////////// 
// Write 
/////////////////////////////////////// 
STDMETHODIMP ILHEpipeviewSIO::Write( 
	DWORD        dwNumItems, 
	OPCHANDLE  * phServer, 
	VARIANT    * pItemValues, 
	HRESULT   ** ppErrors 
    ) 
{ 
	LHEpipeviewGroup &g = *m_Parent; 
	DWORD	i; 
	HRESULT *hr; 
 
	// Allocate memory for the hresults 
	// 
	*ppErrors = hr = (HRESULT*) pIMalloc->Alloc(sizeof(HRESULT) *dwNumItems);		//acc001 
	if(hr == NULL) return E_OUTOFMEMORY; 
 
	// For each item 
	// 
	for (i=0; i< dwNumItems; i++) 
	{ 
		// Validate the handle 
		// 
		int j = phServer[i]; 
		if (!g.ItemValid(j)) 
		{ 
			hr[i] = OPC_E_INVALIDHANDLE; 
			continue;			//acc001 
		} 
 
		// Find the item that matches the server handle 
		// 
		LHEpipeviewItem &item = *g.ItemPtr(j); 
 
		// and write the requested data... 
		// 
		HRESULT r1 = item.SetValue(&pItemValues[i]);		//acc002 
		if(FAILED(r1)) 
			hr[i] = OPC_E_BADTYPE; 
		else 
			hr[i] = S_OK; 
 
	} 
	return S_OK; 
}