size_t wxStreamBuffer::Write(const void *buffer, size_t size) { wxASSERT_MSG( buffer, wxT("Warning: Null pointer is about to be send") ); if (m_stream) { // lasterror is reset before all new IO calls m_stream->Reset(); } size_t ret; if ( !HasBuffer() && m_fixed ) { wxOutputStream *outStream = GetOutputStream(); wxCHECK_MSG( outStream, 0, wxT("should have a stream in wxStreamBuffer") ); // no buffer, just forward the call to the stream ret = outStream->OnSysWrite(buffer, size); } else // we [may] have a buffer, use it { size_t orig_size = size; while ( size > 0 ) { size_t left = GetBytesLeft(); // if the buffer is too large to fit in the stream buffer, split // it in smaller parts // // NB: If stream buffer isn't fixed (as for wxMemoryOutputStream), // we always go to the second case. // // FIXME: fine, but if it fails we should (re)try writing it by // chunks as this will (hopefully) always work (VZ) if ( size > left && m_fixed ) { PutToBuffer(buffer, left); size -= left; buffer = (char *)buffer + left; if ( !FlushBuffer() ) { SetError(wxSTREAM_WRITE_ERROR); break; } m_buffer_pos = m_buffer_start; } else // we can do it in one gulp { PutToBuffer(buffer, size); size = 0; } } ret = orig_size - size; } if (m_stream) { // i am not entirely sure what we do this for m_stream->m_lastcount = ret; } return ret; }
CProcessAnalysis::CProcessAnalysis( CDirEntry *pDirEntry, const CVolume *pVolume, wxEvtHandler *parent, int nID) : CProcess(parent,nID), m_psExe(NULL), m_pDirEntry(pDirEntry) { #define END_LINE sStdin.Append(";\n") #define APPEND_LINE(name,value) \ sStdin.Append(name); \ sStdin.Append(wxS("=")); \ sStdin.Append(value); \ END_LINE #define FORMAT_INT(n) \ s.Printf("%d",n) #define APPEND_INT(name,n) \ FORMAT_INT(n); \ APPEND_LINE(name,s) wxString sStdin; wxString s; const CParmOsiris *pParm = pDirEntry->GetParmOsiris(); const ConfigDir *pDir = mainApp::GetConfig(); sStdin.Alloc(4096); APPEND_LINE("InputDirectory",pParm->GetInputDirectory()); // 1 APPEND_LINE("LadderDirectory",pDir->GetExeConfigPath()); // 2 APPEND_LINE("ReportDirectory",pParm->GetOutputDirectory()); // 3 APPEND_LINE("MarkerSetName",pParm->GetKitName()); // 4 APPEND_LINE("LaneStandardName",pParm->GetLsName()); // 5 APPEND_LINE("CriticalOutputLevel","15"); // 6 APPEND_INT("MinSampleRFU",pParm->GetMinRFU_Sample()); // 7 APPEND_INT("MinLaneStandardRFU",pParm->GetMinRFU_ILS()); // 8 APPEND_INT("MinLadderRFU",pParm->GetMinRFU_Ladder()); // 9 APPEND_INT("MinInterlocusRFU",pParm->GetMinRFU_Interlocus()); // 10 // channel data typedef struct { const vector<int> *pan; const wxChar *ps; } CHANNEL_OVERRIDE; CHANNEL_OVERRIDE chanInfo[] = { { &pParm->GetChannelRFU(), wxS("AnalysisThresholdOverride") }, { &pParm->GetChannelDetection(), wxS("DetectionThresholdOverride") } }; const size_t nOVR = sizeof(chanInfo) / sizeof(chanInfo[0]); wxString sName; for (size_t ndx = 0; ndx < nOVR; ndx++) { const vector<int> *pan = chanInfo[ndx].pan; const wxChar *ps = chanInfo[ndx].ps; vector<int>::const_iterator itr; int nChannel; for(itr = pan->begin(), nChannel = 1; itr != pan->end(); ++itr, ++nChannel) { if((*itr) > 0) { FORMAT_INT(nChannel); sName = ps; sName.Append(wxS(":")); sName.Append(s); APPEND_INT(sName,*itr); } } } // end channel data if(pParm->GetTimeStampSubDir()) { const wxString &s = pDirEntry->GetTimeStamp(); if(!s.IsEmpty()) { APPEND_LINE("OutputSubdirectory",s); } else { wxASSERT_MSG(false,"Time stamp is empty"); } } // the following may eventually be moved to CParmOsiris and // CLabSettings::GetMinRFU() if it is added to the user interface int nMinLadderInterlocus = pParm->GetMinLadderInterlocusRFU(); // pVolume->GetLabSettings()->GetThresholds()->GetRFUladder()->GetMinRFUinterlocus(); int nMinDetection = pParm->GetSampleDetectionThreshold(); // pVolume->GetLabSettings()->GetThresholds()->GetRFUsample()->GetMinDetection(); if(nMinLadderInterlocus >= 0) { APPEND_INT("MinLadderInterlocusRFU",nMinLadderInterlocus); // 11 } if(nMinDetection >= 0) { APPEND_INT("SampleDetectionThreshold",nMinDetection); } s = pParm->GetDataAnalyzed() ? "A" : "R"; APPEND_LINE("RawDataString",s); // 11 or 12 APPEND_LINE("LabSettings",pVolume->GetLabSettingsFileName()); APPEND_LINE("StandardSettings",pVolume->GetStdSettingsFileName()); APPEND_LINE("MessageBook",pDir->GetMessageBookFileName()); const wxString &sOverride(pParm->GetAnalysisOverride()); if(!sOverride.IsEmpty()) { APPEND_LINE("override",sOverride); } END_LINE; #undef APPEND_INT #undef APPEND_LINE #undef END_LINE // finished building stdin for analysis program wxASSERT_MSG(sizeof(char) == 1, "sizeof(char) != 1, " "therefore this code needs to be changed"); s = pDir->GetExePath(); nwxFileUtil::EndWithSeparator(&s); #ifdef __WXMSW__ s += "TestAnalysisDirectoryLC.exe"; #else s += "TestAnalysisDirectoryLC"; #endif m_psExe = strdup(s.utf8_str()); char *argv[] = { m_psExe, NULL }; m_dProgress = 0.0; Run(argv); wxOutputStream *pOut = GetOutputStream(); wxASSERT_MSG(pOut != NULL,"Cannot get output stream for process"); mainApp::LogMessage(sStdin); if(pOut != NULL) { const char *pChar = sStdin.ToUTF8(); size_t nLen = sStdin.Len(); size_t n; while(nLen > 0) { n = pOut->Write((void *)pChar,nLen).LastWrite(); if(n) { pChar += n; nLen -= n; } else { nLen = 0; Cancel(); } } } }