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  

realtime.c

Go to the documentation of this file.
00001 
00002 #include <stdio.h>
00003 #include <math.h>
00004 
00005 #include "thd_iochan.h"
00006 #include "Imon.h"
00007 #include "realtime.h"
00008 
00009 extern ART_comm  gAC;
00010 
00011 /* maybe we will want this elsewhere at some point */
00012 static char orient_side_rai( float coord, char dir );
00013 
00014 /*----------------------------------------------------------------------
00015  * history:  see 'Imon -hist'
00016  *----------------------------------------------------------------------
00017 */
00018 
00019 /************************************************************************/
00020 /*******   This file was based on rtfeedme.c and rtread.c (with   *******/
00021 /*******   many thanks to R.W. Cox and R. Birn).  It is for use   *******/
00022 /*******   as an optional part of Imon.                           *******/
00023 /************************************************************************/
00024 
00025 /*****************************************************************************
00026   Do I/O startup stuff.
00027 
00028   At any given moment, this routine is in one of a number of modes
00029   (the AFNI_mode variable).
00030   The first time in, AFNI_mode == AFNI_OPEN_CONTROL_MODE.  In each mode,
00031   certain tasks must be accomplished and this program must be synchronized
00032   with AFNI.  When the necessary deeds are done, the routine advances to
00033   the next mode.  If the deeds cannot be done when this routine is called,
00034   then it will stay in the same mode, and the next time it is called it
00035   will try to do them again.  This routine should be called repeatedly
00036   until it progresses to the last mode (AFNI_CONTINUE_MODE), which is for
00037   normal transmission of images (one at a time) to AFNI.
00038 
00039   If an error occurs, so that this program can no longer talk to AFNI, then
00040   AFNI_mode is set to 0, which means "do nothing further".  The rest of
00041   the data acquisition software will continue, but these routines will
00042   be stopped dead.
00043 ******************************************************************************/
00044 
00045 /*****************************************************************************/
00046 int ART_start_io( ART_comm * ac, int debug )
00047 /*****************************************************************************/
00048 {
00049    int ii ;
00050 
00051    /***** Check for illegal conditions *****/
00052 
00053    if( ac->mode <= 0 || ac->mode == AFNI_CONTINUE_MODE ) return 0 ;
00054 
00055    /***** If we are at the first time in,
00056           try to open a control socket to talk to AFNI *****/
00057 
00058    if( ac->mode == AFNI_OPEN_CONTROL_MODE ){
00059 
00060       sprintf( ac->ioc_name , "tcp:%s:%d" , ac->host , AFNI_CONTROL_PORT ) ;
00061 
00062       if( debug > 1 )
00063          fprintf(stderr,"Opening control channel %s to AFNI.\n",ac->ioc_name) ;
00064 
00065       ac->ioc = iochan_init( ac->ioc_name , "w" ) ;
00066 
00067       if( ac->ioc == NULL ){
00068          fprintf(stderr,"Can't open control channel %s to AFNI!\a\n",
00069                  ac->ioc_name) ;
00070          return -1;
00071       } else {
00072          if( debug > 1 )
00073              fprintf(stderr,"Entering AFNI_WAIT_CONTROL_MODE.\n") ;
00074 
00075          /* begin waiting for AFNI connection */
00076          ac->mode = AFNI_WAIT_CONTROL_MODE ;
00077       }
00078    }
00079 
00080    /***** Check if the control socket is connected to AFNI *****/
00081 
00082    if( ac->mode == AFNI_WAIT_CONTROL_MODE ){
00083 
00084       ii = iochan_writecheck( ac->ioc , 1 ) ;  /* Check; wait at most 1 msec */
00085 
00086       /** if ii == 0, then the channel is still pending,
00087           so do nothing; otherwise, take some action.    **/
00088 
00089       if( ii < 0 ){
00090          fprintf(stderr,"Control channel to AFNI failed!\n") ;
00091          IOCHAN_CLOSENOW(ac->ioc) ;
00092          ac->mode = 0 ;                    /* disable AFNI */
00093          return -1;
00094       } else if( ii > 0 ){
00095          if( debug > 1 )
00096          {
00097             fprintf(stderr,"Control channel connected to AFNI.");
00098             fprintf(stderr,"  Entering AFNI_OPEN_DATA_MODE.\n") ;
00099          }
00100 
00101          ac->mode = AFNI_OPEN_DATA_MODE ;  /* prepare to send data to AFNI */
00102       }
00103    }
00104 
00105    /***** Send the control information, which says
00106           how we will talk to AFNI in the future (shmem or TCP/IP),
00107           then close the control channel and open this new data channel *****/
00108 
00109    if( ac->mode == AFNI_OPEN_DATA_MODE ){
00110 
00111       /* decide name of data channel: it can be TCP/IP or shared memory */
00112 
00113       if ( ac->use_tcp )
00114          sprintf(ac->ioc_name,"tcp:%s:%d",ac->host,AFNI_TCP_PORT) ;
00115 
00116       strcpy(ac->buf, ac->ioc_name) ;     /* tell AFNI where to read data */
00117 
00118       if( debug > 1 )
00119          fprintf(stderr,"Sending control information to AFNI:\n%s\n",ac->buf) ;
00120 
00121       ii = iochan_sendall( ac->ioc , ac->buf , strlen(ac->buf)+1 ) ;
00122 
00123       /** A negative return is bad news **/
00124 
00125       if( ii < 0 ){
00126          fprintf(stderr,"Transmission of control data to AFNI failed!\a\n") ;
00127          IOCHAN_CLOSENOW(ac->ioc) ;
00128          ac->mode = 0 ;
00129          return -1;
00130       } else {
00131          /* wait for control data to clear */
00132          while( ! iochan_clearcheck(ac->ioc,2) )
00133             iochan_sleep(2) ;
00134          IOCHAN_CLOSENOW(ac->ioc) ;                 /* close control channel */
00135 
00136          if( debug > 1 )
00137             fprintf(stderr,"Opening data channel %s to AFNI.\n",ac->ioc_name) ;
00138 
00139          ac->ioc = iochan_init( ac->ioc_name , "w" ) ; /* open data channel */
00140          if( ac->ioc == NULL ){
00141             fprintf(stderr,"Can't open data channel %s to AFNI!\a\n",
00142                     ac->ioc_name) ;
00143             ac->mode = 0 ;
00144             return -1;
00145          } else {
00146             if( debug > 1 ) fprintf(stderr,"Entering AFNI_CATCHUP_MODE.\n") ;
00147             ac->mode = AFNI_CATCHUP_MODE ;
00148          }
00149       }
00150    }
00151 
00152    /***** Wait for the data channel to be connected to AFNI,
00153           and then send any images that are reconstructed and ready to go *****/
00154 
00155    if( ac->mode == AFNI_CATCHUP_MODE ){
00156 
00157       ii = iochan_writecheck( ac->ioc , 1 ) ;  /* wait at most 1 msec */
00158       if( ii < 0 ){
00159          fprintf(stderr,
00160                  "AFNI data channel aborted before any data was sent!\a\n") ;
00161          IOCHAN_CLOSENOW(ac->ioc) ;
00162          ac->mode = 0 ;
00163          return -1;
00164       } else if( ii > 0 ){                      /* can now send data to AFNI! */
00165          ac->mode = AFNI_CONTINUE_MODE ;
00166 
00167         if ( debug > 1 )
00168             fprintf(stderr,"Entering AFNI_CONTINUE_MODE.\n");
00169       }
00170    }
00171 
00172    return 0;
00173 }
00174 
00175 /*----------------------------------------------------------------------
00176  * note the end of a run
00177  *
00178  * If the (run,seq) pair is new, send a message to afni.
00179  * There is image space in x_im.
00180  *----------------------------------------------------------------------
00181 */
00182 int ART_send_end_of_run( ART_comm * ac, int run, int seq, int debug )
00183 {
00184     static int   prev_run = -1;
00185     static int   prev_seq = -1;
00186     char       * image;
00187 
00188     if ( ac->state != ART_STATE_IN_USE )
00189         return 0;
00190 
00191     if ( (run != prev_run) || (seq != prev_seq) )
00192     {
00193         prev_run = run;
00194         prev_seq = seq;
00195 
00196         image = (char *)ac->param->im_store.x_im;
00197 
00198         if ( image == NULL )
00199         {
00200             fprintf( stderr, "** failure: x_im is NULL\n"
00201                              "   - closing afni connection\n" );
00202 
00203             ac->state = ART_STATE_NO_USE;
00204             ART_exit();
00205             return -1;
00206         }
00207 
00208         strcpy( image, ART_COMMAND_MARKER );
00209         image[ART_COMMAND_MARKER_LEN] = '\0';
00210 
00211         if ( iochan_sendall( ac->ioc, image, ac->param->im_store.im_size ) < 0 )
00212         {
00213             fprintf( stderr, "** failed to transmit EOR to afni @ %s\n"
00214                              "   - closing afni connection\n", ac->host );
00215 
00216             ac->state = ART_STATE_NO_USE;
00217             ART_exit();
00218             return -1;
00219         }
00220 
00221         if ( debug > 1 )
00222             fprintf( stderr, "-- EOR: end of run signal (%d,%d)\n", run, seq );
00223 
00224         /* we will need to send new control info to afni */
00225         ac->state = ART_STATE_TO_SEND_CTRL;
00226 
00227         iochan_sleep(50);                         /* give afni some time    */
00228 
00229         return 1;
00230     }
00231 
00232     return 0;
00233 }
00234 
00235 
00236 /*----------------------------------------------------------------------
00237  * send a volume to afni
00238  *----------------------------------------------------------------------
00239 */
00240 int ART_send_volume( ART_comm * ac, vol_t * v, int debug )
00241 {
00242     char * image;
00243     int    slice, bytes;
00244 
00245     if ( ac == NULL || v == NULL )
00246     {
00247         fprintf( stderr, "failure: ASV called with invalid arguments!\n" );
00248         return -1;
00249     }
00250 
00251     if ( ac->state != ART_STATE_IN_USE )
00252         return 0;
00253 
00254     /* send one complete volume */
00255 
00256     bytes = ac->param->im_store.im_size;
00257 
00258     for ( slice = 0; slice < v->nim; slice++ )
00259     {
00260         image = (char *)ac->param->im_store.im_ary[v->fl_1 + slice];
00261 
00262         if ( ac->swap )              /* maybe we must swap the bytes first */
00263             swap_2( image, bytes/2 );
00264 
00265         if ( iochan_sendall( ac->ioc, image, bytes ) < 0 )
00266         {
00267             fprintf( stderr, "** failed to transmit data to afni @ %s\n"
00268                              "   - closing afni connection\n", ac->host );
00269 
00270             ac->state = ART_STATE_NO_USE;
00271             ART_exit();
00272             return -1;
00273         }
00274     }
00275 
00276     if ( debug > 2 )
00277         fprintf( stderr, "++ sent images from volume (%d:%d) to host %s\n",
00278                  v->run, v->seq_num, ac->host );
00279 
00280     return 0;
00281 }
00282 
00283 
00284 /*----------------------------------------------------------------------
00285  *
00286  *----------------------------------------------------------------------
00287 */
00288 int ART_open_afni_link( ART_comm * ac, int num_tries, int again, int debug )
00289 {
00290     int rv = 0, count;
00291 
00292     if ( ac == NULL )
00293         return -1;
00294 
00295     if ( debug > 1 )
00296         fprintf( stderr, "-- starting I/O to afni\n" );
00297 
00298     if ( ac->state != ART_STATE_TO_OPEN )
00299         return 0;
00300 
00301     for ( count = 0;
00302           (count < num_tries) && (rv == 0) && (ac->mode != AFNI_CONTINUE_MODE);
00303           count++ )
00304     {
00305         rv = ART_start_io( ac, debug );
00306         iochan_sleep(100);              /* even on success, give afni time */
00307     }
00308 
00309     if ( ac->mode == AFNI_CONTINUE_MODE )       /* afni comm is ready! */
00310     {
00311         if ( debug > 0 )
00312             fprintf( stderr, "++ comm link to afni established at <%s>\n",
00313                      ac->host );
00314         ac->state = ART_STATE_TO_SEND_CTRL;
00315     }
00316     else if ( (rv == 0) && again )
00317     {
00318         if ( debug > 0 )
00319         {
00320             fprintf( stderr, "** failed to connect to afni at '%s' - "
00321                      "will try again later\n", ac->host );
00322         }
00323     }
00324     else                        /* bad news - give up on afni communication */
00325     {
00326         fprintf( stderr, "** failed to connect to afni at '%s' - "
00327                  "GIVING UP!\n", ac->host );
00328         ac->state = ART_STATE_NO_USE;
00329     }
00330 
00331     return rv;
00332 }
00333 
00334 
00335 /*----------------------------------------------------------------------
00336  * initialize the AFNI communication struct
00337  *----------------------------------------------------------------------
00338 */
00339 int ART_init_AC_struct( ART_comm * ac )
00340 {
00341     if ( ac == NULL )
00342         return -1;
00343 
00344     ac->state       = ART_STATE_NO_USE;
00345     ac->mode        = 0;
00346     ac->use_tcp     = 1;
00347     ac->swap        = 0;
00348     ac->zorder      = NULL;
00349     strcpy( ac->host, "localhost" );
00350     ac->ioc_name[0] = '\0';
00351     ac->ioc         = NULL;
00352     ac->param       = NULL;
00353 
00354     return 0;
00355 }
00356 
00357 
00358 /*----------------------------------------------------------------------
00359  * send image control information to afni
00360  *----------------------------------------------------------------------
00361 */
00362 int ART_send_control_info( ART_comm * ac, vol_t * v, int debug )
00363 {
00364     char tbuf[ART_TBUF_LEN];          /* temporary buffer for adding to buf */
00365     int  rv;
00366 
00367     if ( (ac == NULL) || (v == NULL) )
00368     {
00369         fprintf( stderr, "failure: ASCI called with invalid parameters\n" );
00370         ac->state = ART_STATE_NO_USE;
00371         return -1;
00372     }
00373 
00374     if ( (ac->state != ART_STATE_TO_SEND_CTRL) ||
00375          (ac->mode  != AFNI_CONTINUE_MODE) )
00376         return 0;
00377 
00378     ac->buf[0] = '\0';                      /* init message buffer to empty */
00379 
00380     /* data organization style */
00381     strcpy( tbuf, "ACQUISITION_TYPE 2D+zt" );
00382     ART_ADD_TO_BUF( ac->buf, tbuf );
00383 
00384     /* slice order */
00385     if ( ac->zorder )
00386         sprintf( tbuf, "ZORDER %s", ac->zorder);
00387     else
00388         strcpy( tbuf, "ZORDER seq" );   /* back to seq for now  [v3.3 rickr] */
00389     ART_ADD_TO_BUF( ac->buf, tbuf );
00390 
00391     /* timing pattern, this may also come from image files - rcr */
00392     if ( ac->param->opts.sp )
00393     {
00394         sprintf( tbuf, "TPATTERN %s", ac->param->opts.sp );
00395         ART_ADD_TO_BUF( ac->buf, tbuf );
00396     }
00397 
00398     /* volume time step */
00399     sprintf( tbuf, "TR %f", v->geh.tr );
00400     ART_ADD_TO_BUF( ac->buf, tbuf );
00401 
00402     /* volume dimensions */
00403     sprintf( tbuf, "XYFOV %f %f %f", fabs(v->geh.nx * v->geh.dx),
00404                                      fabs(v->geh.ny * v->geh.dy),
00405                                      fabs(v->nim    * v->z_delta) );
00406     ART_ADD_TO_BUF( ac->buf, tbuf );
00407 
00408     /* matrix sizes */
00409     sprintf( tbuf, "XYMATRIX %d %d %d", v->geh.nx, v->geh.ny, v->nim );
00410     ART_ADD_TO_BUF( ac->buf, tbuf );
00411 
00412     /* data type - no mrilib.h, and don't duplicate MRI_TYPE_name list */
00413     strcpy( tbuf, "DATUM short" );
00414     ART_ADD_TO_BUF( ac->buf, tbuf );
00415 
00416     /* axes orientations */
00417     sprintf( tbuf, "XYZAXES %c-%c %c-%c %c-%c",
00418                            v->geh.orients[0], v->geh.orients[1],
00419                            v->geh.orients[2], v->geh.orients[3],
00420                            v->geh.orients[4], v->geh.orients[5] );
00421     ART_ADD_TO_BUF( ac->buf, tbuf );
00422 
00423     /* volume offsets                          2003 June 25 [rickr] */
00424     /* now, base on param->ftype               2005 May  16 [rickr] */
00425     if( ac->param->ftype == IFM_IM_FTYPE_GEMS5 )
00426     {
00427         char o0 = v->geh.orients[0];    /* for ease of typing later */
00428         char o2 = v->geh.orients[2];
00429         char o4 = v->geh.orients[4];
00430         int  sx, sy, sz;                /* directional sign values  */
00431 
00432         /* Note - the LPI directions are negatives in GEMS 5.x files, */
00433         /*        so when one of those is the origin, negate it.      */
00434 
00435         /* rcr - this must rely on 0,0,0 being within the volume - fix it */
00436 
00437         /* just note o_i directions in s_i */
00438         if ( o0 == 'L' || o0 == 'P' || o0 == 'I' ) sx = -1; else sx = 1;
00439         if ( o2 == 'L' || o2 == 'P' || o2 == 'I' ) sy = -1; else sy = 1;
00440         if ( o4 == 'L' || o4 == 'P' || o4 == 'I' ) sz = -1; else sz = 1;
00441 
00442         /* note - we do not use a dz/2 offset, as we have slice locations */
00443         sprintf(tbuf,"XYZFIRST %f %f %f",
00444             sx * v->gex.xorg - v->geh.dx/2.0,
00445             sy * v->gex.yorg - v->geh.dy/2.0,
00446             sz * v->z_first );
00447 
00448         ART_ADD_TO_BUF( ac->buf, tbuf );
00449     }
00450     else if( ac->param->ftype == IFM_IM_FTYPE_DICOM )  /* 16 May 2005 */
00451     {
00452         char o0 = v->geh.orients[0];    /* for ease of typing later */
00453         char o2 = v->geh.orients[2];
00454         char o4 = v->geh.orients[4];
00455 
00456         /* if the files were DICOM, then the origin should be accurate */
00457         /* (so pick code based on sign, and remove sign)               */
00458 
00459         sprintf(tbuf,"XYZFIRST %f%c %f%c %f%c",
00460                 fabs(v->gex.xorg), orient_side_rai(v->gex.xorg, o0),
00461                 fabs(v->gex.yorg), orient_side_rai(v->gex.yorg, o2),
00462                 fabs(v->z_first),  orient_side_rai(v->z_first,  o4));
00463         ART_ADD_TO_BUF( ac->buf, tbuf );
00464     }
00465 
00466     /* BYTEORDER interface - send if swap flag is not set */
00467     if ( ! ac->swap )
00468     {
00469         sprintf( tbuf, "BYTEORDER %s", (ac->byte_order == LSB_FIRST) ?
00470                  "LSB_FIRST" : "MSB_FIRST" );
00471         ART_ADD_TO_BUF( ac->buf, tbuf );
00472     }
00473 
00474     /* DRIVE_AFNI interface - open afni windows */
00475     {
00476         char * graph_win;                       /* graph window to open */
00477         char * image_win;                       /* image window to open */
00478         char   o4 = v->geh.orients[4];          /* note last axis       */
00479         int    nt = ac->param->opts.nt;         /* note user defined nt */
00480 
00481         if ( (o4 == 'R') || (o4 == 'r') || (o4 == 'L') || (o4 == 'l') )
00482         {
00483             graph_win = "sagittalgraph";
00484             image_win = "sagittalimage";
00485         }
00486         else if ( (o4 == 'I') || (o4 == 'i') || (o4 == 'S') || (o4 == 's') )
00487         {
00488             graph_win = "axialgraph";
00489             image_win = "axialimage";
00490         }
00491         else
00492         {
00493             graph_win = "coronalgraph";
00494             image_win = "coronalimage";
00495         }
00496         
00497         /* open image and graph window - possibly adding pinnum */
00498         sprintf(tbuf, "DRIVE_AFNI OPEN_WINDOW %s\n"
00499                       "DRIVE_AFNI OPEN_WINDOW %s", image_win, graph_win );
00500 
00501         if ( nt > 0 )
00502             sprintf( tbuf+strlen(tbuf), " pinnum=%d", nt );
00503 
00504         ART_ADD_TO_BUF( ac->buf, tbuf );
00505     }
00506 
00507     /* pass along any user specified realtime command(s)    v3.2 [rickr] */
00508     if ( ac->param->opts.rt_list.str )
00509     {
00510         string_list * list = &ac->param->opts.rt_list;
00511         char        * cp;
00512         int           ns;
00513 
00514         for ( ns = 0; ns < list->nused; ns++ )
00515         {
00516             strncpy( tbuf, list->str[ns], 256 );
00517 
00518             /* sneaky... change any "\n" pairs to '\n' */
00519             for ( cp = tbuf; cp < (tbuf + strlen(tbuf) - 1); cp++ )
00520                 if ( cp[0] == '\\' && cp[1] == 'n' )
00521                 {
00522                     cp[0] = ' ';
00523                     cp[1] = '\n';
00524                     cp++;
00525                 }
00526 
00527             ART_ADD_TO_BUF( ac->buf, tbuf );
00528         }
00529     }
00530 
00531     /* pass along any user specified drive command(s) */
00532     if ( ac->param->opts.drive_list.str )
00533     {
00534         string_list * list = &ac->param->opts.drive_list;
00535         char        * cp;
00536         int           ns;
00537 
00538         for ( ns = 0; ns < list->nused; ns++ )
00539         {
00540             sprintf( tbuf, "DRIVE_AFNI %s", list->str[ns] );
00541 
00542             /* sneaky... change any "\n" pairs to '\n' */
00543             for ( cp = tbuf; cp < (tbuf + strlen(tbuf) - 1); cp++ )
00544                 if ( cp[0] == '\\' && cp[1] == 'n' )
00545                 {
00546                     cp[0] = ' ';
00547                     cp[1] = '\n';
00548                     cp++;
00549                 }
00550 
00551             ART_ADD_TO_BUF( ac->buf, tbuf );
00552         }
00553     }
00554 
00555     /* NOTE interface - add a note to the dataset: the actual Imon command */
00556     {
00557         int count, len, tot_len;
00558 
00559         /* form-feeds will be replaced with newlines in plug_realtime */
00560         sprintf( tbuf, "NOTE created remotely via real-time afni\f"
00561                  "    starting with file : '%s'\f"
00562                  "    creation command   :",
00563                  v->first_file );
00564         tot_len = strlen( tbuf );
00565 
00566         for ( count = 0; count < ac->param->opts.argc; count++ )
00567         {
00568             len = strlen( ac->param->opts.argv[count] );
00569 
00570             /* are we out of space? */
00571             if ( tot_len + len + 5 >= ART_TBUF_LEN )
00572             {
00573                 strcat( tbuf, " ..." );
00574                 break;
00575             }
00576 
00577             strcat( tbuf, " " );
00578             strcat( tbuf, ac->param->opts.argv[count] );
00579         }
00580         
00581         ART_ADD_TO_BUF( ac->buf, tbuf );
00582     }
00583 
00584     if ( debug > 1 )
00585         fprintf( stderr, "++ dataset control info for afni:\n   %s", ac->buf );
00586     if ( (debug > 0) && (strlen(ac->buf) > (ART_TBUF_LEN * 0.8)) )
00587         fprintf(stderr,"** warning: ac->buf len uses %d of %d bytes\n",
00588                 (int)strlen(ac->buf), ART_TBUF_LEN);
00589 
00590     rv = iochan_sendall( ac->ioc, ac->buf, strlen(ac->buf)+1 );
00591 
00592     if ( rv < 0 )
00593     {
00594         fprintf( stderr, "** failure to send control info to afni\n" );
00595         ac->state = ART_STATE_NO_USE;
00596 
00597         return -1;
00598     }
00599 
00600     ac->state = ART_STATE_IN_USE;                 /* declaration of success */
00601 
00602     iochan_sleep(50);                             /* give afni some time    */
00603 
00604     return 0;
00605 }
00606 
00607 
00608 /*----------------------------------------------------------------------
00609  * Function to be called to make sure the AFNI data channels get closed.
00610  *----------------------------------------------------------------------
00611 */
00612 void ART_exit( void )
00613 {
00614     static int been_here = 0;           /* on an error, we may come back */
00615 
00616     if ( been_here == 0 )
00617     {
00618         iochan_close(gAC.ioc);
00619         fprintf( stderr, "ART_exit: closing afni control channel\n" );
00620         been_here = 1;
00621     }
00622 
00623     return;
00624 }
00625 
00626 
00627 /*----------------------------------------------------------------------
00628  * display ART_comm structure contents
00629  *----------------------------------------------------------------------
00630 */
00631 int ART_idisp_ART_comm( char * info, ART_comm * ac )
00632 {
00633     if ( info )
00634         fputs( info, stdout );
00635 
00636     if ( ac == NULL )
00637     {
00638         printf( "ART_idisp_ART_comm: ac == NULL\n" );
00639         return -1;
00640     }
00641 
00642     printf( "ART_comm struct at %p :\n"
00643             "   (state, mode)   = (%d, %d)\n"
00644             "   (use_tcp, swap) = (%d, %d)\n"
00645             "   byte_order      = %d\n"
00646             "   zorder          = %s\n"
00647             "   host            = %s\n"
00648             "   ioc_name        = %s\n"
00649             "   (ioc, param)    = (0x%p, 0x%p)\n",
00650             ac, ac->state, ac->mode, ac->use_tcp, ac->swap, ac->byte_order,
00651             CHECK_NULL_STR(ac->zorder), CHECK_NULL_STR(ac->host),
00652             CHECK_NULL_STR(ac->ioc_name), ac->ioc, ac->param );
00653 
00654     return 0;
00655 }
00656 
00657 
00658 /*----------------------------------------------------------------------
00659  * swap pairs of bytes          - destructive
00660  *----------------------------------------------------------------------
00661 */
00662 int swap_2( void * ptr, int npairs )
00663 {
00664     unsigned char * addr = ptr;
00665     int             count;
00666 
00667     for ( count = 0; count < npairs; count++ )
00668     {
00669         addr[0] ^= addr[1]; addr[1] ^= addr[0]; addr[0] ^= addr[1];
00670         addr += 2;
00671     }
00672 
00673     return 0;
00674 }
00675 
00676 
00677 /* given a coord and direction character, return the side the coord is on */
00678 /* (assume RAI) */
00679 static char orient_side_rai( float coord, char dir )
00680 {
00681     int d = toupper(dir);
00682 
00683     if ( d == 'R' || d == 'L' ) return( coord < 0 ? 'R' : 'L' );
00684     if ( d == 'A' || d == 'P' ) return( coord < 0 ? 'A' : 'P' );
00685     if ( d == 'I' || d == 'S' ) return( coord < 0 ? 'I' : 'S' );
00686 }
00687 
 

Powered by Plone

This site conforms to the following standards: