Details zu DATAARCH

Dataarch ist zuständig für die Ablage der Ergebnisdaten als Dateien. Die Task wird durch ein Signal informiert, wenn neue Ergebnisdaten vorliegen.

bool CDataArchApp::OnSigWsMeasured()
{
	bool bContinue = true;
 
	while (m_pResultsMod->tBuffer.nNextReadVal < m_pResultsMod->tBuffer.nNextWriteVal)
	{
		RefreshLifeCount();
		UI32 nIndex = m_pResultsMod->tBuffer.nNextReadVal % RESULTSBUFSIZE;
		const SResultsData& rResult = m_pResultsMod->atResults[nIndex];
		UI32& rFlags = m_pResultsMod->atResults[nIndex].tHead.nFlags;
 
		//	Bei Ringpuffer-Überlauf Datensätze im schnellen Vorlauf überspringen.
		if (m_pResultsMod->tBuffer.nNextReadVal < rResult.tHead.nWriteVal)
		{
			if (m_bOverFlowMsg)
				LogOutM(LOG, 2"OnSigWsMeasured(): ring buffer overflow");
			m_bOverFlowMsg = false;
			m_nMsrNo = -1;
			m_eMstStatus = MS_SUCCESS;
			m_tTableData.Reset();
			++m_pResultsMod->tBuffer.nNextReadVal;
			continue;
		}
		m_bOverFlowMsg = true;
 
		//	Archivierung einer Messung bei fatalen Fehlern abbrechen
		//	und restliche Datensätze der Messung überspringen.
		bool bCancelCurMsr = false;
		long nListMsrNo = 0;
		bool bAssigned = false;
 
		CMsrListItem tMsrListItem;
		long nResult = CMsrListFile::GetItem(rResult.tHead.nMsrNr, tMsrListItem);
 
		if (rResult.tHead.nMsrNr == 0)
		{
			LogOutM(LOG | MSR, 3"OnSigWsMeasured(): invalid nMsrNr %d - archiving aborted", rResult.tHead.nMsrNr);
			SetHardwareData(tSRDF, 1);
			continue;
		}
 
		//	Messung *muss* noch nicht abgeschlossen sein (Status MS_UNKNOWN in Messungsliste).
		if (-1 == nResult)
		{
			//	Meldung in schon in GetItem()
			bCancelCurMsr = true;
		}
		else if (0 == nResult)
		{
			if (m_bCancelCurMsrMsg)
				LogOutM(LOG | MSR, 3"OnSigWsMeasured(): invalid nMsrNr %d (not in msr_list.txt)", rResult.tHead.nMsrNr);
			bCancelCurMsr = true;
		}
		else if (MS_UNKNOWN != tMsrListItem.GetStatus())
		{
			if (m_bCancelCurMsrMsg)
				LogOut(4"OnSigWsMeasured(): invalid nMsrNr %d (already archived)", rResult.tHead.nMsrNr);
			bCancelCurMsr = true;
		}
		else
		{
			nListMsrNo = rResult.tHead.nMsrNr;
			bAssigned = 0 != ::strlen(tMsrListItem.GetTrain());
		}
 
		if (rResult.tHead.nWheelset > CMsrListItem::MAX_AXIS)
		{
			if (m_bCancelCurMsrMsg)
				LogOut(3"OnSigWsMeasured(): invalid wheelset %d", rResult.tHead.nWheelset);
			bCancelCurMsr = true;
		}
		else if (rResult.tHead.nWheelset < m_tTableData.GetAxis()+1)
		{
			if (m_bCancelCurMsrMsg)
				LogOut(4"OnSigWsMeasured(): wheelset %d already archived", rResult.tHead.nWheelset);
			bCancelCurMsr = true;
		}
 
		if (bCancelCurMsr)
		{
			//	Archivieren der Messung abbrechen
			if (0 != nListMsrNo)
			{
				CMsrListItem tMsrListItem;
				if (0 < CMsrListFile::GetItem(rResult.tHead.nMsrNr, tMsrListItem))
				{
					tMsrListItem.SetStatus(MS_ERROR_UNKNOWN);
					CMsrListFile::UpdateItem(tMsrListItem);
				}
			}
			m_bCancelCurMsrMsg = false;
			m_nMsrNo = -1;
			m_eMstStatus = MS_SUCCESS;
			m_tTableData.Reset();
			++m_pResultsMod->tBuffer.nNextReadVal;
			continue;
		}
		m_bCancelCurMsrMsg = true;
 
		rFlags |= RDF_WS_ARCHIVED;
		++m_pResultsMod->tBuffer.nNextReadVal;
 
		//	Erster Radsatz einer neuen Messung ?
  		if (rResult.tHead.nMsrNr != m_nMsrNo)
		{
			if (-1 != m_nMsrNo)
			{
				LogOut(2"OnSigWsMeasured(): missing RDF_WS_LAST");
				CMsrDatFiles::NewSekDat(m_nMsrNo, MS_ERROR_UNKNOWN, m_tTableData.GetAxis(), m_tTableData.GetTableData(), m_tTableData.GetTableDataLength());
				LogOut(3"OnSigWsMeasured(): last wheelset of measurement %d", m_nMsrNo);
			}
			m_nMsrNo = rResult.tHead.nMsrNr;
			m_eMstStatus = MS_SUCCESS;
			m_tTableData.Reset();
			LogOut(5"OnSigWsMeasured(): first wheelset of measurement %d", m_nMsrNo);
		}
 
		//	Auffüllen fehlender Achsen (nicht nur) am Beginn einer neuen Messung
		CSekTableData::SWheel tDummyWheel;
		::memset(&tDummyWheel, 0sizeof(tDummyWheel));
		tDummyWheel.nFlags = RSF_INVALID;
 
		while (rResult.tHead.nWheelset > m_tTableData.GetAxis()+1)
		{
			m_eMstStatus = MS_ERROR_UNKNOWN;
			long nAxis = m_tTableData.AddAxis(tDummyWheel, tDummyWheel);
			LogOut(4"OnSigWsMeasured(): filled up missing wheelset %d", nAxis);
			//	keine Primärdaten speichern
		}
		//	RDF_WS_ERROR (RDF_WS_INVALID) nur noch mit RDF_WS_LAST als "Abbruch" auszuwerten
		if (0 != (rFlags & RDF_WS_ERROR)  &&  0 != (rFlags & RDF_WS_LAST))
		{
			m_eMstStatus = MS_ERROR_UNKNOWN;
			if (0 != (rFlags & RDF_WS_ERROR_SPEED))
				m_eMstStatus = MS_ERROR_SPEED;
			else if (0 != (rFlags & RDF_WS_ERROR_HW))
				m_eMstStatus = MS_ERROR_HW;
			else if (0 != (rFlags & RDF_WS_ABORTED))
				m_eMstStatus = MS_ERROR_ABORT;
			else if (0 != (rFlags & RDF_WS_ERROR_DIR))
				m_eMstStatus = MS_ERROR_DIR;
			long nAxis = m_tTableData.AddAxis(tDummyWheel, tDummyWheel);
			//	keine Primärdaten speichern
			LogOut(3"CDataArchApp::OnSigWsMeasured(): wheelset %d invalid", nAxis);
		}
		else
		{
			CSekTableData::SWheel tLeftWheel;
			::memset(&tLeftWheel, 0sizeof(tLeftWheel));
			tLeftWheel.nFlags = rResult.atWheel[LINKS].nFlags;
			tLeftWheel.dIE = rResult.atWheel[LINKS].fIE;
			tLeftWheel.dIE2 = rResult.atWheel[LINKS].fIE2;
			tLeftWheel.dRa = rResult.atWheel[LINKS].fRA;
			tLeftWheel.dPfH = rResult.atWheel[LINKS].fFsH;
			tLeftWheel.dEsH = rResult.atWheel[LINKS].fSeH;
			tLeftWheel.dDSkH = rResult.atWheel[LINKS].fDeSh;
 
			CSekTableData::SWheel tRightWheel;
			::memset(&tRightWheel, 0sizeof(tRightWheel));
			tRightWheel.nFlags = rResult.atWheel[RECHTS].nFlags;
			tRightWheel.dIE = rResult.atWheel[RECHTS].fIE;
			tRightWheel.dIE2 = rResult.atWheel[RECHTS].fIE2;
			tRightWheel.dRa = rResult.atWheel[RECHTS].fRA;
			tRightWheel.dPfH = rResult.atWheel[RECHTS].fFsH;
			tRightWheel.dEsH = rResult.atWheel[RECHTS].fSeH;
	  		tRightWheel.dDSkH = rResult.atWheel[RECHTS].fDeSh;
 
			if (!bAssigned)
			{
		  		LogOut(4"OnSigWsMeasured(): unassigned measurement => reuse unused fields for internal values");
				checkValues(tLeftWheel);
				checkValues(tRightWheel);
			}
 
			long nAxis = m_tTableData.AddAxis(tLeftWheel, tRightWheel);
			LogOut(5"OnSigWsMeasured(): secondary data of wheelset %d ok", nAxis);
 
			//	Primärdaten sind optional, d.h. kein Fatal-Error wenn nicht übernehmbar.
			if (
				rResult.atWheel[LINKS].nVals == rResult.atWheel[RECHTS].nVals
				&&	rResult.atWheel[LINKS].nVals >= 2
				&&	rResult.atWheel[LINKS].nVals <= RUNDSAMPLES
			)
			{
				CPrimDatFileSmartPtr spPrimDatFile;
				if (spPrimDatFile.Init(m_nMsrNo, nAxis, rResult.atWheel[LINKS].nVals))
				{
					long nCount = spPrimDatFile.Hdr().nCount;
					SPrimDatFile::SVal* atVal = spPrimDatFile.ValPtr();
					for (long nIdx = 0; nIdx < nCount; ++nIdx)
					{
						atVal[nIdx].anY[LINKS] = rResult.atWheel[LINKS].anPrimData[nIdx];
						atVal[nIdx].anY[RECHTS] = rResult.atWheel[RECHTS].anPrimData[nIdx];
					}
					CMsrDatFiles::NewPrimDat(spPrimDatFile, bAssigned);
				}
			}
			else
			{
				LogOut(MOD_ERR_LOG_LEVEL, "CDataArchApp::OnSigWsMeasured(): primary data of wheelset %d invalid or incompatible", nAxis);
			}
		}
 
		if (0 != (rFlags & RDF_WS_LAST))
		{
			CMsrDatFiles::NewSekDat(m_nMsrNo, m_eMstStatus, m_tTableData.GetAxis(), m_tTableData.GetTableData(), m_tTableData.GetTableDataLength());
			LogOut(MOD_MSG_LOG_LEVEL, "CDataArchApp::OnSigWsMeasured(): last wheelset of measurement %d", m_nMsrNo);
			m_nMsrNo = -1;
			m_eMstStatus = MS_SUCCESS;
			m_tTableData.Reset();
		}
	}
 
	return bContinue;
}