123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- ////////////////////////////////////////////////////////////////////////////////
- //
- // Copyright 2016 RWS Inc, All Rights Reserved
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of version 2 of the GNU General Public License as published by
- // the Free Software Foundation
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License along
- // with this program; if not, write to the Free Software Foundation, Inc.,
- // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- //
- //////////////////////////////////////////////////////////////////////////////
- //
- // FILEWIN.CPP
- //
- // History:
- // 09/19/95 JMI Started.
- //
- // 09/20/95 JMI Made read only.
- //
- //////////////////////////////////////////////////////////////////////////////
- //
- // This object maintains a window on the file. It fills the panes on
- // interval to be read by the user.
- //
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // C Headers.
- //////////////////////////////////////////////////////////////////////////////
- #include <malloc.h>
- //////////////////////////////////////////////////////////////////////////////
- // Blue Headers.
- //////////////////////////////////////////////////////////////////////////////
- #include "System.h"
- #include "bdebug.h"
- #include "bcritic.h"
- //////////////////////////////////////////////////////////////////////////////
- // Green Headers.
- //////////////////////////////////////////////////////////////////////////////
- #include "filewin.h"
- //////////////////////////////////////////////////////////////////////////////
- // Orange Headers.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // Yellow Headers.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // Module specific macros.
- //////////////////////////////////////////////////////////////////////////////
- #define WINDOWINDEX(l) (l % m_lWinSize)
- //////////////////////////////////////////////////////////////////////////////
- // Module specific typedefs.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // Module specific (static) variables.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- // Construction/Destruction Functions.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- //
- // Default constructor.
- //
- //////////////////////////////////////////////////////////////////////////////
- CFileWin::CFileWin()
- {
- Set();
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Destructor.
- //
- //////////////////////////////////////////////////////////////////////////////
- CFileWin::~CFileWin()
- {
- Close();
- }
- //////////////////////////////////////////////////////////////////////////////
- // Internal Functions.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- //
- // Sets variables w/o regard to current values.
- //
- //////////////////////////////////////////////////////////////////////////////
- void CFileWin::Set(void)
- {
- m_pucWindow = NULL;
- m_paneUser.puc = NULL;
- m_paneIn.puc = NULL;
- m_usStatus = 0;
- m_call = NULL;
- m_fnTime = NULL;
- m_sActive = FALSE;
- m_sSuspend = 1; // Start out suspended.
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Resets variables. Performs deallocation if necessary.
- //
- //////////////////////////////////////////////////////////////////////////////
- void CFileWin::Reset(void)
- {
- ASSERT(m_sActive == FALSE);
-
- Suspend();
- Free();
- Set();
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Allocates the file window of size lSize.
- // Returns 0 on success.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::Alloc(long lSize)
- {
- short sRes = 0; // Assume success.
- // Allocate new window . . .
- m_pucWindow = (UCHAR*)malloc(lSize);
- if (m_pucWindow != NULL)
- {
- m_paneUser.puc = m_pucWindow;
- m_paneIn.puc = m_pucWindow;
- m_lWinSize = lSize;
- m_paneUser.lPos = 0L;
- m_paneIn.lPos = 0L;
- }
- else
- {
- TRACE("Alloc(%ld): Unable to allocate file window.\n", lSize);
- sRes = -1;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Frees the file window.
- //
- //////////////////////////////////////////////////////////////////////////////
- void CFileWin::Free(void)
- {
- if (m_pucWindow != NULL)
- {
- free(m_pucWindow);
-
- m_pucWindow = NULL;
- m_paneUser.puc = NULL;
- m_paneIn.puc = NULL;
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Move to next i/o pane.
- // Returns 0 on success.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::NextIOPane(void)
- {
- short sRes = 0; // Assume success.
- // If next pane complete . . .
- if (IsNextInputPaneReady() == TRUE)
- {
- // Get position of next pane.
- m_paneIn.lPos += m_paneIn.lSize;
- // Move ptr to position.
- m_paneIn.puc = m_pucWindow + WINDOWINDEX(m_paneIn.lPos);
- }
- else
- {
- sRes = -1;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Implied this version of CriticalStatic. Reads/writes file.
- //
- //////////////////////////////////////////////////////////////////////////////
- void CFileWin::Critical(void)
- {
- // If time to update . . .
- if (GetTime() > m_lNextTime)
- {
- if (NextIOPane() == 0)
- {
- // Attempt to fill pane.
- m_paneIn.lSize = m_file.Read(m_paneIn.puc, m_paneIn.lSize);
-
- // Get next read time.
- m_lNextTime = GetTime() + m_lInputInterval;
- }
- else
- {
- TRACE("Critical(): Waiting for application to free up current "
- "pane!\n");
- m_usStatus |= STATUS_WAITING;
- }
- }
- // If callback provided . . .
- if (m_call != NULL)
- {
- // If next user pane is complete . . .
- if (NextPane() == 0)
- {
- // Call user.
- (*m_call)(&m_paneUser, m_lUser);
- }
- else
- {
- // If EOF . . .
- if (m_file.IsEOF() == TRUE)
- {
- m_usStatus |= STATUS_EOF;
- }
- else
- {
- // If read error . . .
- if (m_file.Error() == TRUE)
- {
- TRACE("Critical(): A read error stopped reading before complete.\n");
- m_usStatus |= ERROR_FILEACCESS;
- }
- }
- // If not ready b/c file input has stopped . . .
- if (m_usStatus & (STATUS_EOF | ERROR_FILEACCESS))
- {
- // If there is not a full pane of data . . .
- if (m_paneUser.lPos + m_paneUser.lSize * 2 > m_paneIn.lPos + m_paneIn.lSize)
- {
- // Advance.
- m_paneUser.lPos += m_paneUser.lSize;
- m_paneUser.puc = m_pucWindow + WINDOWINDEX(m_paneUser.lPos);
- // Adjust pane size.
- m_paneUser.lSize = (m_paneIn.lPos + m_paneIn.lSize) - m_paneUser.lPos;
- // Call user.
- (*m_call)(&m_paneUser, m_lUser);
- }
- // Suspend this.
- Suspend();
- }
- else
- {
- // User pane caught up with input even though no error nor EOF.
- // This could occur if the user pane is larger than the input
- // pane.
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Called by Blue every time Blu_System is called.
- //
- //////////////////////////////////////////////////////////////////////////////
- void CFileWin::CriticalStatic(CFileWin* pfw)
- {
- pfw->Critical();
- }
-
- //////////////////////////////////////////////////////////////////////////////
- // Public Functions.
- //////////////////////////////////////////////////////////////////////////////
- //////////////////////////////////////////////////////////////////////////////
- //
- // Opens a window into pszFile. sMode indicates read or write
- // { FW_MODE_READ, FW_MODE_WRITE }.
- // Returns 0 on success.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::Open(char* pszFile)
- {
- short sRes = 0; // Assume success.
- // Attempt to open file . . .
- // Endianness doesn't matter (only UCHAR reads).
- if (m_file.Open(pszFile, "rb", ENDIAN_BIG) == 0)
- {
- }
- else
- {
- TRACE("Open(\"%s\"): Unable to open file.\n");
- sRes = -1;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Closes the currently open file.
- // Returns 0 on success.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::Close(void)
- {
- short sRes = 0; // Assume success.
- // If file is open . . .
- if (m_file.IsOpen() == TRUE)
- {
- // Close.
- if (m_file.Close() == 0)
- {
- // Success.
- Suspend();
- Reset();
- }
- else
- {
- TRACE("Close(): CNFile::Close() failed.\n");
- sRes = -1;
- }
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Sets size of window, user pane, and i/o pane. Anything currently in the
- // window will be lost.
- // This function causes a seek.
- // If this fails you could end up with no more buffer, even if you had one
- // before calling this, so CHECK THE RETURN VALUE!
- // ASSUMPTIONS: File is open.
- // Returns 0 on success.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::SetSize(long lWinSize, long lIOPaneSize, long lUserPaneSize)
- {
- short sRes = 0; // Assume success.
- ASSERT(m_file.IsOpen() == TRUE);
- ASSERT(lWinSize % lIOPaneSize == 0);
- ASSERT(lWinSize % lUserPaneSize == 0);
- // Free current window.
- Free();
- // Allocate new window . . .
- if (Alloc(lWinSize) == 0)
- {
- m_paneUser.lSize = lUserPaneSize;
- // Store current file position. Changing the buffer size of a stream
- // requires a seek.
- long lPos = m_file.Tell();
-
- // Attempt to set file buffer size . . .
- if (m_file.SetBufferSize(lIOPaneSize) == 0)
- {
- m_paneIn.lSize = lIOPaneSize;
-
- // Attempt to seek back to current position . . .
- if (m_file.Seek(lPos, SEEK_SET) == 0)
- {
- // Success.
- }
- else
- {
- TRACE("SetSize(): CNFile::Seek failed.\n");
- sRes = -3;
- }
- }
- else
- {
- TRACE("SetSize(): CNFile::SetBufferSize failed.\n");
- sRes = -2;
- }
-
- // If any errors occurred after allocation . . .
- if (sRes != 0)
- {
- Free();
- }
- }
- else
- {
- TRACE("SetSize(): Unable to allocate new window.\n");
- sRes = -1;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Move to next user pane.
- // Returns 0 on success.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::NextPane(void)
- {
- short sRes = 0; // Assume success.
- // If next pane complete . . .
- if (IsNextPaneReady() == TRUE)
- {
- // Get position of next pane.
- m_paneUser.lPos += m_paneUser.lSize;
- // Move ptr to position.
- m_paneUser.puc = m_pucWindow + WINDOWINDEX(m_paneUser.lPos);
- }
- else
- {
- sRes = -1;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Start reading/writing.
- // Returns 0 on success.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::Start(void)
- {
- short sRes = 0; // Assume success.
-
- if (--m_sSuspend == 0)
- {
- if (m_sActive == FALSE)
- {
- if (Blu_AddCritical((CRITICALL)CriticalStatic, (ULONG)this) == 0)
- {
- // Pick up where we left off.
- m_lNextTime = GetTime() + m_lNextTime;
- m_sActive = TRUE;
- }
- else
- {
- sRes = -1;
- TRACE("Start(): Unable to add critical function.\n");
- }
- }
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Suspend reading/writing.
- // Returns 0 on success.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::Suspend(void)
- {
- short sRes = 0; // Assume success.
- m_sSuspend++;
- if (m_sActive == TRUE)
- {
- if (Blu_RemoveCritical((CRITICALL)CriticalStatic) == 0)
- {
- m_sActive = FALSE;
- // Remember how long from suspension until next.
- m_lNextTime = m_lNextTime - GetTime();
- }
- else
- {
- sRes = -1;
- TRACE("Suspend(): Unable to remove critical function.\n");
- }
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Returns TRUE if next user pane is ready; FALSE otherwise.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::IsNextPaneReady(void)
- {
- short sRes = TRUE; // Assume ready.
-
- // If next pane is where the next read is going to occur . . .
- if (m_paneUser.lPos + m_paneUser.lSize * 2L > m_paneIn.lPos + m_paneIn.lSize)
- {
- sRes = FALSE;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- //
- // Returns TRUE if next input pane is ready; FALSE otherwise.
- //
- //////////////////////////////////////////////////////////////////////////////
- short CFileWin::IsNextInputPaneReady(void)
- {
- short sRes = TRUE; // Assume ready.
- long lNextInputPaneStart = WINDOWINDEX(m_paneIn.lPos + m_paneIn.lSize);
- long lNextInputPaneEnd = WINDOWINDEX(m_paneIn.lPos + m_paneIn.lSize * 2L);
- long lCurUserPaneStart = WINDOWINDEX(m_paneUser.lPos);
- long lCurUserPaneEnd = WINDOWINDEX(m_paneUser.lPos + m_paneUser.lSize);
- // If the next input pane intersects the current user pane . . .
- if ( lNextInputPaneStart < lCurUserPaneEnd
- && lNextInputPaneEnd > lCurUserPaneStart)
- {
- // You can't fight the seither.
- sRes = FALSE;
- }
- return sRes;
- }
- //////////////////////////////////////////////////////////////////////////////
- // EOF
- //////////////////////////////////////////////////////////////////////////////
|