Visualization Library 2.1.0

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
DiskFile.cpp
Go to the documentation of this file.
1 /**************************************************************************************/
2 /* */
3 /* Visualization Library */
4 /* http://visualizationlibrary.org */
5 /* */
6 /* Copyright (c) 2005-2020, Michele Bosi */
7 /* All rights reserved. */
8 /* */
9 /* Redistribution and use in source and binary forms, with or without modification, */
10 /* are permitted provided that the following conditions are met: */
11 /* */
12 /* - Redistributions of source code must retain the above copyright notice, this */
13 /* list of conditions and the following disclaimer. */
14 /* */
15 /* - Redistributions in binary form must reproduce the above copyright notice, this */
16 /* list of conditions and the following disclaimer in the documentation and/or */
17 /* other materials provided with the distribution. */
18 /* */
19 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND */
20 /* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */
21 /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */
22 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR */
23 /* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */
24 /* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */
25 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */
26 /* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
27 /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
28 /* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29 /* */
30 /**************************************************************************************/
31 
32 #include <vlCore/DiskFile.hpp>
33 #include <stdio.h>
34 
35 #if defined(__APPLE__) || (__FreeBSD__)
36  #define fseeko64 fseeko
37 #endif
38 
39 using namespace vl;
40 
41 //-----------------------------------------------------------------------------
42 // DiskFile
43 //-----------------------------------------------------------------------------
45 {
46  mHandle = NULL;
47  setPath(path);
48 }
49 //-----------------------------------------------------------------------------
51 {
52  close();
53 }
54 //-----------------------------------------------------------------------------
55 bool DiskFile::open(const String& path, EOpenMode mode)
56 {
57  setPath(path);
58  return open(mode);
59 }
60 //-----------------------------------------------------------------------------
62 {
63  if ( isOpen() )
64  {
65  Log::error("DiskFile::open(): file already open.\n");
66  return false;
67  }
68 
69 #if defined(VL_PLATFORM_WINDOWS)
70  mHandle = INVALID_HANDLE_VALUE;
71  switch(mode)
72  {
73  case OM_ReadOnly:
74  mHandle = CreateFile( (const wchar_t*)path().ptr(),
75  GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); break;
76  case OM_WriteOnly:
77  mHandle = CreateFile( (const wchar_t*)path().ptr(),
78  GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); break;
79  default:
80  break;
81  }
82  if (mHandle == INVALID_HANDLE_VALUE)
83 #elif defined(__GNUG__)
84  // encode to utf8 for linux
85  std::vector<unsigned char> utf8;
86  path().toUTF8( utf8, false );
87  switch(mode)
88  {
89  case OM_ReadOnly: mHandle = fopen( (char*)&utf8[0], "rb"); break;
90  case OM_WriteOnly: mHandle = fopen( (char*)&utf8[0], "wb"); break;
91  default:
92  break;
93  }
94  if (mHandle == NULL)
95 #endif
96  // see the ifs above
97  {
98  Log::error( Say("DiskFile::open(): error opening input file '%s'\n") << path() );
99  return false;
100  }
101 
102  return true;
103 }
104 //-----------------------------------------------------------------------------
105 bool DiskFile::isOpen() const
106 {
107  return mHandle != NULL;
108 }
109 //-----------------------------------------------------------------------------
111 {
112  if (mHandle)
113  {
114  #if defined(VL_PLATFORM_WINDOWS)
115  CloseHandle(mHandle);
116  #elif defined(__GNUG__)
117  fclose(mHandle);
118  #endif
119  }
120  mHandle = NULL;
121 }
122 //-----------------------------------------------------------------------------
123 long long DiskFile::size() const
124 {
125  #if defined(VL_PLATFORM_WINDOWS)
126  // opens the file
127  HANDLE hdl = CreateFile(
128  (const wchar_t*)path().ptr(),
129  FILE_READ_ATTRIBUTES,
130  FILE_SHARE_READ,
131  NULL,
132  OPEN_EXISTING,
133  FILE_ATTRIBUTE_NORMAL,
134  NULL
135  );
136 
137  if (mHandle == INVALID_HANDLE_VALUE)
138  {
139  Log::error( Say("DiskFile::size(): file '%s' does not seem to exist.\n") << path() );
140  return 0;
141  }
142 
143  #if defined(__MINGW32_VERSION)
144  DWORD size = GetFileSize(hdl, NULL);
145  CloseHandle(hdl);
146  if (size != INVALID_FILE_SIZE )
147  return size;
148  else
149  return -1;
150  #else
151  LARGE_INTEGER file_size;
152  BOOL ok = GetFileSizeEx( hdl, &file_size );
153  CloseHandle(hdl);
154  return ok ? file_size.QuadPart : -1;
155  #endif
156  #elif defined(__GNUG__)
157  // http://linux.die.net/man/2/stat
158  struct stat mybuf;
159  memset(&mybuf, 0, sizeof(struct stat));
160  // encode to utf8 for linux
161  std::vector<unsigned char> utf8;
162  path().toUTF8( utf8, false );
163  if (utf8.empty())
164  return 0;
165  if (stat((char*)&utf8[0], &mybuf) == -1)
166  return 0;
167  else
168  return (long long)mybuf.st_size;
169  #endif
170 }
171 //-----------------------------------------------------------------------------
172 bool DiskFile::exists() const
173 {
174  if (path().empty())
175  return false;
176  #if defined(VL_PLATFORM_WINDOWS)
177  /*VL_CHECK( sizeof(wchar_t) == sizeof(unsigned short) )*/
178  // opens the file
179  HANDLE hdl = CreateFile(
180  (const wchar_t*)path().ptr(),
181  FILE_READ_ATTRIBUTES,
182  FILE_SHARE_READ,
183  NULL,
184  OPEN_EXISTING,
185  FILE_ATTRIBUTE_NORMAL,
186  NULL
187  );
188 
189  if (hdl != INVALID_HANDLE_VALUE)
190  {
191  CloseHandle(hdl);
192  return true;
193  }
194  else
195  return false;
196  #elif defined(__GNUG__)
197  std::vector<unsigned char> utf8;
198  path().toUTF8( utf8, false );
199  if (utf8.empty())
200  return false;
201  FILE* fin = fopen( (char*)&utf8[0], "rb");
202  if (fin != NULL)
203  {
204  fclose(fin);
205  return true;
206  }
207  else
208  return false;
209  #endif
210 }
211 //-----------------------------------------------------------------------------
212 long long DiskFile::read_Implementation(void* buffer, long long byte_count)
213 {
214  if (!mHandle)
215  {
216  Log::error("DiskFile::read_Implementation() called on closed file!\n");
217  return 0;
218  }
219 
220  long long count = 0;
221  #if defined(VL_PLATFORM_WINDOWS)
222 
223  #if 0
224  // avoid win xp problem: read fails if request to read much more bytes than the file size
225  // but makes the reading way too slow.
226  long long file_size = size();
227  byte_count = byte_count < file_size ? byte_count : (long long)file_size;
228  #endif
229 
230  char* ptr = (char*)buffer;
231  DWORD NumberOfBytesRead = 0;
232  // reads blocks of 20 megs due to possible problems under win xp
233  long long bytes = byte_count < 20*1024*1024 ? byte_count : 20*1024*1024;
234  while( ReadFile( mHandle, ptr, (DWORD)bytes, &NumberOfBytesRead, NULL ) && NumberOfBytesRead )
235  {
236  byte_count -= NumberOfBytesRead;
237  bytes = byte_count < 20*1024*1024 ? byte_count : 20*1024*1024;
238  ptr += NumberOfBytesRead;
239  count += NumberOfBytesRead;
240  }
241  #elif defined(__GNUG__)
242  char* ptr = (char*)buffer;
243  long long bytes_read = 0;
244  while( (bytes_read = fread(ptr, 1, byte_count, mHandle)) )
245  {
246  byte_count -= bytes_read;
247  ptr += bytes_read;
248  count += bytes_read;
249  }
250  if (ferror(mHandle))
251  perror("Error reading file: ");
252  #endif
253  return count;
254 }
255 //-----------------------------------------------------------------------------
256 long long DiskFile::write_Implementation(const void* buffer, long long byte_count)
257 {
258  if (!mHandle)
259  {
260  Log::error("DiskFile::write_Implementation() called on closed file!\n");
261  return 0;
262  }
263 
264  long long count = 0;
265  #if defined(VL_PLATFORM_WINDOWS)
266  DWORD NumberOfBytesWritten = 0;
267  WriteFile( mHandle, buffer, (DWORD)byte_count, &NumberOfBytesWritten, NULL );
268  count = NumberOfBytesWritten;
269  #elif defined(__GNUG__)
270  count = fwrite( buffer, 1, byte_count, mHandle );
271  if (ferror(mHandle))
272  perror("Error reading file: ");
273  #endif
274  return count;
275 }
276 //-----------------------------------------------------------------------------
278 {
279  if (!mHandle)
280  {
281  Log::error("DiskFile::position_Implementation() called on closed file!\n");
282  return -1;
283  }
284 
285  #if defined(VL_PLATFORM_WINDOWS)
286  LARGE_INTEGER position;
287  position.QuadPart = 0;
288  SetFilePointerEx(
289  mHandle,
290  position,
291  &position,
292  FILE_CURRENT );
293  return position.QuadPart;
294  #elif defined(__GNUG__)
295  return ftell(mHandle);
296  #endif
297 }
298 //-----------------------------------------------------------------------------
299 bool DiskFile::seekSet_Implementation(long long offset)
300 {
301  if (!mHandle)
302  {
303  Log::error("DiskFile::seekSet_Implementation() called on closed file!\n");
304  return false;
305  }
306 
307  #if defined(VL_PLATFORM_WINDOWS)
308  LARGE_INTEGER position;
309  position.QuadPart = offset;
310  if (mHandle)
311  {
312  SetFilePointerEx(
313  mHandle,
314  position,
315  &position,
316  FILE_BEGIN );
317  }
318  #elif defined(__GNUG__)
319  fseeko64(mHandle, offset, SEEK_SET);
320  #endif
321  return true;
322 }
323 //-----------------------------------------------------------------------------
325 {
326  ref<DiskFile> file = new DiskFile;
327  file->operator=(*this);
328  return file;
329 }
330 //-----------------------------------------------------------------------------
FILE * mHandle
Definition: DiskFile.hpp:108
virtual long long size() const
Returns the file size in bytes or -1 on error.
Definition: DiskFile.cpp:123
A simple String formatting class.
Definition: Say.hpp:124
The String class implements an advanced UTF16 (Unicode BMP) string manipulation engine.
Definition: String.hpp:62
virtual long long read_Implementation(void *buffer, long long byte_count)
Definition: DiskFile.cpp:212
static void error(const String &message)
Use this function to provide information about run-time errors: file not found, out of memory...
Definition: Log.cpp:165
const String & path() const
Returns the path of the file.
Definition: VirtualFile.hpp:98
bool open(const String &path, EOpenMode mode)
The specified path is relative to the parent directory. See setPhysicalPath().
Definition: DiskFile.cpp:55
void toUTF8(std::vector< unsigned char > &utf8, bool include_utf8_signature=true) const
Encodes the String into a UTF8 encoded string.
Definition: String.cpp:1218
Visualization Library main namespace.
virtual void close()
Closes the file.
Definition: DiskFile.cpp:110
DiskFile(const DiskFile &other)
Definition: DiskFile.hpp:70
virtual bool seekSet_Implementation(long long offset)
Definition: DiskFile.cpp:299
virtual long long position_Implementation() const
Definition: DiskFile.cpp:277
#define NULL
Definition: OpenGLDefs.hpp:81
virtual ref< VirtualFile > clone() const
Creates a clone of this class instance.
Definition: DiskFile.cpp:324
void setPath(const String &name)
Changes the path bound to a VirtualFile. Use carefully this function, you shouldn&#39;t rename a VirtualF...
The ref<> class is used to reference-count an Object.
Definition: Object.hpp:55
virtual bool exists() const
Returns true if the file exists.
Definition: DiskFile.cpp:172
long long position() const
Returns the current position in the file.
Definition: VirtualFile.cpp:98
virtual bool isOpen() const
Returns true if the file has been opened.
Definition: DiskFile.cpp:105
virtual long long write_Implementation(const void *buffer, long long byte_count)
Definition: DiskFile.cpp:256