source: main/trunk/greenstone2/build-src/packages/isis-gdl/FileSystem.cpp@ 26670

Last change on this file since 26670 was 6127, checked in by mdewsnip, 20 years ago

IsisGdl package for reading CDS/ISIS databases. Provided by Jean-Claude Dauphin at UNESCO, and modified slightly to compile and run under Linux.

  • Property svn:keywords set to Author Date Id Revision
File size: 13.8 KB
Line 
1/**********************************************************************
2 *
3 * FileSystem.cpp
4 * Copyright (C) 2003 UNESCO
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26////////////////////////////////////////////////////////////////////////////////////
27//
28// FileSystem -- The generic file pointer routines are a collection of member
29// functions used to wrap the underlying file system.
30
31
32#include "errno.h"
33#include "stdafx.h"
34#include "FileSystem.h"
35
36
37using namespace FileSystem;
38//---------------------------------------------------------------------
39// FileSystem::FPTR *Create(const _TCHAR *fname)
40//
41// Create a new file and truncate existing files.
42// Returns a null value if the file cannot be
43// created.
44//---------------------------------------------------------------------
45DLL_CODE_API FileSystem::FPTR *FileSystem::Create(const char *fname)
46{
47#if defined(__64_BIT_FILE_SYSTEM__)
48 return FS64Create(fname);
49
50#elif defined(__WIN32__) && defined(__NTFS__)
51 FPTR *stream = new FPTR;
52 if (!stream)
53 return 0;
54 stream->fptr = CreateFile(fname,
55 GENERIC_READ | GENERIC_WRITE,
56 FILE_SHARE_READ | FILE_SHARE_WRITE,
57 NULL, // No security
58 CREATE_ALWAYS,
59 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
60 NULL // No attr. template
61 );
62
63 if (stream->fptr == INVALID_HANDLE_VALUE)
64 {
65 delete stream;
66 return 0;
67 }
68 return stream;
69
70#else // Use the 32-bit stdio version by default
71 FPTR *stream = new FPTR;
72 if (!stream)
73 return 0;
74 stream->fptr = fopen(fname, "w+b");
75 if (stream->fptr == 0)
76 {
77 delete stream; // 01/30/2002: Prevent memory leak
78 return 0;
79 }
80 return stream;
81#endif
82}
83
84//---------------------------------------------------------------------
85// FileSystem::FPTR *Open(const _TCHAR *fname, FileSystemAccessMode mode)
86//
87// Open an existing file. The "mode" variable determines if the file
88// is opened for read only or read/write access. Returns a null value
89// if the specified file cannot be opened. NOTE: This version of the
90// open functions will only accept: FILE_READONLY and FILE_READWRITE
91// access modes.
92//---------------------------------------------------------------------
93DLL_CODE_API FileSystem::FPTR *FileSystem::Open(const char *fname, FileSystem::AccessMode mode)
94{
95#if defined(__64_BIT_FILE_SYSTEM__)
96 return FSOpen(fname, mode);
97
98#elif defined(__WIN32__) && defined(__NTFS__)
99 FPTR *stream = new FPTR;
100 if (!stream)
101 return 0;
102 if (mode == FILE_READONLY)
103 {
104 // Open for read only access
105 stream->fptr = CreateFile(fname,
106 GENERIC_READ,
107 FILE_SHARE_READ | FILE_SHARE_WRITE,
108 NULL, // No security
109 OPEN_EXISTING,
110 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
111 NULL // No attr. template
112 );
113 if (stream->fptr == INVALID_HANDLE_VALUE)
114 {
115 delete stream;
116 return 0;
117 }
118 }
119 else
120 { // Open for read/write access
121 stream->fptr = CreateFile(fname,
122 GENERIC_READ | GENERIC_WRITE,
123 FILE_SHARE_READ | FILE_SHARE_WRITE,
124 NULL, // No security
125 OPEN_EXISTING,
126 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,
127 NULL // No attr. template
128 );
129
130 if (stream->fptr == INVALID_HANDLE_VALUE)
131 {
132 delete stream;
133 return 0;
134 }
135 }
136 return stream;
137
138#else // Use the 32-bit stdio version by default
139 FPTR *stream = new FPTR;
140 if (!stream)
141 return 0;
142
143 if (mode == FILE_READONLY)
144 {
145 // Open for read only access
146 stream->fptr = fopen(fname, "rb");
147 if (stream->fptr == 0)
148 {
149 delete stream; // 01/30/2002: Prevent memory leak
150 return 0;
151 }
152 }
153 else
154 { // Open for read/write access
155 stream->fptr = fopen(fname, "r+b");
156 if (stream->fptr == 0)
157 {
158 delete stream; // 01/30/2002: Prevent memory leak
159 return 0;
160 }
161 }
162 return stream;
163#endif
164}
165
166//---------------------------------------------------------------------
167// int Close(FileSystem::FPTR *stream)
168//
169// Close an open file. Returns a non-zero value to indicate an error
170// condition or zero if successful.
171//---------------------------------------------------------------------
172DLL_CODE_API int FileSystem::Close(FPTR *stream)
173{
174 if (!stream)
175 return 0; // The file stream is not open
176
177#if defined(__64_BIT_FILE_SYSTEM__)
178 return FS64Close(stream);
179
180#elif defined(__WIN32__) && defined(__NTFS__)
181 if (!CloseHandle(stream->fptr))
182 return 1;
183 delete stream;
184 stream = 0;
185 return 0;
186
187#else // Use the 32-bit stdio version by default
188 if (fclose(stream->fptr) != 0)
189 return 1;
190 delete stream;
191 stream = 0; // 02/02/2002: Set pointer to zero after releasing it
192 return 0;
193#endif
194}
195
196//-----------------------------------------------------------------------------
197// int Flush(FileSystem::FPTR *stream)
198//
199// Flush the any open disk buffers. Returns a non-zero value to indicate
200// an error // condition or zero if successful.
201//
202// ATTENTION: ****MS VC++*** YOU SHOULD LINK YOUR APPLICATION WITH COMMODE.OBJ
203// file. COMMODE.OBJ changes the global commit flag such that
204// calling fflush() or _flushall() commits the file buffer to disk.
205// The Windows NT operating system provides the WIN32 API FlushFileBuffers().
206// The _commit() function included with the Visual C++ 32-bit Edition
207// CRT calls FlushFileBuffers to write buffered data to disk.
208//-----------------------------------------------------------------------------
209DLL_CODE_API int FileSystem::Flush(FPTR *stream)
210{
211 if (!stream)
212 return 0; // The file stream is not open
213
214#if defined(__64_BIT_FILE_SYSTEM__)
215 return FS64Flush(stream);
216
217#elif defined(__WIN32__) && defined(__NTFS__)
218 if (!FlushFileBuffers(stream->fptr))
219 return 1;
220 return 0;
221
222#else // Use the 32-bit stdio version by default
223 int ret = fflush(stream->fptr);
224 if (ret != 0)
225 {
226 TRACE("\nerrno=%d\n\n\n", errno);
227 return 1; // Error
228 }
229 else
230 return 0;
231#endif
232}
233
234//---------------------------------------------------------------------
235// int Read(FileSystem::FPTR *stream, void *buf, isis::uint32_t bytes)
236//
237// Read a specified number of bytes from the current file position
238// into a memory buffer. Returns the total number if bytes read from the
239// file.
240//---------------------------------------------------------------------
241DLL_CODE_API isis::ulong32_t FileSystem::Read(FPTR *stream, void *buf,
242 isis::ulong32_t bytes)
243{
244 if (!stream)
245 return (isis::ulong32_t)0; // The file stream is not open
246
247#if defined(__64_BIT_FILE_SYSTEM__)
248 return FS64Read(stream, buf, bytes);
249
250#elif defined(__WIN32__) && defined(__NTFS__)
251 DWORD bytes_read;
252 if (!ReadFile(stream->fptr, (LPVOID)buf, (DWORD)bytes, &bytes_read, NULL))
253 {
254 return (isis::ulong32_t)0;
255 }
256 return (isis::ulong32_t)bytes_read;
257
258#else // Use the 32-bit stdio version by default
259 return (isis::ulong32_t)fread((unsigned char *)buf, 1, bytes, stream->fptr);
260#endif
261}
262//---------------------------------------------------------------------
263// int Write(FileSystem::FPTR *stream, const void *buf, isis::uint32_t bytes)
264//
265// Write a specific number of bytes from a memory buffer to the
266// current file position. Returns the total number if bytes written
267// to the file.
268//---------------------------------------------------------------------
269DLL_CODE_API isis::ulong32_t FileSystem::Write(FPTR *stream, const void *buf,
270 isis::ulong32_t bytes)
271{
272 if (!stream)
273 return (isis::ulong32_t)0; // The file stream is not open
274
275#if defined(__64_BIT_FILE_SYSTEM__)
276 return FS64Write(stream, buf, bytes);
277
278#elif defined(__WIN32__) && defined(__NTFS__)
279 DWORD bytes_moved;
280 if (!WriteFile(stream->fptr, (LPVOID)buf, (DWORD)bytes, &bytes_moved, NULL))
281 {
282 return (isis::ulong32_t)0;
283 }
284 return (isis::ulong32_t)bytes_moved;
285
286#else // Use the 32-bit stdio version by default
287 return (isis::ulong32_t)fwrite((const unsigned char *)buf, 1, bytes, stream->fptr);
288#endif
289}
290//---------------------------------------------------------------------------
291// isis::int32_t Seek(FileSystem::FPTR *stream, isis::int32_t offset, FileSystemSeekMode mode)
292//
293// Seek to the specified offset starting at the beginning (SEEK_SET),
294// end (SEEK_END) or current offset (SEEK_CUR). Returns a negative 1
295// to indicate an error condition or the current stream position if
296// successful.
297//----------------------------------------------------------------------------
298DLL_CODE_API FAU_t FileSystem::Seek(FPTR *stream, FAU_t offset, FileSystem::SeekMode mode)
299{
300 if (!stream)
301 return (FAU_t) - 1; // The file stream is not open
302
303#if defined(__64_BIT_FILE_SYSTEM__)
304 return FS64Seek(stream, offset, mode);
305
306#elif defined(__WIN32__) && defined(__NTFS__)
307 if (mode == FILE_SEEK_BEG)
308 {
309 return (FAU_t)SetFilePointer(stream->fptr, offset, NULL, FILE_BEGIN);
310 }
311 else if (mode == FILE_SEEK_CUR)
312 {
313 return (FAU_t)SetFilePointer(stream->fptr, offset, NULL, FILE_CURRENT);
314 }
315 else if (mode == FILE_SEEK_END)
316 {
317 return (FAU_t)SetFilePointer(stream->fptr, offset, NULL, FILE_END);
318 }
319 else
320 { // An invalid seek mode was specified
321 return (FAU_t) - 1;
322 }
323
324#else // Use the 32-bit stdio version by default
325 if (mode == FILE_SEEK_BEG)
326 {
327 return fseek(stream->fptr, offset, SEEK_SET);
328 }
329 else if (mode == FILE_SEEK_CUR)
330 {
331 return fseek(stream->fptr, offset, SEEK_CUR);
332 }
333 else if (mode == FILE_SEEK_END)
334 {
335 return fseek(stream->fptr, offset, SEEK_CUR);
336 }
337 else
338 { // An invalid seek mode was specified
339 return (FAU_t) - 1;
340 }
341#endif
342}
343//----------------------------------------------------------------------------
344// isis::int32_t Tell(FileSystem::FPTR *stream)
345//
346//----------------------------------------------------------------------------
347DLL_CODE_API FAU_t FileSystem::Tell(FPTR *stream)
348{
349 if (!stream)
350 return (FAU_t) - 1; // The file stream is not open
351
352#if defined(__64_BIT_FILE_SYSTEM__)
353 return FS64Tell(stream);
354
355#elif defined(__WIN32__) && defined(__NTFS__)
356 return (__LWORD__)SetFilePointer(stream->fptr, 0, NULL, FILE_CURRENT);
357
358#else // Use the 32-bit stdio version by default
359 return ftell(stream->fptr);
360#endif
361}
362
363//----------------------------------------------------------------------------
364// int Exists(const char *fname)
365//
366// Returns true if the specified file exists.
367//----------------------------------------------------------------------------
368DLL_CODE_API int FileSystem::Exists(const char *fname)
369// Returns true if the specified file exists.
370{
371#if defined(__64_BIT_FILE_SYSTEM__)
372 return FS64Exists(fname);
373
374#elif defined(__WIN32__) && defined(__NTFS__)
375 HANDLE hFile = CreateFile(fname,
376 GENERIC_READ,
377 FILE_SHARE_READ | FILE_SHARE_WRITE,
378 NULL, // No security
379 OPEN_EXISTING,
380 FILE_ATTRIBUTE_NORMAL,
381 NULL // No attr. template
382 );
383
384 if (hFile == INVALID_HANDLE_VALUE)
385 {
386 return 0;
387 }
388
389 CloseHandle(hFile);
390 return 1;
391
392#else // Use the 32-bit stdio version by default
393 struct stat buf;
394 return stat(fname, &buf) ==(FAU_t)0;
395#endif
396}
397
398
399
400//----------------------------------------------------------------------------
401// FAU_t FileSize(const _TCHAR *fname)
402//
403// Returns the length of the specified file or negative 1 to indicate an
404// error condition.
405//----------------------------------------------------------------------------
406DLL_CODE_API FAU_t FileSystem::FileSize(const char *fname)
407{
408#if defined(__64_BIT_FILE_SYSTEM__)
409 return FS64FileSize(fname);
410
411#elif defined(__WIN32__) && defined(__NTFS__)
412 HANDLE hFile = CreateFile(fname,
413 GENERIC_READ,
414 FILE_SHARE_READ | FILE_SHARE_WRITE,
415 NULL, // No security
416 OPEN_EXISTING,
417 FILE_ATTRIBUTE_NORMAL,
418 NULL // No attr. template
419 );
420
421 // Could not open the specified file
422 if (hFile == INVALID_HANDLE_VALUE)
423 {
424 return (FAU_t) - 1;
425 }
426
427 BY_HANDLE_FILE_INFORMATION info;
428
429 if (GetFileInformationByHandle(hFile, &info) == 0)
430 {
431 return (FAU_t) - 1;
432 }
433 CloseHandle(hFile);
434 return (FAU_t)info.nFileSizeLow;;
435
436#else // Use the 32-bit stdio version by default
437 struct stat buf;
438 int result = stat(fname, &buf);
439 if (result != 0)
440 return -1;
441 return buf.st_size;
442#endif
443}
444
445// #include <io.h>
446// #include <share.h>
447
448
449// int FileSystem::CanOpenForWriting(const _TCHAR *fname)
450// {
451// // Try to open for writing
452// int fd = _tsopen(fname, _O_WRONLY | O_BINARY, _SH_DENYWR);
453// if (fd == -1)
454// return 0;
455// _close(fd);
456// return 1;
457// }
458
459// int FileSystem::CanOpenReadOnly(const _TCHAR *fname)
460// {
461// // Try to open for read only
462// int fd = _tsopen(fname, _O_RDONLY | O_BINARY, _SH_DENYNO);
463// if (fd == -1)
464// return 0;
465// _close(fd);
466// return 1;
467// }
468
469//----------------------------------------------------------------------------
470// int IsReadOnly(const _TCHAR* fname)
471//
472// Returns true if the specified file is read only.
473//----------------------------------------------------------------------------
474// int FileSystem::IsReadOnly(const _TCHAR *fname)
475// {
476// struct _stat buf;
477// _tstat(fname, &buf);
478// if (buf.st_mode & S_IWRITE)
479// return 0;
480// return 1;
481// }
482
Note: See TracBrowser for help on using the repository browser.