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  

niml_do.c

Go to the documentation of this file.
00001 #include "niml_private.h"
00002 
00003 /**** Tables for ni_do callbacks *****/
00004 
00005 static int           doer_num  = 0    ;
00006 static char        **doer_verb = NULL ;
00007 static NI_voidfunc **doer_func = NULL ;
00008 
00009 typedef void (*ddfun)(char *,NI_stream_type *,NI_element *) ;
00010 
00011 /*---------------------------------------------------------------------------*/
00012 /*! Register a callback for a "ni_do" verb.  [12 Feb 2003]
00013 
00014     The function will be called like so
00015       - func( char *object , NI_stream_type *ns , NI_element *nel ) ;
00016       - object = RHS of ni_object attribute (may be NULL)
00017       - ns = stream that sent the message (so you can reply, if you like)
00018       - nel = the data element that contained the message (if you need it)
00019 
00020     Calling with the same verb will replace the function - you can't have
00021     two callbacks for the same verb.  If func is input as NULL, then this
00022     will remove a callback, if it was defined earlier; if func is NULL and
00023     verb was not previously defined, then nothing happens.
00024 
00025     However, you CAN register a callback for a builtin verb.  The normal
00026     processing will take place, then the user callback will be invoked
00027     if that processing was good.  [This feature was added on 30 Dec 2003.]
00028 -----------------------------------------------------------------------------*/
00029 
00030 void NI_register_doer( char *verb , NI_voidfunc *func )
00031 {
00032    int ii ;
00033 
00034    if( verb == NULL || *verb == '\0' ) return ;
00035 
00036    /* see if verb already in table */
00037 
00038    for( ii=0 ; ii < doer_num ; ii++ )
00039      if( strcmp(verb,doer_verb[ii]) == 0 ) break ;
00040 
00041    /* if was in table, replace func (may be NULL) */
00042 
00043    if( ii < doer_num ){
00044      doer_func[ii] = func ; return ;
00045    }
00046 
00047    /* defining a new verb */
00048 
00049    if( func == NULL ) return ;   /* quit if no func */
00050 
00051    /* expand tables of verbs and funcs */
00052 
00053    ii = doer_num++ ;
00054 
00055    doer_verb = NI_realloc( doer_verb, char*, sizeof(char *)*doer_num ) ;
00056    doer_verb[ii] = NI_strdup(verb) ;
00057 
00058    doer_func = NI_realloc( doer_func , NI_voidfunc*, sizeof(NI_voidfunc *)*doer_num ) ;
00059    doer_func[ii] = func ;
00060    return ;
00061 }
00062 
00063 /*---------------------------------------------------------------------------*/
00064 /*! Carry out an action ordered by a "ni_do" element received on
00065     the input stream.  Actions we know about:
00066 
00067    - ni_verb='reopen_this' => open the stream anew and replace it [23 Aug 2002]
00068    - ni_verb='close_this'  => close this stream down              [20 Dec 2002]
00069    - ni_verb='typedef'     => define a NI_rowtype                 [12 Feb 2003]
00070    - user-defined verbs can be added using NI_register_doer()     [12 Feb 2003]
00071 
00072     Return value is -1 if an error occurs, 0 if things are cool.
00073 -----------------------------------------------------------------------------*/
00074 
00075 int NI_do( NI_stream_type *ns , NI_element *nel )
00076 {
00077    char *verb , *object ;
00078    int ii , builtin=0 ;
00079 
00080    /*- check inputs for OK-ositiness -*/
00081 
00082    if( ns == NULL || nel == NULL || nel->type != NI_ELEMENT_TYPE ) return -1 ;
00083 
00084    if( strcmp(nel->name  ,"ni_do") != 0 &&
00085        strcmp(nel->name+1,"ni_do") != 0    ) return -1 ;
00086 
00087    /* 25 Apr 2005: check for diverse forms of the verb and object attributes */
00088 
00089                       verb = NI_get_attribute( nel , "ni_verb" ) ;
00090    if( verb == NULL ) verb = NI_get_attribute( nel , "verb"    ) ;
00091 
00092                         object = NI_get_attribute( nel , "ni_object" ) ;
00093    if( object == NULL ) object = NI_get_attribute( nel , "object"    ) ;
00094    if( object == NULL ) object = NI_get_attribute( nel , "ni_obj"    ) ;
00095    if( object == NULL ) object = NI_get_attribute( nel , "obj"       ) ;
00096 
00097    if( verb == NULL || verb[0] == '\0' ) return -1 ;        /* need a verb;  */
00098                                                            /* but not always */
00099                                                           /* need an object  */
00100    /*******************************************/
00101    /*---- check for various builtin verbs ----*/
00102    /*******************************************/
00103 
00104    if( strcmp(verb,"reopen_this") == 0 ){  /****----- reopen stream ------****/
00105 
00106      NI_stream_type *nsnew ;
00107 
00108      if( object == NULL || object[0] == '\0' ) return -1 ;  /* bad */
00109 
00110      nsnew = NI_stream_open( object , "r" ) ;             /* open new stream */
00111      if( nsnew == NULL ) return -1 ;                                  /* bad */
00112 
00113      NI_stream_close_keep(ns,0) ;                        /* trash old stream */
00114      *ns = *nsnew; NI_free(nsnew);                       /* replace old guts */
00115      builtin = 1 ;
00116 
00117    } /****------------------------- end reopen --------------------------*****/
00118 
00119    else if( strcmp(verb,"close_this") == 0 ){  /****-- close this stream -****/
00120 
00121      NI_stream_close_keep(ns,0);                   /* close and mark as dead */
00122      builtin = 1 ;
00123 
00124    } /****------------------------ end close_this ------------------------****/
00125 
00126    else if( strcmp(verb,"typedef") == 0 ){    /****-- define a NIML type -****/
00127                                               /****   [12 Feb 2003]       ****/
00128      char tnam[256] , tdef[8200] ;
00129      int tt ;
00130 
00131      if( object == NULL || object[0] == '\0' ) return -1 ;  /* bad */
00132 
00133      tnam[0] = tdef[0] = '\0' ;
00134      sscanf(object,"%255s %8199s",tnam,tdef) ;
00135      tt = NI_rowtype_define( tnam , tdef ) ;
00136      if( tt < 0 ) return -1 ;                    /* bad definition */
00137      builtin = 1 ;
00138 
00139    } /****------------------------ end typedef ---------------------------****/
00140 
00141    /**************************************************************/
00142    /**** Here, check for user-defined callbacks [12 Feb 2003] ****/
00143 
00144    for( ii=0 ; ii < doer_num ; ii++ ){
00145      if( strcmp(verb,doer_verb[ii]) == 0 ){
00146        if( doer_func[ii] != NULL ){
00147          void (*df)(char *,NI_stream_type *,NI_element *) = (ddfun)doer_func[ii] ;
00148          df( object , ns , nel ) ;
00149        }
00150        return 0 ;
00151      }
00152    }
00153 
00154    /*--- if we get here, we got a verb we don't recognize ---*/
00155 
00156    return ((builtin) ? 0 : -1) ;
00157 }
 

Powered by Plone

This site conforms to the following standards: