Doxygen Source Code Documentation
niml_elemio.c File Reference
#include "niml_private.h"Go to the source code of this file.
Defines | |
| #define | clear_buffer(ns) ( (ns)->nbuf = (ns)->npos = 0 ) |
| #define | NVBUF 127 |
| #define | IS_USELESS(c) ( isspace(c) || iscntrl(c) ) |
| #define | IS_CRLF(c) ( (c) == 0x0D || (c) == 0x0A ) |
| #define | AF 0 |
| #define | ADDOUT if(nout<0){AF;fprintf(stderr,"NIML: write abort!\n");return -1;} else ntot+=nout |
| #define | AF NI_free(att) |
| #define | AF 0 |
Functions | |
| int | scan_for_angles (NI_stream_type *, int) |
| int | header_stuff_is_group (header_stuff *hs) |
| int | header_stuff_is_procins (header_stuff *hs) |
| int | NI_write_procins (NI_stream_type *ns, char *str) |
| void | NI_read_header_only (int r) |
| void | NI_skip_procins (int r) |
| void * | NI_read_element_header (NI_stream_type *ns, int msec) |
| void * | NI_read_element (NI_stream_type *ns, int msec) |
| int | NI_decode_one_double (NI_stream_type *ns, double *val, int ltend) |
| int | NI_decode_one_string (NI_stream_type *ns, char **str, int ltend) |
| void | NI_reset_buffer (NI_stream_type *ns) |
| void | NI_set_typename_mode (int nmode) |
| char * | NI_type_name (int code) |
| int | NI_write_element (NI_stream_type *ns, void *nini, int tmode) |
Variables | |
| int | read_header_only = 0 |
| int | skip_procins = 0 |
| int | name_mode = NI_NAMEMODE_NORMAL |
Define Documentation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 9 of file niml_elemio.c. Referenced by NI_decode_one_double(). |
|
|
Definition at line 477 of file niml_elemio.c. Referenced by NI_decode_one_double(), and NI_decode_one_string(). |
|
|
Definition at line 476 of file niml_elemio.c. Referenced by NI_decode_one_double(), and NI_decode_one_string(). |
|
|
Definition at line 474 of file niml_elemio.c. Referenced by NI_decode_one_double(). |
Function Documentation
|
|
Check if header_stuff marks this NIML element as a group. ---------------------------------------------------------------------- Definition at line 15 of file niml_elemio.c. References get_header_attribute(), and header_stuff::name. Referenced by NI_read_element().
00016 {
00017 char *atr ;
00018 if( hs == NULL ) return 0 ;
00019 if( strcmp(hs->name,"ni_group") == 0 ) return 1 ;
00020 atr = get_header_attribute( hs , "ni_form" ) ;
00021 if( atr != NULL && strcmp(atr,"ni_group") == 0 ) return 1 ;
00022 return 0 ;
00023 }
|
|
|
Check if header_stuff marks NIML element as a processing instruction. ---------------------------------------------------------------------- Definition at line 29 of file niml_elemio.c. References header_stuff::name. Referenced by NI_read_element().
|
|
||||||||||||||||
|
From the NI_stream ns, starting at buffer position ns->npos, decode one number into *val.
Definition at line 489 of file niml_elemio.c. References NI_stream_type::bad, NI_stream_type::buf, clear_buffer, IS_CRLF, IS_USELESS, MARKED_FOR_DEATH, NI_stream_type::nbuf, NI_dpr(), NI_reset_buffer(), NI_stream_fillbuf(), NI_stream_type::npos, and NVBUF. Referenced by NI_text_to_val().
00490 {
00491 int epos , num_restart, need_data, nn ;
00492 char vbuf[NVBUF+1] ; /* number string from buffer */
00493
00494 /*-- check inputs for stupidness --*/
00495
00496 if( ns == NULL || ns->bad == MARKED_FOR_DEATH || val == NULL ) return 0 ;
00497
00498 /*--- might loop back here to check if have enough data for a number ---*/
00499
00500 num_restart = 0 ;
00501 Restart:
00502 num_restart++ ; need_data = 0 ;
00503 if( num_restart > 19 ) return 0 ; /*** too much ==> give up ***/
00504
00505 #ifdef NIML_DEBUG
00506 NI_dpr(" {restart: npos=%d nbuf=%d}",ns->npos,ns->nbuf) ;
00507 #endif
00508
00509 /*-- advance over useless characters in the buffer --*/
00510
00511 while( ns->npos < ns->nbuf && IS_USELESS(ns->buf[ns->npos]) ) ns->npos++ ;
00512
00513 /*-- check if we ran into the closing '<' prematurely
00514 (before any useful characters); if we did, then we are done --*/
00515
00516 if( ltend && ns->npos < ns->nbuf && ns->buf[ns->npos] == '<' ) return 0 ;
00517
00518 /*-- 20 Mar 2003: check if we ran into a comment character '#';
00519 if we did, skip to the end of the line (or '<') --*/
00520
00521 if( ltend && ns->npos < ns->nbuf && ns->buf[ns->npos] == '#' ){
00522 int npold = ns->npos ;
00523 while( ns->npos < ns->nbuf && !IS_CRLF(ns->buf[ns->npos]) ){
00524 if( ns->buf[ns->npos] == '<' ) return 0 ; /* STOP HERE! */
00525 ns->npos++ ;
00526 }
00527 if( ns->npos < ns->nbuf ){ /* found end of line, so try again */
00528 num_restart = 0 ; goto Restart ;
00529 }
00530 /* if here, didn't find '<' or end of line in buffer */
00531 /* so reset pointer back to '#', then read more data */
00532 ns->npos = npold ; need_data = 1 ;
00533 }
00534
00535 /*-- if we need some data, try to get some --*/
00536
00537 if( !need_data ) /* need at least 2 unused */
00538 need_data = (ns->nbuf-ns->npos < 2) ; /* bytes to decode a number */
00539
00540 /*-- An input value is decoded from a string of non-useless
00541 characters delimited by a useless character (or by the
00542 element closing '<').
00543 Note that the 1st character we are now at is non-useless.
00544 Scan forward to see if we have a useless character later. --*/
00545
00546 if( !need_data ){ /* so have at least 2 characters */
00547
00548 #ifdef NIML_DEBUG
00549 nn = ns->nbuf-ns->npos ; if( nn > 19 ) nn = 19 ;
00550 NI_dpr(" {buf=%.*s}" , nn , ns->buf+ns->npos ) ;
00551 #endif
00552
00553 for( epos=ns->npos+1 ; epos < ns->nbuf ; epos++ )
00554 if( ns->buf[epos] == '<' || IS_USELESS(ns->buf[epos]) ) break ;
00555
00556 /*- epos is either the delimiter position, or the end of data bytes -*/
00557
00558 need_data = (epos == ns->nbuf) ; /* no delimiter ==> need more data */
00559
00560 #ifdef NIML_DEBUG
00561 if( need_data ) NI_dpr(" {eob}") ;
00562 #endif
00563
00564 /*- If the string of characters we have is not yet
00565 delimited, and it is too long to be a number,
00566 throw out all the data in the buffer and quit. -*/
00567
00568 if( need_data && epos-ns->npos > NVBUF ){ clear_buffer(ns); return 0; }
00569 }
00570
00571 /*-- read more data now if it is needed --*/
00572
00573 if( need_data ){
00574
00575 NI_reset_buffer(ns) ; /* discard used up data in buffer */
00576
00577 /*- read at least 1 byte,
00578 waiting up to 666 ms (unless the data stream goes bad) -*/
00579
00580 #ifdef NIML_DEBUG
00581 NI_dpr(" {fill buf}") ;
00582 #endif
00583 nn = NI_stream_fillbuf( ns , 1 , 666 ) ;
00584
00585 if( nn >= 0 ) goto Restart ; /* check if buffer is adequate now */
00586
00587 /*- if here, the stream went bad. If there are still
00588 data bytes in the stream, we can try to interpret them.
00589 Otherwise, must quit without success. -*/
00590
00591 if( ns->nbuf == 0 ){ ns->npos=0; return 0; } /* quitting */
00592
00593 epos = ns->nbuf ;
00594 }
00595
00596 /*-- if here, try to interpret data bytes ns->npos .. epos-1 --*/
00597
00598 nn = epos-ns->npos ; if( nn > NVBUF ) nn = NVBUF ; /* # bytes to read */
00599 memcpy( vbuf, ns->buf+ns->npos, nn ); vbuf[nn] = '\0'; /* put bytes in vbuf */
00600 *val = 0.0 ; /* initialize val */
00601 sscanf( vbuf , "%lf" , val ) ; /* interpret them */
00602 ns->npos = epos ; return 1 ; /* retire undefeated */
00603 }
|
|
||||||||||||||||
|
From the NI_stream ns, starting at buffer position ns->npos, decode one string into newly NI_malloc()-ed space pointed to by *str.
Definition at line 615 of file niml_elemio.c. References NI_stream_type::bad, NI_stream_type::buf, find_string(), intpair::i, IS_CRLF, IS_QUOTE_CHAR, IS_USELESS, intpair::j, MARKED_FOR_DEATH, NI_stream_type::nbuf, NI_malloc, NI_reset_buffer(), NI_stream_fillbuf(), and NI_stream_type::npos. Referenced by NI_text_to_val().
00616 {
00617 int epos , num_restart, need_data, nn ;
00618 intpair sp ;
00619
00620 /*-- check inputs for stupidness --*/
00621
00622 if( ns == NULL || ns->bad == MARKED_FOR_DEATH || str == NULL ) return 0 ;
00623
00624 /*--- might loop back here to check if have enough data ---*/
00625
00626 num_restart = 0 ;
00627 Restart:
00628 num_restart++ ; need_data = 0 ;
00629 if( num_restart > 19 ) return 0 ; /*** give up ***/
00630
00631 /*-- advance over useless characters in the buffer --*/
00632
00633 while( ns->npos < ns->nbuf && IS_USELESS(ns->buf[ns->npos]) ) ns->npos++ ;
00634
00635 /*-- check if we ran into the closing '<' prematurely
00636 (before any useful characters); if we did, then we are done --*/
00637
00638 if( ltend && ns->npos < ns->nbuf && ns->buf[ns->npos] == '<' ) return 0 ;
00639
00640 /*-- 20 Mar 2003: check if we ran into a comment character '#';
00641 if we did, skip to the end of the line (or '<') --*/
00642
00643 if( ltend && ns->npos < ns->nbuf && ns->buf[ns->npos] == '#' ){
00644 int npold = ns->npos ;
00645 while( ns->npos < ns->nbuf && !IS_CRLF(ns->buf[ns->npos]) ){
00646 if( ns->buf[ns->npos] == '<' ) return 0 ; /* STOP HERE! */
00647 ns->npos++ ;
00648 }
00649 if( ns->npos < ns->nbuf ){ /* found end of line, so try again */
00650 num_restart = 0 ; goto Restart ;
00651 }
00652 /* if here, didn't find '<' or end of line in buffer */
00653 /* so reset pointer back to '#', then read more data */
00654 ns->npos = npold ; need_data = 1 ;
00655 }
00656
00657 /*-- if we need some data, try to get some --*/
00658
00659 if( !need_data ) /* need at least 2 unused */
00660 need_data = (ns->nbuf-ns->npos < 2) ; /* bytes to decode a string */
00661
00662 if( !need_data ){ /* so have at least 2 characters */
00663
00664 /* search for the string from here forward */
00665
00666 sp = find_string( ns->npos , ns->nbuf , ns->buf ) ;
00667
00668 need_data = (sp.i < 0) || /* didn't find a string */
00669 (sp.j <= sp.i) || /* ditto */
00670 (sp.j == ns->nbuf) ; /* hit end of data bytes */
00671 }
00672
00673 /*-- read more data now if it is needed --*/
00674
00675 if( need_data ){
00676
00677 NI_reset_buffer(ns) ; /* discard used up data in buffer */
00678
00679 /*- read at least 1 byte,
00680 waiting up to 666 ms (unless the data stream goes bad) -*/
00681
00682 nn = NI_stream_fillbuf( ns , 1 , 666 ) ;
00683
00684 if( nn >= 0 ) goto Restart ; /* check if buffer is adequate now */
00685
00686 /*- if here, the stream went bad. If there are still
00687 data bytes in the stream, we can try to interpret them.
00688 Otherwise, must quit without success. -*/
00689
00690 if( ns->nbuf == 0 ){ ns->npos=0; return 0; } /* quitting */
00691
00692 sp.i = 0 ; sp.j = ns->nbuf ;
00693 }
00694
00695 /*-- if here, data bytes sp.i .. sp.j-1 are the string --*/
00696
00697 nn = sp.j - sp.i ; /* length of string */
00698 *str = NI_malloc(char, nn+1) ; /* make the string */
00699 memcpy( *str , ns->buf+sp.i , nn ) ; /* copy data to string */
00700 (*str)[nn] = '\0' ; /* terminate string */
00701
00702 /* skip close quote character, if present */
00703
00704 if( sp.j < ns->nbuf && IS_QUOTE_CHAR(ns->buf[sp.j]) ) sp.j++ ;
00705
00706 ns->npos = sp.j ; return 1 ;
00707 }
|
|
||||||||||||
|
Read an element (maybe a group) from the stream, waiting up to msec milliseconds for the header to appear. (After that, this function may wait a long time for the rest of the element to appear, unless the data stream comes to a premature end.) Return is NULL if nothing can be read at this time. Otherwise, use NI_element_type(return value) to determine if the element read is a data element or a group element. Note that a header that is longer than ns->bufsize will never be read properly, since we must have the entire header in the buffer before processing it. This should only be a problem for deranged users. If such a vast header is encountered, it will be flushed. If header start '<' and stop '>' are encountered, then this function will read data until it can create an element, or until the data stream is bad (i.e., the file ends, or the socket closes). If NULL is returned, that can be because there is no data to read even in the buffer, or because the input data stream has gone bad (i.e., will return no more data ever). To check for the latter case, use NI_stream_readcheck(). If a "<ni_do ... />" or "<?ni_do ... ?>" element is encountered, it will not be returned to the caller. Instead, the actions it orders will be carried out in function NI_do(), and the function will loop back to find some other input. ---------------------------------------------------------------------- Definition at line 126 of file niml_elemio.c. References NI_element::attr_lhs, NI_procins::attr_lhs, NI_element::attr_num, NI_procins::attr_num, NI_element::attr_rhs, NI_procins::attr_rhs, NI_stream_type::b64_numleft, NI_stream_type::bad, NI_stream_type::buf, destroy_header_stuff(), header_stuff::empty, header_stuff_is_group(), header_stuff_is_procins(), header_stuff::lhs, make_empty_data_element(), make_empty_group_element(), MARKED_FOR_DEATH, NI_element::name, NI_procins::name, header_stuff::name, header_stuff::nattr, NI_add_to_group(), NI_BASE64_MODE, NI_BINARY_MODE, NI_byteorder(), NI_clock_time(), NI_do(), NI_dpr(), NI_free, NI_free_element(), NI_LSB_FIRST, NI_LTEND_MASK, NI_malloc, NI_MSB_FIRST, NI_PROCINS_TYPE, NI_read_columns(), NI_reset_buffer(), NI_sleep(), NI_strdup(), NI_stream_goodcheck(), NI_stream_readcheck(), NI_SWAP_MASK, NI_TEXT_MODE, NI_stream_type::npos, parse_header_stuff(), read_header_only, header_stuff::rhs, scan_for_angles(), string_index(), swap, NI_procins::type, NI_element::vec, NI_element::vec_axis_len, NI_element::vec_filled, NI_element::vec_len, NI_element::vec_num, NI_element::vec_rank, and NI_element::vec_typ. Referenced by AFNI_niml_workproc(), AFNI_start_version_check(), AIVVV_workproc(), Dtable_from_nimlstring(), main(), NI_read_element_header(), NI_read_file_nohead(), NI_suck_stream(), SUMA_FakeIt(), SUMA_LoadNimlDset(), SUMA_LoadVisualState(), SUMA_niml_workproc(), SUMA_OpenDrawnROI_NIML(), THD_load_3D(), THD_open_3D(), THD_open_nifti(), THD_read_niml_atr(), and XSAVE_input().
00127 {
00128 int ii,nn,nhs , num_restart ;
00129 char *cstart , *cstop ;
00130 header_stuff *hs ;
00131 int start_time=NI_clock_time() , mleft ;
00132
00133 if( ns == NULL || ns->bad == MARKED_FOR_DEATH || ns->buf == NULL )
00134 return NULL ; /* bad input stream */
00135
00136 #ifdef NIML_DEBUG
00137 NI_dpr("ENTER NI_read_element\n") ;
00138 #endif
00139
00140 if( msec < 0 ) msec = 999999999 ; /* a long time (11+ days) */
00141
00142 /* if we have a socket that hasn't connected,
00143 then see if it can connect now */
00144
00145 if( ns->bad ){
00146 nn = NI_stream_goodcheck( ns , msec ) ;
00147 if( nn < 1 ) return NULL ; /* didn't connect */
00148 }
00149
00150 /*-- Try to find the element header --*/
00151
00152 num_restart = 0 ;
00153 HeadRestart: /* loop back here to retry */
00154 num_restart++ ;
00155 mleft = msec - (NI_clock_time()-start_time) ; /* time left */
00156 if( num_restart > 1 && mleft <= 0 ) return NULL ; /* don't allow too many loops */
00157
00158 #ifdef NIML_DEBUG
00159 NI_dpr("NI_read_element: HeadRestart scan_for_angles; num_restart=%d\n" ,
00160 num_restart ) ;
00161 #endif
00162
00163 nn = scan_for_angles( ns , 0 ) ; /* look for '<stuff>' */
00164
00165 /* didn't find it */
00166
00167 if( nn < 0 ){
00168 if( NI_stream_readcheck(ns,0) < 0 ) return NULL ; /* connection lost */
00169 NI_sleep(2); goto HeadRestart; /* try again */
00170 }
00171
00172 #ifdef NIML_DEBUG
00173 NI_dpr("NI_read_element: found '<'\n") ;
00174 #endif
00175
00176 /* ns->buf[ns->npos] = opening '<' ; ns->buf[nn-1] = closing '>' */
00177
00178 /* see if we found '<>', which is meaningless,
00179 or a trailer '</stuff>', which is illegal here */
00180
00181 if( nn - ns->npos <= 2 || ns->buf[ns->npos+1] == '/' ){
00182 ns->npos = nn; NI_reset_buffer(ns); /* toss the '<..>', try again */
00183 #ifdef NIML_DEBUG
00184 NI_dpr("NI_read_element: illegal header found? skipping\n") ;
00185 #endif
00186 goto HeadRestart ;
00187 }
00188
00189 /*----- Parse the header data and prepare to make an element! -----*/
00190
00191 #ifdef NIML_DEBUG
00192 NI_dpr("NI_read_element: parsing putative header\n") ;
00193 #endif
00194
00195 hs = parse_header_stuff( nn - ns->npos , ns->buf + ns->npos , &nhs ) ;
00196
00197 if( hs == NULL ){ /* something bad happened there */
00198 fprintf(stderr,"NI_read_element: bad element header found!\n") ;
00199 ns->npos = nn; NI_reset_buffer(ns); /* toss the '<..>', try again */
00200 goto HeadRestart ;
00201 }
00202
00203 /*----- If here, have parsed a header (and will not HeadRestart).
00204 First, expunge the data bytes that were consumed to make
00205 the header; that is, we can then start reading data from
00206 ns->buf[ns->npos] .. ns->buf[ns->nbuf-1] --*/
00207
00208 ns->npos = nn ;
00209
00210 #ifdef NIML_DEBUG
00211 NI_dpr("NI_read_element: header parsed successfully\n") ;
00212 #endif
00213
00214 /*--------------- Now make an element of some kind ---------------*/
00215
00216 if( header_stuff_is_procins(hs) ){ /*--- a processing instruction ---*/
00217
00218 NI_procins *npi ;
00219
00220 if( strcmp(hs->name,"?ni_do") == 0 ){ /* 19 Apr 2005: special case! */
00221 NI_element *nel ;
00222 nel = make_empty_data_element( hs ) ; /* temporary element */
00223 destroy_header_stuff( hs ) ;
00224 NI_do( ns , nel ) ; /* do the stuff it says */
00225 NI_free_element( nel ) ; /* then destroy it */
00226 if( ns->bad == MARKED_FOR_DEATH || ns->buf == NULL ) return NULL ;
00227 num_restart = 0 ; goto HeadRestart ;
00228 }
00229
00230 /* 03 Jun 2005: if ordered to skip these things, do so */
00231
00232 if( skip_procins ){
00233 destroy_header_stuff( hs ) ; num_restart = 0 ; goto HeadRestart ;
00234 }
00235
00236 /* normal case: make a procins element and give it to the caller */
00237
00238 npi = NI_malloc(NI_procins,sizeof(NI_procins)) ;
00239 npi->type = NI_PROCINS_TYPE ;
00240 npi->name = NI_strdup( hs->name + 1 ) ; /* skip the '?' */
00241
00242 npi->attr_num = hs->nattr ;
00243 if( npi->attr_num > 0 ){
00244 npi->attr_lhs = hs->lhs ; hs->lhs = NULL ;
00245 npi->attr_rhs = hs->rhs ; hs->rhs = NULL ;
00246 } else {
00247 npi->attr_lhs = npi->attr_rhs = NULL ;
00248 }
00249
00250 destroy_header_stuff( hs ) ;
00251
00252 return npi ;
00253
00254 } /*--- end of reading a processing instruction ---*/
00255
00256 else if( header_stuff_is_group(hs) ){ /*---- a group element ----*/
00257
00258 NI_group *ngr ;
00259 void *nini ;
00260 int empty=hs->empty ;
00261
00262 read_header_only = 0 ; /* 23 Mar 2003 */
00263
00264 start_time = NI_clock_time() ; /* allow up to 10 sec for next */
00265 msec = 9999 ; /* element to appear, before giving up */
00266
00267 ngr = make_empty_group_element( hs ) ; /* copies name and attributes */
00268 destroy_header_stuff( hs ) ;
00269 if( empty ) return ngr ; /* 03 Jun 2002: empty group is legal */
00270
00271 /* we now have to read the elements within the group */
00272
00273 num_restart = 0 ;
00274 while(1){ /* loop to find an element */
00275
00276 #ifdef NIML_DEBUG
00277 NI_dpr("NI_read_element: ni_group scan_for_angles; num_restart=%d\n",
00278 num_restart ) ;
00279 #endif
00280
00281 nn = scan_for_angles( ns , 10 ) ; /* find header/trailer '<...>' */
00282
00283 mleft = msec - (NI_clock_time()-start_time) ;
00284 if( mleft < 0 ) mleft = 0 ;
00285
00286 if( nn <= 0 ){ /* didn't find it */
00287 if( NI_stream_readcheck(ns,0) < 0 ) break ; /* real bad */
00288 if( num_restart > 1 && mleft == 0 ) break ; /* time's up */
00289 num_restart++ ;
00290 continue ; /* try again (but not forever) */
00291 }
00292
00293 /* check if we found a trailer element '</stuff>' */
00294
00295 if( ns->buf[ns->npos+1] == '/' ){ /* trailer */
00296 ns->npos = nn ; /* so end the group */
00297 break ;
00298 }
00299
00300 /* not a trailer, so try to make an element out of it */
00301
00302 nini = NI_read_element( ns , mleft ) ; /* recursion! */
00303 if( nini != NULL ){
00304 NI_add_to_group( ngr , nini ) ; /* this is good */
00305 num_restart = 0 ;
00306 start_time = NI_clock_time() ; /* restart the wait clock */
00307 } else { /* this is bad */
00308 if( NI_stream_readcheck(ns,0) < 0 ) break ; /* real bad */
00309 mleft = msec - (NI_clock_time()-start_time) ;
00310 if( num_restart > 1 && mleft <= 0 ) break ; /* time's up */
00311 num_restart++ ;
00312 }
00313 }
00314
00315 /* and we are done */
00316
00317 return ngr ;
00318
00319 } /* end of reading group element */
00320
00321 else { /*------------------------ a data element ---------------------*/
00322
00323 NI_element *nel ;
00324 int form, swap, nbrow , row,col ;
00325
00326 nel = make_empty_data_element( hs ) ;
00327 destroy_header_stuff( hs ) ;
00328
00329 /*-- check if this is an empty element --*/
00330
00331 if( nel == NULL || /* nel == NULL should never happen. */
00332 nel->vec_rank == 0 || /* These other cases are indication */
00333 nel->vec_num == 0 || /* that this is an 'empty' element. */
00334 nel->vec_typ == NULL || /* ==> The header is all there is. */
00335 nel->vec == NULL ||
00336 nel->name[0] == '!' || /* Stupid XML declaration */
00337 read_header_only ){
00338
00339 #ifdef NIML_DEBUG
00340 NI_dpr("NI_read_element: returning empty element\n") ;
00341 #endif
00342
00343 /*-- 23 Aug 2002: do something, instead of returning data? --*/
00344
00345 if( nel != NULL && strcmp(nel->name,"ni_do") == 0 ){
00346 NI_do( ns , nel ) ;
00347 NI_free_element( nel ) ;
00348 if( ns->bad == MARKED_FOR_DEATH || ns->buf == NULL ) return NULL ;
00349 num_restart = 0 ; goto HeadRestart ;
00350 }
00351
00352 if( read_header_only && nel->vec != NULL ){
00353 for( ii=0 ; ii < nel->vec_num ; ii++ ) NI_free(nel->vec[ii]) ;
00354 NI_free(nel->vec) ; nel->vec = NULL ;
00355 }
00356
00357 return nel ; /* default: return element */
00358 }
00359
00360 /*-- If here, must read data from the buffer into nel->vec --*/
00361
00362 /* Find the form of the input */
00363
00364 form = NI_TEXT_MODE ; /* default is text mode */
00365 swap = 0 ; /* and (obviously) don't byte swap */
00366
00367 ii = string_index( "ni_form" , nel->attr_num , nel->attr_lhs ) ;
00368
00369 if( ii >= 0 && nel->attr_rhs[ii] != NULL ){ /* parse ni_form=rhs */
00370
00371 /* binary or base64 mode? */
00372
00373 if( strstr(nel->attr_rhs[ii],"binary") != NULL )
00374 form = NI_BINARY_MODE ;
00375 else if( strstr(nel->attr_rhs[ii],"base64") != NULL ){
00376 form = NI_BASE64_MODE ;
00377 ns->b64_numleft = 0 ; /* 21 Apr 2005: reset Base64 leftovers */
00378 }
00379
00380 /* check byteorder in header vs. this CPU */
00381
00382 if( form != NI_TEXT_MODE ){
00383 int order=NI_MSB_FIRST ; /* default input byteorder */
00384 if( strstr(nel->attr_rhs[ii],"lsb") != NULL ) order = NI_LSB_FIRST;
00385 swap = ( order != NI_byteorder() ) ; /* swap bytes? */
00386 }
00387 }
00388
00389 /*-- 13 Feb 2003: Use new NI_read_columns() function to get data. --*/
00390
00391 if( form == NI_TEXT_MODE ) ii = NI_LTEND_MASK ; /* end on '<' char */
00392 else if( swap ) ii = NI_SWAP_MASK ; /* swap binary data */
00393 else ii = 0 ; /* no special flag */
00394
00395 row = NI_read_columns( ns ,
00396 nel->vec_num, nel->vec_typ,
00397 nel->vec_len, nel->vec , form, ii );
00398
00399 nel->vec_filled = (row >= 0) ? row : 0 ;
00400
00401 /* 27 Mar 2003: allow for case where vec_len is
00402 inferred from how much data we read */
00403
00404 if( nel->vec_len == 0 ){
00405 if( nel->vec_axis_len == NULL )
00406 nel->vec_axis_len = NI_malloc(int, sizeof(int)) ;
00407
00408 nel->vec_axis_len[0] = nel->vec_len = nel->vec_filled ;
00409 nel->vec_rank = 1 ;
00410 }
00411
00412 /*-- Now scan for the end-of-element marker '</something>' and
00413 skip all input bytes up to (and including) the final '>'. --*/
00414
00415 num_restart = 0 ;
00416 TailRestart:
00417 num_restart++ ;
00418
00419 if( num_restart < 99 ){ /* don't loop forever, dude */
00420 int is_tail ;
00421
00422 #ifdef NIML_DEBUG
00423 NI_dpr("NI_read_element: TailRestart scan_for_angles; num_restart=%d\n" ,
00424 num_restart ) ;
00425 #endif
00426
00427 nn = scan_for_angles( ns , 99 ) ; /* find '<...>' */
00428
00429 /* if we didn't find '<...>' at all,
00430 then if the I/O stream is bad, just exit;
00431 otherwise, try scanning for '<...>' again */
00432
00433 if( nn < 0 ){
00434 if( NI_stream_readcheck(ns,0) < 0 ) return nel ;
00435 goto TailRestart ;
00436 }
00437
00438 /* we have '<...>', but make sure it starts with '</' */
00439
00440 is_tail = ( ns->buf[ns->npos+1] == '/' ) ;
00441
00442 if( !is_tail ){ /* no '/'? */
00443 ns->npos = nn ; NI_reset_buffer(ns) ; /* skip '<...>' */
00444 goto TailRestart ; /* and try again */
00445 }
00446
00447 ns->npos = nn ; /* skip '</...>' and we are done here! */
00448 }
00449
00450 /*-- And are done with the input stream and the data element! --*/
00451
00452 #ifdef NIML_DEBUG
00453 NI_dpr("NI_read_element: returning filled data element\n") ;
00454 #endif
00455
00456 /*-- 23 Aug 2002: do something, instead of returning data? --*/
00457
00458 if( strcmp(nel->name,"ni_do") == 0 ){
00459 NI_do( ns , nel ) ;
00460 NI_free_element( nel ) ;
00461 num_restart = 0 ; goto HeadRestart ;
00462 }
00463
00464 return nel ;
00465
00466 } /* end of reading data element */
00467
00468 return NULL ; /* should never be reached */
00469 }
|
|
||||||||||||
|
Read only the header part of the next element. ---------------------------------------------------------------------- Definition at line 86 of file niml_elemio.c. References NI_read_element(), and read_header_only.
00087 {
00088 void *nini ;
00089 read_header_only = 1 ;
00090 nini = NI_read_element( ns , msec ) ;
00091 read_header_only = 0 ;
00092 return nini ;
00093 }
|
|
|
Definition at line 77 of file niml_elemio.c. References r, and read_header_only. Referenced by THD_open_3D().
00077 { read_header_only=r ; } /* 23 Mar 2003 */
|
|
|
Reset the unscanned bytes in the buffer to start at position 0 instead of position ns->npos; then set ns->npos to 0. ------------------------------------------------------------------------ Definition at line 714 of file niml_elemio.c. References NI_stream_type::bad, NI_stream_type::buf, MARKED_FOR_DEATH, NI_stream_type::nbuf, and NI_stream_type::npos. Referenced by NI_decode_one_double(), NI_decode_one_string(), NI_read_element(), NI_stream_readbuf(), NI_stream_readbuf64(), and scan_for_angles().
00715 {
00716 if( ns == NULL || ns->npos <= 0 || ns->nbuf <= 0 ) return ;
00717 if( ns->buf == NULL || ns->bad == MARKED_FOR_DEATH ) return ;
00718
00719 if( ns->npos < ns->nbuf ){ /* haven't used up all data yet */
00720 memmove( ns->buf, ns->buf+ns->npos, ns->nbuf-ns->npos ) ;
00721 ns->nbuf -= ns->npos ;
00722 } else {
00723 ns->nbuf = 0 ; /* all data in buffer is used up */
00724 }
00725 ns->npos = 0 ; /* further scanning starts at beginning */
00726 }
|
|
|
Set the mode for writing type names:
Definition at line 877 of file niml_elemio.c. References name_mode, NI_ATTMODE_LAST, and NI_NAMEMODE_NORMAL.
00878 {
00879 if( nmode > 0 && nmode <= NI_ATTMODE_LAST ) name_mode = nmode ;
00880 else name_mode = NI_NAMEMODE_NORMAL;
00881 }
|
|
|
Definition at line 80 of file niml_elemio.c. References r, and skip_procins. Referenced by THD_load_3D(), and THD_open_3D().
00080 { skip_procins = r ; } /* 03 Jun 2005 */
|
|
|
Return the type name given the integer code. Definition at line 886 of file niml_elemio.c. References name_mode, NI_NAMEMODE_ALIAS, NI_rowtype_code_to_alias(), and NI_rowtype_code_to_name(). Referenced by NI_write_element().
00887 {
00888 return (name_mode == NI_NAMEMODE_ALIAS) ? NI_rowtype_code_to_alias(code)
00889 : NI_rowtype_code_to_name (code) ;
00890 }
|
|
||||||||||||||||
|
Write an element (data or group) to a stream. Return value is number of bytes written to the stream. If return is -1, something bad happened. You should then check the stream with NI_stream_goodcheck(), for example. If the stream is temporarily unable to write (e.g., the socket buffer is full), then this function will wait until it is ready. If you don't want that behavior, you should use NI_stream_writecheck() before calling this function. -------------------------------------------------------------------------- Definition at line 904 of file niml_elemio.c. References att_len, NI_element::attr_lhs, NI_group::attr_lhs, NI_procins::attr_lhs, NI_element::attr_num, NI_group::attr_num, NI_procins::attr_num, NI_element::attr_rhs, NI_group::attr_rhs, NI_procins::attr_rhs, NI_stream_type::bad, cbuf, NI_element::name, NI_group::name, NI_procins::name, NI_BASE64_MODE, NI_BINARY_MODE, NI_byteorder(), NI_dpr(), NI_ELEMENT_TYPE, NI_element_type(), NI_free, NI_GROUP_TYPE, NI_has_String(), NI_HEADERONLY_FLAG, NI_HEADERSHARP_FLAG, NI_is_name(), NI_LSB_FIRST, NI_malloc, NI_PROCINS_TYPE, NI_realloc, NI_rowtype_find_code(), NI_set_attribute(), NI_size_column(), NI_stream_goodcheck(), NI_stream_write(), NI_stream_writeable(), NI_stream_writecheck(), NI_stream_writestring(), NI_STRING_TYPE, NI_strlen(), NI_TEXT_MODE, NI_type_name(), NI_write_columns(), NI_element::outmode, NI_group::outmode, NI_group::part, NI_group::part_num, quotize_float_vector(), quotize_int_vector(), quotize_string(), quotize_string_vector(), tt, NI_stream_type::type, NI_element::vec, NI_element::vec_axis_delta, NI_element::vec_axis_label, NI_element::vec_axis_len, NI_element::vec_axis_origin, NI_element::vec_axis_unit, NI_element::vec_len, NI_element::vec_num, NI_element::vec_rank, and NI_element::vec_typ. Referenced by AFNI_niml_redisplay_CB(), AFNI_niml_viewpoint_CB(), AFNI_version_check(), Dtable_to_nimlstring(), DWI_NIML_create_graph(), main(), nifti_set_afni_extension(), NIML_to_stderr(), SUMA_DsetInfo(), SUMA_Engine(), SUMA_FakeIt(), SUMA_nel_stdout(), SUMA_Paint_SO_ROIplanes_w(), SUMA_SaveVisualState(), SUMA_SendDset_Afni(), SUMA_SendToSuma(), SUMA_ShowNel(), SUMA_Write_DrawnROI_NIML(), THD_write_nimlatr(), v2s_write_outfile_niml(), and XSAVE_output().
00905 {
00906 char *wbuf , *att=NULL , *qtt , *btt ;
00907 int nwbuf , ii,jj,row,col , tt=NI_element_type(nini) , ntot=0,nout ;
00908 int att_len , kk ;
00909
00910 char *bbuf , *cbuf ; /* base64 stuff */
00911 int bb=0 , cc=0 ;
00912
00913 char *att_prefix , *att_equals , *att_trail ;
00914 int header_only , header_sharp , outmode ;
00915
00916 /*--- 09 Mar 2005: outmode overrided tmode, if present ---*/
00917
00918 switch( tt ){
00919 default: return -1 ; /* bad input! */
00920
00921 case NI_GROUP_TYPE:{
00922 NI_group *ngr = (NI_group *) nini ;
00923 outmode = ngr->outmode ;
00924 }
00925 break ;
00926
00927 case NI_ELEMENT_TYPE:{
00928 NI_element *nel = (NI_element *) nini ;
00929 outmode = nel->outmode ;
00930 }
00931 break ;
00932
00933 case NI_PROCINS_TYPE:{ /* 16 Mar 2005 */
00934 outmode = NI_TEXT_MODE ;
00935 }
00936 break ;
00937 }
00938 if( outmode >= 0 ) tmode = outmode ;
00939
00940 /*--- determine special cases from the flags above bit #7 ---*/
00941
00942 header_only = ((tmode & NI_HEADERONLY_FLAG ) != 0) ; /* 20 Feb 2003 */
00943 header_sharp = ((tmode & NI_HEADERSHARP_FLAG) != 0) ; /* 20 Mar 2003 */
00944
00945 /* ADDOUT = after writing, add byte count if OK, else quit */
00946 /* AF = thing to do if ADDOUT is quitting */
00947
00948 #ifdef NIML_DEBUG
00949 NI_dpr("ENTER NI_write_element\n") ;
00950 #endif
00951
00952 #undef AF
00953 #define AF 0
00954 #define ADDOUT if(nout<0){AF;fprintf(stderr,"NIML: write abort!\n");return -1;} else ntot+=nout
00955
00956 if( !NI_stream_writeable(ns) ) return -1 ; /* stupid user */
00957
00958 if( ns->bad ){ /* socket that hasn't connected yet */
00959 #ifdef NIML_DEBUG
00960 NI_dpr("NI_write_element: write socket not connected\n") ;
00961 #endif
00962 jj = NI_stream_goodcheck(ns,666) ; /* try to connect it */
00963 if( jj < 1 ) return jj ; /* 0 is nothing yet, -1 is death */
00964 #ifdef NIML_DEBUG
00965 NI_dpr("NI_write_element: write socket now connected\n") ;
00966 #endif
00967 } else { /* check if good ns has gone bad */
00968 jj = NI_stream_writecheck(ns,666) ;
00969 if( jj < 0 ) return jj ;
00970 }
00971
00972 tmode &= 255 ;
00973 if( ns->type == NI_STRING_TYPE ) /* string output only in text mode */
00974 tmode = NI_TEXT_MODE ;
00975
00976 if( tmode != NI_TEXT_MODE ) header_sharp = 0 ; /* 20 Mar 2003 */
00977
00978 /*-- 15 Oct 2002: write attributes with lots of space, or little --*/
00979 /*-- 20 Mar 2003: modified for "# lhs = rhs" type of header --*/
00980
00981 att_prefix = (header_sharp) ? (char *)"\n# " /* write this before each attribute */
00982 : (char *)"\n " ;
00983
00984 att_equals = (header_sharp) ? (char *)" = " /* write this between lhs and rhs */
00985 : (char *)"=" ;
00986
00987 att_trail = (header_sharp) ? (char *)"\n# " /* write this before closing ">" */
00988 : (char *)" " ;
00989
00990 /*------------------ write a processing instruction ------------------*/
00991
00992 if( tt == NI_PROCINS_TYPE ){
00993
00994 NI_procins *npi = (NI_procins *)nini ;
00995
00996 if( header_sharp ){ nout = NI_stream_writestring(ns,"# "); ADDOUT; }
00997
00998 nout = NI_stream_writestring( ns , "<?" ) ; ADDOUT ;
00999 nout = NI_stream_writestring( ns , npi->name ) ; ADDOUT ;
01000
01001 /*- attributes -*/
01002
01003 for( ii=0 ; ii < npi->attr_num ; ii++ ){
01004
01005 jj = NI_strlen( npi->attr_lhs[ii] ) ; if( jj == 0 ) continue ;
01006 nout = NI_stream_writestring( ns , " " ) ; ADDOUT ;
01007 if( NI_is_name(npi->attr_lhs[ii]) ){
01008 nout = NI_stream_write( ns , npi->attr_lhs[ii] , jj ) ;
01009 } else {
01010 att = quotize_string( npi->attr_lhs[ii] ) ;
01011 nout = NI_stream_writestring( ns , att ) ; NI_free(att) ;
01012 }
01013 ADDOUT ;
01014
01015 jj = NI_strlen( npi->attr_rhs[ii] ) ; if( jj == 0 ) continue ;
01016 nout = NI_stream_writestring( ns , "=" ) ; ADDOUT ;
01017 att = quotize_string( npi->attr_rhs[ii] ) ;
01018 nout = NI_stream_writestring( ns , att ) ; NI_free(att) ; ADDOUT ;
01019 }
01020
01021 nout = NI_stream_writestring( ns , " ?>\n" ) ; ADDOUT ;
01022
01023 return ntot ; /*** done with processing instruction ***/
01024
01025 /*------------------ write a group element ------------------*/
01026
01027 } else if( tt == NI_GROUP_TYPE ){
01028
01029 NI_group *ngr = (NI_group *) nini ;
01030 char *gname ;
01031
01032 /* 24 Feb 2005: all group elements used to be named "ni_group",
01033 but no more; now they have attribute ni_form="ni_group" */
01034
01035 gname = ngr->name ;
01036 if( gname == NULL || *gname == '\0' ) gname = "ni_group" ;
01037
01038 /*- group header -*/
01039
01040 if( header_sharp ){ nout = NI_stream_writestring(ns,"# "); ADDOUT; }
01041 #if 1
01042 nout = NI_stream_writestring( ns , "<" ) ; ADDOUT ;
01043 nout = NI_stream_writestring( ns , gname ) ; ADDOUT ;
01044 #else
01045 nout = NI_stream_writestring( ns , "<ni_group" ) ; ADDOUT ;
01046 #endif
01047
01048 /*- attributes -*/
01049
01050 NI_set_attribute( ngr , "ni_form" , "ni_group" ) ; /* 24 Feb 2005 */
01051
01052 for( ii=0 ; ii < ngr->attr_num ; ii++ ){
01053
01054 jj = NI_strlen( ngr->attr_lhs[ii] ) ; if( jj == 0 ) continue ;
01055 nout = NI_stream_writestring( ns , att_prefix ) ; ADDOUT ;
01056 if( NI_is_name(ngr->attr_lhs[ii]) ){
01057 nout = NI_stream_write( ns , ngr->attr_lhs[ii] , jj ) ;
01058 } else {
01059 att = quotize_string( ngr->attr_lhs[ii] ) ;
01060 nout = NI_stream_writestring( ns , att ) ; NI_free(att) ;
01061 }
01062 ADDOUT ;
01063
01064 jj = NI_strlen( ngr->attr_rhs[ii] ) ; if( jj == 0 ) continue ;
01065 nout = NI_stream_writestring( ns , att_equals ) ; ADDOUT ;
01066 att = quotize_string( ngr->attr_rhs[ii] ) ;
01067 nout = NI_stream_writestring( ns , att ) ; NI_free(att) ; ADDOUT ;
01068 }
01069
01070 /*- close group header -*/
01071
01072 nout = NI_stream_writestring( ns , att_trail ) ; ADDOUT ;
01073 nout = NI_stream_writestring( ns , ">\n" ) ; ADDOUT ;
01074
01075 /*- write the group parts (recursively) -*/
01076
01077 for( ii=0 ; ii < ngr->part_num ; ii++ ){
01078 nout = NI_write_element( ns , ngr->part[ii] , tmode ) ; ADDOUT ;
01079 }
01080
01081 /*- group trailer -*/
01082
01083 if( header_sharp ){ nout = NI_stream_writestring(ns,"# "); ADDOUT; }
01084 #if 1
01085 nout = NI_stream_writestring( ns , "</" ) ; ADDOUT ;
01086 nout = NI_stream_writestring( ns , gname ) ; ADDOUT ;
01087 nout = NI_stream_writestring( ns , ">\n" ) ; ADDOUT ;
01088 #else
01089 nout = NI_stream_writestring( ns , "</ni_group>\n" ) ; ADDOUT ;
01090 #endif
01091
01092 return ntot ; /*** done with group element ***/
01093
01094 /*------------------ write a data element ------------------*/
01095
01096 } else if( tt == NI_ELEMENT_TYPE ){
01097
01098 NI_element *nel = (NI_element *) nini ;
01099
01100 /*- sanity check (should never fail) -*/
01101
01102 jj = NI_strlen(nel->name) ; if( jj == 0 ) return -1 ;
01103
01104 /*- select the data output mode -*/
01105
01106 /* Strings can only be written in text mode */
01107
01108 if( tmode != NI_TEXT_MODE ){
01109 for( jj=0 ; jj < nel->vec_num ; jj++ ){
01110 if( NI_has_String(NI_rowtype_find_code(nel->vec_typ[jj])) ){
01111 tmode = NI_TEXT_MODE ; break ;
01112 }
01113 }
01114 }
01115
01116 switch( tmode ){
01117 default: tmode = NI_TEXT_MODE ; break ;
01118
01119 case NI_BINARY_MODE: break ;
01120 case NI_BASE64_MODE: break ;
01121 }
01122
01123 /* space to hold attribute strings */
01124
01125 att_len = 8192 + 64*nel->vec_num + 128*nel->vec_rank ;
01126 att = NI_malloc(char, att_len ) ;
01127
01128 #undef AF
01129 #define AF NI_free(att) /* free att if we have to quit early now */
01130
01131 /* write start of header "<name" */
01132
01133 if( header_sharp ){ nout = NI_stream_writestring(ns,"# "); ADDOUT; }
01134 strcpy(att,"<") ; strcat(att,nel->name) ;
01135 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01136
01137 /*- write "special" attributes, if not an empty element -*/
01138
01139 if( nel->vec_len > 0 && nel->vec_num > 0 ){
01140 int ll , tt ;
01141
01142 /* ni_form (depends on tmode) */
01143
01144 switch( tmode ){
01145 default:
01146 case NI_TEXT_MODE:
01147 *att = '\0' ; /* text form is default */
01148 break ;
01149
01150 case NI_BINARY_MODE:
01151 case NI_BASE64_MODE:
01152 sprintf(att,"%sni_form%s\"%s.%s\"" ,
01153 att_prefix , att_equals ,
01154 (tmode == NI_BINARY_MODE) ? "binary" : "base64" ,
01155 (NI_byteorder()==NI_LSB_FIRST) ? "lsbfirst" : "msbfirst" );
01156 break ;
01157 }
01158 if( *att != '\0' ){
01159 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01160 }
01161
01162 /** do ni_type **/
01163
01164 sprintf(att,"%sni_type%s\"" , att_prefix , att_equals ) ;
01165 for( ll=-1,ii=0 ; ii < nel->vec_num ; ii++ ){
01166 if( nel->vec_typ[ii] != ll ){ /* not the previous type */
01167 if( ll >= 0 ){ /* write the previous type out now */
01168 btt = att + strlen(att) ;
01169 if( jj > 1 ) sprintf(btt,"%d*%s,",jj,NI_type_name(ll)) ;
01170 else sprintf(btt,"%s," , NI_type_name(ll)) ;
01171 }
01172 ll = nel->vec_typ[ii] ; /* save new type code */
01173 jj = 1 ; /* it now has count 1 */
01174
01175 } else { /* same as previous type */
01176 jj++ ; /* so add 1 to its count */
01177 }
01178 }
01179 /* write the last type we found */
01180 btt = att + strlen(att) ;
01181 if( jj > 1 ) sprintf(btt,"%d*%s\"",jj,NI_type_name(ll)) ;
01182 else sprintf(btt,"%s\"" , NI_type_name(ll)) ;
01183
01184 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01185
01186 /** do ni_dimen **/
01187
01188 if( nel->vec_rank > 1 ){
01189 sprintf(att,"%sni_dimen%s" , att_prefix , att_equals ) ;
01190 qtt = quotize_int_vector( nel->vec_rank ,
01191 nel->vec_axis_len , ',' ) ;
01192 strcat(att,qtt) ; NI_free(qtt) ;
01193 } else {
01194 sprintf(att,"%sni_dimen%s\"%d\"",att_prefix,att_equals,nel->vec_len);
01195 }
01196 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01197
01198 #if 0
01199 /** 26 Mar 2003: write number of bytes of data contained herein **/
01200
01201 for( jj=ii=0 ; ii < nel->vec_num ; ii++ )
01202 jj += NI_size_column( NI_rowtype_find_code(nel->vec_typ[ii]) ,
01203 nel->vec_len , nel->vec[ii] ) ;
01204 sprintf(att,"%sni_datasize%s\"%d\"" , att_prefix , att_equals , jj ) ;
01205 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01206 #endif
01207
01208 #if 0
01209 /* extras: ni_veclen and ni_vecnum attributes */
01210
01211 sprintf(att,"%sni_veclen%s\"%d\"", att_prefix,att_equals,nel->vec_len) ;
01212 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01213
01214 sprintf(att,"%sni_vecnum%s\"%d\"", att_prefix,att_equals,nel->vec_num) ;
01215 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01216 #endif
01217 /* ni_delta */
01218
01219 if( nel->vec_axis_delta != NULL ){
01220 sprintf(att,"%sni_delta%s",att_prefix,att_equals) ;
01221 qtt = quotize_float_vector( nel->vec_rank ,
01222 nel->vec_axis_delta , ',' ) ;
01223 strcat(att,qtt) ; NI_free(qtt) ;
01224 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01225 }
01226
01227 /* ni_origin */
01228
01229 if( nel->vec_axis_origin != NULL ){
01230 sprintf(att,"%sni_origin%s",att_prefix,att_equals) ;
01231 qtt = quotize_float_vector( nel->vec_rank ,
01232 nel->vec_axis_origin , ',' ) ;
01233 strcat(att,qtt) ; NI_free(qtt) ;
01234 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01235 }
01236
01237 /* ni_units */
01238
01239 if( nel->vec_axis_unit != NULL ){
01240 sprintf(att,"%sni_units%s",att_prefix,att_equals) ;
01241 qtt = quotize_string_vector( nel->vec_rank ,
01242 nel->vec_axis_unit , ',' ) ;
01243 strcat(att,qtt) ; NI_free(qtt) ;
01244 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01245 }
01246
01247 /* ni_axes */
01248
01249 if( nel->vec_axis_label != NULL ){
01250 sprintf(att,"%sni_axes%s",att_prefix,att_equals) ;
01251 qtt = quotize_string_vector( nel->vec_rank ,
01252 nel->vec_axis_label , ',' ) ;
01253 strcat(att,qtt) ; NI_free(qtt) ;
01254 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01255 }
01256
01257 }
01258
01259 /*- other attributes -*/
01260
01261 for( ii=0 ; ii < nel->attr_num ; ii++ ){
01262
01263 jj = NI_strlen( nel->attr_lhs[ii] ) ; if( jj == 0 ) continue ;
01264
01265 /* skip "special" attributes */
01266
01267 if( strcmp(nel->attr_lhs[ii],"ni_form") == 0 ) continue ;
01268 if( strcmp(nel->attr_lhs[ii],"ni_type") == 0 ) continue ;
01269 if( strcmp(nel->attr_lhs[ii],"ni_dimen") == 0 ) continue ;
01270 if( strcmp(nel->attr_lhs[ii],"ni_veclen") == 0 ) continue ;
01271 if( strcmp(nel->attr_lhs[ii],"ni_vecnum") == 0 ) continue ;
01272 if( strcmp(nel->attr_lhs[ii],"ni_delta") == 0 ) continue ;
01273 if( strcmp(nel->attr_lhs[ii],"ni_origin") == 0 ) continue ;
01274 if( strcmp(nel->attr_lhs[ii],"ni_units") == 0 ) continue ;
01275 if( strcmp(nel->attr_lhs[ii],"ni_axes") == 0 ) continue ;
01276 if( strcmp(nel->attr_lhs[ii],"ni_datasize") == 0 ) continue ; /* 13 Apr 2004 */
01277
01278 kk = NI_strlen( nel->attr_rhs[ii] ) ;
01279
01280 /* do the work */
01281
01282 if( jj+kk+128 > att_len ){ /* 13 Jun 2003 */
01283 att_len = jj+kk+128 ;
01284 att = NI_realloc( att , char, att_len ) ;
01285 }
01286
01287 strcpy(att,att_prefix) ;
01288
01289 if( NI_is_name(nel->attr_lhs[ii]) ){ /* the 'normal' case */
01290 strcat(att,nel->attr_lhs[ii]) ;
01291 } else { /* not legal in XML */
01292 qtt = quotize_string( nel->attr_lhs[ii] ) ;
01293 strcat(att,qtt) ; NI_free(qtt) ;
01294 }
01295
01296 if( kk > 0 ){
01297 strcat(att,att_equals) ;
01298 qtt = quotize_string( nel->attr_rhs[ii] ) ; /* RHS always quoted */
01299 strcat(att,qtt) ; NI_free(qtt) ;
01300 }
01301 nout = NI_stream_writestring( ns , att ) ; ADDOUT ;
01302 }
01303
01304 NI_free(att) ; att = NULL ; /* done with attributes */
01305
01306 #undef AF
01307 #define AF 0 /* nothing to do if we have to quit early */
01308
01309 /*- close header -*/
01310
01311 if( nel->vec_len == 0 || /* An 'empty' element (no data) */
01312 nel->vec_num == 0 ||
01313 nel->vec_typ == NULL ||
01314 nel->vec == NULL ){
01315
01316 nout = NI_stream_writestring( ns , att_trail ) ; ADDOUT ;
01317 nout = NI_stream_writestring( ns , "/>\n" ) ; ADDOUT ;
01318
01319 #ifdef NIML_DEBUG
01320 NI_dpr("NI_write_element: empty element '%s' had %d total bytes\n",nel->name,ntot) ;
01321 #endif
01322 return ntot ; /*** done with empty data element ***/
01323 }
01324
01325 /*- if here, must write some data out -*/
01326
01327 /* first, terminate the header,
01328 and allocate space for the write buffer (1 row at a time) */
01329
01330 switch( tmode ){
01331 default:
01332 case NI_TEXT_MODE:
01333 btt = ">\n" ; /* add a newline */
01334 break ;
01335
01336 case NI_BINARY_MODE:
01337 btt = ">" ; /* no newline */
01338 break ;
01339
01340 case NI_BASE64_MODE:
01341 btt = ">\n" ; /* add a newline */
01342 break ;
01343 }
01344
01345 nout = NI_stream_writestring( ns , att_trail ) ; ADDOUT ;
01346 nout = NI_stream_writestring( ns , btt ) ; ADDOUT ;
01347
01348 /*-- 13 Feb 2003: data output is now done elsewhere --*/
01349
01350 if( !header_only ){
01351 nout = NI_write_columns( ns, nel->vec_num, nel->vec_typ,
01352 nel->vec_len, nel->vec , tmode ) ;
01353 ADDOUT ;
01354 }
01355 #ifdef NIML_DEBUG
01356 else NI_dpr("NI_write_element: header_only case\n") ;
01357 #endif
01358
01359 /*- write element trailer -*/
01360
01361 if( header_sharp ){ nout = NI_stream_writestring(ns,"# "); ADDOUT; }
01362 nout = NI_stream_writestring( ns , "</" ) ; ADDOUT ;
01363 nout = NI_stream_writestring( ns , nel->name ) ; ADDOUT ;
01364 nout = NI_stream_writestring( ns , ">\n\n" ) ; ADDOUT ;
01365
01366 #ifdef NIML_DEBUG
01367 NI_dpr("NI_write_element: data element '%s' had %d total bytes\n",nel->name,ntot) ;
01368 #endif
01369 return ntot ; /*** done with full data element ***/
01370
01371 } /* end of write data element */
01372
01373 return -1 ; /* should never be reachable */
01374 }
|
|
||||||||||||
|
Write a simple processing instruction to the stream:
Definition at line 45 of file niml_elemio.c. References NI_stream_type::bad, free, IS_STRING_CHAR, malloc, NI_stream_goodcheck(), NI_stream_writeable(), NI_stream_writecheck(), and NI_stream_writestring(). Referenced by main(), and SUMA_SendDset_Afni().
00046 {
00047 char *buf ; int jj ;
00048
00049 /* check inputs for good-ositifulness */
00050
00051 if( !NI_stream_writeable(ns) ) return -1 ; /* stupid user */
00052 if( str == NULL || !IS_STRING_CHAR(*str) ) return -1 ;
00053
00054 /* check if stream is ready to take data */
00055
00056 if( ns->bad ){ /* socket that hasn't connected yet */
00057 jj = NI_stream_goodcheck(ns,666) ; /* try to connect it */
00058 if( jj < 1 ) return jj ; /* 0 is nothing yet, -1 is death */
00059 } else { /* check if good ns has gone bad */
00060 jj = NI_stream_writecheck(ns,666) ;
00061 if( jj < 0 ) return jj ;
00062 }
00063
00064 /* write the processing instruction: "<?str ?>\n" */
00065
00066 buf = (char *)malloc(strlen(str)+16) ;
00067 sprintf( buf , "<?%s ?>\n" , str ) ;
00068 jj = NI_stream_writestring( ns , buf ) ;
00069
00070 free((void *)buf) ; return jj ;
00071 }
|
|
||||||||||||
|
Scan stream for an element header or trailer:'<characters>', starting at byte offset ns->npos, and waiting msec milliseconds. Returns with the stream buffer set so that the opening '<' is at ns->buf[ns->npos] and the closing '>' is at ns->buf[q-1], where q is this function's return value. Note that read operations may change ns->npos from its value when this function was called. If the return value is -1, then we couldn't find a '<stuff>' string. This may be due to:
Definition at line 750 of file niml_elemio.c. References NI_stream_type::bad, NI_stream_type::buf, NI_stream_type::bufsize, free, malloc, MARKED_FOR_DEATH, NI_stream_type::nbuf, NI_clock_time(), NI_reset_buffer(), NI_stream_fillbuf(), and NI_stream_type::npos. Referenced by NI_read_element().
00751 {
00752 int nn, epos, need_data, num_restart ;
00753 char goal ;
00754 int start_time = NI_clock_time() , mleft , nbmin ;
00755 int caseb=0 ; /* 1 => force rescan even if time is up */
00756
00757 if( ns == NULL ) return -1 ; /* bad input */
00758
00759 if( ns->buf == NULL || ns->bad == MARKED_FOR_DEATH ) return -1 ;
00760
00761 epos = ns->npos ;
00762
00763 if( msec < 0 ) msec = 999999999 ; /* a long time (11+ days) */
00764
00765 /*-- Will loop back here if we have to re-read/re-scan --*/
00766
00767 goal = '<' ; /* first goal is opening '<' (second goal is '>') */
00768 num_restart = 0 ;
00769 Restart: /* loop back here to retry */
00770 num_restart++ ;
00771 mleft = msec - (NI_clock_time()-start_time) ; /* time left */
00772
00773 if( num_restart > 3 && mleft <= 0 && !caseb ){ /* failure */
00774 NI_reset_buffer(ns) ; /* and out of time */
00775 return -1 ;
00776 }
00777
00778 /*-- scan ahead to find goal character in the buffer --*/
00779
00780 while( epos < ns->nbuf && ns->buf[epos] != goal ) epos++ ;
00781
00782 /*-- if we found our goal, do something about it --*/
00783
00784 if( epos < ns->nbuf ){
00785
00786 /*-- if our goal was the closing '>', we are done! (maybe) --*/
00787
00788 if( goal == '>' ){
00789
00790 /*- 01 Jun 2005: see if we are at a comment; if so, must start over -*/
00791
00792 if( epos - ns->npos >= 4 && strncmp(ns->buf+ns->npos,"<!--",4) == 0 ){
00793
00794 if( strncmp(ns->buf+epos-2,"-->",3) == 0 ){ /* got a full comment */
00795
00796 #if 0
00797 { int ncp = 1+epos-ns->npos ; char *cpt=malloc(10+ncp) ;
00798 memcpy(cpt,ns->buf+ns->npos,ncp) ; cpt[ncp] = '\0' ;
00799 fprintf(stderr, "\nSkipping NIML comment: '%s'\n",cpt); free(cpt);
00800 }
00801 #endif
00802
00803 ns->npos = epos+1 ; NI_reset_buffer(ns) ; /* skip it & try again */
00804 epos = 0 ; goal = '<' ;
00805 } else { /* '>' doesn't close comment! */
00806 epos++ ; /* so look for another one!!! */
00807 }
00808 caseb = 1 ; goto Restart ;
00809 }
00810
00811 /*** not a comment, so we can exit triumphantly! ***/
00812
00813 return epos+1 ; /* marks the character after '>' */
00814 }
00815
00816 /*-- if here, our goal was the opening '<';
00817 set the buffer position to this location,
00818 set the new goal, and scan for the new goal --*/
00819
00820 ns->npos = epos ; /* mark where we found '<' */
00821 goal = '>' ; /* the new goal */
00822 caseb = 1 ; /* force rescan, even if time is up */
00823 goto Restart ; /* scan again! */
00824 }
00825
00826 /*-- if we get to here, we didn't find our goal:
00827 (a) if the goal was the opening '<', then throw
00828 away all data in the buffer, and get some more data
00829 (b) if the goal was the closing '>', then we need more data
00830 in the buffer, but need to keep the existing data
00831 (c) UNLESS the buffer is full AND npos is zero
00832 - in this case, the universe ends right here and now --*/
00833
00834 if( goal == '<' ){ /* case (a) */
00835
00836 ns->nbuf = ns->npos = epos = 0 ; caseb = 0 ;
00837
00838 } else if( ns->nbuf < ns->bufsize || ns->npos > 0 ){ /* case (b) */
00839
00840 NI_reset_buffer(ns) ; epos = ns->nbuf ; caseb = 1 ;
00841
00842 } else { /* case (c) */
00843
00844 ns->nbuf = 0 ; return -1 ; /* death of Universe! */
00845 }
00846
00847 /*-- if we are here, we need more data before scanning again --*/
00848
00849 /*-- read at least nbmin bytes,
00850 waiting up to mleft ms (unless the data stream goes bad) --*/
00851
00852 if( mleft <= 0 ) mleft = 1 ;
00853 nbmin = (goal == '<') ? 4 : 1 ;
00854
00855 nn = NI_stream_fillbuf( ns , nbmin , mleft ) ;
00856
00857 if( nn >= nbmin ) caseb = 1 ; /* got new data => force rescan */
00858
00859 if( nn >= 0 ) goto Restart ; /* scan some more for the goal */
00860
00861 /*-- if here, the stream went bad, so exit --*/
00862
00863 ns->nbuf = ns->npos = 0 ; return -1 ;
00864 }
|
Variable Documentation
|
|
Mode for writing names. Definition at line 869 of file niml_elemio.c. Referenced by NI_set_typename_mode(), and NI_type_name(). |
|
|
Definition at line 76 of file niml_elemio.c. Referenced by NI_read_element(), NI_read_element_header(), and NI_read_header_only(). |
|
|
Definition at line 79 of file niml_elemio.c. Referenced by NI_skip_procins(). |