Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

t_ncio.c

Go to the documentation of this file.
00001 /*
00002  *   Copyright 1995, University Corporation for Atmospheric Research
00003  *   See top level COPYRIGHT file for copying and redistribution conditions.
00004  */
00005 
00006 #include <stdio.h>
00007 #include <stdlib.h>
00008 #include <string.h>
00009 #include <ctype.h>
00010 #include <assert.h>
00011 #include "ncio.h" 
00012 #ifndef ENOERR
00013 #define ENOERR 0
00014 #endif
00015 
00016 
00017 static void
00018 usage(const char *av0)
00019 {
00020         (void)fprintf(stderr,
00021                 "Usage: %s [options] fname\t\nOptions:\n", av0);
00022         (void)fprintf(stderr,
00023                 "\t-v           Verbose\n") ;
00024         (void)fprintf(stderr,
00025                 "\t-w           Open Read/Write, default is read only\n") ;
00026         (void)fprintf(stderr,
00027                 "\t-c           Create, clobber existing\n") ;
00028         (void)fprintf(stderr,
00029                 "\t-n           Create, error if it already exists\n") ;
00030         (void)fprintf(stderr,
00031                 "\t-L           Use locking if available\n") ;
00032         (void)fprintf(stderr,
00033                 "\t-S           Share updates (turn off caching)\n") ;
00034         (void)fprintf(stderr,
00035                 "\t-U           Delete (unlink) on close\n") ;
00036         (void)fprintf(stderr,
00037                 "\t-o igeto     Initial get offset\n") ;
00038         (void)fprintf(stderr,
00039                 "\t-i igetsz    Initial get size\n") ;
00040         (void)fprintf(stderr,
00041                 "\t-I initialsz Initial file size for create\n") ;
00042         (void)fprintf(stderr,
00043                 "\t-s sizehint  Buffer size\n") ;
00044         exit(EXIT_FAILURE);
00045 }
00046 
00047 
00048 static long
00049 argscale(const char *arg, const char *tag)
00050 {
00051         long value = 0;
00052                 /* last character */
00053         const char *cp = arg + strlen(arg) -1;
00054         value = atol(arg);
00055         if(isalpha(*cp))
00056         {
00057                 switch(*cp) {
00058                 case 'k':
00059                 case 'K':
00060                         value *= 1024;
00061                         break;
00062                 case 'm':
00063                 case 'M':
00064                         value *= (1024*1024);
00065                         break;
00066                 default:
00067                         value = 0; /* trigger error below */
00068                         break;
00069                 }
00070         }
00071         if(value == 0)
00072         {
00073                 fprintf(stderr,
00074                          "Illegal %s \"%s\", ignored\n", tag, arg);
00075         }
00076         return value;
00077 }
00078 
00079 
00080 static void
00081 modify_ex(off_t offset, size_t extent, void *vp)
00082 {
00083         unsigned char *obuf = vp;
00084         const unsigned char *const end = &obuf[extent];
00085         unsigned char *cp = obuf;
00086 
00087         if(cp >= end) return;
00088         *cp++ = (unsigned char)( offset               >> 24);
00089         if(cp >= end) return;
00090         *cp++ = (unsigned char)((offset & 0x00ff0000) >> 16);
00091         if(cp >= end) return;
00092         *cp++ = (unsigned char)((offset & 0x0000ff00) >>  8);
00093         if(cp >= end) return;
00094         *cp++ = (unsigned char)( offset & 0x000000ff);
00095         if(cp >= end) return;
00096         *cp++ = (unsigned char)( extent               >> 24);
00097         if(cp >= end) return;
00098         *cp++ = (unsigned char)((extent & 0x00ff0000) >> 16);
00099         if(cp >= end) return;
00100         *cp++ = (unsigned char)((extent & 0x0000ff00) >>  8);
00101         if(cp >= end) return;
00102         *cp++   = (unsigned char)( extent & 0x000000ff);
00103 
00104         while(cp < end)
00105         {
00106                 *cp++ = (unsigned char) (cp - obuf); 
00107         }
00108 }
00109 
00110 
00111 typedef struct riu {
00112         struct riu *next;
00113         struct riu *prev;
00114         off_t offset;
00115         size_t extent;
00116         void *vp;
00117 } riu;
00118 
00119 static void
00120 free_riu(riu *riup)
00121 {
00122         if(riup == NULL)
00123                 return;
00124         free(riup);
00125 }
00126 
00127 static riu *
00128 new_riu(off_t offset, size_t extent, void *vp)
00129 {
00130         riu *riup = (riu *)malloc(sizeof(riu));
00131         if(riup == NULL)
00132         {
00133                 fprintf(stderr,
00134                         "new_riu: malloc failed\n");
00135                 exit(EXIT_FAILURE);
00136         }
00137         riup->next = NULL;
00138         riup->prev = NULL;
00139         riup->offset = offset;
00140         riup->extent = extent;
00141         riup->vp = vp;
00142         return riup;
00143 }
00144 
00145 static riu *stack = NULL;
00146 
00147 static void
00148 riu_push(off_t offset, size_t extent, void *vp)
00149 {
00150         riu *riup = new_riu(offset, extent, vp);
00151         /* assert(riup != NULL); */
00152         riup->next = stack;
00153         if(stack != NULL)
00154                 stack->prev = riup;
00155         stack = riup;
00156 }
00157 
00158 static int
00159 riu_pop(off_t offset, int modify)
00160 {
00161         riu *riup = stack;
00162         while(riup != NULL)
00163         {
00164                 if(riup->offset == offset)
00165                 {
00166                         if(modify)
00167                         {
00168                                 modify_ex(riup->offset, riup->extent, riup->vp);
00169                         }
00170                         if(riup->next != NULL)
00171                         {
00172                                 riup->next->prev = riup->prev;
00173                         }
00174                         if(riup == stack)
00175                         {
00176                                 stack = riup->next;
00177                         }
00178                         else
00179                         {
00180                                 assert(riup->prev != NULL);
00181                                 riup->prev->next = riup->next;
00182                         }
00183                         free_riu(riup);
00184                         return 1;
00185                 }
00186                 riup = riup->next;
00187         }
00188         /* else, not found */
00189         return 0;
00190 }
00191 
00192 main(int ac, char *av[])
00193 {
00194         char *path = "";
00195         ncio *nciop;
00196         char linebuf[128];
00197         off_t offset;
00198         size_t extent;
00199         void *vp;
00200         int status = ENOERR;
00201         int verbose = 0;
00202         int flags = 0;
00203         int create = 0;
00204         off_t igeto = 0;
00205         size_t igetsz = 0;
00206         size_t initialsz = 0;
00207         int doUnlink = 0;
00208         size_t sizehint = NC_SIZEHINT_DEFAULT;
00209 
00210         {
00211         extern int optind;
00212         extern int opterr;
00213         extern char *optarg;
00214         int ch;
00215 
00216         opterr = 1;
00217 
00218         while ((ch = getopt(ac, av, "vwcnLSUo:i:I:s:")) != EOF)
00219                 switch (ch) {
00220                 case 'v':
00221                         verbose = 1;
00222                         break;
00223                 case 'w':
00224                         flags |= NC_WRITE;
00225                         break;
00226                 case 'c':
00227                         create = 1;
00228                         break;
00229                 case 'n':
00230                         create = 1;
00231                         flags |= NC_NOCLOBBER;
00232                         break;
00233                 case 'L':
00234                         flags |= NC_LOCK;
00235                         break;
00236                 case 'S':
00237                         flags |= NC_SHARE;
00238                         break;
00239                 case 'U':
00240                         doUnlink = 1;
00241                         break;
00242                 case 'o':
00243                         igeto = argscale(optarg, "igeto");
00244                         break;
00245                 case 'i':
00246                         igetsz = argscale(optarg, "igetsz");
00247                         break;
00248                 case 'I':
00249                         initialsz = argscale(optarg, "initialsz");
00250                         break;
00251                 case 's':
00252                         sizehint = argscale(optarg, "sizehint");
00253                         break;
00254                 case '?':
00255                         usage(av[0]);
00256                         break;
00257                 }
00258 
00259         /* last arg, the file name, is required */
00260         if(ac - optind <= 0)
00261                 usage(av[0]) ;
00262         path = av[optind];
00263 
00264 
00265         }
00266         
00267         if(!create)
00268         {
00269                 status = ncio_open(path, flags,
00270                                 igeto, igetsz, &sizehint,
00271                                 &nciop, &vp);
00272                 if(status != ENOERR)
00273                 {
00274                         fprintf(stderr, "ncio_open: %s: %s\n",
00275                                 path, strerror(status));
00276                         return(EXIT_FAILURE);
00277                 }
00278         } else {
00279                 status = ncio_create(path, flags, initialsz,
00280                         igeto, igetsz, &sizehint,
00281                         &nciop, &vp);
00282                 if(status != ENOERR)
00283                 {
00284                         fprintf(stderr, "ncio_create: %s: %s\n",
00285                                 path, strerror(status));
00286                         return(EXIT_FAILURE);
00287                 }
00288         }
00289 
00290         while(fgets(linebuf, sizeof(linebuf), stdin) != NULL)
00291         {
00292                 offset = 0;
00293                 extent = 0;
00294 
00295                 if(*linebuf == '#')
00296                         continue; /* comment */
00297                 if(sscanf(linebuf, "rel 0x%lx", &offset) == 1
00298                         || sscanf(linebuf, "rel %ld", &offset) == 1)
00299                 {
00300                         if(verbose)
00301                                 printf("- rel  %8ld\n", offset);
00302                         if(!riu_pop(offset, 0))
00303                                 continue;
00304                         status = nciop->rel(nciop, offset, 0);
00305                         if(status)
00306                         {
00307                                 fprintf(stderr, "- rel  error: %s\n",
00308                                         strerror(status));
00309                                 continue;
00310                         }
00311                 }
00312                 else if(sscanf(linebuf, "relm 0x%lx", &offset) == 1
00313                         || sscanf(linebuf, "relm %ld", &offset) == 1)
00314                 {
00315                         if(verbose)
00316                                 printf("- relm %8ld\n", offset);
00317                         if(!riu_pop(offset, 1))
00318                                 continue;
00319                         status = nciop->rel(nciop, offset, RGN_MODIFIED);
00320                         if(status)
00321                         {
00322                                 fprintf(stderr, "- relm %8ld error: %s\n",
00323                                         offset, strerror(status));
00324                                 continue;
00325                         }
00326                 }
00327                 else if(sscanf(linebuf, "get 0x%lx %ld", &offset, &extent) == 2
00328                         || sscanf(linebuf, "get %ld %ld", &offset, &extent) == 2)
00329                 {
00330                         if(verbose)
00331                                 printf("- get  %10ld %8ld\n", offset, extent);
00332                         status = nciop->get(nciop, offset, extent, 0, &vp);
00333                         if(status)
00334                         {
00335                                 fprintf(stderr, "- get  error: %s\n",
00336                                         strerror(status));
00337                                 continue;
00338                         }
00339                         riu_push(offset, extent, vp);
00340                 }
00341                 else if(sscanf(linebuf, "getw 0x%lx %ld", &offset, &extent) == 2
00342                         || sscanf(linebuf, "getw %ld %ld", &offset, &extent) == 2)
00343                 {
00344                         if(verbose)
00345                                 printf("- getw %10ld %8ld\n", offset, extent);
00346                         status = nciop->get(nciop, offset, extent, RGN_WRITE, &vp);
00347                         if(status)
00348                         {
00349                                 fprintf(stderr, "- getw  error: %s\n",
00350                                         strerror(status));
00351                                 continue;
00352                         }
00353                         riu_push(offset, extent, vp);
00354                 }
00355                 else if(strchr(linebuf, 'q') != NULL)
00356                         break;
00357                 else
00358                         printf("???\n");
00359         }
00360 
00361         status = ncio_close(nciop, doUnlink);
00362         if(status != ENOERR)
00363         {
00364                 fprintf(stderr, "ncio_close(%s): %s: %s\n",
00365                         doUnlink ? "doUnlink" : "",
00366                         path, strerror(status));
00367                 return(EXIT_FAILURE);
00368         }
00369 
00370         return(EXIT_SUCCESS);
00371 }
 

Powered by Plone

This site conforms to the following standards: