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_ncx.c

Go to the documentation of this file.
00001 /*
00002  *      Copyright 1996, University Corporation for Atmospheric Research
00003  *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
00004  */
00005 
00006 #include <stdio.h>
00007 #include <limits.h>
00008 /* alias poorly named limits.h macros */
00009 #define  SHORT_MAX  SHRT_MAX
00010 #define  SHORT_MIN  SHRT_MIN
00011 #define USHORT_MAX USHRT_MAX
00012 #include <rpc/types.h>
00013 #include <rpc/xdr.h>
00014 #include <string.h>
00015 #include "ncx.h"
00016 
00017 #define NO_UNSIGNED
00018 #define NO_UNSIGNED_LONG
00019 
00020 /*
00021  * This program tests the xdr_mem implementation and
00022  * the ncx_ implementation, and compares the two.
00023  * Link like this: 
00024  * cc t_ncx.c ncx.o [-lsome_xdr_lib] -o t_nxc
00025  * Successful output is:
00026         xdr_encode ends at byte 640
00027         xdr_check  ends at byte 640
00028         ncx_encode ends at byte 640
00029         ncx_check  ends at byte 640
00030         xdr_check  ends at byte 640
00031         ncx_check  ends at byte 640
00032  * with exit status 0;
00033  */
00034 
00035 #define XBSZ 1024
00036 
00037 char xdrb[XBSZ];
00038 char ncxb[XBSZ];
00039 
00040 #define ArraySize(thang) (sizeof(thang)/sizeof(thang[0]))
00041 #define uiArraySize(thang) ((u_int)ArraySize(thang))
00042 #define eSizeOf(thang) ((u_int)(sizeof(thang[0])))
00043 
00044 /*
00045  * Some test data
00046  */
00047 
00048 static char text[] = { "Hiya sailor. New in town?" };
00049 
00050 /*
00051  * Some test data
00052  * The ideas is that ncx_putn_type_type(...., types)
00053  * should not return NC_ERANGE.
00054  */
00055 
00056 #if SCHAR_MAX == X_SCHAR_MAX && SCHAR_MIN == X_SCHAR_MIN
00057 static schar schars[] = {
00058         SCHAR_MIN, SCHAR_MIN +1,
00059         -1, 0, 1,
00060         SCHAR_MAX - 1, SCHAR_MAX
00061 };
00062 #else
00063 /* The implementation and this test assume 8 bit bytes. */
00064 #error "Not 8 bit bytes ??"
00065 #endif
00066 
00067 static short shorts[] = {
00068 #if SHORT_MAX <= X_SHORT_MAX
00069         SHORT_MIN, SHORT_MIN + 1,
00070 #  if SCHAR_MAX < X_SHORT_MAX
00071         SCHAR_MIN - 1, SCHAR_MIN, SCHAR_MIN + 1,
00072 #  endif
00073         -1, 0, 1,
00074 #  if SCHAR_MAX < X_SHORT_MAX
00075         SCHAR_MAX - 1, SCHAR_MAX, SCHAR_MAX + 1,
00076 #  endif
00077         SHORT_MAX - 1, SHORT_MAX
00078 #else
00079         X_SHORT_MIN, X_SHORT_MIN + 1,
00080 #  if SCHAR_MAX < X_SHORT_MAX
00081         SCHAR_MIN - 1, SCHAR_MIN, SCHAR_MIN + 1,
00082 #  endif
00083         -1, 0, 1,
00084 #  if SCHAR_MAX < X_SHORT_MAX
00085         SCHAR_MAX - 1, SCHAR_MAX, SCHAR_MAX + 1,
00086 #  endif
00087         X_SHORT_MAX - 1, X_SHORT_MAX
00088 #endif
00089 };
00090 
00091 static int ints[] = {
00092 #if INT_MAX <= X_INT_MAX
00093         INT_MIN, INT_MIN +1,
00094 #  if SHORT_MAX < X_INT_MAX
00095         SHORT_MIN -1, SHORT_MIN, SHORT_MIN + 1,
00096 #  endif
00097 #  if SCHAR_MAX < X_INT_MAX
00098         SCHAR_MIN - 1, SCHAR_MIN, SCHAR_MIN + 1,
00099 #  endif
00100         -1, 0, 1,
00101 #  if SCHAR_MAX < X_INT_MAX
00102         SCHAR_MAX - 1, SCHAR_MAX, SCHAR_MAX + 1,
00103 #  endif
00104 #  if SHORT_MAX < X_INT_MAX
00105         SHORT_MAX - 1, SHORT_MAX, SHORT_MAX +1,
00106 #  endif
00107         INT_MAX - 1, INT_MAX
00108 #else
00109         X_INT_MIN, X_INT_MIN +1,
00110 #  if SHORT_MAX < X_INT_MAX
00111         SHORT_MIN -1, SHORT_MIN, SHORT_MIN + 1,
00112 #  endif
00113 #  if SCHAR_MAX < X_INT_MAX
00114         SCHAR_MIN - 1, SCHAR_MIN, SCHAR_MIN + 1,
00115 #  endif
00116         -1, 0, 1,
00117 #  if SCHAR_MAX < X_INT_MAX
00118         SCHAR_MAX - 1, SCHAR_MAX, SCHAR_MAX + 1,
00119 #  endif
00120 #  if SHORT_MAX < X_INT_MAX
00121         SHORT_MAX - 1, SHORT_MAX, SHORT_MAX +1,
00122 #  endif
00123         X_INT_MAX - 1, X_INT_MAX
00124 #endif /* INT */
00125 };
00126 
00127 
00128 /* N.B. only testing longs over X_INT range for now */
00129 static long longs[] = {
00130 #if LONG_MAX <= X_INT_MAX
00131         LONG_MIN, LONG_MIN +1,
00132 #  if INT_MAX < X_INT_MAX
00133         INT_MIN -1, INT_MIN, INT_MIN + 1,
00134 #  endif
00135 #  if SHORT_MAX < X_INT_MAX
00136         SHORT_MIN -1, SHORT_MIN, SHORT_MIN + 1,
00137 #  endif
00138 #  if SCHAR_MAX < X_INT_MAX
00139         SCHAR_MIN - 1, SCHAR_MIN, SCHAR_MIN + 1,
00140 #  endif
00141         -1, 0, 1,
00142 #  if SCHAR_MAX < X_INT_MAX
00143         SCHAR_MAX - 1, SCHAR_MAX, SCHAR_MAX + 1,
00144 #  endif
00145 #  if SHORT_MAX < X_INT_MAX
00146         SHORT_MAX - 1, SHORT_MAX, SHORT_MAX +1,
00147 #  endif
00148 #  if INT_MAX < X_INT_MAX
00149         INT_MAX -1, INT_MAX, INT_MAX + 1,
00150 #  endif
00151         LONG_MAX - 1, LONG_MAX
00152 #else
00153         X_INT_MIN, X_INT_MIN +1,
00154 #  if SHORT_MAX < X_INT_MAX
00155         SHORT_MIN -1, SHORT_MIN, SHORT_MIN + 1,
00156 #  endif
00157 #  if SCHAR_MAX < X_INT_MAX
00158         SCHAR_MIN - 1, SCHAR_MIN, SCHAR_MIN + 1,
00159 #  endif
00160         -1, 0, 1,
00161 #  if SCHAR_MAX < X_INT_MAX
00162         SCHAR_MAX - 1, SCHAR_MAX, SCHAR_MAX + 1,
00163 #  endif
00164 #  if SHORT_MAX < X_INT_MAX
00165         SHORT_MAX - 1, SHORT_MAX, SHORT_MAX +1,
00166 #  endif
00167         X_INT_MAX - 1, X_INT_MAX
00168 #endif
00169 };
00170 
00171 static float floats[] = {
00172          -100.625, -100.5, -100.375, -100.25, -100.125,
00173         -1.0, -.125, 0., .125, 1.,
00174          100.125, 100.25, 100.375, 100.5, 100.625
00175 };
00176 
00177 /* The big numbers require 25 bits: 2^(25-i)+1/2^i, i = 2, 3, ..., 6 */
00178 static double doubles[] = {
00179         -8388608.25, -4194304.125, -2097152.0625, -1048576.03125, -524288.015625
00180         -100.625, -100.5, -100.375, -100.25, -100.125,
00181         -1.0, -.125, 0., .125, 1.,
00182         100.125, 100.25, 100.375, 100.5, 100.625,
00183         524288.015625, 1048576.03125, 2097152.0625, 4194304.125, 8388608.25
00184 };
00185 
00186 /* End of test data */
00187 
00188 /*
00189  *      Copyright 1993, University Corporation for Atmospheric Research
00190  *      See netcdf/COPYRIGHT file for copying and redistribution conditions.
00191  */
00192 /*      $Id: t_ncx.c,v 1.2 2001/12/28 14:16:27 rwcox Exp $ */
00193 
00194 /* putget.c */
00195 /*
00196  * xdr 1 - 3 bytes, leaving adjoining bytes within the word ok.
00197  * (minimum unit of io is 4 bytes)
00198  */
00199 static bool_t
00200 xdr_NCvbyte(XDR *xdrs, unsigned rem, unsigned count, char *value) 
00201 {
00202         char buf[4] ;
00203         u_int origin ;
00204         enum xdr_op  x_op = xdrs->x_op ; /* save state */
00205 
00206         if(x_op == XDR_ENCODE)
00207         {
00208         /*
00209          * Since we only read/write multiples of four bytes,
00210          * We will read in the word to change one byte in it.
00211          */
00212                 origin = xdr_getpos( xdrs ) ;
00213                 /* next op is a get */
00214                 xdrs->x_op = XDR_DECODE ;
00215         }
00216 
00217         if(!xdr_opaque(xdrs, buf, 4))
00218         {
00219                 /* get failed, assume we are trying to read off the end */
00220                 (void)memset(buf, 0, sizeof(buf)) ;
00221         }
00222 
00223         if(x_op == XDR_ENCODE) /* back to encode */
00224                 xdrs->x_op = x_op ;
00225 
00226         while(count-- != 0)
00227         {
00228                 if(x_op == XDR_ENCODE)
00229                         buf[rem] = *value ;
00230                 else
00231                         *value = buf[rem] ;
00232         
00233                 rem++ ;
00234                 value++ ;
00235         }
00236 
00237         if(x_op == XDR_ENCODE)
00238         {
00239                 if( !xdr_setpos(xdrs, origin) )
00240                         return(FALSE) ;
00241                 if( !xdr_opaque(xdrs, buf, 4))
00242                         return(FALSE) ;
00243         }
00244 
00245         return(TRUE) ;
00246 }
00247 
00248 
00249 /* xdrshorts.c */
00250 /* you may wish to tune this: big on a cray, small on a PC? */
00251 #define NC_SHRT_BUFSIZ 8192
00252 #define NC_NSHRTS_PER (NC_SHRT_BUFSIZ/2) /* number of netshorts the buffer holds */
00253 
00254 /*
00255  * xdr a short leaving adjoining short within the word ok.
00256  * (minimum unit of io is 4 bytes)
00257  */
00258 static bool_t
00259 xdr_NCvshort(XDR *xdrs, unsigned which, short *value)
00260 {
00261         unsigned char buf[4] ; /* unsigned is important here */
00262         u_int origin ;
00263         enum xdr_op  x_op = xdrs->x_op ; /* save state */
00264 
00265         if(x_op == XDR_ENCODE)
00266         {
00267                 origin = xdr_getpos( xdrs ) ;
00268                 /* next op is a get */
00269                 xdrs->x_op = XDR_DECODE ;
00270         }
00271 
00272         if(!xdr_opaque(xdrs, (caddr_t)buf, 4))
00273         {
00274                 /* get failed, assume we are trying to read off the end */
00275                 (void)memset(buf, 0, sizeof(buf)) ;
00276         }
00277 
00278         if(x_op == XDR_ENCODE) /* back to encode */
00279                 xdrs->x_op = x_op ;
00280 
00281         if(which != 0) which = 2 ;
00282 
00283         if(xdrs->x_op == XDR_ENCODE)
00284         {
00285                 buf[which +1] = *value % 256 ;
00286                 buf[which] = (*value >> 8) ;
00287 
00288                 if( !xdr_setpos(xdrs, origin) )
00289                         return(FALSE) ;
00290                 if( !xdr_opaque(xdrs, (caddr_t)buf, 4))
00291                         return(FALSE) ;
00292         }
00293         else
00294         {
00295                 *value = (((unsigned)buf[which] & 0x7f) << 8) +
00296                          (unsigned)buf[which + 1] ;
00297                 if((unsigned)buf[which] & 0x80)
00298                 {
00299                         /* extern is neg */
00300                         *value -= 0x8000 ;
00301                 }
00302         }
00303         return(TRUE) ;
00304 }
00305 
00306 /*
00307  * internal function, bulk xdr of an even number of shorts, less than NC_NSHRTS_PER
00308  */
00309 static
00310 bool_t
00311 NCxdr_shortsb(XDR *xdrs, short *sp, u_int nshorts)
00312 {
00313         unsigned char buf[NC_SHRT_BUFSIZ] ;
00314         unsigned char *cp ;
00315         unsigned int nbytes = nshorts * 2;
00316 
00317         /* assert(nshorts <= NC_NSHRTS_PER) ; */
00318         /* assert(nshorts > 0) ; */
00319 
00320         if(xdrs->x_op == XDR_ENCODE)
00321         {
00322                 for(cp = buf ; cp < &buf[nbytes] ; sp++, cp += 2 )
00323                 {
00324                         *(cp +1) = *sp % 256 ;
00325                         *cp = (*sp >> 8) ;
00326                 }
00327         }
00328 
00329         if(!xdr_opaque(xdrs, (caddr_t)buf, nbytes))
00330                 return FALSE ;
00331         
00332         if(xdrs->x_op == XDR_DECODE)
00333         {
00334                 for(cp = buf ; cp < &buf[nbytes] ; sp++, cp += 2 )
00335                 {
00336                         *sp = (((unsigned)*cp & 0x7f) << 8) +
00337                                  (unsigned)*(cp +1) ;
00338                         if((unsigned)*cp & 0x80)
00339                         {
00340                                 /* extern is neg */
00341                                 *sp -= 0x8000 ;
00342                         }
00343                 }
00344         }
00345 
00346         return TRUE ;
00347 }
00348 
00349 
00350 /*
00351  * Translate an array of cnt short integers at sp.
00352  */
00353 bool_t
00354 xdr_shorts(XDR *xdrs, short *sp, u_int cnt)
00355 {
00356         int odd ; /* 1 if cnt is odd, 0 otherwise */
00357 
00358         if(cnt == 0)
00359                 return TRUE ;   /* ? */
00360 
00361         odd = cnt % 2 ;
00362         if(odd) 
00363                 cnt-- ;
00364         /* cnt is even, odd is set if apropos */
00365 
00366         while(cnt > NC_NSHRTS_PER)
00367         {
00368                 if(!NCxdr_shortsb(xdrs, sp, NC_NSHRTS_PER))
00369                         return FALSE ;
00370                 /* else */
00371                 sp += NC_NSHRTS_PER ;
00372                 cnt -= NC_NSHRTS_PER ;
00373         }
00374 
00375         /* we know cnt <= NC_NSHRTS_PER at this point */
00376 
00377         if(cnt != 0)
00378         {
00379                 if(!NCxdr_shortsb(xdrs, sp, cnt))
00380                         return FALSE ;
00381                 /* else */
00382                 sp += cnt ;
00383                 cnt = 0 ;
00384         }
00385 
00386         if(odd)
00387                 if(!xdr_NCvshort(xdrs, 0, sp))
00388                         return FALSE ;
00389 
00390         return TRUE ;
00391 }
00392 
00393 /*
00394  * Use standard xdr interface (plus the netcdf xdr_shorts())
00395  * to encode data to 'buf'
00396  * Returns 0 on success.
00397  */
00398 static int
00399 xdr_encode(char *buf, u_int sz)
00400 {
00401         XDR xdrs[1];
00402         u_int pos;
00403         int ii;
00404 
00405         xdrmem_create(xdrs, buf, sz, XDR_ENCODE);
00406 
00407         if(!xdr_opaque(xdrs, (caddr_t)text, (u_int)sizeof(text)))
00408                 return 1;
00409 
00410         if(!xdr_opaque(xdrs, (caddr_t)schars, (u_int)sizeof(schars)))
00411                 return 2;
00412 
00413         if(!xdr_shorts(xdrs, shorts, uiArraySize(shorts)))
00414                 return 3;
00415 
00416         if(!xdr_vector(xdrs, (char *)ints,
00417                         uiArraySize(ints), eSizeOf(ints),
00418                         (xdrproc_t)xdr_int))
00419                 return 4;
00420 
00421         /* double the ints to check both ncx_ interfaces */
00422         if(!xdr_vector(xdrs, (char *)ints,
00423                         uiArraySize(ints), eSizeOf(ints),
00424                         (xdrproc_t)xdr_int))
00425                 return 5;
00426 
00427 #ifndef NO_UNSIGNED
00428         if(!xdr_vector(xdrs, (char *)u_ints,
00429                         uiArraySize(u_ints), eSizeOf(u_ints),
00430                         (xdrproc_t)xdr_u_int))
00431                 return 6;
00432 #endif
00433 
00434         if(!xdr_vector(xdrs, (char *)longs,
00435                         uiArraySize(longs), eSizeOf(longs),
00436                         (xdrproc_t)xdr_long))
00437                 return 7;
00438 
00439 #ifndef NO_UNSIGNED_LONG
00440         if(!xdr_vector(xdrs, (char *)u_longs,
00441                         uiArraySize(u_longs), eSizeOf(u_longs),
00442                         (xdrproc_t)xdr_u_long))
00443                 return 9;
00444 #endif
00445 
00446         if(!xdr_vector(xdrs, (char *)floats,
00447                         uiArraySize(floats), eSizeOf(floats),
00448                         (xdrproc_t)xdr_float))
00449                 return 10;
00450 
00451         if(!xdr_vector(xdrs, (char *)doubles,
00452                         uiArraySize(doubles), eSizeOf(doubles),
00453                         (xdrproc_t)xdr_double))
00454                 return 11;
00455 
00456         /* mix it up */
00457         for(ii = 1; ii < 5; ii++)
00458         {
00459                 if(
00460                                 !xdr_opaque(xdrs, (caddr_t)text, ii)
00461                                 || !xdr_shorts(xdrs, shorts, ii)
00462                                 || !xdr_opaque(xdrs, (caddr_t)schars, ii)
00463                 )
00464                         return (11 + ii);
00465         }
00466 
00467         /*
00468          * Test non-aligned unit ops used by netcdf.
00469          */
00470 
00471         for(ii = 1; ii < 5; ii++)
00472         {
00473                 pos = xdr_getpos(xdrs);
00474                 if(!xdr_NCvbyte(xdrs, ii, BYTES_PER_XDR_UNIT -ii, &text[ii]))
00475                         return (15 + ii);
00476                 if(!xdr_setpos(xdrs, pos + BYTES_PER_XDR_UNIT))
00477                         return (15 + ii);
00478         }
00479 
00480         for(ii = 1; ii < 5; ii++)
00481         {
00482                 pos = xdr_getpos(xdrs);
00483                 if(!xdr_NCvbyte(xdrs, ii, BYTES_PER_XDR_UNIT -ii,
00484                                 (char *)&schars[ii]))
00485                         return (19 + ii);
00486                 if(!xdr_setpos(xdrs, pos + BYTES_PER_XDR_UNIT))
00487                         return (18 + ii);
00488         }
00489 
00490         for(ii = 1; ii < 3; ii++)
00491         {
00492                 pos = xdr_getpos(xdrs);
00493                 if(!xdr_NCvshort(xdrs, ii%2, &shorts[ii]))
00494                         return (23 + ii);
00495                 if(!xdr_setpos(xdrs, pos + BYTES_PER_XDR_UNIT))
00496                         return (23 + ii);
00497         }
00498 
00499         pos = xdr_getpos(xdrs);
00500         (void) printf("xdr_encode ends at byte %u\n", pos);
00501 
00502         return 0;
00503 }
00504 
00505 
00506 static int
00507 cmp_chars(const char *c1, const char *c2, size_t nchars)
00508 {
00509         int status = 0;
00510         const char *const end = c1 + nchars;
00511 
00512         while(c1 < end)
00513         {
00514                 if(*c1 != *c2)
00515                 {
00516                         (void) fprintf(stderr,
00517                                         "%c != %c char\n",
00518                                         *c1,
00519                                         *c2);
00520                         if(status == 0)
00521                                 status = *c2 < *c1 ? -1 : 1;
00522                 }
00523                 c1++, c2++;
00524         }
00525 
00526         return status;
00527 }
00528 
00529 static int
00530 cmp_schars(const schar *b1, const schar *b2, size_t nbytes)
00531 {
00532         int status = 0;
00533         const schar *const end = b1 + nbytes;
00534 
00535         while(b1 < end)
00536         {
00537                 if(*b1 != *b2)
00538                 {
00539                         (void) fprintf(stderr,
00540                                         "0x%02x != 0x%02x byte\n",
00541                                         (unsigned)(*b1),
00542                                         (unsigned)(*b2));
00543                                 
00544                         if(status == 0)
00545                                 status = *b2 < *b1 ? -1 : 1;
00546                 }
00547                 b1++, b2++;
00548         }
00549 
00550         return status;
00551 }
00552 
00553 static int
00554 cmp_shorts(const short *s1, const short *s2, size_t nshorts)
00555 {
00556         int status = 0;
00557         const short *const end = s1 + nshorts;
00558 
00559         while(s1 < end)
00560         {
00561                 if(*s1 != *s2)
00562                 {
00563                         (void) fprintf(stderr,
00564                                         "0x%04x != 0x%04x (%hd) short\n",
00565                                         (unsigned)(*s1),
00566                                         (unsigned)(*s2), *s2);
00567                         if(status == 0)
00568                                 status = *s2 < *s1 ? -1 : 1;
00569                 }
00570                 s1++, s2++;
00571         }
00572 
00573         return status;
00574 }
00575 
00576 static int
00577 cmp_ints(const int *i1, const int *i2, size_t nints)
00578 {
00579         int status = 0;
00580         const int *const end = i1 + nints;
00581 
00582         while(i1 < end)
00583         {
00584                 if(*i1 != *i2)
00585                 {
00586                         (void) fprintf(stderr,
00587                                         "0x%08x != 0x%08x int\n",
00588                                         (unsigned)(*i1),
00589                                         (unsigned)(*i2));
00590                         if(status == 0)
00591                                 status = *i2 < *i1 ? -1 : 1;
00592                 }
00593                 i1++, i2++;
00594         }
00595 
00596         return status;
00597 }
00598 
00599 #ifndef NO_UNSIGNED
00600 static int
00601 cmp_u_ints(const unsigned int *i1, const unsigned int *i2, size_t nints)
00602 {
00603         int status = 0;
00604         const unsigned int *const end = i1 + nints;
00605 
00606         while(i1 < end)
00607         {
00608                 if(*i1 != *i2)
00609                 {
00610                         (void) fprintf(stderr,
00611                                         "(%u) 0x%08x != 0x%08x (%u) uint\n",
00612                                         *i1, *i1,
00613                                         *i2, *i2);
00614                         if(status == 0)
00615                                 status = *i2 < *i1 ? -1 : 1;
00616                 }
00617                 i1++, i2++;
00618         }
00619 
00620         return status;
00621 }
00622 #endif
00623 
00624 static int
00625 cmp_longs(const long *l1, const long *l2, size_t nlongs)
00626 {
00627         int status = 0;
00628         const long *const end = l1 + nlongs;
00629 
00630         while(l1 < end)
00631         {
00632                 if(*l1 != *l2)
00633                 {
00634                         (void) fprintf(stderr,
00635                                         "0x%016lx != 0x%016lx long\n",
00636                                         (unsigned long)(*l1),
00637                                         (unsigned long)(*l2));
00638                         if(status == 0)
00639                                 status = *l2 < *l1 ? -1 : 1;
00640                 }
00641                 l1++, l2++;
00642         }
00643 
00644         return status;
00645 }
00646 
00647 #ifndef NO_UNSIGNED_LONG
00648 static int
00649 cmp_u_longs(const unsigned long *l1, const unsigned long *l2, size_t nlongs)
00650 {
00651         int status = 0;
00652         const unsigned long *const end = l1 + nlongs;
00653 
00654         while(l1 < end)
00655         {
00656                 if(*l1 != *l2)
00657                 {
00658                         (void) fprintf(stderr,
00659                                         "0x%016lx != 0x%016lx ulong\n",
00660                                         *l1,
00661                                         *l2);
00662                         if(status == 0)
00663                                 status = *l2 < *l1 ? -1 : 1;
00664                 }
00665                 l1++, l2++;
00666         }
00667 
00668         return status;
00669 }
00670 #endif
00671 
00672 static int
00673 cmp_floats(const float *f1, const float *f2, size_t nfloats)
00674 {
00675 #define F_EPS 1.0e-6
00676 
00677         int status = 0;
00678         const float *const end = f1 + nfloats;
00679 
00680         while(f1 < end)
00681         {
00682                 if(*f1 < *f2 && *f2 - *f1 > F_EPS)
00683                 {
00684                         (void) fprintf(stderr,
00685                                         "%.9e != %.9e float (diff %.9e)\n",
00686                                         *f1, *f2, *f1 - *f2);
00687                         if(status == 0)
00688                                 status = 1;
00689                 }
00690                 else if( *f2 < *f1 && *f1 - *f2 > F_EPS)
00691                 {
00692                         (void) fprintf(stderr,
00693                                         "%.9e != %.9e float (diff %.9e)\n",
00694                                         *f1, *f2, *f1 - *f2);
00695                         if(status == 0)
00696                                 status = -1;
00697                 }
00698                 f1++, f2++;
00699         }
00700 
00701         return status;
00702 }
00703 
00704 static int
00705 cmp_doubles(const double *d1, const double *d2, size_t ndoubles)
00706 {
00707 #define D_EPS 1.0e-15
00708 
00709         int status = 0;
00710         const double *const end = d1 + ndoubles;
00711 
00712         while(d1 < end)
00713         {
00714                 if(*d1 < *d2 && *d2 - *d1 > D_EPS)
00715                 {
00716                         (void) fprintf(stderr,
00717                                         "%.17e != %.17e double (diff %.17e)\n",
00718                                         *d1, *d2, *d1 - *d2);
00719                         if(status == 0)
00720                                 status = 1;
00721                 }
00722                 else if( *d2 < *d1 && *d1 - *d2 > D_EPS)
00723                 {
00724                         (void) fprintf(stderr,
00725                                         "%.17e != %.17e double (diff %.17e)\n",
00726                                         *d1, *d2, *d1 - *d2);
00727                         if(status == 0)
00728                                 status = -1;
00729                 }
00730                 d1++, d2++;
00731         }
00732 
00733         return status;
00734 }
00735 
00736 /*
00737  * Verify that data in buf is as encoded
00738  * by xdr_encode() above.
00739  * Returns zero on sucess.
00740  */
00741 static int
00742 xdr_check(char *buf, u_int sz)
00743 {
00744         XDR xdrs[1];
00745         char tbuf[XBSZ];
00746         u_int pos;
00747         int ii;
00748         int jj;
00749 
00750         xdrmem_create(xdrs, buf, sz, XDR_DECODE);
00751 
00752         (void) memset(tbuf, 0, sizeof(text)+4);
00753         if(!xdr_opaque(xdrs, (caddr_t)tbuf, (u_int)sizeof(text))
00754                         || cmp_chars(tbuf, text,
00755                                  sizeof(text)) != 0)
00756                 return 1;
00757 
00758         (void) memset(tbuf, 0, sizeof(schars)+4);
00759         if(!xdr_opaque(xdrs, (caddr_t)tbuf, (u_int)sizeof(schars))
00760                         || cmp_schars((schar *)tbuf, schars,
00761                                 sizeof(schars)) != 0)
00762                 return 2;
00763 
00764         (void) memset(tbuf, 0, sizeof(shorts)+4);
00765         if(!xdr_shorts(xdrs, (short *)tbuf, uiArraySize(shorts))
00766                         || cmp_shorts((short *)tbuf, shorts,
00767                                  ArraySize(shorts)) != 0)
00768                 return 3;
00769 
00770         (void) memset(tbuf, 0, sizeof(ints)+4);
00771         if(!xdr_vector(xdrs, tbuf,
00772                 uiArraySize(ints), eSizeOf(ints),
00773                 (xdrproc_t)xdr_int)
00774                         || cmp_ints((int *)tbuf, ints,
00775                                  ArraySize(ints)) != 0)
00776                 return 4;
00777 
00778         /* double the ints to check both ncx_ interfaces */
00779         (void) memset(tbuf, 0, sizeof(ints)+4);
00780         if(!xdr_vector(xdrs, tbuf,
00781                 uiArraySize(ints), eSizeOf(ints),
00782                 (xdrproc_t)xdr_int)
00783                         || cmp_ints((int *)tbuf, ints,
00784                                  ArraySize(ints)) != 0)
00785                 return 5;
00786 
00787 #ifndef NO_UNSIGNED
00788         (void) memset(tbuf, 0, sizeof(u_ints)+4);
00789         if(!xdr_vector(xdrs, tbuf,
00790                 uiArraySize(u_ints), eSizeOf(u_ints),
00791                 (xdrproc_t)xdr_u_int)
00792                         || cmp_u_ints((unsigned int *)tbuf, u_ints,
00793                                 ArraySize(u_ints)) != 0)
00794                 return 6;
00795 #endif
00796 
00797         (void) memset(tbuf, 0, sizeof(longs)+4);
00798         if(!xdr_vector(xdrs, tbuf,
00799                 uiArraySize(longs), eSizeOf(longs), (xdrproc_t)xdr_long)
00800                         || cmp_longs((long *)tbuf, longs,
00801                                  ArraySize(longs)) != 0)
00802                 return 7;
00803 
00804 #ifndef NO_UNSIGNED_LONG
00805         (void) memset(tbuf, 0, sizeof(u_longs)+4);
00806         if(!xdr_vector(xdrs, tbuf,
00807                 uiArraySize(u_longs), eSizeOf(u_longs), (xdrproc_t)xdr_u_long)
00808                         || cmp_u_longs((unsigned long *)tbuf, u_longs,
00809                                 ArraySize(u_longs)) != 0)
00810                 return 9;
00811 #endif
00812 
00813         (void) memset(tbuf, 0, sizeof(floats)+4);
00814         if(!xdr_vector(xdrs, tbuf,
00815                 uiArraySize(floats), eSizeOf(floats), (xdrproc_t)xdr_float)
00816                         || cmp_floats((float *)tbuf, floats,
00817                                  ArraySize(floats)) != 0)
00818                 return 10;
00819 
00820         (void) memset(tbuf, 0, sizeof(doubles)+4);
00821         if(!xdr_vector(xdrs, tbuf,
00822                 uiArraySize(doubles), eSizeOf(doubles), (xdrproc_t)xdr_double)
00823                         || cmp_doubles((double *)tbuf, doubles,
00824                                  ArraySize(doubles)) != 0)
00825                 return 11;
00826 
00827         for(ii = 1; ii < 5; ii++)
00828         {
00829                 char tx[4];
00830                 short sh[4];
00831                 schar by[4];
00832                 if(
00833                                 !xdr_opaque(xdrs, (caddr_t)tx, ii)
00834                                 || !xdr_shorts(xdrs, sh, ii)
00835                                 || !xdr_opaque(xdrs, (caddr_t)by, ii)
00836                 )
00837                         return (11 + ii);
00838                 for(jj = 0; jj < ii; jj++)
00839                 {
00840                         if(tx[jj] != text[jj])
00841                         {
00842                                 (void) fprintf(stderr, "\txdr %c != %c text[%d]\n",
00843                                                 tx[jj], text[jj], jj);
00844                                 return (11 + ii);
00845                         }
00846                         /* else */
00847                         if(sh[jj] != shorts[jj])
00848                         {
00849                                 (void) fprintf(stderr, "\txdr %hd != %hd shorts[%d]\n",
00850                                                 sh[jj], shorts[jj], jj);
00851                                 return (11 + ii);
00852                         }
00853                         /* else */
00854                         if(by[jj] != schars[jj])
00855                         {
00856                                 (void) fprintf(stderr,
00857                                         "\txdr 0x%02x != 0x%02x schars[%d]\n",
00858                                                 (unsigned) by[jj],
00859                                                 (unsigned) schars[jj], jj);
00860                                 return (11 + ii);
00861                         }
00862                         /* else */
00863                 }
00864         }
00865 
00866         /*
00867          * Test non-aligned unit ops used by netcdf.
00868          */
00869 
00870         for(ii = 1; ii < 5; ii++)
00871         {
00872                 pos = xdr_getpos(xdrs);
00873                 (void) memset(tbuf, 0, BYTES_PER_XDR_UNIT);
00874                 if(!xdr_NCvbyte(xdrs, ii, BYTES_PER_XDR_UNIT -ii, tbuf)
00875                                 || cmp_chars(&text[ii], tbuf,
00876                                         BYTES_PER_XDR_UNIT -ii) != 0)
00877                         return (15 + ii);
00878                 if(!xdr_setpos(xdrs, pos + BYTES_PER_XDR_UNIT))
00879                         return (15 + ii);
00880         }
00881 
00882         for(ii = 1; ii < 5; ii++)
00883         {
00884                 pos = xdr_getpos(xdrs);
00885                 (void) memset(tbuf, 0, BYTES_PER_XDR_UNIT);
00886                 if(!xdr_NCvbyte(xdrs, ii, BYTES_PER_XDR_UNIT -ii, tbuf)
00887                                 || cmp_schars((schar *)tbuf, &schars[ii],
00888                                         BYTES_PER_XDR_UNIT -ii) != 0)
00889                         return (19 + ii);
00890                 if(!xdr_setpos(xdrs, pos + BYTES_PER_XDR_UNIT))
00891                         return (19 + ii);
00892         }
00893 
00894         for(ii = 1; ii < 3; ii++)
00895         {
00896                 pos = xdr_getpos(xdrs);
00897                 (void) memset(tbuf, 0, BYTES_PER_XDR_UNIT);
00898                 if(!xdr_NCvshort(xdrs, ii%2, (short *)tbuf)
00899                                 || cmp_shorts((short *)tbuf, &shorts[ii], 1))
00900                         return (23 + ii);
00901                 if(!xdr_setpos(xdrs, pos + BYTES_PER_XDR_UNIT))
00902                         return (23 + ii);
00903         }
00904 
00905         pos = xdr_getpos(xdrs);
00906         (void) printf("xdr_check  ends at byte %u\n", pos);
00907 
00908         return 0;
00909 }
00910 
00911 
00912 /* Poor man's template */
00913 #define NCX_VEC(xpp, nn, vecp, TYPE, proc, step) \
00914 { \
00915 \
00916         size_t nelems = (nn); \
00917         TYPE *elemp = (vecp); \
00918 \
00919         while(nelems != 0) \
00920         { \
00921                 status = (proc)((*(xpp)), elemp); \
00922                 if(status != ENOERR) \
00923                         break; \
00924                 (*(xpp)) = (void *)((char *)(*(xpp)) + (step)); \
00925                 elemp ++; \
00926                 nelems--; \
00927         } \
00928 }
00929 
00930 
00931 /*
00932  * Use ncx interface
00933  * to encode data to 'buf'
00934  * Returns zero on success.
00935  */
00936 static int
00937 ncx_encode(char *buf)
00938 {
00939         int status = ENOERR;
00940 
00941         void *vp = buf;
00942         int ii;
00943 
00944         if(ncx_pad_putn_text(&vp, sizeof(text), text))
00945                 return 1;
00946 
00947         if(ncx_pad_putn_schar_schar(&vp, sizeof(schars), schars))
00948                 return 2;
00949 
00950         if(ncx_pad_putn_short_short(&vp, ArraySize(shorts), shorts))
00951                 return 3;
00952 
00953         if(ncx_putn_int_int(&vp, ArraySize(ints), ints))
00954                 return 4;
00955 
00956         NCX_VEC(&vp, ArraySize(ints), ints,
00957                         int, ncx_put_int_int, X_SIZEOF_INT);
00958         if(status != ENOERR)
00959                 return 5;
00960 
00961 #ifndef NO_UNSIGNED
00962         NCX_VEC(&vp, ArraySize(u_ints), u_ints,
00963                         unsigned int, ncx_put_uint_uint, X_SIZEOF_INT);
00964         if(status != ENOERR)
00965                 return 6;
00966 #endif
00967 
00968         if(ncx_putn_int_long(&vp, ArraySize(longs), longs))
00969                 return 7;
00970 
00971 #ifndef NO_UNSIGNED_LONG
00972         NCX_VEC(&vp, ArraySize(u_longs), u_longs,
00973                         unsigned long, ncx_put_ulong_ulong, X_SIZEOF_LONG);
00974         if(status != ENOERR)
00975                 return 9;
00976 #endif
00977 
00978         if(ncx_putn_float_float(&vp, ArraySize(floats), floats))
00979                 return 10;
00980 
00981         if(ncx_putn_double_double(&vp, ArraySize(doubles), doubles))
00982                 return 11;
00983 
00984         /* mix it up */
00985         for(ii = 1; ii < 5; ii++)
00986         {
00987                 if(
00988                                 ncx_pad_putn_text(&vp, ii, text)
00989                                 || ncx_pad_putn_short_short(&vp, ii, shorts)
00990                                 || ncx_pad_putn_schar_schar(&vp, ii, schars)
00991                 )
00992                         return (11 + ii);
00993         }
00994 
00995         /*
00996          * Test non-aligned unit ops used by netcdf.
00997          */
00998 
00999         for(ii = 1; ii < 5; ii++)
01000         {
01001                 vp = (char *)vp + ii;
01002                 if(ncx_putn_text(&vp, X_ALIGN - ii, &text[ii]))
01003                         return (15 + ii);
01004         }
01005 
01006         for(ii = 1; ii < 5; ii++)
01007         {
01008                 vp = (char *)vp + ii;
01009                 if(ncx_putn_schar_schar(&vp, X_ALIGN - ii, &schars[ii]))
01010                         return (19 + ii);
01011         }
01012 
01013         for(ii = 1; ii < 3; ii++)
01014         {
01015                 char *pos = vp;
01016                 vp = (char *)vp + (ii%2) * 2;
01017                 if(ncx_putn_short_short(&vp, 1, &shorts[ii]))
01018                         return (23 + ii);
01019                 vp = pos + X_ALIGN;
01020         }
01021 
01022         (void) printf("ncx_encode ends at byte %u\n",
01023                  (unsigned)(((char *)vp) - buf));
01024 
01025         return 0;
01026 }
01027 
01028 /* 
01029  * Verify the ncx_getn_xxx() routines.
01030  * Returns zero on success.
01031  */
01032 static int
01033 ncx_check(char *buf)
01034 {
01035         int status = ENOERR;
01036         const void *vp = buf;
01037         char tbuf[XBSZ];
01038         int ii;
01039         int jj;
01040 
01041         (void) memset(tbuf, 0, sizeof(text)+4);
01042         if(ncx_pad_getn_text(&vp, sizeof(text), tbuf)
01043                         || cmp_chars(tbuf, text,
01044                                  sizeof(text)) != 0)
01045                 return 1;
01046 
01047         (void) memset(tbuf, 0, sizeof(schars)+4);
01048         if(ncx_pad_getn_schar_schar(&vp, sizeof(schars), (schar *)tbuf)
01049                         || cmp_schars((schar *)tbuf, schars,
01050                                  sizeof(schars)) != 0)
01051                 return 2;
01052 
01053         (void) memset(tbuf, 0, sizeof(shorts)+4);
01054         if(ncx_pad_getn_short_short(&vp, ArraySize(shorts), (short *)tbuf)
01055                         || cmp_shorts((short *)tbuf, shorts,
01056                                  ArraySize(shorts)) != 0)
01057                 return 3;
01058 
01059         (void) memset(tbuf, 0, sizeof(ints)+4);
01060         if(ncx_getn_int_int(&vp, ArraySize(ints), (int *)tbuf)
01061                         || cmp_ints((int *)tbuf, ints,
01062                                  ArraySize(ints)) != 0)
01063                 return 4;
01064 
01065         (void) memset(tbuf, 0, sizeof(ints)+4);
01066         NCX_VEC(&vp, ArraySize(ints), (int *)tbuf,
01067                                 int, ncx_get_int_int, X_SIZEOF_INT);
01068         if(status != ENOERR
01069                         || cmp_ints((int *)tbuf, ints,
01070                                  ArraySize(ints)) != 0)
01071                 return 5;
01072 
01073 #ifndef NO_UNSIGNED
01074         (void) memset(tbuf, 0, sizeof(u_ints)+4);
01075         NCX_VEC(&vp, ArraySize(u_ints), (unsigned int *)tbuf,
01076                                 unsigned, ncx_get_uint_uint, X_SIZEOF_INT);
01077         if(status != ENOERR
01078                         || cmp_u_ints((unsigned int *)tbuf, u_ints,
01079                                  ArraySize(u_ints)) != 0)
01080                 return 6;
01081 #endif
01082 
01083         (void) memset(tbuf, 0, sizeof(longs)+4);
01084         if(ncx_getn_int_long(&vp, ArraySize(longs), (long *)tbuf)
01085                         || cmp_longs((long *)tbuf, longs,
01086                                  ArraySize(longs)) != 0)
01087                 return 7;
01088 
01089 #ifndef NO_UNSIGNED_LONG
01090         (void) memset(tbuf, 0, sizeof(u_longs)+4);
01091         NCX_VEC(&vp, ArraySize(u_longs), (unsigned long *)tbuf,
01092                         unsigned long, ncx_get_ulong_ulong, X_SIZEOF_LONG);
01093         if(status != ENOERR
01094                         || cmp_u_longs((unsigned long *)tbuf, u_longs,
01095                                 ArraySize(u_longs)) != 0)
01096                 return 9;
01097 #endif
01098 
01099         (void) memset(tbuf, 0, sizeof(floats)+4);
01100         if(ncx_getn_float_float(&vp, ArraySize(floats), (float *)tbuf)
01101                         || cmp_floats((float *)tbuf, floats,
01102                                  ArraySize(floats)) != 0)
01103                 return 10;
01104 
01105         (void) memset(tbuf, 0, sizeof(doubles)+4);
01106         if(ncx_getn_double_double(&vp, ArraySize(doubles), (double *)tbuf)
01107                         || cmp_doubles((double *)tbuf, doubles,
01108                                  ArraySize(doubles)) != 0)
01109                 return 11;
01110 
01111         for(ii = 1; ii < 5; ii++)
01112         {
01113                 char tx[4];
01114                 short sh[4];
01115                 schar by[4];
01116                 if(
01117                                 ncx_pad_getn_text(&vp, ii, tx)
01118                                 || ncx_pad_getn_short_short(&vp, ii, sh)
01119                                 || ncx_pad_getn_schar_schar(&vp, ii, by)
01120                 )
01121                         return (11 + ii);
01122                 for(jj = 0; jj < ii; jj++)
01123                 {
01124                         if(tx[jj] != text[jj])
01125                         {
01126                                 (void) fprintf(stderr,
01127                                         "\tncx %c != %c text[%d]\n",
01128                                                 tx[jj], text[jj], jj);
01129                                 return (11 + ii);
01130                         }
01131                         /* else */
01132                         if(sh[jj] != shorts[jj])
01133                         {
01134                                 (void) fprintf(stderr,
01135                                          "\tncx %hd != %hd shorts[%d]\n",
01136                                                 sh[jj], shorts[jj], jj);
01137                                 return (11 + ii);
01138                         }
01139                         /* else */
01140                         if((unsigned)by[jj] != (unsigned)schars[jj])
01141                         {
01142                                 (void) fprintf(stderr,
01143                                         "\tncx 0x%02x != 0x%02x schars[%d] %d\n",
01144                                                 by[jj], schars[jj], jj, ii);
01145                                 return (11 + ii);
01146                         }
01147                 }
01148         }
01149 
01150         /*
01151          * Test non-aligned unit ops used by netcdf.
01152          */
01153 
01154         for(ii = 1; ii < 5; ii++)
01155         {
01156                 (void) memset(tbuf, 0, X_ALIGN);
01157                 vp = (char *)vp + ii;
01158                 if(ncx_getn_text(&vp, X_ALIGN -ii, tbuf)
01159                                 || cmp_chars(tbuf, &text[ii],
01160                                          X_ALIGN -ii) != 0)
01161                         return (15 + ii);
01162         }
01163 
01164         for(ii = 1; ii < 5; ii++)
01165         {
01166                 (void) memset(tbuf, 0, X_ALIGN);
01167                 vp = (char *)vp + ii;
01168                 if(ncx_getn_schar_schar(&vp, X_ALIGN -ii, (schar *)tbuf)
01169                                 || cmp_schars((schar *)tbuf, &schars[ii],
01170                                          X_ALIGN -ii) != 0)
01171                         return (19 + ii);
01172         }
01173 
01174         for(ii = 1; ii < 3; ii++)
01175         {
01176                 const char *pos = vp;
01177                 (void) memset(tbuf, 0, X_ALIGN);
01178                 vp = (char *)vp + (ii%2) *2;
01179                 if(ncx_getn_short_short(&vp, 1, (short *)tbuf)
01180                                 || cmp_shorts((short *)tbuf, &shorts[ii],
01181                                          1) != 0)
01182                         return (23 + ii);
01183                 vp = pos + X_ALIGN;
01184         }
01185 
01186         (void) printf("ncx_check  ends at byte %u\n",
01187                  (unsigned)(((char *)vp) - buf));
01188 
01189 
01190         return 0;
01191 }
01192 
01193 
01194 int
01195 main(int ac, char *av[])
01196 {
01197         int status;
01198 
01199         status = xdr_encode(xdrb, sizeof(xdrb));
01200         if(status)
01201         {
01202                 (void) fprintf(stderr,
01203                          "xdr_encode failed %d\n", status);
01204                 return 1;
01205         }
01206 
01207         status = xdr_check(xdrb, sizeof(xdrb));
01208         if(status)
01209         {
01210                 (void) fprintf(stderr,
01211                          "xdr_check of xdrb failed %d\n", status);
01212                 return 1;
01213         }
01214 
01215         status = ncx_encode(ncxb);
01216         if(status)
01217         {
01218                 (void) fprintf(stderr,
01219                          "ncx_encode failed %d\n", status);
01220                 return 1;
01221         }
01222 
01223         /* cross check */
01224         status = xdr_check(ncxb, sizeof(ncxb));
01225         if(status)
01226         {
01227                 (void) fprintf(stderr,
01228                          "xdr_check of ncxb failed %d\n", status);
01229                 return 1;
01230         }
01231 
01232         status = ncx_check(xdrb);
01233         if(status)
01234         {
01235                 (void) fprintf(stderr,
01236                          "ncx_check of xdrb failed %d\n", status);
01237                 return 1;
01238         }
01239 
01240         status = ncx_check(ncxb);
01241         if(status)
01242         {
01243                 (void) fprintf(stderr,
01244                          "ncx_check of ncxb failed %d\n", status);
01245                 return 1;
01246         }
01247 
01248         return 0;
01249 }
 

Powered by Plone

This site conforms to the following standards: