XnStatus XnDeviceModuleHolder::UnsafeSetProperty(const XnProperty* pRequest, XnProperty* pProp)
{
	XnStatus nRetVal = XN_STATUS_OK;
	
	if (pRequest->GetType() != pProp->GetType())
	{
		XN_LOG_WARNING_RETURN(XN_STATUS_DEVICE_PROPERTY_BAD_TYPE, XN_MASK_DDK, "Property '%s' has the wrong type!", pRequest->GetName());
	}

	switch (pRequest->GetType())
	{
	case XN_PROPERTY_TYPE_INTEGER:
		{
			XnActualIntProperty* pActualRequest = (XnActualIntProperty*)pRequest;
			XnActualIntProperty* pActualProp = (XnActualIntProperty*)pProp;
			nRetVal = pActualProp->UnsafeUpdateValue(pActualRequest->GetValue());
			XN_IS_STATUS_OK(nRetVal);
			break;
		}
	case XN_PROPERTY_TYPE_REAL:
		{
			XnActualRealProperty* pActualRequest = (XnActualRealProperty*)pRequest;
			XnActualRealProperty* pActualProp = (XnActualRealProperty*)pProp;
			nRetVal = pActualProp->UnsafeUpdateValue(pActualRequest->GetValue());
			XN_IS_STATUS_OK(nRetVal);
			break;
		}
	case XN_PROPERTY_TYPE_STRING:
		{
			XnActualStringProperty* pActualRequest = (XnActualStringProperty*)pRequest;
			XnActualStringProperty* pActualProp = (XnActualStringProperty*)pProp;
			nRetVal = pActualProp->UnsafeUpdateValue(pActualRequest->GetValue());
			XN_IS_STATUS_OK(nRetVal);
			break;
		}
	case XN_PROPERTY_TYPE_GENERAL:
		{
			XnActualGeneralProperty* pActualRequest = (XnActualGeneralProperty*)pRequest;
			XnActualGeneralProperty* pActualProp = (XnActualGeneralProperty*)pProp;
			nRetVal = pActualProp->UnsafeUpdateValue(pActualRequest->GetValue());
			XN_IS_STATUS_OK(nRetVal);
			break;
		}
	default:
		XN_LOG_WARNING_RETURN(XN_STATUS_ERROR, XN_MASK_DDK, "Unknown property type: %d\n", pRequest->GetType());
	} // switch
	
	return (XN_STATUS_OK);
}
XnStatus XnSensorStreamHelper::SimpleSetFirmwareParam(XnActualIntProperty& Property, XnUInt16 nValue)
{
	XnStatus nRetVal = XN_STATUS_OK;
	
	nRetVal = BeforeSettingFirmwareParam(Property, nValue);
	XN_IS_STATUS_OK(nRetVal);

	nRetVal = Property.UnsafeUpdateValue(nValue);
	XN_IS_STATUS_OK(nRetVal);

	nRetVal = AfterSettingFirmwareParam(Property);
	XN_IS_STATUS_OK(nRetVal);
	
	return (XN_STATUS_OK);
}
XnStatus XnDeviceFileReader::ReadInitialState(XnPropertySet *pSet)
{
	XnStatus nRetVal = XN_STATUS_OK;

	if (m_nFileVersion < 4)
	{
		if (m_pBCData == NULL)
		{
			nRetVal = BCInit();
			XN_IS_STATUS_OK(nRetVal);
		}

		return BCReadInitialState(pSet);
	}

	// first read first object - modules properties - using base
	nRetVal = XnStreamReaderDevice::ReadInitialState(pSet);
	XN_IS_STATUS_OK(nRetVal);

	// now continue reading until we get to first data
	XnPackedDataType nType;
	XnBool bStateEnd = FALSE;
	XnUInt64 nPositionBefore;

	while (!bStateEnd)
	{
		nRetVal = GetIOStream()->Tell(&nPositionBefore);
		XN_IS_STATUS_OK(nRetVal);

		nRetVal = GetDataPacker()->ReadNextObject(&nType);
		XN_IS_STATUS_OK(nRetVal);

		switch (nType)
		{
		case XN_PACKED_NEW_STREAM:
			{
				XnChar strType[XN_DEVICE_MAX_STRING_LENGTH];
				XnChar strName[XN_DEVICE_MAX_STRING_LENGTH];
				XN_PROPERTY_SET_CREATE_ON_STACK(props);
				nRetVal = GetDataPacker()->ReadNewStream(strType, strName, &props);
				XN_IS_STATUS_OK(nRetVal);

				XnActualPropertiesHash* pStreamProps;
				nRetVal = XnPropertySetDataDetachModule(props.pData, strName, &pStreamProps);
				XN_IS_STATUS_OK(nRetVal);

				nRetVal = XnPropertySetDataAttachModule(pSet->pData, strName, pStreamProps);
				XN_IS_STATUS_OK(nRetVal);
				break;
			}
		case XN_PACKED_INT_PROPERTY:
			{
				XnChar strModule[XN_DEVICE_MAX_STRING_LENGTH];
				XnChar strProp[XN_DEVICE_MAX_STRING_LENGTH];
				XnUInt64 nValue;
				nRetVal = GetDataPacker()->ReadProperty(strModule, strProp, &nValue);
				XN_IS_STATUS_OK(nRetVal);

				XnActualPropertiesHash* pModule = NULL;
				nRetVal = pSet->pData->Get(strModule, pModule);
				XN_IS_STATUS_OK(nRetVal);

				XnProperty* pProp = NULL;
				nRetVal = pModule->Get(strProp, pProp);
				XN_IS_STATUS_OK(nRetVal);

				XnActualIntProperty* pIntProp = (XnActualIntProperty*)pProp;
				nRetVal = pIntProp->UnsafeUpdateValue(nValue);
				XN_IS_STATUS_OK(nRetVal);
				break;
			}
		case XN_PACKED_REAL_PROPERTY:
			{
				XnChar strModule[XN_DEVICE_MAX_STRING_LENGTH];
				XnChar strProp[XN_DEVICE_MAX_STRING_LENGTH];
				XnDouble dValue;
				nRetVal = GetDataPacker()->ReadProperty(strModule, strProp, &dValue);
				XN_IS_STATUS_OK(nRetVal);

				XnActualPropertiesHash* pModule;
				nRetVal = pSet->pData->Get(strModule, pModule);
				XN_IS_STATUS_OK(nRetVal);

				XnProperty* pProp;
				nRetVal = pModule->Get(strProp, pProp);
				XN_IS_STATUS_OK(nRetVal);

				XnActualRealProperty* pRealProp = (XnActualRealProperty*)pProp;
				nRetVal = pRealProp->UnsafeUpdateValue(dValue);
				XN_IS_STATUS_OK(nRetVal);
				break;
			}
		case XN_PACKED_STRING_PROPERTY:
			{
				XnChar strModule[XN_DEVICE_MAX_STRING_LENGTH];
				XnChar strProp[XN_DEVICE_MAX_STRING_LENGTH];
				XnChar strValue[XN_DEVICE_MAX_STRING_LENGTH];
				nRetVal = GetDataPacker()->ReadProperty(strModule, strProp, strValue);
				XN_IS_STATUS_OK(nRetVal);

				XnActualPropertiesHash* pModule;
				nRetVal = pSet->pData->Get(strModule, pModule);
				XN_IS_STATUS_OK(nRetVal);

				XnProperty* pProp;
				nRetVal = pModule->Get(strProp, pProp);
				XN_IS_STATUS_OK(nRetVal);

				XnActualStringProperty* pStringProp = (XnActualStringProperty*)pProp;
				nRetVal = pStringProp->UnsafeUpdateValue(strValue);
				XN_IS_STATUS_OK(nRetVal);
				break;
			}
		case XN_PACKED_GENERAL_PROPERTY:
			{
				XnChar strModule[XN_DEVICE_MAX_STRING_LENGTH];
				XnChar strProp[XN_DEVICE_MAX_STRING_LENGTH];
				XnGeneralBuffer gbValue;
				nRetVal = GetDataPacker()->ReadProperty(strModule, strProp, &gbValue);
				XN_IS_STATUS_OK(nRetVal);

				XnActualPropertiesHash* pModule;
				nRetVal = pSet->pData->Get(strModule, pModule);
				XN_IS_STATUS_OK(nRetVal);

				XnProperty* pProp;
				nRetVal = pModule->Get(strProp, pProp);
				XN_IS_STATUS_OK(nRetVal);

				XnActualGeneralProperty* pIntProp = (XnActualGeneralProperty*)pProp;
				nRetVal = pIntProp->UnsafeUpdateValue(gbValue);
				XN_IS_STATUS_OK(nRetVal);
				break;
			}
		default:
			// reached end of initial state. go back to beginning of this object
			nRetVal = GetIOStream()->Seek(nPositionBefore);
			XN_IS_STATUS_OK(nRetVal);

			// stop reading
			bStateEnd = TRUE;
		}
	} // objects loop
	
	return (XN_STATUS_OK);
}
XnStatus XnSensorFirmwareParams::CommitTransactionAsBatch()
{
	XnStatus nRetVal = XN_STATUS_OK;

	if (!m_bInTransaction)
	{
		return XN_STATUS_ERROR;
	}

	// we are no longer in transaction, even if we fail to commit.
	m_bInTransaction = FALSE;

	if (m_TransactionOrder.Size() != 0)
	{
		XnUInt32 nMaxCount = m_TransactionOrder.Size();
		XnInnerParamData* pParams;
		XN_VALIDATE_CALLOC(pParams, XnInnerParamData, nMaxCount);

		XnChar strLogMessage[1024];
		XnUInt32 nMaxLength = 1024;
		XnUInt32 nLength = 0;
		XnUInt32 nChars;
		xnOSStrFormat(strLogMessage + nLength, nMaxLength - nLength, &nChars, "Setting firmware params:\n\t");
		nLength += nChars;

		XnUInt32 nCount = 0;

		for (XnActualIntPropertyList::Iterator it = m_TransactionOrder.begin(); it != m_TransactionOrder.end(); ++it)
		{
			XnActualIntProperty* pProp = *it;

			XnUInt32 nValue;
			nRetVal = m_Transaction.Get(pProp, nValue);
			if (nRetVal != XN_STATUS_OK)
			{
				xnOSFree(pParams);
				return (nRetVal);
			}

			XnFirmwareParam* pParam;
			nRetVal = CheckFirmwareParam(pProp, nValue, &pParam);
			if (nRetVal != XN_STATUS_OK)
			{
				xnOSFree(pParams);
				return (nRetVal);
			}

			if (pParam != NULL)
			{
				xnOSStrFormat(strLogMessage + nLength, nMaxLength - nLength, &nChars, "%s = %u\n\t", pProp->GetName(), nValue);
				nLength += nChars;

				pParams[nCount].nParam = pParam->nFirmwareParam;
				pParams[nCount].nValue = (XnUInt16)nValue;
				nCount++;
			}
		}

		xnLogVerbose(XN_MASK_SENSOR_PROTOCOL, "%s", strLogMessage);

		// set all params
		nRetVal = m_pCommands->SetMultipleFirmwareParams(pParams, nCount);
		xnOSFree(pParams);
		XN_IS_STATUS_OK(nRetVal);

		// and update their props
		for (XnActualIntPropertyList::Iterator it = m_TransactionOrder.begin(); it != m_TransactionOrder.end(); ++it)
		{
			XnActualIntProperty* pProp = *it;

			XnUInt32 nValue;
			nRetVal = m_Transaction.Get(pProp, nValue);
			XN_IS_STATUS_OK(nRetVal);

			nRetVal = pProp->UnsafeUpdateValue(nValue);
			XN_IS_STATUS_OK(nRetVal);
		}
	}

	m_Transaction.Clear();
	m_TransactionOrder.Clear();

	return (XN_STATUS_OK);
}