Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

230 lines
6.9 KiB

//--------------------------------------------------------------------
// Microsoft OLE DB iparser object
// (C) Copyright 1997 Microsoft Corporation. All Rights Reserved.
//
// @doc
//
// @module iparser.CPP | IParser object implementation
//
//
#pragma hdrstop
#include "msidxtr.h"
// CImpIParser::CImpIParser ---------------------------------------------------
//
// @mfunc Constructor
//
CImpIParser::CImpIParser()
{
m_cRef = 1;
m_pGlobalPropertyList = 0;
m_pGlobalViewList = 0;
}
// CImpIParser::~CImpIParser --------------------------------------------------
//
// @mfunc Destructor
//
CImpIParser::~CImpIParser()
{
delete m_pGlobalPropertyList;
delete m_pGlobalViewList;
}
//-----------------------------------------------------------------------------
// @func CImpIParser::CreateSession
//
// Creates a unique session within the parser. This session is required to keep
// the views and properties in their correct lifetimes.
//
// @rdesc HRESULT
// S_OK - IParserSession created
// DB_E_DIALECTNOTSUPPOERTED - Specified dialect was not supported
// E_OUTOFMEMORY - low on resources
// E_FAIL - unexpected error
// E_INVALIDARG - pGuidDialect, pIParserVerify, pIColMapCreator,
// or ppIParserSession was a NULL pointer
// (DEBUG ONLY).
//-----------------------------------------------------------------------------
STDMETHODIMP CImpIParser::CreateSession(
const GUID * pGuidDialect, // in | dialect for this session
LPCWSTR pwszMachine, // in | provider's current machine
IParserVerify * pIParserVerify, // in | ptr to ParserVerify
IColumnMapperCreator * pIColMapCreator,
IParserSession ** ppIParserSession ) // out | a unique parser session
{
SCODE sc = S_OK;
#ifdef DEBUG
if ( 0 == ppIParserSession || 0 == pIParserVerify ||
0 == pIColMapCreator || 0 == pGuidDialect)
sc = E_INVALIDARG;
else
#endif
{
TRANSLATE_EXCEPTIONS;
TRY
{
if ( 0 != ppIParserSession )
*ppIParserSession = 0;
// Check Dialect
if ( DBGUID_MSSQLTEXT == *pGuidDialect || DBGUID_MSSQLJAWS == *pGuidDialect )
{
XPtr<CViewList> xpGlobalViewList;
if ( 0 == m_pGlobalViewList )
xpGlobalViewList.Set( new CViewList() );
XInterface<CImpIParserSession>
xpIParserSession( new CImpIParserSession( pGuidDialect,
pIParserVerify,
pIColMapCreator,
xpGlobalViewList.GetPointer() ) );
XPtr<CPropertyList> xpGlobalPropertyList;
sc = xpIParserSession->FInit( pwszMachine,
&m_pGlobalPropertyList );
if ( FAILED(sc) )
xpIParserSession.Free();
else
{
if ( 0 == m_pGlobalPropertyList )
xpGlobalPropertyList.Set( new CPropertyList(NULL) );
}
delete m_pGlobalViewList;
m_pGlobalViewList = xpGlobalViewList.Acquire();
delete m_pGlobalPropertyList;
m_pGlobalPropertyList = xpGlobalPropertyList.Acquire();
*ppIParserSession = xpIParserSession.Acquire();
}
else
sc = DB_E_DIALECTNOTSUPPORTED;
}
CATCH( CException, e )
{
sc = e.GetErrorCode();
}
END_CATCH
UNTRANSLATE_EXCEPTIONS;
}
return sc;
}
//-----------------------------------------------------------------------------
// @func CImpIParser::QueryInterface
//
// @mfunc Returns a pointer to a specified interface. Callers use
// QueryInterface to determine which interfaces the called object
// supports.
//
// @rdesc HResult indicating the status of the method
// @flag S_OK | Interface is supported and ppvObject is set.
// @flag E_NOINTERFACE | Interface is not supported by the object
// @flag E_INVALIDARG | One or more arguments are invalid.
//-----------------------------------------------------------------------------
STDMETHODIMP CImpIParser::QueryInterface(
REFIID riid, //@parm IN | Interface ID of the interface being queried for.
LPVOID* ppv ) //@parm OUT | Pointer to interface that was instantiated
{
if ( 0 == ppv )
return ResultFromScode(E_INVALIDARG);
// This is the non-delegating IUnknown implementation
if ( (riid == IID_IParser) ||
(riid == IID_IUnknown) )
*ppv = (LPVOID)this;
else
*ppv = 0;
// If we're going to return an interface, AddRef it first
if ( 0 != *ppv )
{
((LPUNKNOWN)*ppv)->AddRef();
return S_OK;
}
return ResultFromScode(E_NOINTERFACE);
}
//-----------------------------------------------------------------------------
// CImpIParser::AddRef
//
// @mfunc Increments a persistence count for the object.
//
// @rdesc Reference count after operation.
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CImpIParser::AddRef()
{
return InterlockedIncrement((long *) &m_cRef);
}
//-----------------------------------------------------------------------------
// CImpIParser::Release
//
// @mfunc Decrements a persistence count for the object and if
// persistence count is 0, the object destroys itself.
//
// @rdesc Current reference count
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CImpIParser::Release()
{
Assert(m_cRef > 0);
ULONG cRef= InterlockedDecrement( (long *) &m_cRef );
if ( 0 == cRef )
{
TRACE("IParser refcount=0, now deleting.\n");
delete this;
return 0;
}
TRACE("IParser refcount=%d after Release().\n", cRef);
return cRef;
}
//-----------------------------------------------------------------------------
// @func MakeIParser
//
// Creates an IParser
//
// @rdesc HRESULT
// S_OK if successful; Error code otherwise
//-----------------------------------------------------------------------------
HRESULT __stdcall MakeIParser(
IParser** ppIParser )
{
SCODE sc = S_OK;
if ( 0 == ppIParser )
sc = E_INVALIDARG;
else
{
TRANSLATE_EXCEPTIONS;
TRY
{
XInterface<CImpIParser> xpIParser( new CImpIParser() );
*ppIParser = xpIParser.Acquire();
}
CATCH( CException, e )
{
sc = e.GetErrorCode();
}
END_CATCH
UNTRANSLATE_EXCEPTIONS;
}
return sc;
}