Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/DiskFile.cpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #include <vlCore/DiskFile.hpp>
00033 #include <stdio.h>
00034 
00035 #if defined(__APPLE__) || (__FreeBSD__)
00036   #define fseeko64 fseeko
00037 #endif
00038 
00039 using namespace vl;
00040 
00041 //-----------------------------------------------------------------------------
00042 // DiskFile
00043 //-----------------------------------------------------------------------------
00044 DiskFile::DiskFile(const String& path)
00045 {
00046   mHandle = NULL;
00047   setPath(path);
00048 }
00049 //-----------------------------------------------------------------------------
00050 DiskFile::~DiskFile()
00051 {
00052   close();
00053 }
00054 //-----------------------------------------------------------------------------
00055 bool DiskFile::open(const String& path, EOpenMode mode)
00056 {
00057   setPath(path);
00058   return open(mode);
00059 }
00060 //-----------------------------------------------------------------------------
00061 bool DiskFile::open(EOpenMode mode)
00062 {
00063   if ( isOpen() )
00064   {
00065     Log::error("DiskFile::open(): file already open.\n");
00066     return false;
00067   }
00068 
00069 #if defined(VL_PLATFORM_WINDOWS)
00070   mHandle = INVALID_HANDLE_VALUE;
00071   switch(mode)
00072   {
00073   case OM_ReadOnly:
00074       mHandle = CreateFile( (const wchar_t*)path().ptr(),
00075                             GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); break;
00076   case OM_WriteOnly:
00077       mHandle = CreateFile( (const wchar_t*)path().ptr(),
00078                             GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); break;
00079   default:
00080     break;
00081   }
00082   if (mHandle == INVALID_HANDLE_VALUE)
00083 #elif defined(__GNUG__)
00084   // encode to utf8 for linux
00085   std::vector<unsigned char> utf8;
00086   path().toUTF8( utf8, false );
00087   switch(mode)
00088   {
00089   case OM_ReadOnly:  mHandle = fopen( (char*)&utf8[0], "rb"); break;
00090   case OM_WriteOnly: mHandle = fopen( (char*)&utf8[0], "wb"); break;
00091   default:
00092     break;
00093   }
00094   if (mHandle == NULL)
00095 #endif
00096   // see the ifs above
00097   {
00098     Log::error( Say("DiskFile::open(): error opening input file '%s'\n") << path() );
00099     return false;
00100   }
00101 
00102   return true;
00103 }
00104 //-----------------------------------------------------------------------------
00105 bool DiskFile::isOpen() const
00106 {
00107   return mHandle != NULL;
00108 }
00109 //-----------------------------------------------------------------------------
00110 void DiskFile::close()
00111 {
00112   if (mHandle)
00113   {
00114     #if defined(VL_PLATFORM_WINDOWS)
00115       CloseHandle(mHandle);
00116     #elif defined(__GNUG__)
00117       fclose(mHandle);
00118     #endif
00119   }
00120   mHandle = NULL;
00121 }
00122 //-----------------------------------------------------------------------------
00123 long long DiskFile::size() const
00124 {
00125   #if defined(VL_PLATFORM_WINDOWS)
00126     // opens the file
00127     HANDLE hdl = CreateFile(
00128       (const wchar_t*)path().ptr(),
00129       FILE_READ_ATTRIBUTES,
00130       FILE_SHARE_READ,
00131       NULL,
00132       OPEN_EXISTING,
00133       FILE_ATTRIBUTE_NORMAL,
00134       NULL
00135     );
00136 
00137     if (mHandle == INVALID_HANDLE_VALUE)
00138     {
00139       Log::error( Say("DiskFile::size(): file '%s' does not seem to exist.\n") << path() );
00140       return 0;
00141     }
00142 
00143     #if defined(__MINGW32_VERSION)
00144       DWORD size = GetFileSize(hdl, NULL);
00145       CloseHandle(hdl);
00146       if (size != INVALID_FILE_SIZE )
00147         return size;
00148       else
00149         return -1;
00150     #else
00151       LARGE_INTEGER file_size;
00152       BOOL ok = GetFileSizeEx( hdl, &file_size );
00153       CloseHandle(hdl);
00154       return ok ? file_size.QuadPart : -1;
00155     #endif
00156   #elif defined(__GNUG__)
00157     // http://linux.die.net/man/2/stat
00158     struct stat mybuf;
00159     memset(&mybuf, 0, sizeof(struct stat));
00160     // encode to utf8 for linux
00161     std::vector<unsigned char> utf8;
00162     path().toUTF8( utf8, false );
00163     if (utf8.empty())
00164       return 0;
00165     if (stat((char*)&utf8[0], &mybuf) == -1)
00166       return 0;
00167     else
00168       return (long long)mybuf.st_size;
00169   #endif
00170 }
00171 //-----------------------------------------------------------------------------
00172 bool DiskFile::exists() const
00173 {
00174   if (path().empty())
00175     return false;
00176   #if defined(VL_PLATFORM_WINDOWS)
00177     /*VL_CHECK( sizeof(wchar_t) == sizeof(unsigned short) )*/
00178     // opens the file
00179     HANDLE hdl = CreateFile(
00180       (const wchar_t*)path().ptr(),
00181       FILE_READ_ATTRIBUTES,
00182       FILE_SHARE_READ,
00183       NULL,
00184       OPEN_EXISTING,
00185       FILE_ATTRIBUTE_NORMAL,
00186       NULL
00187     );
00188 
00189     if (hdl != INVALID_HANDLE_VALUE)
00190     {
00191       CloseHandle(hdl);
00192       return true;
00193     }
00194     else
00195       return false;
00196   #elif defined(__GNUG__)
00197     std::vector<unsigned char> utf8;
00198     path().toUTF8( utf8, false );
00199     if (utf8.empty())
00200       return false;
00201     FILE* fin = fopen( (char*)&utf8[0], "rb");
00202     if (fin != NULL)
00203     {
00204       fclose(fin);
00205       return true;
00206     }
00207     else
00208       return false;
00209   #endif
00210 }
00211 //-----------------------------------------------------------------------------
00212 long long DiskFile::read_Implementation(void* buffer, long long byte_count)
00213 {
00214   if (!mHandle)
00215   {
00216     Log::error("DiskFile::read_Implementation() called on closed file!\n");
00217     return 0;
00218   }
00219 
00220   long long count = 0;
00221   #if defined(VL_PLATFORM_WINDOWS)
00222 
00223     #if 0
00224       // avoid win xp problem: read fails if request to read much more bytes than the file size
00225       // but makes the reading way too slow.
00226       long long file_size = size();
00227       byte_count = byte_count < file_size ? byte_count : (long long)file_size;
00228     #endif
00229 
00230     char* ptr = (char*)buffer;
00231     DWORD NumberOfBytesRead = 0;
00232     // reads blocks of 20 megs due to possible problems under win xp
00233     long long bytes = byte_count < 20*1024*1024 ? byte_count : 20*1024*1024;
00234     while( ReadFile( mHandle, ptr, (DWORD)bytes, &NumberOfBytesRead, NULL ) && NumberOfBytesRead )
00235     {
00236       byte_count -= NumberOfBytesRead;
00237       bytes = byte_count < 20*1024*1024 ? byte_count : 20*1024*1024;
00238       ptr   += NumberOfBytesRead;
00239       count += NumberOfBytesRead;
00240     }
00241   #elif defined(__GNUG__)
00242     char* ptr = (char*)buffer;
00243     long long bytes_read = 0;
00244     while( (bytes_read = fread(ptr, 1, byte_count, mHandle)) )
00245     {
00246       byte_count -= bytes_read;
00247       ptr   += bytes_read;
00248       count += bytes_read;
00249     }
00250     if (ferror(mHandle))
00251       perror("Error reading file: ");
00252   #endif
00253   return count;
00254 }
00255 //-----------------------------------------------------------------------------
00256 long long DiskFile::write_Implementation(const void* buffer, long long byte_count)
00257 {
00258   if (!mHandle)
00259   {
00260     Log::error("DiskFile::write_Implementation() called on closed file!\n");
00261     return 0;
00262   }
00263 
00264   long long count = 0;
00265   #if defined(VL_PLATFORM_WINDOWS)
00266     DWORD NumberOfBytesWritten = 0;
00267     WriteFile( mHandle, buffer, (DWORD)byte_count, &NumberOfBytesWritten, NULL );
00268     count = NumberOfBytesWritten;
00269   #elif defined(__GNUG__)
00270     count = fwrite( buffer, 1, byte_count, mHandle );
00271     if (ferror(mHandle))
00272       perror("Error reading file: ");
00273   #endif
00274   return count;
00275 }
00276 //-----------------------------------------------------------------------------
00277 long long DiskFile::position_Implementation() const
00278 {
00279   if (!mHandle)
00280   {
00281     Log::error("DiskFile::position_Implementation() called on closed file!\n");
00282     return -1;
00283   }
00284 
00285   #if defined(VL_PLATFORM_WINDOWS)
00286     LARGE_INTEGER position;
00287     position.QuadPart = 0;
00288     SetFilePointerEx(
00289       mHandle,
00290       position,
00291       &position,
00292       FILE_CURRENT );
00293     return position.QuadPart;
00294   #elif defined(__GNUG__)
00295     return ftell(mHandle);
00296   #endif
00297 }
00298 //-----------------------------------------------------------------------------
00299 bool DiskFile::seekSet_Implementation(long long offset)
00300 {
00301   if (!mHandle)
00302   {
00303     Log::error("DiskFile::seekSet_Implementation() called on closed file!\n");
00304     return false;
00305   }
00306 
00307   #if defined(VL_PLATFORM_WINDOWS)
00308     LARGE_INTEGER position;
00309     position.QuadPart = offset;
00310     if (mHandle)
00311     {
00312       SetFilePointerEx(
00313         mHandle,
00314         position,
00315         &position,
00316         FILE_BEGIN );
00317     }
00318   #elif defined(__GNUG__)
00319     fseeko64(mHandle, offset, SEEK_SET);
00320   #endif
00321   return true;
00322 }
00323 //-----------------------------------------------------------------------------
00324 ref<VirtualFile> DiskFile::clone() const
00325 {
00326   ref<DiskFile> file = new DiskFile;
00327   file->operator=(*this);
00328   return file;
00329 }
00330 //-----------------------------------------------------------------------------

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:28.
Permission is granted to use this page to write and publish articles regarding Visualization Library.