Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

plfilesrc.cpp

Go to the documentation of this file.
00001 /*
00002 /--------------------------------------------------------------------
00003 |
00004 |      $Id: plfilesrc.cpp,v 1.1 2004/05/21 21:02:52 maxx Exp $
00005 |      File Data Source Class
00006 |
00007 |      This is a class which takes a file as a source of picture data.
00008 |
00009 |      Copyright (c) 1996-1998 Ulrich von Zadow
00010 |
00011 \--------------------------------------------------------------------
00012 */
00013 
00014 #include "plstdpch.h"
00015 
00016 #include "plfilesrc.h"
00017 #include "plexcept.h"
00018 
00019 
00020 PLFileSource::PLFileSource
00021     ( PLIProgressNotification * pNotification
00022     )
00023   : PLDataSource (pNotification),
00024 #ifdef PL_FILE_MAPPING
00025     m_hf (INVALID_HANDLE_VALUE),    // File handle.
00026     m_hm (NULL),    // Handle to file-mapping object.
00027 #else
00028     m_pFile (NULL),
00029     m_pBuffer (NULL),
00030     m_pReadPos (NULL),
00031     m_BytesReadFromFile(0),
00032 #endif
00033     m_pStartData (NULL),
00034     m_pCurPos (NULL)
00035 {
00036 }
00037 
00038 PLFileSource::~PLFileSource
00039     ()
00040 {
00041 #ifdef PL_FILE_MAPPING
00042   if (m_hf)
00043     Close();
00044 #else
00045   if (m_pFile)
00046     Close();
00047 #endif
00048 }
00049 
00050 int PLFileSource::Open
00051     ( const char * pszFName
00052     )
00053 {
00054   int FileSize;
00055 
00056 #ifdef PL_FILE_MAPPING
00057   PLBYTE * pBuffer = NULL;
00058   try
00059   {
00060     m_hf = CreateFile (pszFName, GENERIC_READ, FILE_SHARE_READ, NULL,
00061                        OPEN_EXISTING,
00062                        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
00063                        NULL);
00064 
00065     if (m_hf == INVALID_HANDLE_VALUE)
00066     {
00067       m_hf = NULL;
00068       switch (GetLastError())
00069       {
00070         case ERROR_PATH_NOT_FOUND:
00071           // sprintf (sz, "Path not found.", pszFName);
00072           return PL_ERRPATH_NOT_FOUND;
00073         case ERROR_FILE_NOT_FOUND:
00074           // sprintf (sz, "File not found.", pszFName);
00075           return PL_ERRFILE_NOT_FOUND;
00076         case ERROR_ACCESS_DENIED:
00077           // sprintf (sz, "Access denied.", pszFName);
00078           return PL_ERRACCESS_DENIED;
00079         case ERROR_SHARING_VIOLATION:
00080           // sprintf (sz, "Sharing violation.", pszFName);
00081           return PL_ERRACCESS_DENIED;
00082         default:
00083           // sprintf (sz, "CreateFile returned %d.",
00084           //          pszFName, GetLastError());
00085           return PL_ERRFILE_NOT_FOUND;
00086       }
00087     }
00088 
00089     FileSize = ::GetFileSize (m_hf, NULL);
00090 
00091     m_hm = CreateFileMapping (m_hf, NULL, PAGE_READONLY, 0, 0, NULL);
00092 
00093     // This happens if the file is empty.
00094     if (m_hm == NULL)
00095     {  // raiseError (PL_ERRACCESS_DENIED, "CreateFileMapping failed.");
00096       if (m_hf) CloseHandle (m_hf);
00097       m_hf = NULL;
00098       return PL_ERRACCESS_DENIED;
00099     }
00100 
00101     pBuffer = (PLBYTE *) MapViewOfFile (m_hm, FILE_MAP_READ, 0, 0, 0);
00102 
00103     if (pBuffer == NULL)
00104       // raiseError (PL_ERRACCESS_DENIED, "MapViewOfFile failed.");
00105       return PL_ERRACCESS_DENIED;
00106     m_pStartData = pBuffer;
00107     m_pCurPos = pBuffer;
00108 
00109     // We've got the file mapped to memory.
00110     PLDataSource::Open (pszFName, FileSize);
00111   }
00112   catch (PLTextException)
00113   {
00114     // Clean up on error
00115     if (pBuffer) UnmapViewOfFile (pBuffer);
00116     if (m_hm) CloseHandle (m_hm);
00117     if (m_hf) CloseHandle (m_hf);
00118     throw;
00119   }
00120   return 0;
00121 
00122 #else
00123 
00124   // Generic code assuming memory mapped files are not available.
00125   m_pFile = NULL;
00126   if (strcmp (pszFName, ""))
00127     m_pFile = fopen (pszFName, "rb");
00128 
00129   if (m_pFile == NULL)
00130   { // Crude...
00131     m_pFile = 0;
00132     return -1;
00133   }
00134 
00135   // Determine file size. Can this be done in an easier way using ANSI C?
00136   fseek (m_pFile, 0, SEEK_END);
00137   FileSize = ftell (m_pFile);
00138   fseek (m_pFile, 0, SEEK_SET);
00139 
00140   // Create a buffer for the file.
00141   m_pBuffer = new PLBYTE[FileSize];
00142   //  this only works if our implementation of "new" does not throw...
00143   if (m_pBuffer == 0)
00144   {
00145     fclose (m_pFile);
00146     return -1;
00147   }
00148 
00149   m_pReadPos = m_pBuffer;
00150   m_pCurPos = m_pBuffer;
00151   m_BytesReadFromFile = 0;
00152   PLDataSource::Open (pszFName, FileSize);
00153   fillBuffer ();
00154   return 0;
00155 #endif
00156 }
00157 
00158 void PLFileSource::Close
00159     ()
00160 {
00161 #ifdef PL_FILE_MAPPING
00162   UnmapViewOfFile (m_pStartData);
00163   PLDataSource::Close ();
00164   CloseHandle (m_hm);
00165   CloseHandle (m_hf);
00166   m_hm = NULL;
00167   m_hf = NULL;
00168 #else
00169   //Note that 'new' is used to get the memory, not alloc, so don't use free
00170   delete [] m_pBuffer;
00171   m_pBuffer = NULL;
00172   PLDataSource::Close ();
00173   fclose (m_pFile);
00174   m_pFile = NULL;
00175 #endif
00176 }
00177 
00178 PLBYTE * PLFileSource::ReadNBytes
00179     ( int n
00180     )
00181 {
00182   PLDataSource::ReadNBytes(n);
00183 #ifndef PL_FILE_MAPPING
00184   if (!bytesAvailable(n))
00185     fillBuffer(n);
00186 #endif
00187   m_pCurPos += n;
00188   return m_pCurPos-n;
00189 }
00190 
00192 PLBYTE * PLFileSource::GetBufferPtr
00193     ( int MinBytesInBuffer
00194     )
00195 {
00196   PLASSERT (MinBytesInBuffer < 4096);
00197 #ifndef PL_FILE_MAPPING
00198   if (!bytesAvailable(MinBytesInBuffer))
00199     fillBuffer();
00200 #endif
00201   return m_pCurPos;
00202 }
00203 
00204 PLBYTE * PLFileSource::ReadEverything
00205     ()
00206 {
00207 #ifdef PL_FILE_MAPPING
00208   return m_pCurPos;
00209 #else
00210   int BytesToRead = GetFileSize()-m_BytesReadFromFile;
00211   int i = fread (m_pReadPos, 1, BytesToRead, m_pFile);
00212   PLASSERT (i==BytesToRead);
00213   m_BytesReadFromFile += BytesToRead;
00214   m_pReadPos += BytesToRead;
00215   return m_pCurPos;
00216 #endif
00217 }
00218 
00219 
00220 #ifndef PL_FILE_MAPPING
00221 void PLFileSource::fillBuffer
00222     ( int n
00223     )
00224 {
00225   // bdelmee; code change for the sake of portability
00226   int BytesToRead = GetFileSize() - m_BytesReadFromFile;
00227   if ( BytesToRead > n )
00228     BytesToRead = n;
00229   int i = fread (m_pReadPos, 1, BytesToRead, m_pFile);
00230   PLASSERT (i==BytesToRead);
00231   m_BytesReadFromFile += BytesToRead;
00232   m_pReadPos += BytesToRead;
00233 }
00234 
00235 bool PLFileSource::bytesAvailable
00236     ( int n
00237     )
00238 {
00239   if (m_pReadPos-m_pCurPos >= n)
00240     return true;
00241   else
00242     return false;
00243 }
00244 #endif
00245 /*
00246 /--------------------------------------------------------------------
00247 |
00248 |      $Log: plfilesrc.cpp,v $
00249 |      Revision 1.1  2004/05/21 21:02:52  maxx
00250 |      Initial Version of vuVolume, moderatly changed to make it compile on my windows and linux machine.
00251 |
00252 |      Revision 1.1  2002/11/13 01:58:21  mspindle
00253 |      *** empty log message ***
00254 |
00255 |      Revision 1.2  2001/10/06 22:37:08  uzadow
00256 |      Linux compatibility.
00257 |
00258 |      Revision 1.1  2001/09/16 19:03:22  uzadow
00259 |      Added global name prefix PL, changed most filenames.
00260 |
00261 |      Revision 1.10  2001/09/13 20:46:45  uzadow
00262 |      Removed 4096-byte limit for fillBuffer that was causing PLPNGEncoder
00263 |      to fail under Linux.
00264 |
00265 |      Revision 1.9  2001/02/04 14:31:52  uzadow
00266 |      Member initialization list cleanup (Erik Hoffmann).
00267 |
00268 |      Revision 1.8  2001/01/21 14:28:21  uzadow
00269 |      Changed array cleanup from delete to delete[].
00270 |
00271 |      Revision 1.7  2000/09/01 13:27:07  Administrator
00272 |      Minor bugfixes
00273 |
00274 |      Revision 1.6  2000/01/16 20:43:13  anonymous
00275 |      Removed MFC dependencies
00276 |
00277 |      Revision 1.5  1999/12/08 15:39:45  Ulrich von Zadow
00278 |      Unix compatibility changes
00279 |
00280 |      Revision 1.4  1999/10/03 18:50:51  Ulrich von Zadow
00281 |      Added automatic logging of changes.
00282 |
00283 |
00284 --------------------------------------------------------------------
00285 */

Generated on Wed Dec 15 21:20:30 2004 for vuVolume by  doxygen 1.3.9.1