Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

fortread.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: fortread.h,v $
00013  *      $Author: johns $       $Locker:  $             $State: Exp $
00014  *      $Revision: 1.10 $       $Date: 2016/11/28 05:01:54 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Unformatted and formatted fortran file reading routines for
00019  *   use in various plugins to simplify dealing with fortran i/o quirks.
00020  ***************************************************************************/
00021 
00022 #ifndef FORTREAD_H
00023 #define FORTREAD_H
00024 
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 
00028 #include "endianswap.h"
00029 
00030 #define FORT_RECLEN_32BIT 4
00031 #define FORT_RECLEN_64BIT 8
00032 
00033 /*
00034  * consume a record length marker
00035  */
00036 static int fort_eat_recmark(FILE *ifp, int recmarklen) {
00037   int tmp;
00038   if (recmarklen == FORT_RECLEN_64BIT) {
00039     if (fread(&tmp, 4, 1, ifp) != 1) 
00040       return -1;
00041     if (fread(&tmp, 4, 1, ifp) != 1) 
00042       return -1;
00043   } else {
00044     if (fread(&tmp, 4, 1, ifp) != 1) 
00045       return -1;
00046   }
00047 
00048   return 0;
00049 }
00050 
00051 /*
00052  * Determine endianness and length of Fortran 
00053  * record length markers within unformatted binary files.
00054  */
00055 static int fort_get_endian_reclen(int reclen, int word0, int word1, 
00056                                   int *swap, int *recmarklen) {
00057   /* check for 32-bit record length markers */
00058   if (reclen == word0) {
00059     *swap=0;
00060     *recmarklen=FORT_RECLEN_32BIT;
00061     return 0;
00062   } else {
00063     int tmp = word0;
00064     swap4_aligned(&tmp, 1);   
00065     if (tmp == reclen) {
00066       *swap=0;
00067       *recmarklen=FORT_RECLEN_32BIT;
00068       return 0;
00069     }
00070   }
00071   
00072   /* check for 64-bit record length markers */ 
00073   if (reclen == (word0+word1)) {
00074     *swap=0;
00075     *recmarklen=FORT_RECLEN_64BIT;
00076   } else {
00077     int tmp0=word0;
00078     int tmp1=word1;
00079     swap4_aligned(&tmp0, 1);   
00080     swap4_aligned(&tmp1, 1);   
00081     *swap=1;
00082     *recmarklen=FORT_RECLEN_64BIT;
00083   }
00084     
00085   return -1; /* completely unrecognized record length marker */
00086 }
00087 
00088 
00089 
00090 /*  Unformatted reads.
00091  *
00092  *   Each function reads the next record from the file (provided it contains
00093  *   no more than n elements), optionally swapping its contents before
00094  *   writing it into dest. 
00095  *   Returns the number of elements on success, 0 on failure.
00096  *
00097  *   TODO: These should perhaps rewind the file to the beginning of the
00098  *   record on failure.
00099  */
00100 
00101 /* Only works with aligned four-byte quantities, swap4_aligned() will */
00102 /* cause a bus error on sume platforms if used on unaligned data      */
00103 static int fortread_4(void *dest, int n, int swap, FILE *fd) {
00104   int dataBegin, dataEnd, count;
00105 
00106   if (fread(&dataBegin, sizeof(int), 1, fd) != 1) return 0;
00107   if (swap) swap4_aligned(&dataBegin, 1);
00108   if ((dataBegin <= 0) || (n < dataBegin/4)) return 0;
00109 
00110   count = fread(dest, 4, dataBegin/4, fd);
00111   if (count != dataBegin/4) return 0;
00112   if (swap) swap4_aligned(dest, dataBegin/4);
00113 
00114   if (fread(&dataEnd, sizeof(int), 1, fd) != 1) return 0;
00115   if (swap) swap4_aligned(&dataBegin, 1);
00116   if (dataEnd != dataBegin) return 0;
00117 
00118   return count;
00119 }
00120 
00121 /* Formatted reads:
00122  *
00123  * copy at most 'len' characters from source to target. 
00124  *
00125  * leading white space is skipped over but counts towards 'len'.
00126  * the copy stops at first whitspace or a '\0'.
00127  * unlike strncpy(3) the result will always be \0 terminated.
00128  *
00129  * intended for copying (short) strings from formatted fortran  
00130  * i/o files that must not contain whitespace (e.g. residue names, 
00131  * atom name/types etc. in .pdb, .psf and alike.). 
00132  */
00133 static void strnwscpy(char *target, const char *source, const int len) {
00134   int i, c;
00135 
00136   for (i=0, c=0; i<len; ++i) {
00137     if (*source == '\0' || (c > 0 && *source == ' ')) {
00138       break;
00139     }
00140 
00141     if (*source == ' ') { 
00142       source++;
00143     } else {
00144       *target++ = *source++;
00145       c++;
00146     }
00147   }
00148   *target = '\0';
00149 }
00150 
00151 #endif
00152 

Generated on Tue Aug 11 03:06:30 2020 for VMD Plugins (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002