//=============================================================================================== // PROCEDURE: GetLastEntry // PURPOSE: Returns the last Synch structure added to the synch array. // BOOL CSynch::GetLastEntry(Synch *pSynch) { MEMBERASSERT(); WPTRASSERT(pSynch); if (!m_uSynchCount) return FALSE; *pSynch = m_LastEntry; return TRUE; }
//=============================================================================================== // FUNCTION: _QueryInterface // PURPOSE: Internal helper method for QueryInterface. // BOOL CUnknown::_QueryInterface(REFIID riid, LPVOID FAR *ppvObj) { MEMBERASSERT(); ASSERT(m_pInterface!=NULL); WPTRASSERT(ppvObj); HRESULT hr = m_pInterface->QueryInterface(riid, ppvObj); if (OLE_SUCCEEDED(hr)) return TRUE; return _SetLastError(hr); }
//=============================================================================================== // FUNCTION: SetInterface // PURPOSE: Sets the interface to be wrapped by the object. // NOTES: The held interface can be released by calling SetInterface(NULL). // void CUnknown::SetInterface(PUNKNOWN pInterface) { MEMBERASSERT(); // If an object is curently wrapped, release the object. if (m_pInterface) { WPTRASSERT(m_pInterface); m_pInterface->Release(); } // Set the new interface pointer and clear the last error variable. m_pInterface = pInterface; m_hrLastError = S_OK; }
//=============================================================================================== // FUNCTION: _AllocReadWriteBuffer // PURPOSE: Allocate read/write buffers for this file // static BOOL AllocReadWriteBuffer(ATF_FILEINFO *pATF, DWORD dwDesiredAccess) { WPTRASSERT(pATF); // init all settings: pATF->lBufSize = 0L; pATF->lPos = 0L; pATF->lBufReadLimit = 0L; pATF->pszBuf = NULL; pATF->bRead = TRUE; // if querying only: if (dwDesiredAccess == 0) return TRUE; #if defined(_MSC_VER) char szRootDir[_MAX_DRIVE+2]; if (_GetRootDir(pATF->pszFileName, szRootDir, sizeof(szRootDir))) { DWORD dwSectorsPerCluster = 0; DWORD dwBytesPerSector = 0; DWORD dwNumberOfFreeClusters = 0; DWORD dwTotalNumberOfClusters = 0; GetDiskFreeSpaceA(szRootDir, &dwSectorsPerCluster, &dwBytesPerSector, &dwNumberOfFreeClusters, &dwTotalNumberOfClusters); pATF->lBufSize = min((dwSectorsPerCluster * dwBytesPerSector), (long)ATF_MAX_BUFFER_SIZE); ASSERT(pATF->lBufSize > 0); } else pATF->lBufSize = ATF_MAX_BUFFER_SIZE; #else pATF->lBufSize = ATF_MAX_BUFFER_SIZE; #endif // Allocate one more than the size for zero termination. pATF->pszBuf = (char *)calloc(pATF->lBufSize+1, sizeof(char)); if (pATF->pszBuf == NULL) { pATF->lBufSize = 0L; return FALSE; } pATF->lPos = pATF->lBufSize; // empty read buffer pATF->lBufReadLimit = pATF->lBufSize; return TRUE; }
//=============================================================================================== // FUNCTION: QueryInterface // PURPOSE: This method returns a reference to the request interface, if it exists. // BOOL CUnknown::QueryInterface(REFIID riid, CUnknown *pUnknown) { MEMBERASSERT(); WPTRASSERT(pUnknown); ASSERT(m_pInterface!=NULL); // Clear the interface in the return object in case of failure. pUnknown->SetInterface(NULL); // Query for the interface. void *pInterface = NULL; if (!_QueryInterface(riid, &pInterface)) return FALSE; // Set the return value. pUnknown->SetInterface(PUNKNOWN(pInterface)); return TRUE; }
//=============================================================================================== // FUNCTION: FillToNextBlock // PURPOSE: Pads the data file out to the next ABF_BLOCKSIZE byte boundary. // BOOL CFileDescriptor::FillToNextBlock( long *plBlockNum ) { WPTRASSERT(plBlockNum); LONGLONG llOffset = 0; VERIFY(m_File.Seek(0L, FILE_END, &llOffset)); UINT uFillLastBlock = ABF_BLOCKSIZE - UINT(llOffset % ABF_BLOCKSIZE); if (uFillLastBlock != ABF_BLOCKSIZE) { BYTE cBuffer[ABF_BLOCKSIZE] = {0}; if (!Write( cBuffer, uFillLastBlock )) return FALSE; llOffset += uFillLastBlock; } *plBlockNum = long(llOffset / ABF_BLOCKSIZE); return TRUE; }
//=============================================================================================== // FUNCTION: _FreeReadWriteBuffer // PURPOSE: Free the read/write buffers used by this file; flushes write buffer to disk if necessary // static BOOL FreeReadWriteBuffer(ATF_FILEINFO *pATF) { WPTRASSERT(pATF); DWORD dwBytesWritten = 0; if (!pATF->bRead && pATF->lPos != 0L) #if defined(_MSC_VER) WriteFile(pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL); #else c_WriteFile((FILE*)pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL); #endif if (pATF->pszBuf) free(pATF->pszBuf); pATF->pszBuf = NULL; pATF->lBufSize = 0L; pATF->lPos = 0L; pATF->lBufReadLimit = 0L; pATF->bRead = TRUE; return TRUE; }
DWORD SetFilePointerBuf(ATF_FILEINFO *pATF, long lToMove, PLONG plDistHigh, DWORD dwMoveMethod) { WPTRASSERT(pATF); DWORD dwBytesWritten; // move real file position to lPos: if (pATF->bRead) { #if defined(_MSC_VER) if (SetFilePointer(pATF->hFile, pATF->lPos - pATF->lBufReadLimit, NULL, FILE_CURRENT) == 0xFFFFFFFF) #else if (c_SetFilePointer((FILE*)pATF->hFile, pATF->lPos - pATF->lBufReadLimit, NULL, FILE_CURRENT) == 0xFFFFFFFF) #endif return 0xFFFFFFFF; } // flush write buffer if non-empty - this positions the file pointer appropriately. else { if (pATF->lPos != 0L) { #if defined(_MSC_VER) if (!WriteFile(pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #else if (!c_WriteFile((FILE*)pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #endif return 0xFFFFFFFF; } } pATF->bRead = TRUE; pATF->lPos = pATF->lBufSize; pATF->lBufReadLimit = pATF->lBufSize; #if defined(_MSC_VER) return SetFilePointer(pATF->hFile, lToMove, plDistHigh, dwMoveMethod); #else return c_SetFilePointer((FILE*)pATF->hFile, lToMove, plDistHigh, dwMoveMethod); #endif }
//============================================================================================== // FUNCTION: Resize. // PURPOSE: Sizes/Resizes the bitmap to the dimensions given. // void CDisplaySurface::Resize(LPCRECT prDisplay) { MEMBERASSERT(); ASSERT(m_hdcBM); WPTRASSERT(prDisplay); int nPaletteSize = m_nPaletteSize; int nBitsPerPixel = m_nBitsPerPixel; if (m_bMatchScreen) { ASSERT(m_hdcWin); nPaletteSize = GetDeviceCaps(m_hdcWin, SIZEPALETTE); nBitsPerPixel = GetDeviceCaps(m_hdcWin, BITSPIXEL); } // If nothing has changed, just get out. if (m_rDisplay.EqualRect(prDisplay) && (nPaletteSize == m_nPaletteSize) && (nBitsPerPixel == m_nBitsPerPixel)) return; HDC hDC = Lock(); // Save the new surface properties. m_nPaletteSize = nPaletteSize; m_nBitsPerPixel = nBitsPerPixel; m_rDisplay = *prDisplay; // If a DIB was created previously, delete it. FreeBitmap(); int nWidth = m_rDisplay.Width(); nWidth = max(nWidth, 1); int nHeight = m_rDisplay.Height(); nHeight = max(nHeight, 1); // Match the screen color depth. UINT uDIBWidthBits = nWidth * nBitsPerPixel; UINT uDIBWidthBytes = ((uDIBWidthBits + 31) & (~31)) >> 3; m_ActualSize.cx = uDIBWidthBytes; m_ActualSize.cy = nHeight; if (m_bInverted) nHeight = -nHeight; // add the storage for the DIB colors, if we have any! // m_nPaletteSize will be 256 for an 8 bit DIB, and 0 for all other DIBs int nBytes = sizeof(BITMAPINFOHEADER) + m_nPaletteSize * sizeof(RGBQUAD); ASSERT(m_pBitmapInfo==NULL); m_pBitmapInfo = (BITMAPINFO *)malloc(nBytes); memset(m_pBitmapInfo, 0, nBytes); // if we've run out of memory, get out of here if (!m_pBitmapInfo) return; // set up the information that we need BITMAPINFOHEADER *pBitmapInfoHeader = &(m_pBitmapInfo->bmiHeader); pBitmapInfoHeader->biSize = sizeof(BITMAPINFOHEADER); // always this pBitmapInfoHeader->biWidth = nWidth; // the width of the bitmap pBitmapInfoHeader->biHeight = nHeight; // the height, but negative so we display it upside down pBitmapInfoHeader->biPlanes = 1; // Always 1 pBitmapInfoHeader->biBitCount = WORD(m_nBitsPerPixel); // BPP for DIB pBitmapInfoHeader->biCompression = BI_RGB; // no compression pBitmapInfoHeader->biSizeImage = 0; // Calculation not needed for BI_RGB pBitmapInfoHeader->biXPelsPerMeter = 0; // These are arbitrary pBitmapInfoHeader->biYPelsPerMeter = 0; // These are arbitrary pBitmapInfoHeader->biClrUsed = m_nPaletteSize; // Use biBitCount to determine colors used pBitmapInfoHeader->biClrImportant = 0; // All colors important, set to 0 m_Palette.DeleteObject(); if (m_nPaletteSize > 0) { #ifdef _MFC_VER m_Palette.CreateHalftonePalette( CDC::FromHandle(m_hdcWin) ); #else m_Palette.CreateHalftonePalette(m_hdcWin); #endif ASSERT(m_nPaletteSize <= 256); PALETTEENTRY PalEntries[256] = { 0 }; PALETTEENTRY IdentityPalEntries[256] = { 0 }; // fill them in int nEntries = m_Palette.GetPaletteEntries(0, m_nPaletteSize, PalEntries); LPPALETTEENTRY pPalEntries = PalEntries; CreateIdentityPalette(PalEntries, IdentityPalEntries, nEntries); pPalEntries = IdentityPalEntries; // now convert to DIB color RGBQUAD *pDIBColorTable = m_pBitmapInfo->bmiColors; for (int i = 0; i < m_nPaletteSize; i++) { pDIBColorTable[i].rgbBlue = pPalEntries[i].peBlue; pDIBColorTable[i].rgbGreen = pPalEntries[i].peGreen; pDIBColorTable[i].rgbRed = pPalEntries[i].peRed; pDIBColorTable[i].rgbReserved = 0; } } // Create the DIB section. m_hBitmap = CreateDIBSection( hDC, m_pBitmapInfo, DIB_RGB_COLORS, (LPVOID *)(&m_pDibBits), NULL, 0); ASSERT(m_hBitmap); m_hbmSave = SelectBitmap( hDC, m_hBitmap ); SetViewportOrgEx( hDC, -m_rDisplay.left, -m_rDisplay.top, NULL); Clear( &m_rDisplay ); Unlock(); }
int putsBuf(ATF_FILEINFO *pATF, LPCSTR pszString) { WPTRASSERT(pATF); DWORD dwBytes = strlen(pszString); DWORD dwBytesWritten; // perform write if buffer size is 0: if (pATF->lBufSize == 0L) #if defined(_MSC_VER) return WriteFile(pATF->hFile, pszString, dwBytes, &dwBytesWritten, NULL); #else return c_WriteFile((FILE*)pATF->hFile, pszString, dwBytes, &dwBytesWritten, NULL); #endif // switch to write mode: if (pATF->bRead) { pATF->bRead = FALSE; pATF->lPos = 0; } long lBufSize = pATF->lBufSize; char *pszWriteBuf = pATF->pszBuf; // determine free size left in buffer: long lFreeSize = lBufSize - pATF->lPos; ASSERT(lFreeSize > 0L); // move up to a single buffer long lMoveSize = min((DWORD)lFreeSize, dwBytes); memcpy(pszWriteBuf + pATF->lPos, pszString, lMoveSize); pATF->lPos += lMoveSize; // case 1: doesn't fill buffer if (pATF->lPos < lBufSize) return TRUE; // write initial buffer - results handled in case 2 and 3: #if defined(_MSC_VER) BOOL bReturn = WriteFile(pATF->hFile, pszWriteBuf, lBufSize, &dwBytesWritten, NULL); #else BOOL bReturn = c_WriteFile((FILE*)pATF->hFile, pszWriteBuf, lBufSize, &dwBytesWritten, NULL); #endif // case 2: fills buffer, less than one buffer overflow (write one, move the rest) if (dwBytes - (DWORD)lMoveSize < (DWORD)lBufSize) { pATF->lPos = dwBytes - lMoveSize; if (pATF->lPos > 0L) memcpy(pszWriteBuf, pszString + lMoveSize, pATF->lPos); return bReturn; } // case 3: multiple buffer's worth (write mem buffer, write the remainder, reset internals) if (bReturn) #if defined(_MSC_VER) bReturn = WriteFile(pATF->hFile, pszString + lMoveSize, dwBytes - lMoveSize, &dwBytesWritten, NULL); #else bReturn = c_WriteFile((FILE*)pATF->hFile, pszString + lMoveSize, dwBytes - lMoveSize, &dwBytesWritten, NULL); #endif pATF->lPos = 0L; return bReturn; }
int getsBuf(ATF_FILEINFO *pATF, LPSTR pszString, DWORD dwBufSize) { WPTRASSERT(pATF); // ******************************************************************************* // check for unbuffered status: if (pATF->lBufSize == 0) return getsUnBuf(pATF, pszString, dwBufSize); DWORD dwToRead = dwBufSize; // ******************************************************************************* // switch to read mode, if necessary: if (!pATF->bRead) { DWORD dwBytesWritten; // commit current cache: if (pATF->lPos > 0) #if defined(_MSC_VER) if (!WriteFile(pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #else if (!c_WriteFile((FILE*)pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #endif return GETS_ERROR; pATF->bRead = TRUE; pATF->lPos = pATF->lBufSize; pATF->lBufReadLimit = pATF->lBufSize; } // ******************************************************************************* // process: dwToRead--; // for terminating 0 pszString[dwToRead] = '\0'; LPSTR pszReturnBuf = pszString; LPSTR pszReadBuf = pATF->pszBuf; while (dwToRead > 0L) { // determine amount left in buffer: long lBytesInBuf = pATF->lBufReadLimit - pATF->lPos; ASSERT(lBytesInBuf >= 0L); // move up to a single buffer long lMoveSize = min(lBytesInBuf, (long)dwToRead); if (lMoveSize > 0) { // look for a line terminator LPSTR pszStart = pszReadBuf + pATF->lPos; LPSTR pszTerm = strchr(pszStart, pATF->cLineTerm); // If found and inside the read range terminate the string and the read. if (pszTerm && (pszTerm < pszStart+lMoveSize)) { *pszTerm = '\0'; lMoveSize = pszTerm - pszStart + 1; // When the counter gets decremented below, the loop will terminate. dwToRead = lMoveSize; } // Copy the data into the return buffer. strncpy(pszReturnBuf, pszStart, lMoveSize); pszReturnBuf[lMoveSize] = '\0'; // Advance the buffer position pATF->lPos += lMoveSize; dwToRead -= lMoveSize; pszReturnBuf += lMoveSize; } else { // read another buffer if done with the current one: if (dwToRead > 0) // ie - we arrived here because lBytesInBuf == 0 { DWORD dwBytesRead; #if defined(_MSC_VER) if (!ReadFile(pATF->hFile, pszReadBuf, pATF->lBufSize, &dwBytesRead, NULL)) #else if (!c_ReadFile((FILE*)pATF->hFile, pszReadBuf, pATF->lBufSize, &dwBytesRead, NULL)) #endif return GETS_ERROR; if (dwBytesRead == 0) return GETS_EOF; if (dwBytesRead != (DWORD)pATF->lBufSize) pATF->lBufReadLimit = dwBytesRead; else pATF->lBufReadLimit = pATF->lBufSize; pATF->lPos = 0; // Zero terminate the read block after the last byte read. // No bounds problem because we allocated the I/O buffer to be one byte // more than pATF->lBufSize. pszReadBuf[dwBytesRead] = '\0'; // If the line terminator has not been set, set it now. if (pATF->cLineTerm == '\0') pATF->cLineTerm = GetLineTerminator(pszReadBuf); } } } // Take out the last character if it is '\r'. // (present if \r\n pairs terminate lines) int l = strlen(pszString); if (l && (pszString[l-1]=='\r')) { l--; pszString[l] = '\0'; } return (DWORD(l) < dwBufSize-1) ? 0 : GETS_NOEOL; }
//=============================================================================================== // PROCEDURE: Write // PURPOSE: Copies the complete synch array to another file, packing out the file-offset entry. // BOOL CSynch::Write( HANDLE hDataFile, UINT uAcquiredSamples, UINT *puSynchCount, UINT uSampleSize ) { MEMBERASSERT(); ASSERT( hDataFile != INVALID_HANDLE_VALUE ); WPTRASSERT(puSynchCount); // Flush any cached Synch entries to the temp file. This should not fail as the reserve file // will have been released just prior to calling this function. If it does fail, we will // still be able to work with the Synch entries that were saved ok. if (m_uCacheCount) _Flush(); // Set the return value for the number of synch entries. If none exist, return. *puSynchCount = 0; if (m_uSynchCount == 0) return TRUE; // Seek to the end of the passed file. This will only fail for invalid file handles. CFileIO_NoClose OutFile(hDataFile); LONGLONG llCurrentPos = 0; if (!OutFile.Seek(0, FILE_END, &llCurrentPos)) return FALSE; // Seek to the start of the temporary file. SetFilePointer(m_hfSynchFile, 0L, NULL, FILE_BEGIN); // Read the Synch data in a buffer at a time and write it out to the passed file. UINT uEntries = m_uSynchCount; UINT uWritten = 0; UINT uCount = 0; while ( uEntries > 0 ) { uCount = min(uEntries, SYNCH_BUFFER_SIZE); // Read in a buffer from the temp file. VERIFY(Read( m_SynchBuffer, uWritten, uCount)); // Pack the buffer, removing the dwFileOffset members and checking for invalid synch entries. // If an invalid entry is found, the count is truncated at the last valid entry. if (!_PackBuffer(uAcquiredSamples, uCount, uSampleSize)) uEntries = uCount; // Write the packed buffer out to the temp file. if ( !OutFile.Write( m_SynchBuffer, uCount * 2 * sizeof(DWORD) )) { // If an error occurs, go back to the start of the block and truncate the file // ready for the next attempt after the user has freed up some disk space. VERIFY(OutFile.Seek(llCurrentPos, FILE_BEGIN)); VERIFY(OutFile.SetEndOfFile()); return FALSE; } uEntries -= uCount; uWritten += uCount; } // Seek back to end of the temporary file. SetFilePointer(m_hfSynchFile, 0L, NULL, FILE_END); //TRACE1( "CSynch::Write current file pointer is %d after seek to end.\n", // SetFilePointer(m_hfSynchFile, 0, NULL, FILE_CURRENT) ); *puSynchCount = uWritten; return TRUE; }
//=============================================================================================== // FUNCTION: getsUnBuf // PURPOSE: Unbuffered version of gets // RETURNS: ZERO on success // GETS_EOF on EOF // GETS_ERROR on error // static int getsUnBuf(ATF_FILEINFO *pATF, LPSTR pszString, DWORD dwBufSize) { WPTRASSERT(pATF); ASSERT(dwBufSize > 1L); // Must be at least one character and a '\0'; DWORD dwToRead = dwBufSize; // Zero terminate the buffer at the last element and reduce the length count // to be sure that we are returning a zero term8inated string. dwToRead--; pszString[dwToRead] = '\0'; LPSTR pszThisRead = pszString; while (dwToRead > 0L) { // Do the read. DWORD dwBytesToRead = min(MAX_READ_SIZE, dwToRead); DWORD dwBytesRead = 0L; if (!ReadFileBuf(pATF, pszThisRead, dwBytesToRead, &dwBytesRead, NULL)) return GETS_ERROR; if (dwBytesRead == 0L) return GETS_EOF; // Zero terminate the read block after the last byte read. // No bounds problem because we predecremented the string size // up front to allow for a trailing '\0'. pszThisRead[dwBytesRead] = '\0'; // If the line terminator has not been set, set it now. if (pATF->cLineTerm == '\0') pATF->cLineTerm = GetLineTerminator(pszString); // look for a line terminator. LPSTR pszTerm = strchr(pszThisRead, pATF->cLineTerm); if (pszTerm) { // Zero out the terminator and step on past it. *pszTerm++ = '\0'; // Set the count of bytes to back up in the file. int nCount = (pszThisRead + dwBytesRead) - pszTerm; // adjust file position if we find a line terminator before the end of the buffer we have just read; if (nCount < 0) SetFilePointerBuf(pATF, nCount, NULL, FILE_CURRENT); break; } dwToRead -= dwBytesRead; pszThisRead += dwBytesRead; } // Take out the last character if it is '\r'. // (present if \r\n pairs terminate lines) int l = strlen(pszThisRead); if (l && (pszThisRead[l-1]=='\r')) { --l; pszThisRead[l] = '\0'; } return (DWORD(l) < dwBufSize-1) ? 0 : GETS_NOEOL; }
BOOL ReadFileBuf(ATF_FILEINFO *pATF, LPVOID pvBuffer, DWORD dwBytes, DWORD *pdwRead, LPOVERLAPPED lpOverlapped) { WPTRASSERT(pATF); // perform read if buffer size is 0: if (pATF->lBufSize == 0L) #if defined(_MSC_VER) return ReadFile(pATF->hFile, pvBuffer, dwBytes, pdwRead, lpOverlapped); #else return c_ReadFile((FILE*)pATF->hFile, pvBuffer, dwBytes, pdwRead, lpOverlapped); #endif // switch to read mode: if (!pATF->bRead) { DWORD dwBytesWritten; // commit current cache: if (pATF->lPos > 0L) #if defined(_MSC_VER) if (!WriteFile(pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #else if (!c_WriteFile((FILE*)pATF->hFile, pATF->pszBuf, pATF->lPos, &dwBytesWritten, NULL)) #endif return FALSE; pATF->bRead = TRUE; pATF->lPos = pATF->lBufSize; pATF->lBufReadLimit = pATF->lBufSize; } DWORD dwBytesRead; BOOL bReturn; long lBufSize = pATF->lBufSize; char *pszReadBuf = pATF->pszBuf; // determine amount left in buffer: long lBytesInBuf = pATF->lBufReadLimit - pATF->lPos; ASSERT(lBytesInBuf >= 0L); // move up to a single buffer long lMoveSize = min((DWORD)lBytesInBuf, dwBytes); if (lMoveSize > 0L) { memcpy(pvBuffer, pszReadBuf + pATF->lPos, lMoveSize); pATF->lPos += lMoveSize; } // case 1: request doesn't run past the end of the buffer if (pATF->lPos < pATF->lBufReadLimit) { if (pdwRead) *pdwRead = dwBytes; return TRUE; } // case 2: request runs past end of buffer, and wants more than (or =) another buffer's worth: // (perform a full read; leaves buffer empty) if (dwBytes - (DWORD)lMoveSize >= (DWORD)pATF->lBufReadLimit) { #if defined(_MSC_VER) bReturn = ReadFile(pATF->hFile, ((BYTE *)pvBuffer + lMoveSize), dwBytes - lMoveSize, &dwBytesRead, lpOverlapped); #else bReturn = c_ReadFile((FILE*)pATF->hFile, ((BYTE *)pvBuffer + lMoveSize), dwBytes - lMoveSize, &dwBytesRead, lpOverlapped); #endif if (pdwRead) *pdwRead = lMoveSize + dwBytesRead; pATF->lPos = lBufSize; pATF->lBufReadLimit = lBufSize; return bReturn; } // case 3: request runs past end of buffer, and wants less than another buffer's worth: // (read in another buffer, copy wanted portion, advance lPos) #if defined(_MSC_VER) bReturn = ReadFile(pATF->hFile, pszReadBuf, lBufSize, &dwBytesRead, lpOverlapped); #else bReturn = c_ReadFile((FILE*)pATF->hFile, pszReadBuf, lBufSize, &dwBytesRead, lpOverlapped); #endif if (bReturn) { pATF->lBufReadLimit = dwBytesRead; int nMoveAmount = min((int)(dwBytes - lMoveSize), pATF->lBufReadLimit); memcpy((BYTE *)pvBuffer + lMoveSize, pszReadBuf, nMoveAmount); if (pdwRead) *pdwRead = lMoveSize + nMoveAmount; pATF->lPos = nMoveAmount; } else { if (pdwRead) *pdwRead = lMoveSize; pATF->lPos = lBufSize; } return bReturn; }
BOOL WriteFileBuf(ATF_FILEINFO *pATF, LPCVOID pvBuffer, DWORD dwBytes, DWORD *pdwWritten, LPOVERLAPPED lpOverlapped) { WPTRASSERT(pATF); long lBufSize = pATF->lBufSize; char *pszWriteBuf = pATF->pszBuf; // perform write if buffer size is 0: if (lBufSize == 0L) #if defined(_MSC_VER) return WriteFile(pATF->hFile, pvBuffer, dwBytes, pdwWritten, lpOverlapped); #else return c_WriteFile((FILE*)pATF->hFile, pvBuffer, dwBytes, pdwWritten, lpOverlapped); #endif // switch to write mode: if (pATF->bRead) { pATF->bRead = FALSE; pATF->lPos = 0; } // determine free size left in buffer: long lFreeSize = lBufSize - pATF->lPos; ASSERT(lFreeSize > 0L); // move up to a single buffer long lMoveSize = min((DWORD)lFreeSize, dwBytes); memcpy(pszWriteBuf + pATF->lPos, pvBuffer, lMoveSize); pATF->lPos += lMoveSize; // case 1: doesn't fill buffer if (pATF->lPos < lBufSize) { if (pdwWritten) *pdwWritten = dwBytes; return TRUE; } // write initial buffer - results handled in case 2 and 3: DWORD dwBytesWritten = 0; #if defined(_MSC_VER) BOOL bReturn = WriteFile(pATF->hFile, pszWriteBuf, lBufSize, &dwBytesWritten, lpOverlapped); #else BOOL bReturn = c_WriteFile((FILE*)pATF->hFile, pszWriteBuf, lBufSize, &dwBytesWritten, lpOverlapped); #endif // case 2: fills buffer, less than one buffer overflow (write one, move the rest) if (dwBytes - (DWORD)lMoveSize < (DWORD)lBufSize) { if (dwBytes - lMoveSize > 0L) memcpy(pszWriteBuf, ((BYTE *)pvBuffer + lMoveSize), dwBytes-lMoveSize); pATF->lPos = dwBytes - lMoveSize; if (pdwWritten) *pdwWritten = dwBytes; return bReturn; } // case 3: multiple buffer's worth (write mem buffer, write the remainder, reset internals) if (bReturn) { #if defined(_MSC_VER) bReturn = WriteFile(pATF->hFile, ((BYTE *)pvBuffer + lMoveSize), dwBytes - lMoveSize, &dwBytesWritten, lpOverlapped); #else bReturn = c_WriteFile((FILE*)pATF->hFile, ((BYTE *)pvBuffer + lMoveSize), dwBytes - lMoveSize, &dwBytesWritten, lpOverlapped); #endif if (pdwWritten) *pdwWritten = dwBytes; } else if (pdwWritten) *pdwWritten = dwBytesWritten; pATF->lPos = 0L; return bReturn; }
//=============================================================================================== // FUNCTION: UpdateTag // PURPOSE: Updates an entry in the tag array. // BOOL CFileDescriptor::UpdateTag( UINT uTag, const ABFTag *pTag) { MEMBERASSERT(); WPTRASSERT( pTag ); return m_Tags.Update( uTag, pTag ); }
//=============================================================================================== // FUNCTION: RemoveExtraChannels // PURPOSE: Removes "extra" channels when P/N is enabled and files are opened as protocols. // NOTES: This function allows Clampex 10 data files (with P/N enabled) to be opened as a protocol. // These files have an extra channel that stores the raw data (in addition to the corrected data). // Therefore there is some tweaking and scaling of header parameters. // static BOOL RemoveExtraChannels( ABFFileHeader *pFH, UINT uFlags ) { WPTRASSERT( pFH ); // Must be episodic stimulation mode. if( pFH->nOperationMode != ABF_WAVEFORMFILE ) return FALSE; // P/N must be enabled. if( !ABFH_IsPNEnabled( pFH ) ) return FALSE; // This fix only applies to files with one ADC channel and one P/N channel. if( pFH->nADCNumChannels != 2 ) return FALSE; // Must be a data file (i.e. not a protocol). if( pFH->lActualAcqLength == 0 ) return FALSE; bool bFudge = false; if( uFlags & ABF_PARAMFILE ) bFudge = true; else { long lActualSamplesPerEpisode = pFH->lActualAcqLength / pFH->lActualEpisodes; if( lActualSamplesPerEpisode != pFH->lNumSamplesPerEpisode ) bFudge = true; } if( !bFudge ) return FALSE; int nIndex = ABF_UNUSED_CHANNEL; for( UINT i=0; i<ABF_ADCCOUNT; i++ ) { if( pFH->nADCSamplingSeq[i] == ABF_UNUSED_CHANNEL ) { nIndex = i - 1; // i.e. the previous channel is the last valid channel. break; } } if( nIndex == ABF_UNUSED_CHANNEL ) return FALSE; // There are extra channels to be stripped. short nOldChans = pFH->nADCNumChannels; short nNewChans = nOldChans - 1; pFH->nADCNumChannels = nNewChans; pFH->lNumSamplesPerEpisode = MulDiv( pFH->lNumSamplesPerEpisode, nNewChans, nOldChans ); // Adjust the statistics search regions. pFH->lStatsBaselineStart = MulDiv( pFH->lStatsBaselineStart, nNewChans, nOldChans ); pFH->lStatsBaselineEnd = MulDiv( pFH->lStatsBaselineEnd, nNewChans, nOldChans ); for( UINT i=0; i<ABF_STATS_REGIONS; i++ ) { pFH->lStatsStart[i] = MulDiv( pFH->lStatsStart[i], nNewChans, nOldChans ); pFH->lStatsEnd[i] = MulDiv( pFH->lStatsEnd[i], nNewChans, nOldChans ); } return TRUE; }