// interopsvcObj.cpp : Implementation of CinteropsvcObj

#include "stdafx.h"
#include "interopsvcObj.h"

#include "..\wmsoapstruct\wmsoapstruct.h"
#include "..\wmsoapstruct\wmsoapstruct_i.c"

// CinteropsvcObj

STDMETHODIMP CinteropsvcObj::echoVoid()
{
	// does nothing

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoString(VARIANT inputString, VARIANT *outputString)
{
	VariantCopy(outputString, &inputString);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoStringArray(VARIANT inputStringArray, VARIANT *outputStringArray)
{
	SafeArrayCopy(inputStringArray.parray, &outputStringArray->parray);
	outputStringArray->vt |= (VT_VARIANT | VT_ARRAY);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoInteger(VARIANT inputInteger, VARIANT *outputInteger)
{
	VariantCopy(outputInteger, &inputInteger);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoIntegerArray(VARIANT inputIntegerArray, VARIANT *outputIntegerArray)
{
	SafeArrayCopy(inputIntegerArray.parray, &outputIntegerArray->parray);
	outputIntegerArray->vt |= (VT_VARIANT | VT_ARRAY);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoFloat(VARIANT inputFloat, VARIANT *outputFloat)
{
	VariantCopy(outputFloat, &inputFloat);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoFloatArray(VARIANT inputFloatArray, VARIANT *outputFloatArray)
{
	SafeArrayCopy(inputFloatArray.parray, &outputFloatArray->parray);
	outputFloatArray->vt |= (VT_VARIANT | VT_ARRAY);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoStruct(VARIANT inputStruct, VARIANT *outputStruct)
{
	// now get Iwmsoapstruct pointer
	IDispatch *pDispIn = inputStruct.pdispVal;
	Iwmsoapstruct *pIwmsoapstructIn;
	HRESULT res = pDispIn->QueryInterface(IID_Iwmsoapstruct, (void **)&pIwmsoapstructIn);
	if (FAILED(res))
	{
		return E_FAIL;
	}
	// instantiate struct object
	Iwmsoapstruct *pIwmsoapstructOut;
	res = CoCreateInstance( CLSID_wmsoapstruct,
							NULL, CLSCTX_SERVER,
							IID_Iwmsoapstruct,
							(void **) &pIwmsoapstructOut);
	if (FAILED(res))
	{
		return E_FAIL;
	}
	// copy
	long lPos;
	VARIANT_BOOL bResult;
	VARIANT varContent;
	BSTR bstrMemberName;
	
    VariantInit(&varContent);
	for (pIwmsoapstructIn->GetFirstMember(&bstrMemberName, &varContent, &lPos, &bResult);
			bResult == VARIANT_TRUE;
			pIwmsoapstructIn->GetNextMember(&bstrMemberName, &varContent, &lPos, &bResult))
	{
		VARIANT_BOOL bSuccess;
		if (FAILED(pIwmsoapstructOut->SetMember(bstrMemberName, varContent, &bSuccess)) ||
                bSuccess == VARIANT_FALSE)
        {
		    SysFreeString(bstrMemberName);
		    VariantClear(&varContent);
    		pIwmsoapstructIn->Release();
    		pIwmsoapstructOut->Release();
		    return E_FAIL;
	    }
		SysFreeString(bstrMemberName);
		VariantClear(&varContent);
	}
	// now get IDispatch pointer
	IDispatch *pIDispatchOut;
	res = pIwmsoapstructOut->QueryInterface(IID_IDispatch, (void **)&pIDispatchOut);
	if (FAILED(res))
	{
		pIwmsoapstructIn->Release();
		pIwmsoapstructOut->Release();
		return E_FAIL;
	}
	outputStruct->pdispVal = pIDispatchOut;
	outputStruct->vt |= VT_DISPATCH;
	// release
	pIwmsoapstructIn->Release();
	pIwmsoapstructOut->Release();
	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoStructArray(VARIANT inputStructArray, VARIANT *outputStructArray)
{
	SafeArrayCopy(inputStructArray.parray, &outputStructArray->parray);
	outputStructArray->vt |= (VT_VARIANT | VT_ARRAY);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoBase64(VARIANT inputBase64, VARIANT *outputBase64)
{
	SafeArrayCopy(inputBase64.parray, &outputBase64->parray);
	outputBase64->vt |= (VT_I1 | VT_ARRAY);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoHexBinary(VARIANT inputHexBinary, VARIANT *outputHexBinary)
{
	SafeArrayCopy(inputHexBinary.parray, &outputHexBinary->parray);
	outputHexBinary->vt |= (VT_I1 | VT_ARRAY);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoDate(VARIANT inputDate, VARIANT *outputDate)
{
	VariantCopy(outputDate, &inputDate);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoDecimal(VARIANT inputDecimal, VARIANT *outputDecimal)
{
	VariantCopy(outputDecimal, &inputDecimal);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoBoolean(VARIANT inputBoolean, VARIANT *outputBoolean)
{
	VariantCopy(outputBoolean, &inputBoolean);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoPolyMorph(VARIANT inputPolyMorph, VARIANT *outputPolyMorph)
{
	VariantCopy(outputPolyMorph, &inputPolyMorph);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoPolyMorphArray(VARIANT inputPolyMorphArray, VARIANT *outputPolyMorphArray)
{
	SafeArrayCopy(inputPolyMorphArray.parray, &outputPolyMorphArray->parray);
	outputPolyMorphArray->vt |= (VT_VARIANT | VT_ARRAY);

	return S_OK;
}

STDMETHODIMP CinteropsvcObj::echoPolyMorphStruct(VARIANT inputPolyMorphStruct, VARIANT *outputPolyMorphStruct)
{
	// now get Iwmsoapstruct pointer
	IDispatch *pDispIn = inputPolyMorphStruct.pdispVal;
	Iwmsoapstruct *pIwmsoapstructIn;
	HRESULT res = pDispIn->QueryInterface(IID_Iwmsoapstruct, (void **)&pIwmsoapstructIn);
	if (FAILED(res))
	{
		return E_FAIL;
	}
	// instantiate struct object
	Iwmsoapstruct *pIwmsoapstructOut;
	res = CoCreateInstance( CLSID_wmsoapstruct,
							NULL, CLSCTX_SERVER,
							IID_Iwmsoapstruct,
							(void **) &pIwmsoapstructOut);
	if (FAILED(res))
	{
		return E_FAIL;
	}
	// copy
	long lPos;
	VARIANT_BOOL bResult;
	VARIANT varContent;
	BSTR bstrMemberName;
	
    VariantInit(&varContent);
	for (pIwmsoapstructIn->GetFirstMember(&bstrMemberName, &varContent, &lPos, &bResult);
			bResult == VARIANT_TRUE;
			pIwmsoapstructIn->GetNextMember(&bstrMemberName, &varContent, &lPos, &bResult))
	{
		VARIANT_BOOL bSuccess;
		if (FAILED(pIwmsoapstructOut->SetMember(bstrMemberName, varContent, &bSuccess)) ||
                bSuccess == VARIANT_FALSE)
        {
		    SysFreeString(bstrMemberName);
		    VariantClear(&varContent);
    		pIwmsoapstructIn->Release();
    		pIwmsoapstructOut->Release();
		    return E_FAIL;
	    }
		SysFreeString(bstrMemberName);
		VariantClear(&varContent);
	}
	// now get IDispatch pointer
	IDispatch *pIDispatchOut;
	res = pIwmsoapstructOut->QueryInterface(IID_IDispatch, (void **)&pIDispatchOut);
	if (FAILED(res))
	{
		pIwmsoapstructIn->Release();
		pIwmsoapstructOut->Release();
		return E_FAIL;
	}
	outputPolyMorphStruct->pdispVal = pIDispatchOut;
	outputPolyMorphStruct->vt |= VT_DISPATCH;
	// release
	pIwmsoapstructIn->Release();
	pIwmsoapstructOut->Release();
	return S_OK;
}
