Main Page   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

fastio.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2006 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 /***************************************************************************
00009  * RCS INFORMATION:
00010  *
00011  *      $RCSfile: fastio.h,v $
00012  *      $Author: johns $       $Locker:  $             $State: Exp $
00013  *      $Revision: 1.19 $       $Date: 2006/01/27 20:31:44 $
00014  *
00015  ***************************************************************************
00016  * DESCRIPTION:
00017  *   This is a simple abstraction layer for system-dependent I/O calls
00018  * that allow plugins to do binary I/O using the fastest possible method.
00019  *
00020  * This code is intended for use by binary trajectory reader plugins that
00021  * work with multi-gigabyte data sets, reading only binary data.
00022  *
00023  ***************************************************************************/
00024 
00025 /* Compiling on windows */
00026 #if defined(_MSC_VER)
00027 
00028 #if 1 
00029 /* use native Windows I/O calls */
00030 #define FASTIO_NATIVEWIN32 1
00031 
00032 #include <stdio.h>
00033 #include <windows.h>
00034 
00035 typedef HANDLE fio_fd;
00036 typedef LONGLONG fio_size_t;
00037 typedef void * fio_caddr_t;
00038 
00039 typedef struct {
00040   fio_caddr_t iov_base;
00041   int iov_len;
00042 } fio_iovec;
00043 
00044 #define FIO_READ  0x01
00045 #define FIO_WRITE 0x02
00046 
00047 #define FIO_SEEK_CUR  FILE_CURRENT
00048 #define FIO_SEEK_SET  FILE_BEGIN
00049 #define FIO_SEEK_END  FILE_END
00050 
00051 static int fio_win32convertfilename(const char *filename, char *newfilename, int maxlen) {
00052   int i;
00053   int len=strlen(filename);
00054  
00055   if ((len + 1) >= maxlen)
00056     return -1;
00057    
00058   for (i=0; i<len; i++) {
00059     if (filename[i] == '/')
00060       newfilename[i] = '\\';
00061     else
00062       newfilename[i] = filename[i];
00063   }
00064   newfilename[len] = '\0'; /* NUL terminate the string */
00065 
00066   return 0;
00067 }
00068 
00069 static int fio_open(const char *filename, int mode, fio_fd *fd) {
00070   HANDLE fp;
00071   char winfilename[8192];
00072   DWORD access;
00073   DWORD sharing;
00074   LPSECURITY_ATTRIBUTES security;
00075   DWORD createmode;
00076   DWORD flags;
00077 
00078   if (fio_win32convertfilename(filename, winfilename, sizeof(winfilename)))
00079     return -1;  
00080 
00081   access = 0;
00082   if (mode & FIO_READ)
00083     access |= GENERIC_READ;
00084   if (mode & FIO_WRITE)
00085     access |= GENERIC_WRITE;
00086 #if 0
00087   access = FILE_ALL_ACCESS; /* XXX hack if above modes fail */
00088 #endif
00089 
00090   sharing = 0;       /* disallow sharing with other processes  */
00091   security = NULL;   /* child processes don't inherit anything */
00092 
00093   /* since we never append, blow away anything that's already there */
00094   if (mode & FIO_WRITE)
00095     createmode = CREATE_ALWAYS;
00096   else 
00097     createmode = OPEN_EXISTING;
00098 
00099   flags = FILE_ATTRIBUTE_NORMAL;
00100 
00101   fp = CreateFile(winfilename, access, sharing, security, 
00102                   createmode, flags, NULL);
00103 
00104   if (fp == NULL) {
00105     return -1;
00106   } else {
00107     *fd = fp;
00108     return 0;
00109   }
00110 }
00111 
00112 
00113 static int fio_fclose(fio_fd fd) {
00114   BOOL rc;
00115   rc = CloseHandle(fd);
00116   if (rc) 
00117     return 0;
00118   else 
00119     return -1;
00120 }
00121 
00122 static fio_size_t fio_fread(void *ptr, fio_size_t size, 
00123                             fio_size_t nitems, fio_fd fd) {
00124   BOOL rc;
00125   DWORD len;
00126   DWORD readlen;
00127 
00128   len = size * nitems;
00129 
00130   rc = ReadFile(fd, ptr, len, &readlen, NULL);
00131   if (rc) {
00132     if (readlen == len)
00133       return nitems;
00134     else 
00135       return 0;
00136   } else {
00137     return 0;
00138   }
00139 }
00140 
00141 static fio_size_t fio_readv(fio_fd fd, const fio_iovec * iov, int iovcnt) {
00142   int i;
00143   fio_size_t len = 0; 
00144 
00145   for (i=0; i<iovcnt; i++) {
00146     fio_size_t rc = fio_fread(iov[i].iov_base, iov[i].iov_len, 1, fd);
00147     if (rc != 1)
00148       break;
00149     len += iov[i].iov_len;
00150   }
00151 
00152   return len;
00153 }
00154 
00155 static fio_size_t fio_fwrite(void *ptr, fio_size_t size, 
00156                              fio_size_t nitems, fio_fd fd) {
00157   BOOL rc;
00158   DWORD len;
00159   DWORD writelen;
00160 
00161   len = size * nitems; 
00162  
00163   rc = WriteFile(fd, ptr, len, &writelen, NULL);
00164   if (rc) {
00165     if (writelen == len)
00166       return nitems;
00167     else
00168       return 0;
00169   } else {
00170     return 0;
00171   }
00172 }
00173 
00174 static fio_size_t fio_fseek(fio_fd fd, fio_size_t offset, int whence) {
00175 #if 1
00176   /* code that works with older MSVC6 compilers */
00177   LONGLONG finaloffset;
00178   LARGE_INTEGER bigint;
00179   LARGE_INTEGER finalint;
00180 
00181   bigint.QuadPart = offset;
00182   finalint = bigint;      /* set the high part, which will be overwritten */
00183   finalint.LowPart = SetFilePointer(fd, bigint.LowPart, &finalint.HighPart, whence);
00184   if (finalint.LowPart == -1) {
00185     /* if (finalint.LowPart == INVALID_SET_FILE_POINTER) { */
00186     /* INVALID_SET_FILE_POINTER is a possible "ok" low order result when */
00187     /* working with 64-bit offsets, so we have to also check the system  */
00188     /* error value for this thread to be sure */
00189     if (GetLastError() != ERROR_SUCCESS) {
00190       return -1;
00191     }
00192   } 
00193 
00194   finaloffset = finalint.QuadPart;
00195   return 0;
00196 #else
00197   BOOL rc;
00198   LONGLONG finaloffset;
00199 
00200   /* SetFilePointerEx() only exists with new .NET compilers */
00201   rc = SetFilePointerEx(fd, offset, &finaloffset, whence);
00202 
00203   if (rc) 
00204     return 0;
00205   else
00206     return -1;
00207 #endif
00208 }
00209 
00210 static fio_size_t fio_ftell(fio_fd fd) {
00211   /* code that works with older MSVC6 compilers */
00212   LONGLONG finaloffset;
00213   LARGE_INTEGER bigint;
00214   LARGE_INTEGER finalint;
00215 
00216   bigint.QuadPart = 0;
00217   finalint = bigint;      /* set the high part, which will be overwritten */
00218 
00219   finalint.LowPart = SetFilePointer(fd, bigint.LowPart, &finalint.HighPart, FILE_CURRENT);
00220   if (finalint.LowPart == -1) {
00221     /* if (finalint.LowPart == INVALID_SET_FILE_POINTER) { */
00222     /* INVALID_SET_FILE_POINTER is a possible "ok" low order result when */
00223     /* working with 64-bit offsets, so we have to also check the system  */
00224     /* error value for this thread to be sure */
00225     if (GetLastError() != ERROR_SUCCESS) {
00226       return -1;
00227     }
00228   }
00229 
00230   finaloffset = finalint.QuadPart;
00231 
00232   return finaloffset;
00233 }
00234 
00235 
00236 #else
00237 
00238 /* Version for machines with plain old ANSI C  */
00239 
00240 #include <stdio.h>
00241 
00242 typedef FILE * fio_fd;
00243 typedef size_t fio_size_t;  /* MSVC doesn't uinversally support ssize_t */
00244 typedef void * fio_caddr_t; /* MSVC doesn't universally support caddr_t */
00245 
00246 typedef struct {
00247   fio_caddr_t iov_base;
00248   int iov_len;
00249 } fio_iovec;
00250 
00251 #define FIO_READ  0x01
00252 #define FIO_WRITE 0x02
00253 
00254 #define FIO_SEEK_CUR SEEK_CUR
00255 #define FIO_SEEK_SET SEEK_SET
00256 #define FIO_SEEK_END SEEK_END
00257 
00258 static int fio_open(const char *filename, int mode, fio_fd *fd) {
00259   char * modestr;
00260   FILE *fp;
00261  
00262   if (mode == FIO_READ) 
00263     modestr = "rb";
00264 
00265   if (mode == FIO_WRITE) 
00266     modestr = "wb";
00267 
00268   fp = fopen(filename, modestr);
00269   if (fp == NULL) {
00270     return -1;
00271   } else {
00272     *fd = fp;
00273     return 0;
00274   }
00275 }
00276 
00277 static int fio_fclose(fio_fd fd) {
00278   return fclose(fd);
00279 }
00280 
00281 static fio_size_t fio_fread(void *ptr, fio_size_t size, 
00282                             fio_size_t nitems, fio_fd fd) {
00283   return fread(ptr, size, nitems, fd);
00284 }
00285 
00286 static fio_size_t fio_readv(fio_fd fd, const fio_iovec * iov, int iovcnt) {
00287   int i;
00288   fio_size_t len = 0; 
00289 
00290   for (i=0; i<iovcnt; i++) {
00291     fio_size_t rc = fread(iov[i].iov_base, iov[i].iov_len, 1, fd);
00292     if (rc != 1)
00293       break;
00294     len += iov[i].iov_len;
00295   }
00296 
00297   return len;
00298 }
00299 
00300 static fio_size_t fio_fwrite(void *ptr, fio_size_t size, 
00301                              fio_size_t nitems, fio_fd fd) {
00302   return fwrite(ptr, size, nitems, fd);
00303 }
00304 
00305 static fio_size_t fio_fseek(fio_fd fd, fio_size_t offset, int whence) {
00306   return fseek(fd, offset, whence);
00307 }
00308 
00309 static fio_size_t fio_ftell(fio_fd fd) {
00310   return ftell(fd);
00311 }
00312 #endif /* plain ANSI C */
00313 
00314 #else 
00315 
00316 /* Version for UNIX machines */
00317 #include <unistd.h>
00318 #include <sys/types.h>
00319 #include <sys/stat.h>
00320 #include <fcntl.h>
00321 
00322 typedef int fio_fd;
00323 typedef off_t fio_size_t;      /* off_t is 64-bits with LFS builds */
00324 
00325 /* enable use of kernel readv() if available */
00326 #if defined(__sun) || defined(__APPLE_CC__) || defined(__linux)
00327 #define USE_KERNEL_READV 1
00328 #endif
00329 
00330 typedef void * fio_caddr_t;
00331 
00332 #if defined(USE_KERNEL_READV)
00333 #include <sys/uio.h>
00334 typedef struct iovec fio_iovec;
00335 #else
00336 
00337 typedef struct {
00338   fio_caddr_t iov_base;
00339   int iov_len;
00340 } fio_iovec;
00341 #endif
00342 
00343 
00344 #define FIO_READ  0x01
00345 #define FIO_WRITE 0x02
00346 
00347 #define FIO_SEEK_CUR SEEK_CUR
00348 #define FIO_SEEK_SET SEEK_SET
00349 #define FIO_SEEK_END SEEK_END
00350 
00351 static int fio_open(const char *filename, int mode, fio_fd *fd) {
00352   int nfd;
00353   int oflag = 0;
00354 
00355   if (mode == FIO_READ) 
00356     oflag = O_RDONLY;
00357 
00358   if (mode == FIO_WRITE) 
00359     oflag = O_WRONLY | O_CREAT | O_TRUNC;
00360 
00361   nfd = open(filename, oflag, 0666);
00362   if (nfd < 0) {
00363     return -1;
00364   } else {
00365     *fd = nfd;
00366     return 0;
00367   }
00368 }
00369 
00370 static int fio_fclose(fio_fd fd) {
00371   return close(fd);
00372 }
00373 
00374 static fio_size_t fio_fread(void *ptr, fio_size_t size, 
00375                             fio_size_t nitems, fio_fd fd) {
00376   int i;
00377   fio_size_t len = 0; 
00378   int cnt = 0;
00379 
00380   for (i=0; i<nitems; i++) {
00381     fio_size_t rc = read(fd, (void*) (((char *) ptr) + (cnt * size)), size);
00382     if (rc != size)
00383       break;
00384     len += rc;
00385     cnt++;
00386   }
00387 
00388   return cnt;
00389 }
00390 
00391 static fio_size_t fio_readv(fio_fd fd, const fio_iovec * iov, int iovcnt) {
00392 #if defined(USE_KERNEL_READV)
00393   return readv(fd, iov, iovcnt);
00394 #else
00395   int i;
00396   fio_size_t len = 0; 
00397 
00398   for (i=0; i<iovcnt; i++) {
00399     fio_size_t rc = read(fd, iov[i].iov_base, iov[i].iov_len);
00400     if (rc != iov[i].iov_len)
00401       break;
00402     len += iov[i].iov_len;
00403   }
00404 
00405   return len;
00406 #endif
00407 }
00408 
00409 static fio_size_t fio_fwrite(void *ptr, fio_size_t size, 
00410                              fio_size_t nitems, fio_fd fd) {
00411   int i;
00412   fio_size_t len = 0; 
00413   int cnt = 0;
00414 
00415   for (i=0; i<nitems; i++) {
00416     fio_size_t rc = write(fd, ptr, size);
00417     if (rc != size)
00418       break;
00419     len += rc;
00420     cnt++;
00421   }
00422 
00423   return cnt;
00424 }
00425 
00426 static fio_size_t fio_fseek(fio_fd fd, fio_size_t offset, int whence) {
00427  if (lseek(fd, offset, whence) >= 0)
00428    return 0;  /* success (emulate behavior of fseek) */
00429  else 
00430    return -1; /* failure (emulate behavior of fseek) */
00431 }
00432 
00433 static fio_size_t fio_ftell(fio_fd fd) {
00434   return lseek(fd, 0, SEEK_CUR);
00435 }
00436 
00437 #endif
00438 
00439 
00440 /* higher level routines that are OS independent */
00441 
00442 static int fio_write_int32(fio_fd fd, int i) {
00443   return (fio_fwrite(&i, 4, 1, fd) != 1);
00444 }
00445 
00446 static int fio_read_int32(fio_fd fd, int *i) {
00447   return (fio_fread(i, 4, 1, fd) != 1);
00448 }
00449 
00450 static int fio_write_str(fio_fd fd, const char *str) {
00451   int len = strlen(str);
00452   return (fio_fwrite((void *) str, len, 1, fd) != 1);
00453 }
00454 

Generated on Wed Mar 22 13:15:29 2006 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002