00001 #include "niml_private.h"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 typedef struct { char a; byte b; } Qadgop_byte ;
00013 typedef struct { char a; short b; } Qadgop_short ;
00014 typedef struct { char a; int b; } Qadgop_int ;
00015 typedef struct { char a; float b; } Qadgop_float ;
00016 typedef struct { char a; double b; } Qadgop_double ;
00017 typedef struct { char a; complex b; } Qadgop_complex ;
00018 typedef struct { char a; rgb b; } Qadgop_rgb ;
00019 typedef struct { char a; rgba b; } Qadgop_rgba ;
00020
00021
00022
00023 static int type_alignment[NI_NUM_BASIC_TYPES+1] ;
00024 static int type_size [NI_NUM_BASIC_TYPES+1] ;
00025 static char *type_name [NI_NUM_BASIC_TYPES+1] = {
00026 "byte" , "short" , "int" ,
00027 "float" , "double" , "complex" ,
00028 "rgb" , "rgba" , "String"
00029 } ;
00030
00031 static char *type_alias[NI_NUM_BASIC_TYPES+1] = {
00032 "uint8" , "int16" , "int32" ,
00033 "float32" , "float64" , "complex64" ,
00034 "rgb8" , "rgba8" , "CString"
00035 } ;
00036
00037
00038
00039 typedef struct { char a; void *b; } Qadgop_pointer ;
00040 static int pointer_alignment ;
00041 static int pointer_size ;
00042
00043
00044
00045
00046 static Htable *rowtype_table = NULL ;
00047
00048
00049
00050
00051 static NI_rowtype **rowtype_array = NULL ;
00052 static int rowtype_num = 0 ;
00053
00054
00055
00056
00057 #define ROWTYPE_OFFSET 1001
00058
00059
00060
00061
00062
00063 #define ROWTYPE_BASE_CODE (ROWTYPE_OFFSET-NI_NUM_BASIC_TYPES-1)
00064
00065
00066
00067 #define ROWTYPE_is_builtin_code(cc) ((cc) >= 0 && (cc) < ROWTYPE_OFFSET)
00068
00069
00070
00071 #define ROWTYPE_register(rr) \
00072 do{ int nn ; \
00073 if( rowtype_table == NULL ) setup_basic_types() ; \
00074 addto_Htable( (rr)->name , (rr) , rowtype_table ) ; \
00075 nn = rowtype_num + 1 ; \
00076 rowtype_array = NI_realloc( rowtype_array , \
00077 NI_rowtype*, \
00078 sizeof(NI_rowtype *)*nn ); \
00079 rowtype_array[nn-1] = rr ; rowtype_num = nn ; \
00080 } while(0)
00081
00082
00083
00084
00085 static int ROWTYPE_debug = 0 ;
00086
00087
00088
00089 void NI_rowtype_debug( int n ){ ROWTYPE_debug = n ; }
00090
00091
00092
00093
00094 static void setup_basic_types(void)
00095 {
00096 NI_rowtype *rt ;
00097 int ii ;
00098
00099 if( rowtype_table != NULL ) return ;
00100
00101
00102
00103 type_alignment[NI_BYTE ] = offsetof(Qadgop_byte ,b) ;
00104 type_alignment[NI_SHORT ] = offsetof(Qadgop_short ,b) ;
00105 type_alignment[NI_INT ] = offsetof(Qadgop_int ,b) ;
00106 type_alignment[NI_FLOAT ] = offsetof(Qadgop_float ,b) ;
00107 type_alignment[NI_DOUBLE ] = offsetof(Qadgop_double ,b) ;
00108 type_alignment[NI_COMPLEX] = offsetof(Qadgop_complex,b) ;
00109 type_alignment[NI_RGB ] = offsetof(Qadgop_rgb ,b) ;
00110 type_alignment[NI_RGBA ] = offsetof(Qadgop_rgba ,b) ;
00111
00112 type_size[NI_BYTE ] = sizeof(byte ) ;
00113 type_size[NI_SHORT ] = sizeof(short ) ;
00114 type_size[NI_INT ] = sizeof(int ) ;
00115 type_size[NI_FLOAT ] = sizeof(float ) ;
00116 type_size[NI_DOUBLE ] = sizeof(double ) ;
00117 type_size[NI_COMPLEX] = sizeof(complex) ;
00118 type_size[NI_RGB ] = sizeof(rgb ) ;
00119 type_size[NI_RGBA ] = sizeof(rgba ) ;
00120
00121
00122
00123 rowtype_table = new_Htable(19) ;
00124
00125 for( ii=0 ; ii < NI_NUM_BASIC_TYPES ; ii++ ){
00126
00127 rt = NI_new( NI_rowtype ) ;
00128 rt->code = ii ;
00129 rt->size = type_size[ii] ;
00130 rt->psiz = rt->size ;
00131 rt->algn = type_alignment[ii] ;
00132 rt->name = NI_strdup(type_name[ii]);
00133 rt->userdef = NI_strdup(type_name[ii]);
00134 rt->flag = 0 ;
00135
00136 rt->comp_num = 1 ;
00137 rt->comp_typ = NI_malloc(int, sizeof(int)) ;
00138 rt->comp_typ[0] = ii ;
00139 rt->comp_dim = NI_malloc(int, sizeof(int)) ;
00140 rt->comp_dim[0] = -1 ;
00141
00142 rt->part_num = 1 ;
00143 rt->part_typ = NI_malloc(int, sizeof(int)) ;
00144 rt->part_typ[0] = ii ;
00145 rt->part_off = NI_malloc(int, sizeof(int)) ;
00146 rt->part_off[0] = 0 ;
00147 rt->part_siz = NI_malloc(int, sizeof(int)) ;
00148 rt->part_siz[0] = type_size[ii] ;
00149 rt->part_dim = NI_malloc(int, sizeof(int)) ;
00150 rt->part_dim[0] = -1 ;
00151 rt->part_rtp = NI_malloc(NI_rowtype*, sizeof(NI_rowtype *)) ;
00152 rt->part_rtp[0] = rt ;
00153
00154 ROWTYPE_register( rt ) ;
00155 }
00156
00157
00158
00159 pointer_alignment = offsetof(Qadgop_pointer,b) ;
00160 pointer_size = sizeof(void *) ;
00161
00162
00163
00164 type_alignment[NI_STRING] = pointer_alignment ;
00165 type_size [NI_STRING] = pointer_size ;
00166
00167 rt = NI_new( NI_rowtype ) ;
00168 rt->code = NI_STRING ;
00169 rt->size = pointer_size ;
00170 rt->psiz = 0 ;
00171 rt->algn = pointer_alignment ;
00172 rt->name = NI_strdup("String") ;
00173 rt->userdef = NI_strdup("String") ;
00174 rt->flag = ROWTYPE_VARSIZE_MASK ;
00175
00176 rt->comp_num = 1 ;
00177 rt->comp_typ = NI_malloc(int, sizeof(int)) ;
00178 rt->comp_typ[0] = NI_STRING ;
00179 rt->comp_dim = NI_malloc(int, sizeof(int)) ;
00180 rt->comp_dim[0] = -1 ;
00181
00182 rt->part_num = 1 ;
00183 rt->part_typ = NI_malloc(int, sizeof(int)) ;
00184 rt->part_typ[0] = NI_STRING ;
00185 rt->part_off = NI_malloc(int, sizeof(int)) ;
00186 rt->part_off[0] = 0 ;
00187 rt->part_siz = NI_malloc(int, sizeof(int)) ;
00188 rt->part_siz[0] = pointer_size ;
00189 rt->part_dim = NI_malloc(int, sizeof(int)) ;
00190 rt->part_dim[0] = -1 ;
00191
00192 rt->part_rtp = NI_malloc(NI_rowtype*, sizeof(NI_rowtype *)) ;
00193 rt->part_rtp[0] = rt ;
00194
00195 ROWTYPE_register( rt ) ;
00196
00197 if( ROWTYPE_debug )
00198 profile_Htable( "rowtype_table" , rowtype_table ) ;
00199 }
00200
00201
00202
00203
00204 #undef ERREX
00205 #define ERREX(str) \
00206 do { fprintf(stderr,"** NI_rowtype_define('%s','%s'): %s\n",tname,tdef,str); \
00207 return -1 ; } while(0)
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 int NI_rowtype_define( char *tname , char *tdef )
00267 {
00268 NI_rowtype *rt , *qt ;
00269 int ii,jj , id,jd,kd,isdim,nn , almax,cbase,np,pb , last_size ;
00270 NI_str_array *sar ;
00271 char *tp,*sp,*bp , str[256] ;
00272
00273
00274
00275 if( !NI_is_name(tname) ) ERREX("bad typename") ;
00276 if( strlen(tname) > 255 ) ERREX("toolong typename") ;
00277 if( tdef == NULL || *tdef == '\0' ) ERREX("empty type definition") ;
00278
00279
00280
00281 if( rowtype_table == NULL ) setup_basic_types() ;
00282
00283
00284
00285
00286 rt = NI_rowtype_find_name( tname ) ;
00287 if( rt != NULL ){
00288 if( strcmp(rt->userdef,tdef) != 0 ){
00289 fprintf(stderr,
00290 "++ NI_rowtype_define: illegal attempt to redefine type '%s'\n"
00291 "++ old definition: %s\n"
00292 "++ (failed) new definition: %s\n" ,
00293 tname , rt->userdef , tdef ) ;
00294 }
00295 return rt->code ;
00296 }
00297
00298
00299
00300 sar = NI_decode_string_list( tdef , ",;" ) ;
00301
00302 if( sar == NULL || sar->num < 1 ){
00303 NI_free(sar) ; ERREX("illegal definition") ;
00304 }
00305
00306
00307
00308 rt = NI_new( NI_rowtype ) ;
00309 rt->name = NI_strdup( tname ) ;
00310 rt->userdef = NI_strdup( tdef ) ;
00311 rt->flag = 0 ;
00312
00313
00314
00315 rt->part_num = rt->comp_num = 0 ;
00316
00317 for( ii=0 ; ii < sar->num ; ii++ ){
00318
00319 tp = sar->str[ii] ;
00320 id = 0 ; kd = strlen(tp) ;
00321 if( kd == 0 ){
00322 delete_rowtype(rt); NI_delete_str_array(sar); ERREX("empty component name?");
00323 }
00324
00325
00326
00327 sp = strchr(tp,'*') ;
00328 bp = strchr(tp,'[') ;
00329
00330 if( sp != NULL || bp != NULL ){
00331
00332 if( sp != NULL && bp != NULL ){
00333 delete_rowtype(rt); NI_delete_str_array(sar); ERREX("two repeat counts?");
00334 }
00335
00336 if( sp != NULL ){
00337 nn = 0 ;
00338 id = (sp-tp)+1 ;
00339 } else {
00340 kd = (bp-tp) ;
00341 nn = kd+1 ;
00342 }
00343
00344 jd = -1 ;
00345 if( tp[nn] != '#' ){
00346 isdim = 0 ;
00347 sscanf( tp+nn , "%d" , &jd ) ;
00348 if( jd <= 0 ){
00349 delete_rowtype(rt); NI_delete_str_array(sar); ERREX("bad repeat number");
00350 }
00351 } else {
00352 isdim = 1 ;
00353 sscanf( tp+nn+1 , "%d" , &jd ) ;
00354 if( jd <= 0 || jd > ii ){
00355 delete_rowtype(rt); NI_delete_str_array(sar); ERREX("bad #index");
00356 }
00357 if( rt->comp_typ[jd-1] != NI_INT ||
00358 rt->comp_dim[jd-1] >= 0 ){
00359 delete_rowtype(rt); NI_delete_str_array(sar); ERREX("non-int #index");
00360 }
00361 }
00362 } else {
00363 isdim = 0 ; jd = 1 ;
00364 }
00365
00366
00367
00368 if( kd-id < 1 || kd-id > 255 ){
00369 delete_rowtype(rt); NI_delete_str_array(sar); ERREX("toolong component name");
00370 }
00371
00372 NI_strncpy( str , tp+id , kd-id+1 ) ;
00373 qt = NI_rowtype_find_name( str ) ;
00374 if( qt == NULL ){
00375 delete_rowtype(rt); NI_delete_str_array(sar); ERREX("bad component type");
00376 }
00377
00378 if( !isdim ){
00379
00380 rt->comp_typ = NI_realloc( rt->comp_typ, int, sizeof(int)*(rt->comp_num+jd) );
00381 rt->comp_dim = NI_realloc( rt->comp_dim, int, sizeof(int)*(rt->comp_num+jd) );
00382
00383 for( jj=0 ; jj < jd ; jj++ ){
00384 rt->comp_typ[rt->comp_num + jj] = qt->code ;
00385 rt->comp_dim[rt->comp_num + jj] = -1 ;
00386 }
00387
00388 rt->comp_num += jd ;
00389 rt->part_num += jd * qt->part_num ;
00390
00391 if( ROWTYPE_is_varsize(qt) )
00392 rt->flag |= ROWTYPE_VARSIZE_MASK ;
00393
00394 } else {
00395
00396
00397
00398
00399
00400 if( ROWTYPE_is_varsize(qt) ){
00401 delete_rowtype(rt); NI_delete_str_array(sar);
00402 ERREX("variable dim array must have fixed dim type");
00403 }
00404
00405 rt->comp_typ = NI_realloc( rt->comp_typ, int, sizeof(int)*(rt->comp_num+1) );
00406 rt->comp_dim = NI_realloc( rt->comp_dim, int, sizeof(int)*(rt->comp_num+1) );
00407
00408 rt->comp_typ[rt->comp_num] = qt->code ;
00409 rt->comp_dim[rt->comp_num] = jd-1 ;
00410
00411 rt->comp_num ++ ;
00412 rt->part_num ++ ;
00413
00414 rt->flag |= ROWTYPE_VARSIZE_MASK ;
00415
00416 }
00417
00418 }
00419
00420 NI_delete_str_array(sar) ;
00421
00422 if( rt->part_num == 0 ){ delete_rowtype(rt); ERREX("no components?"); }
00423
00424
00425
00426
00427 rt->part_off = NI_malloc(int, sizeof(int) * rt->part_num ) ;
00428 rt->part_typ = NI_malloc(int, sizeof(int) * rt->part_num ) ;
00429 rt->part_dim = NI_malloc(int, sizeof(int) * rt->part_num ) ;
00430 rt->part_siz = NI_malloc(int, sizeof(int) * rt->part_num ) ;
00431 rt->part_rtp = NI_malloc(NI_rowtype*, sizeof(NI_rowtype *) * rt->part_num ) ;
00432
00433 almax = 1 ;
00434 cbase = 0 ;
00435 id = 0 ;
00436
00437 for( ii=0 ; ii < rt->comp_num ; ii++ ){
00438
00439
00440 if( rt->comp_dim[ii] >= 0 ){
00441
00442
00443 if( pointer_alignment > 1 ){
00444 jd = cbase % pointer_alignment ;
00445 if( jd > 0 ) cbase += (pointer_alignment-jd) ;
00446 }
00447
00448
00449
00450
00451
00452
00453
00454 rt->part_typ[id] = rt->comp_typ[ii] ;
00455 rt->part_off[id] = cbase ;
00456 rt->part_siz[id] = pointer_size ;
00457 rt->part_rtp[id] = NI_rowtype_find_code( rt->part_typ[id] ) ;
00458
00459
00460
00461
00462 for( jd=kd=0 ; jd < rt->comp_dim[ii] ; jd++ ){
00463 if( rt->comp_dim[jd] >= 0 ){
00464 kd++ ;
00465 } else {
00466 qt = NI_rowtype_find_code( rt->comp_typ[jd] ) ;
00467 kd += qt->part_num ;
00468 }
00469 }
00470 rt->part_dim[id] = kd ;
00471
00472 kd = pointer_alignment ;
00473 if( kd > almax ) almax = kd ;
00474
00475 id++ ; cbase += pointer_size ;
00476
00477 } else {
00478
00479 qt = NI_rowtype_find_code( rt->comp_typ[ii] ) ;
00480
00481
00482
00483 if( qt->algn > 1 ){
00484 jd = cbase % qt->algn ;
00485 if( jd > 0 ) cbase += (qt->algn-jd) ;
00486 }
00487
00488 pb = id ;
00489 np = qt->part_num ;
00490
00491 rt->part_typ[id] = qt->part_typ[0] ;
00492 rt->part_off[id] = cbase ;
00493 rt->part_dim[id] = -1 ;
00494 rt->part_rtp[id] = NI_rowtype_find_code( rt->part_typ[id] ) ;
00495
00496 kd = rt->part_rtp[id]->algn ;
00497 if( kd > almax ) almax = kd ;
00498
00499 last_size = rt->part_rtp[id]->size ;
00500 rt->part_siz[id] = last_size ;
00501
00502 id++ ;
00503
00504
00505
00506 for( jj=1 ; jj < np ; jj++,id++ ){
00507
00508 rt->part_typ[id] = qt->part_typ[jj] ;
00509 rt->part_rtp[id] = NI_rowtype_find_code( rt->part_typ[id] ) ;
00510
00511 if( qt->part_dim[jj] < 0 ){
00512
00513 nn = last_size ;
00514 jd = rt->part_off[id-1] ;
00515 kd = rt->part_rtp[id]->algn ;
00516 if( kd > almax ) almax = kd ;
00517
00518 nn += jd ;
00519 if( kd > 1 ){
00520 jd = nn % kd ;
00521 if( jd > 0 ) nn += (kd-jd) ;
00522 }
00523 rt->part_off[id] = nn ;
00524 rt->part_dim[id] = -1 ;
00525
00526 last_size = rt->part_rtp[id]->size ;
00527 rt->part_siz[id] = last_size ;
00528
00529 } else {
00530
00531 nn = last_size ;
00532 jd = rt->part_off[id-1] ;
00533 kd = pointer_alignment ;
00534 if( kd > almax ) almax = kd ;
00535 nn += jd ;
00536 if( kd > 1 ){
00537 jd = nn % kd ;
00538 if( jd > 0 ) nn += (kd-jd) ;
00539 }
00540 rt->part_off[id] = nn ;
00541 last_size = pointer_size ;
00542 rt->part_siz[id] = last_size ;
00543
00544
00545
00546
00547
00548 rt->part_dim[id] = pb + qt->part_dim[jj] ;
00549
00550 }
00551
00552 }
00553
00554
00555
00556
00557 cbase += qt->size ;
00558
00559 }
00560
00561 }
00562
00563
00564
00565
00566
00567
00568
00569 rt->algn = almax ;
00570 if( rt->algn > 1 ){
00571 jd = cbase % rt->algn ;
00572 if( jd > 0 ) cbase += (rt->algn-jd) ;
00573 }
00574 rt->size = cbase ;
00575
00576
00577
00578
00579
00580
00581
00582
00583 rt->psiz = 0 ;
00584 if( !ROWTYPE_is_varsize(rt) ){
00585 for( ii=0 ; ii < rt->part_num ; ii++ )
00586 rt->psiz += rt->part_siz[ii] ;
00587 }
00588
00589
00590
00591
00592
00593
00594 rt->code = ROWTYPE_BASE_CODE + rowtype_num ;
00595
00596
00597
00598 if( ROWTYPE_debug ){
00599 fprintf(stderr,"\n") ;
00600 fprintf(stderr,"NI_rowtype_define: '%s' = '%s'\n",tname,tdef) ;
00601 fprintf(stderr," code = %d\n",rt->code) ;
00602 fprintf(stderr," size = %d\n",rt->size) ;
00603 fprintf(stderr," psiz = %d\n",rt->psiz) ;
00604 fprintf(stderr," algn = %d\n",rt->algn) ;
00605 fprintf(stderr," flag = %d\n",rt->flag) ;
00606
00607 fprintf(stderr," comp_num = %d\n",rt->part_num) ;
00608
00609 fprintf(stderr," comp_typ = " ) ;
00610 for( ii=0 ; ii < rt->comp_num ; ii++ ) fprintf(stderr,"%4d ",rt->comp_typ[ii]) ;
00611 fprintf(stderr,"\n") ;
00612
00613 fprintf(stderr," comp_dim = " ) ;
00614 for( ii=0 ; ii < rt->comp_num ; ii++ ) fprintf(stderr,"%4d ",rt->comp_dim[ii]) ;
00615 fprintf(stderr,"\n") ;
00616
00617 fprintf(stderr," part_num = %d\n",rt->part_num) ;
00618
00619 fprintf(stderr," part_typ = " ) ;
00620 for( ii=0 ; ii < rt->part_num ; ii++ ) fprintf(stderr,"%4d ",rt->part_typ[ii]) ;
00621 fprintf(stderr,"\n") ;
00622
00623 fprintf(stderr," part_off = " ) ;
00624 for( ii=0 ; ii < rt->part_num ; ii++ ) fprintf(stderr,"%4d ",rt->part_off[ii]) ;
00625 fprintf(stderr,"\n") ;
00626
00627 fprintf(stderr," part_siz = " ) ;
00628 for( ii=0 ; ii < rt->part_num ; ii++ ) fprintf(stderr,"%4d ",rt->part_siz[ii]) ;
00629 fprintf(stderr,"\n") ;
00630
00631 fprintf(stderr," part_dim = " ) ;
00632 for( ii=0 ; ii < rt->part_num ; ii++ ) fprintf(stderr,"%4d ",rt->part_dim[ii]) ;
00633 fprintf(stderr,"\n") ;
00634 }
00635
00636
00637
00638
00639 ROWTYPE_register(rt) ;
00640 return rt->code ;
00641 }
00642
00643
00644
00645
00646 NI_procins * NI_rowtype_procins( NI_rowtype *rt )
00647 {
00648 NI_procins *npi ;
00649 char *rhs ;
00650
00651 if( rt == NULL ) return NULL ;
00652
00653 npi = NI_new_processing_instruction( "ni_do" ) ;
00654 NI_set_attribute( npi , "ni_verb" , "typedef" ) ;
00655
00656 rhs = NI_malloc(char,strlen(rt->name)+strlen(rt->userdef)+4) ;
00657 sprintf( rhs , "%s %s" , rt->name , rt->userdef ) ;
00658 NI_set_attribute( npi , "ni_object" , rhs ) ;
00659 NI_free( rhs ) ;
00660 return npi ;
00661 }
00662
00663
00664
00665
00666
00667
00668
00669
00670 NI_rowtype * NI_rowtype_find_name( char *nn )
00671 {
00672 NI_rowtype *rt ; int ii ;
00673 static int busy=0 ;
00674
00675 if( nn == NULL || *nn == '\0' ) return NULL ;
00676 if( rowtype_table == NULL ) setup_basic_types() ;
00677 rt = (NI_rowtype *) findin_Htable(nn,rowtype_table) ;
00678 if( rt != NULL ) return rt ;
00679
00680
00681
00682 for( ii=0 ; ii <= NI_NUM_BASIC_TYPES ; ii++ )
00683 if( strcmp(type_alias[ii],nn) == 0 ) return rowtype_array[ii] ;
00684
00685
00686
00687
00688 if( busy ) return NULL ;
00689
00690 ii = strlen(nn) ;
00691 if( ii < 12 || strncmp(nn,"VECTOR_",7) != 0 || strchr(nn+7,'_') == NULL )
00692 return NULL ;
00693
00694 { char bt[32] , rt[64] ; int tt , dd ;
00695
00696
00697
00698 for( ii=7 ; ii < 32 && nn[ii] != '\0' && nn[ii] != '_' ; ii++ )
00699 bt[ii-7] = nn[ii] ;
00700 if( nn[ii] != '_' ) return NULL ;
00701 bt[ii-7] = '\0' ;
00702
00703
00704
00705 for( tt=0 ; tt <= NI_NUM_BASIC_TYPES ; tt++ )
00706 if( strcmp(type_name[tt],bt) == 0 ) break ;
00707
00708 if( tt > NI_NUM_BASIC_TYPES ){
00709 for( tt=0 ; tt <= NI_NUM_BASIC_TYPES ; tt++ )
00710 if( strcmp(type_alias[tt],bt) == 0 ) break ;
00711 if( tt > NI_NUM_BASIC_TYPES ) return NULL ;
00712 }
00713
00714
00715
00716 dd = 0 ; sscanf( nn+ii+1 , "%d" , &dd ) ;
00717 if( dd <= 0 ) return NULL ;
00718
00719
00720
00721 sprintf(rt,"%s[%d]",type_name[tt],dd) ;
00722
00723 busy = 1 ;
00724 tt = NI_rowtype_define( nn , rt ) ;
00725 busy = 0 ;
00726 if( tt >= ROWTYPE_OFFSET ) return rowtype_array[tt-ROWTYPE_BASE_CODE] ;
00727 }
00728
00729 return NULL ;
00730 }
00731
00732
00733
00734
00735 NI_rowtype * NI_rowtype_find_code( int nn )
00736 {
00737 if( nn < 0 ) return NULL ;
00738 if( rowtype_table == NULL ) setup_basic_types() ;
00739 if( nn >= ROWTYPE_OFFSET ) nn = nn - ROWTYPE_BASE_CODE ;
00740 if( nn < 0 || nn >= rowtype_num ) return NULL ;
00741 return rowtype_array[nn] ;
00742 }
00743
00744
00745
00746
00747
00748
00749 int NI_rowtype_name_to_code( char *nn )
00750 {
00751 NI_rowtype *rt = NI_rowtype_find_name( nn ) ;
00752 if( rt != NULL ) return rt->code ;
00753 return -1 ;
00754 }
00755
00756
00757
00758
00759
00760
00761
00762
00763 char * NI_rowtype_code_to_name( int nn )
00764 {
00765 NI_rowtype *rt = NI_rowtype_find_code( nn ) ;
00766 if( rt != NULL ) return rt->name ;
00767 return NULL ;
00768 }
00769
00770
00771
00772
00773
00774
00775
00776 char * NI_rowtype_code_to_alias( int nn )
00777 {
00778 if( rowtype_table == NULL ) setup_basic_types() ;
00779 if( nn <= NI_NUM_BASIC_TYPES ) return type_alias[nn] ;
00780 return NI_rowtype_code_to_name( nn ) ;
00781 }
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794 int NI_rowtype_name_to_size( char *nn )
00795 {
00796 NI_rowtype *rt = NI_rowtype_find_name( nn ) ;
00797 if( rt != NULL ) return rt->size ;
00798 return -1 ;
00799 }
00800
00801
00802
00803
00804
00805
00806 int NI_rowtype_code_to_size( int dtyp )
00807 {
00808 static int last_dtyp=-1 , last_size=-1 ;
00809 NI_rowtype *rt ;
00810
00811 if( rowtype_table == NULL ) setup_basic_types() ;
00812 if( dtyp < 0 ) return -1 ;
00813 if( dtyp < ROWTYPE_OFFSET ) return type_size[dtyp] ;
00814 if( dtyp == last_dtyp ) return last_size ;
00815
00816 rt = NI_rowtype_find_code(dtyp) ;
00817 if( rt != NULL ){
00818 last_dtyp = dtyp; last_size = rt->size; return last_size;
00819 }
00820 return -1 ;
00821 }
00822
00823
00824
00825
00826
00827
00828
00829
00830 int NI_rowtype_vsize( NI_rowtype *rt , void *dpt )
00831 {
00832 int ii,jj , ss ;
00833 char *dat = (char *)dpt ;
00834
00835 if( rt == NULL ) return 0;
00836 if( !ROWTYPE_is_varsize(rt) ) return rt->psiz;
00837 if( dat == NULL ) return 0;
00838
00839
00840
00841
00842 for( ii=ss=0 ; ii < rt->part_num ; ii++ ){
00843 if( rt->part_typ[ii] == NI_STRING ){
00844 char *str = *((char **)((dat) + (rt)->part_off[ii])) ;
00845 ss += NI_strlen(str) ;
00846 } else if( rt->part_dim[ii] < 0 ){
00847 ss += rt->part_siz[ii] ;
00848 } else {
00849 jj = ROWTYPE_part_dimen(rt,dat,ii) ;
00850 ss += jj * rt->part_rtp[ii]->psiz ;
00851 }
00852 }
00853
00854 return ss ;
00855 }
00856
00857
00858
00859
00860
00861
00862
00863 void NI_val_to_text( NI_rowtype *rt , char *dpt , char *wbuf )
00864 {
00865 int jj = strlen(wbuf) ;
00866
00867 switch( rt->code ){
00868
00869
00870
00871 default:{
00872 if( rt != NULL ){
00873 int ii ;
00874 for( ii=0 ; ii < rt->part_num ; ii++ )
00875 NI_val_to_text( rt->part_rtp[ii] , dpt + rt->part_off[ii] , wbuf ) ;
00876 }
00877 }
00878 break ;
00879
00880
00881
00882 case NI_BYTE:{
00883 byte *vpt = (byte *)dpt ;
00884 sprintf(wbuf+jj," %u",(unsigned int)vpt[0]) ;
00885 }
00886 break ;
00887
00888 case NI_SHORT:{
00889 short *vpt = (short *)dpt ;
00890 sprintf(wbuf+jj," %d",(int)vpt[0]) ;
00891 }
00892 break ;
00893
00894 case NI_INT:{
00895 int *vpt = (int *)dpt ;
00896 sprintf(wbuf+jj," %d",vpt[0]) ;
00897 }
00898 break ;
00899
00900
00901
00902 case NI_RGB:{
00903 rgb *vpt = (rgb *)dpt ;
00904 sprintf(wbuf+jj," %u %u %u",vpt[0].r,vpt[0].g,vpt[0].b) ;
00905 }
00906 break ;
00907
00908 case NI_RGBA:{
00909 rgba *vpt = (rgba *)dpt ;
00910 sprintf(wbuf+jj," %u %u %u %u",
00911 vpt[0].r,vpt[0].g,vpt[0].b,vpt[0].a) ;
00912 }
00913 break ;
00914
00915
00916
00917
00918 case NI_FLOAT:{
00919 float *vpt = (float *)dpt ;
00920 char fbuf[32] ; int ff ;
00921 sprintf(fbuf,"%12.6g",vpt[0]) ;
00922 for( ff=strlen(fbuf) ; fbuf[ff]==' ' ; ff-- ) fbuf[ff] = '\0' ;
00923 for( ff=0 ; fbuf[ff] == ' ' ; ff++ ) ;
00924 sprintf(wbuf+jj," %s",fbuf+ff) ;
00925 }
00926 break ;
00927
00928 case NI_DOUBLE:{
00929 double *vpt = (double *)dpt ;
00930 char fbuf[32] ; int ff ;
00931 sprintf(fbuf,"%18.12g",vpt[0]) ;
00932 for( ff=strlen(fbuf) ; fbuf[ff]==' ' ; ff-- ) fbuf[ff] = '\0' ;
00933 for( ff=0 ; fbuf[ff] == ' ' ; ff++ ) ;
00934 sprintf(wbuf+jj," %s",fbuf+ff) ;
00935 }
00936 break ;
00937
00938 case NI_COMPLEX:{
00939 complex *vpt = (complex *)dpt ;
00940 char fbuf[32],gbuf[32] ; int ff,gg ;
00941 sprintf(fbuf,"%12.6g",vpt[0].r) ;
00942 for( ff=strlen(fbuf) ; fbuf[ff]==' ' ; ff-- ) fbuf[ff] = '\0' ;
00943 for( ff=0 ; fbuf[ff] == ' ' ; ff++ ) ;
00944 sprintf(gbuf,"%12.6g",vpt[0].i) ;
00945 for( gg=strlen(gbuf) ; gbuf[gg]==' ' ; gg-- ) gbuf[gg] = '\0' ;
00946 for( gg=0 ; gbuf[gg] == ' ' ; gg++ ) ;
00947 sprintf(wbuf+jj," %s %s",fbuf+ff,gbuf+gg) ;
00948 }
00949 break ;
00950
00951 case NI_STRING:{
00952 char **vpt = (char **)dpt , *str ;
00953 str = quotize_string( *vpt ) ;
00954 sprintf(wbuf+jj," %s",str) ;
00955 NI_free(str) ;
00956 }
00957 break ;
00958
00959 }
00960 }
00961
00962
00963
00964
00965
00966
00967 void NI_multival_to_text( NI_rowtype *rt , int nv , char *dpt , char *wbuf )
00968 {
00969 int ii , jj=rt->size ;
00970
00971 for( ii=0 ; ii < nv ; ii++ )
00972 NI_val_to_text( rt , dpt+ii*jj , wbuf ) ;
00973 }
00974
00975
00976
00977
00978
00979
00980
00981
00982 int NI_val_to_binary( NI_rowtype *rt , char *dpt , char *wbuf )
00983 {
00984 int jj=0 ;
00985
00986 if( rt->size == rt->psiz ){
00987
00988 jj = rt->size ;
00989 memcpy(wbuf,dpt,jj) ;
00990
00991 } else if( !ROWTYPE_is_varsize(rt) ){
00992
00993 int ii ;
00994 for( ii=0 ; ii < rt->part_num ; ii++ ){
00995 memcpy(wbuf+jj,dpt+rt->part_off[ii],rt->part_siz[ii]) ;
00996 jj += rt->part_siz[ii] ;
00997 }
00998
00999 }
01000
01001 return jj ;
01002 }
01003
01004
01005
01006
01007
01008
01009
01010 int NI_multival_to_binary( NI_rowtype *rt , int nv , char *dpt , char *wbuf )
01011 {
01012 int jj=0 ;
01013
01014 if( rt->size == rt->psiz ){
01015
01016 jj = nv * rt->size ;
01017 memcpy(wbuf,dpt,jj);
01018
01019 } else if( rt->psiz > 0 ){
01020
01021 int ii ;
01022 for( ii=0 ; ii < nv ; ii++ )
01023 jj += NI_val_to_binary( rt , dpt+(ii*rt->size) , wbuf+jj ) ;
01024
01025 }
01026 return jj ;
01027 }
01028
01029
01030
01031
01032
01033 int NI_has_String( NI_rowtype *rt )
01034 {
01035 int ii , jj ;
01036
01037 if( rt == NULL ) return 0 ;
01038
01039
01040
01041 if( ROWTYPE_is_builtin_code(rt->code) ) return (rt->code == NI_STRING) ;
01042
01043
01044
01045 for( ii=0 ; ii < rt->part_num ; ii++ ){
01046 if( ROWTYPE_is_builtin_code(rt->part_rtp[ii]->code) ){
01047 if( rt->part_rtp[ii]->code == NI_STRING ) return 1;
01048 } else {
01049 if( NI_has_String( rt->part_rtp[ii] ) ) return 1;
01050 }
01051 }
01052 return 0 ;
01053 }
01054
01055
01056
01057
01058
01059
01060 int NI_write_rowtype( NI_stream_type *ns , NI_rowtype *rt ,
01061 int ndat , void *dat , int tmode )
01062 {
01063 void *dpt = dat ;
01064 if( rt == NULL ) return -1 ;
01065 return NI_write_columns( ns , 1 , &(rt->code) , ndat , &dpt , tmode ) ;
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089 int NI_write_columns( NI_stream_type *ns,
01090 int col_num , int *col_typ ,
01091 int col_len , void **col_dpt , int tmode )
01092 {
01093 int ii,jj , row , dim , ntot,nout , col ;
01094 char *ptr , **col_dat=(char **)col_dpt ;
01095 int nwbuf,bb=0,cc=0;
01096 char *wbuf=NULL ;
01097 char *bbuf=NULL ;
01098 char *cbuf=NULL ;
01099
01100 NI_rowtype **rt=NULL ;
01101 int *vsiz=NULL , vsiz_tot=0 ;
01102 int *fsiz=NULL , fsiz_tot=0 ;
01103
01104 # undef FREEUP
01105 # define FREEUP do{ NI_free(wbuf); NI_free(bbuf); NI_free(cbuf); \
01106 NI_free(rt) ; NI_free(vsiz); NI_free(fsiz); \
01107 } while(0)
01108
01109
01110
01111 if( col_num <= 0 || col_len <= 0 ) return 0 ;
01112 if( col_typ == NULL || col_dat == NULL ) return -1 ;
01113 if( !NI_stream_writeable(ns) ) return -1 ;
01114
01115 #if 0
01116 fprintf(stderr,"NI_write_columns: col_num=%d col_len=%d tmode=%d\n",col_num,col_len,tmode) ;
01117 #endif
01118
01119
01120
01121 if( ns->bad ){
01122 jj = NI_stream_goodcheck(ns,666) ;
01123 if( jj < 1 ) return jj ;
01124 }
01125 #if 1
01126 jj = NI_stream_writecheck(ns,666) ;
01127 if( jj < 0 ) return jj ;
01128 #endif
01129
01130 if( ns->type == NI_STRING_TYPE )
01131 tmode = NI_TEXT_MODE ;
01132
01133
01134
01135 rt = NI_malloc(NI_rowtype*, sizeof(NI_rowtype *) * col_num ) ;
01136 vsiz = NI_malloc(int, sizeof(int) * col_num ) ;
01137 fsiz = NI_malloc(int, sizeof(int) * col_num ) ;
01138 for( col=0 ; col < col_num ; col++ ){
01139
01140
01141
01142 rt[col] = NI_rowtype_find_code( col_typ[col] ) ;
01143
01144
01145
01146 if( rt[col] == NULL || col_dat[col] == NULL ){ FREEUP; return -1; }
01147
01148 vsiz[col] = ROWTYPE_is_varsize(rt[col]) ;
01149 fsiz[col] = rt[col]->size ;
01150 vsiz_tot += vsiz[col] ;
01151 fsiz_tot += fsiz[col] ;
01152
01153
01154
01155 if( tmode != NI_TEXT_MODE && NI_has_String(rt[col]) ) tmode = NI_TEXT_MODE;
01156 }
01157
01158
01159
01160
01161
01162 if( col_num == 1 && tmode == NI_BINARY_MODE && fsiz[0] == rt[0]->psiz ){
01163 #if 0
01164 int ct = NI_clock_time() ;
01165 #endif
01166 nout = NI_stream_write( ns , col_dat[0] , fsiz[0]*col_len ) ;
01167 #if 0
01168 ct = NI_clock_time()-ct ;
01169 fprintf(stderr,"NI_write_columns FAST case: %d bytes in %d ms\n",fsiz[0]*col_len,ct) ;
01170 #endif
01171 FREEUP ; return nout ;
01172 }
01173
01174
01175
01176 switch( tmode ){
01177 default: tmode = NI_TEXT_MODE ;
01178 case NI_TEXT_MODE: nwbuf = 6*fsiz_tot ; break ;
01179
01180 case NI_BASE64_MODE:
01181 case NI_BINARY_MODE: nwbuf = fsiz_tot ; break ;
01182 }
01183 wbuf = NI_malloc(char, nwbuf+128) ;
01184
01185
01186
01187 if( tmode == NI_BASE64_MODE ){
01188 bbuf = NI_malloc(char, nwbuf+128) ; bb = 0 ;
01189 cbuf = NI_malloc(char, 2*nwbuf+128) ; cc = 0 ;
01190 load_encode_table() ;
01191 }
01192
01193
01194
01195
01196
01197 # undef ADDOUT
01198 # define ADDOUT \
01199 if( nout < 0 ){ \
01200 fprintf(stderr,"NIML:: write abort!\n"); \
01201 FREEUP ; return -1 ; \
01202 } else ntot+=nout
01203
01204
01205
01206
01207 ntot = 0 ;
01208
01209 for( row=0 ; row < col_len ; row++ ){
01210
01211
01212
01213 if( vsiz_tot ){
01214 for( jj=col=0 ; col < col_num ; col++ ){
01215 ptr = col_dat[col] + fsiz[col]*row ;
01216 jj += NI_rowtype_vsize( rt[col] , ptr );
01217 }
01218 if( tmode == NI_TEXT_MODE ) jj *= 6 ;
01219 if( jj > nwbuf ){
01220 nwbuf = jj ;
01221 wbuf = NI_realloc(wbuf, char,nwbuf+128) ;
01222 if( tmode == NI_BASE64_MODE ){
01223 bbuf = NI_realloc(bbuf, char, nwbuf+128) ;
01224 cbuf = NI_realloc(cbuf, char,2*nwbuf+128) ;
01225 }
01226 }
01227 }
01228
01229
01230
01231 switch( tmode ){
01232 case NI_TEXT_MODE: wbuf[0] = '\0'; break;
01233 case NI_BASE64_MODE:
01234 case NI_BINARY_MODE: jj = 0 ; break;
01235 }
01236
01237
01238
01239 for( col=0 ; col < col_num ; col++ ){
01240 ptr = col_dat[col] + fsiz[col]*row ;
01241
01242
01243
01244
01245
01246
01247
01248 for( ii=0 ; ii < rt[col]->part_num ; ii++ ){
01249
01250 if( rt[col]->part_dim[ii] < 0 ){
01251 switch( tmode ){
01252
01253 case NI_TEXT_MODE:
01254 NI_val_to_text( rt[col]->part_rtp[ii],
01255 ptr+rt[col]->part_off[ii], wbuf ) ;
01256 break ;
01257
01258 case NI_BASE64_MODE:
01259 case NI_BINARY_MODE:
01260 jj += NI_val_to_binary( rt[col]->part_rtp[ii],
01261 ptr+rt[col]->part_off[ii], wbuf+jj ) ;
01262 break ;
01263 }
01264
01265 } else {
01266
01267 char **apt = (char **)(ptr+rt[col]->part_off[ii]);
01268
01269
01270 dim = ROWTYPE_part_dimen(rt[col],ptr,ii) ;
01271 if( dim > 0 && *apt != NULL ){
01272 switch( tmode ){
01273 case NI_TEXT_MODE:
01274 NI_multival_to_text( rt[col]->part_rtp[ii] , dim ,
01275 *apt , wbuf ) ;
01276 break ;
01277 case NI_BASE64_MODE:
01278 case NI_BINARY_MODE:
01279 jj += NI_multival_to_binary( rt[col]->part_rtp[ii] , dim ,
01280 *apt , wbuf+jj ) ;
01281 break ;
01282 }
01283 }
01284 }
01285
01286 }
01287 }
01288
01289
01290
01291 switch( tmode ){
01292
01293 case NI_TEXT_MODE:
01294 strcat(wbuf,"\n") ;
01295 nout = NI_stream_writestring( ns , wbuf ) ;
01296 ADDOUT ;
01297 break ;
01298
01299 case NI_BINARY_MODE:
01300 nout = NI_stream_write( ns , wbuf , jj ) ;
01301 #ifdef NIML_DEBUG
01302 if( nout != jj ) NI_dpr("NI_write_columns: col#%d sends %d bytes; nout=%d\n",col,jj,nout) ;
01303 #endif
01304 ADDOUT ;
01305 break ;
01306
01307 case NI_BASE64_MODE:{
01308 int nb , nb3 , nb64 , pp,qq ;
01309 byte a,b,c,w,x,y,z ;
01310
01311
01312
01313
01314
01315 memcpy(bbuf+bb,wbuf,jj) ;
01316 nb = jj+bb ;
01317 if( nb < 3 ){ bb = nb; break; }
01318 nb3 = 3*(nb/3) ;
01319
01320
01321
01322
01323 for( qq=pp=0 ; pp < nb3 ; ){
01324 a = bbuf[pp++] ; b = bbuf[pp++] ; c = bbuf[pp++] ;
01325 B64_encode3(a,b,c,w,x,y,z) ;
01326 cbuf[qq++] = w ; cbuf[qq++] = x ;
01327 cbuf[qq++] = y ; cbuf[qq++] = z ;
01328 cc += 4; if( cc > 64 ){ cbuf[qq++]=B64_EOL2; cc=0; }
01329 }
01330
01331
01332
01333 nout = NI_stream_write( ns , cbuf , qq ) ;
01334 ADDOUT ;
01335
01336
01337
01338 bb = nb - nb3 ;
01339 if( bb > 0 ){
01340 bbuf[0] = bbuf[nb3] ;
01341 if( bb > 1 ) bbuf[1] = bbuf[nb3+1] ;
01342 }
01343 }
01344 break ;
01345 }
01346
01347 }
01348
01349
01350
01351
01352
01353 if( tmode == NI_BASE64_MODE ){
01354 if( bb > 0 ){
01355 byte w,x,y,z , a=bbuf[0],b=bbuf[1] ;
01356 if( bb == 2 ) B64_encode2(a,b,w,x,y,z) ;
01357 else B64_encode1(a,w,x,y,z) ;
01358 cbuf[0] = w ; cbuf[1] = x ;
01359 cbuf[2] = y ; cbuf[3] = z ; cbuf[4] = B64_EOL2 ;
01360 nout = NI_stream_write( ns , cbuf , 5 ) ;
01361 ADDOUT ;
01362 } else if( cc > 0 ){
01363 cbuf[0] = B64_EOL2 ;
01364 nout = NI_stream_write( ns , cbuf , 1 ) ;
01365 ADDOUT ;
01366 }
01367 }
01368
01369
01370
01371 FREEUP ;
01372 return ntot ;
01373 }
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411 int NI_read_columns( NI_stream_type *ns,
01412 int col_num, int *col_typ,
01413 int col_len, void **col_dpt, int tmode, int flags )
01414 {
01415 int ii,jj , row , dim , nin , col , nn ;
01416 char *ptr , **col_dat=(char **)col_dpt ;
01417
01418 NI_rowtype **rt=NULL ;
01419 int *vsiz=NULL , vsiz_tot=0 ;
01420 int *fsiz=NULL , fsiz_tot=0 ;
01421
01422 int (*ReadFun)( NI_stream_type *, NI_rowtype *, void *, int ) ;
01423 int ltend = (flags & NI_LTEND_MASK) != 0 ;
01424 int swap = (flags & NI_SWAP_MASK) != 0 ;
01425 int ReadFlag ;
01426 int open_ended = (col_len==0) , row_top ;
01427
01428 # undef FREEUP
01429 # define FREEUP do{ NI_free(rt); NI_free(vsiz); NI_free(fsiz); } while(0)
01430
01431
01432
01433 if( col_num <= 0 || col_len < 0 ) return 0 ;
01434 if( col_typ == NULL || col_dat == NULL ) return -1 ;
01435 if( !NI_stream_readable(ns) ) return -1 ;
01436
01437 #ifdef NIML_DEBUG
01438 NI_dpr("ENTER NI_read_columns\n") ;
01439 #endif
01440
01441
01442
01443 if( ns->bad ){
01444 jj = NI_stream_goodcheck(ns,666) ;
01445 if( jj < 1 ) return jj ;
01446 }
01447 jj = NI_stream_hasinput(ns,666) ;
01448 if( jj < 0 ) return jj ;
01449
01450
01451
01452 rt = NI_malloc(NI_rowtype*, sizeof(NI_rowtype *) * col_num ) ;
01453 vsiz = NI_malloc(int, sizeof(int) * col_num ) ;
01454 fsiz = NI_malloc(int, sizeof(int) * col_num ) ;
01455 if( open_ended ) col_len = 1 ;
01456 for( col=0 ; col < col_num ; col++ ){
01457
01458 rt[col] = NI_rowtype_find_code( col_typ[col] ) ;
01459 if( rt[col] == NULL ){ FREEUP; return -1; }
01460 if( tmode != NI_TEXT_MODE && NI_has_String(rt[col]) ){ FREEUP; return -1; }
01461
01462 vsiz[col] = ROWTYPE_is_varsize(rt[col]) ;
01463 fsiz[col] = rt[col]->size ;
01464 vsiz_tot += vsiz[col] ;
01465 fsiz_tot += fsiz[col] ;
01466
01467
01468
01469 if( col_dat[col] == NULL ){
01470 col_dat[col] = NI_malloc(char, fsiz[col]*col_len ) ;
01471 } else {
01472 if( open_ended ){ FREEUP; return -1; }
01473 memset( col_dat[col], 0 , fsiz[col]*col_len ) ;
01474 }
01475 }
01476
01477
01478
01479
01480
01481 if( col_num == 1 &&
01482 fsiz[0] == rt[0]->psiz &&
01483 tmode == NI_BINARY_MODE &&
01484 !open_ended ){
01485
01486 nin = NI_stream_readbuf( ns , col_dat[0] , fsiz[0]*col_len ) ;
01487 if( nin < fsiz[0] ){ FREEUP; return (nin >= 0) ? 0 : -1 ; }
01488 nin = nin / fsiz[0] ;
01489 goto ReadFinality ;
01490 }
01491
01492
01493
01494 if( col_num == 1 &&
01495 fsiz[0] == rt[0]->psiz &&
01496 tmode == NI_BASE64_MODE &&
01497 !open_ended ){
01498
01499 nin = NI_stream_readbuf64( ns , col_dat[0] , fsiz[0]*col_len ) ;
01500 if( nin < fsiz[0] ){ FREEUP; return (nin >= 0) ? 0 : -1 ; }
01501 nin = nin / fsiz[0] ;
01502 goto ReadFinality ;
01503 }
01504
01505
01506
01507 switch( tmode ){
01508 case NI_TEXT_MODE: ReadFun = NI_text_to_val ; ReadFlag = ltend; break;
01509 case NI_BINARY_MODE: ReadFun = NI_binary_to_val; ReadFlag = swap ; break;
01510 case NI_BASE64_MODE: ReadFun = NI_base64_to_val; ReadFlag = swap ; break;
01511 default:
01512 fprintf(stderr,"\n** NI_read_columns: unknown input tmode=%d\n",tmode);
01513 FREEUP ; return -1 ;
01514 }
01515
01516
01517
01518 row_top = (open_ended) ? 1999999999 : col_len ;
01519
01520 for( row=0 ; row < row_top ; row++ ){
01521
01522
01523 #ifdef NIML_DEBUG
01524 NI_dpr(" Starting row #%d\n",row) ;
01525 #endif
01526
01527
01528
01529 if( open_ended && row >= col_len ){
01530 #ifdef NIML_DEBUG
01531 NI_dpr(" Extending column lengths!\n") ;
01532 #endif
01533 jj = (int)(1.2*col_len+32) ;
01534 for( col=0 ; col < col_num ; col++ ){
01535 col_dat[col] = NI_realloc( col_dat[col] , char, fsiz[col]*jj ) ;
01536 memset( col_dat[col]+fsiz[col]*col_len, 0 , fsiz[col]*(jj-col_len) ) ;
01537 }
01538 col_len = jj ;
01539 }
01540
01541
01542
01543 for( col=0 ; col < col_num ; col++ ){
01544 ptr = col_dat[col] + fsiz[col]*row ;
01545 nn = ReadFun( ns, rt[col], ptr, ReadFlag ) ;
01546 if( !nn ) break ;
01547 }
01548 if( !nn ) break ;
01549 }
01550
01551 if( row == 0 ){
01552 if( open_ended ){
01553 for( col=0 ; col < col_num ; col++ ) NI_free(col_dat[col]) ;
01554 }
01555 FREEUP; return -1;
01556 }
01557
01558 nin = row ;
01559
01560 if( open_ended && nin < col_len ){
01561 for( col=0 ; col < col_num ; col++ )
01562 col_dat[col] = NI_realloc( col_dat[col] , char, fsiz[col]*nin ) ;
01563 }
01564
01565
01566
01567 ReadFinality:
01568
01569 if( tmode != NI_TEXT_MODE && swap ){
01570 for( col=0 ; col < col_num ; col++ )
01571 NI_swap_column( rt[col] , nin , col_dat[col] ) ;
01572 }
01573
01574 #ifdef NIML_DEBUG
01575 NI_dpr("Leaving NI_read_columns\n") ;
01576 #endif
01577
01578 FREEUP ; return nin ;
01579 }
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591 int NI_binary_to_val( NI_stream_type *ns, NI_rowtype *rt, void *dpt, int swap )
01592 {
01593 int nn , jj ;
01594
01595 if( rt->code == NI_STRING ) return 0 ;
01596
01597 if( rt->size == rt->psiz ){
01598
01599
01600 jj = NI_stream_readbuf( ns , (char *)dpt , rt->size ) ;
01601 return (jj == rt->size) ;
01602
01603 } else {
01604
01605 char *dat = (char *)dpt , **aaa = NULL ;
01606 int ii , naaa = 0 , iaaa = 0 ;
01607
01608 if( ROWTYPE_is_varsize(rt) ){
01609 for( naaa=ii=0 ; ii < rt->part_num ; ii++ )
01610 if( rt->part_dim[ii] >= 0 ) naaa++ ;
01611 if( naaa > 0 )
01612 aaa = NI_malloc(char*, sizeof(char *)*naaa) ;
01613 }
01614
01615
01616
01617
01618 for( nn=1,ii=0 ; ii < rt->part_num ; ii++ ){
01619
01620 if( rt->part_dim[ii] < 0 ){
01621
01622 nn = NI_binary_to_val( ns, rt->part_rtp[ii], dat+rt->part_off[ii], 0 );
01623
01624 } else {
01625
01626 char **apt = (char **)(dat+rt->part_off[ii]);
01627
01628 int dim = ROWTYPE_part_dimen(rt,dat,ii) ;
01629 int siz = rt->part_rtp[ii]->size ;
01630
01631 if( swap ) NI_swap4( 1 , &dim ) ;
01632
01633
01634 if( dim > 0 ){
01635 *apt = NI_malloc(char, siz * dim );
01636
01637 if( siz != rt->part_rtp[ii]->psiz ){
01638 for( jj=0 ; jj < dim ; jj++ ){
01639 nn = NI_binary_to_val( ns, rt->part_rtp[ii],
01640 *apt + siz * jj , 0 ) ;
01641 if( !nn ) break ;
01642 }
01643
01644 } else {
01645 jj = NI_stream_readbuf( ns , *apt , siz*dim ) ;
01646 nn = ( jj == siz*dim ) ;
01647 }
01648
01649 } else {
01650 *apt = NULL ;
01651 }
01652 aaa[iaaa++] = *apt ;
01653
01654 }
01655
01656 if( !nn ) break ;
01657 }
01658
01659
01660
01661 if( !nn ){
01662 for( ii=0 ; ii < iaaa ; ii++ ) NI_free( aaa[ii] ) ;
01663 }
01664 NI_free( aaa ) ;
01665 }
01666
01667 return nn ;
01668 }
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680 int NI_base64_to_val( NI_stream_type *ns, NI_rowtype *rt, void *dpt, int swap )
01681 {
01682 int nn , jj ;
01683
01684 if( rt->code == NI_STRING ) return 0 ;
01685
01686 if( rt->size == rt->psiz ){
01687
01688
01689 jj = NI_stream_readbuf64( ns , (char *)dpt , rt->size ) ;
01690 return (jj == rt->size) ;
01691
01692 } else {
01693
01694 char *dat = (char *)dpt , **aaa = NULL ;
01695 int ii , naaa = 0 , iaaa = 0 ;
01696
01697 if( ROWTYPE_is_varsize(rt) ){
01698 for( naaa=ii=0 ; ii < rt->part_num ; ii++ )
01699 if( rt->part_dim[ii] >= 0 ) naaa++ ;
01700 if( naaa > 0 )
01701 aaa = NI_malloc(char*, sizeof(char *)*naaa) ;
01702 }
01703
01704
01705
01706
01707 for( nn=1,ii=0 ; ii < rt->part_num ; ii++ ){
01708
01709 if( rt->part_dim[ii] < 0 ){
01710
01711 nn = NI_base64_to_val( ns, rt->part_rtp[ii], dat+rt->part_off[ii], 0 );
01712
01713 } else {
01714
01715 char **apt = (char **)(dat+rt->part_off[ii]);
01716
01717 int dim = ROWTYPE_part_dimen(rt,dat,ii) ;
01718 int siz = rt->part_rtp[ii]->size ;
01719
01720 if( swap ) NI_swap4( 1 , &dim ) ;
01721
01722
01723 if( dim > 0 ){
01724 *apt = NI_malloc(char, siz * dim );
01725
01726 if( siz != rt->part_rtp[ii]->psiz ){
01727 for( jj=0 ; jj < dim ; jj++ ){
01728 nn = NI_base64_to_val( ns, rt->part_rtp[ii],
01729 *apt + siz * jj , 0 ) ;
01730 if( !nn ) break ;
01731 }
01732
01733 } else {
01734 jj = NI_stream_readbuf64( ns , *apt , siz*dim ) ;
01735 nn = ( jj == siz*dim ) ;
01736 }
01737
01738 } else {
01739 *apt = NULL ;
01740 }
01741 aaa[iaaa++] = *apt ;
01742
01743 }
01744
01745 if( !nn ) break ;
01746 }
01747
01748
01749
01750 if( !nn ){
01751 for( ii=0 ; ii < iaaa ; ii++ ) NI_free( aaa[ii] ) ;
01752 }
01753 NI_free( aaa ) ;
01754 }
01755
01756 return nn ;
01757 }
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767 int NI_text_to_val( NI_stream_type *ns, NI_rowtype *rt, void *dpt, int ltend )
01768 {
01769 int nn ;
01770
01771 switch( rt->code ){
01772
01773
01774
01775 default:{
01776 char *dat = (char *)dpt , **aaa = NULL ;
01777 int ii , jj , naaa = 0 , iaaa = 0 ;
01778
01779 if( ROWTYPE_is_varsize(rt) ){
01780 for( naaa=ii=0 ; ii < rt->part_num ; ii++ )
01781 if( rt->part_dim[ii] >= 0 ) naaa++ ;
01782 if( naaa > 0 )
01783 aaa = NI_malloc(char*, sizeof(char *)*naaa) ;
01784 }
01785
01786
01787
01788 for( nn=1,ii=0 ; ii < rt->part_num ; ii++ ){
01789
01790 if( rt->part_dim[ii] < 0 ){
01791
01792 nn = NI_text_to_val( ns, rt->part_rtp[ii],
01793 dat+rt->part_off[ii], ltend );
01794
01795 } else {
01796
01797 char **apt = (char **)(dat+rt->part_off[ii]);
01798
01799 int dim = ROWTYPE_part_dimen(rt,dat,ii) ;
01800 int siz = rt->part_rtp[ii]->size ;
01801 if( dim > 0 ){
01802 *apt = NI_malloc(char, siz * dim );
01803 for( jj=0 ; jj < dim ; jj++ ){
01804 nn = NI_text_to_val( ns, rt->part_rtp[ii],
01805 *apt + siz * jj , ltend ) ;
01806 if( !nn ) break ;
01807 }
01808 } else {
01809 *apt = NULL ;
01810 }
01811 aaa[iaaa++] = *apt ;
01812
01813 }
01814
01815 if( !nn ) break ;
01816 }
01817
01818
01819
01820 if( !nn ){
01821 for( ii=0 ; ii < iaaa ; ii++ ) NI_free( aaa[ii] ) ;
01822 NI_free( aaa ) ;
01823 return 0 ;
01824 }
01825 NI_free( aaa ) ;
01826 }
01827 break ;
01828
01829
01830
01831 case NI_STRING:{
01832 char *val=NULL ;
01833 char **vpt = (char **) dpt ;
01834 nn = NI_decode_one_string( ns , &val , ltend ) ;
01835 if( !nn || val == NULL ) return 0 ;
01836 unescape_inplace(val) ;
01837 *vpt = val ;
01838 }
01839 break ;
01840
01841
01842
01843 case NI_BYTE:{
01844 double val ;
01845 byte *vpt = (byte *) dpt ;
01846 nn = NI_decode_one_double( ns , &val , ltend ) ;
01847 if( !nn ) return 0 ;
01848 *vpt = (byte) val ;
01849 }
01850 break ;
01851
01852 case NI_SHORT:{
01853 double val ;
01854 short *vpt = (short *) dpt ;
01855 nn = NI_decode_one_double( ns , &val , ltend ) ;
01856 if( !nn ) return 0 ;
01857 *vpt = (short) val ;
01858 }
01859 break ;
01860
01861 case NI_INT:{
01862 double val ;
01863 int *vpt = (int *) dpt ;
01864 nn = NI_decode_one_double( ns , &val , ltend ) ;
01865 if( !nn ) return 0 ;
01866 *vpt = (int) val ;
01867 }
01868 break ;
01869
01870 case NI_FLOAT:{
01871 double val ;
01872 float *vpt = (float *) dpt ;
01873 nn = NI_decode_one_double( ns , &val , ltend ) ;
01874 if( !nn ) return 0 ;
01875 *vpt = (float) val ;
01876 }
01877 break ;
01878
01879 case NI_DOUBLE:{
01880 double val ;
01881 double *vpt = (double *) dpt ;
01882 nn = NI_decode_one_double( ns , &val , ltend ) ;
01883 if( !nn ) return 0 ;
01884 *vpt = (double) val ;
01885 }
01886 break ;
01887
01888 case NI_COMPLEX:{
01889 double v1,v2 ;
01890 complex *vpt = (complex *) dpt ;
01891 nn = NI_decode_one_double( ns , &v1 , ltend ) ;
01892 if( !nn ) return 0 ;
01893 nn = NI_decode_one_double( ns , &v2 , ltend ) ;
01894 if( !nn ) return 0 ;
01895 vpt->r = (float) v1 ;
01896 vpt->i = (float) v2 ;
01897 }
01898 break ;
01899
01900 case NI_RGB:{
01901 double v1,v2,v3 ;
01902 rgb *vpt = (rgb *) dpt ;
01903 nn = NI_decode_one_double( ns , &v1 , ltend ) ;
01904 if( !nn ) return 0 ;
01905 nn = NI_decode_one_double( ns , &v2 , ltend ) ;
01906 if( !nn ) return 0 ;
01907 nn = NI_decode_one_double( ns , &v3 , ltend ) ;
01908 if( !nn ) return 0 ;
01909 vpt->r = (byte) v1 ;
01910 vpt->g = (byte) v2 ;
01911 vpt->b = (byte) v3 ;
01912 }
01913 break ;
01914
01915 case NI_RGBA:{
01916 double v1,v2,v3,v4 ;
01917 rgba *vpt = (rgba *) dpt ;
01918 nn = NI_decode_one_double( ns , &v1 , ltend ) ;
01919 if( !nn ) return 0 ;
01920 nn = NI_decode_one_double( ns , &v2 , ltend ) ;
01921 if( !nn ) return 0 ;
01922 nn = NI_decode_one_double( ns , &v3 , ltend ) ;
01923 if( !nn ) return 0 ;
01924 nn = NI_decode_one_double( ns , &v4 , ltend ) ;
01925 if( !nn ) return 0 ;
01926 vpt->r = (byte) v1 ;
01927 vpt->g = (byte) v2 ;
01928 vpt->b = (byte) v3 ;
01929 vpt->a = (byte) v4 ;
01930 }
01931 break ;
01932
01933 }
01934
01935 return 1 ;
01936 }
01937
01938
01939
01940
01941
01942 void NI_swap_column( NI_rowtype *rt , int nrow , char *dat )
01943 {
01944 if( rt == NULL || nrow <= 0 || dat == NULL ) return ;
01945
01946 switch( rt->code ){
01947
01948 case NI_RGB:
01949 case NI_RGBA:
01950 case NI_STRING:
01951 case NI_BYTE: return ;
01952
01953
01954
01955 case NI_SHORT:
01956 NI_swap2( nrow , dat ) ;
01957 return ;
01958
01959 case NI_INT:
01960 case NI_FLOAT:
01961 NI_swap4( nrow , dat ) ;
01962 return ;
01963
01964 case NI_DOUBLE:
01965 NI_swap8( nrow , dat ) ;
01966 return ;
01967
01968 case NI_COMPLEX:
01969 NI_swap4( 2*nrow , dat ) ;
01970 return ;
01971
01972
01973
01974 default:{
01975 int ii , row , fsiz = rt->size ;
01976 char *ptr ;
01977
01978 for( row=0 ; row < nrow ; row++ ){
01979 ptr = dat + fsiz*row ;
01980
01981
01982
01983 for( ii=0 ; ii < rt->part_num ; ii++ ){
01984
01985 if( rt->part_dim[ii] < 0 ){
01986
01987 NI_swap_column( rt->part_rtp[ii] , 1 , ptr+rt->part_off[ii] ) ;
01988
01989 } else {
01990
01991 char **apt = (char **)(ptr+rt->part_off[ii]);
01992
01993 int dim = ROWTYPE_part_dimen(rt,dat,ii) ;
01994 NI_swap_column( rt->part_rtp[ii] , dim , *apt ) ;
01995
01996 }
01997 }
01998 }
01999 }
02000 return ;
02001 }
02002 }
02003
02004
02005
02006
02007
02008
02009
02010 void NI_free_column( NI_rowtype *rt , int col_len , void *cpt )
02011 {
02012 char *dat=(char *)cpt , *ptr ;
02013 int ii , jj ;
02014
02015 if( rt == NULL || dat == NULL || col_len < 1 ) return ;
02016
02017
02018
02019 if( ROWTYPE_is_varsize(rt) ){
02020 for( ii=0 ; ii < col_len ; ii++ ){
02021 ptr = dat + rt->size * ii ;
02022 for( jj=0 ; jj < rt->part_num ; jj++ ){
02023 if( rt->part_typ[jj] == NI_STRING ||
02024 rt->part_dim[jj] >= 0 ){
02025 char **apt = (char **)(ptr+rt->part_off[jj]) ;
02026 NI_free(*apt) ; *apt = NULL ;
02027 }
02028 }
02029 }
02030 }
02031
02032
02033
02034 NI_free(cpt) ; return ;
02035 }
02036
02037
02038
02039
02040
02041
02042 void * NI_copy_column( NI_rowtype *rt , int col_len , void *cpt )
02043 {
02044 char *dat=(char *)cpt , *ndat , *nptr , *qpt ;
02045 int ii , jj , kk ;
02046
02047 if( rt == NULL || dat == NULL || col_len < 1 ) return NULL ;
02048
02049
02050
02051 ndat = NI_malloc(char, rt->size * col_len ) ;
02052 memcpy( ndat , dat , rt->size * col_len ) ;
02053
02054
02055
02056
02057
02058 if( ROWTYPE_is_varsize(rt) ){
02059 for( ii=0 ; ii < col_len ; ii++ ){
02060 nptr = ndat + rt->size * ii ;
02061 for( jj=0 ; jj < rt->part_num ; jj++ ){
02062
02063 if( rt->part_typ[jj] == NI_STRING ){
02064 char **apt = (char **)(nptr+rt->part_off[jj]) ;
02065 qpt = NI_strdup(*apt) ; *apt = qpt ;
02066 } else if( rt->part_dim[jj] >= 0 ){
02067 char **apt = (char **)(nptr+rt->part_off[jj]) ;
02068 if( *apt != NULL ){
02069 kk = ROWTYPE_part_dimen(rt,nptr,jj) * rt->part_rtp[jj]->size ;
02070 qpt = NI_malloc(char, kk) ; memcpy(qpt,*apt,kk) ; *apt = qpt ;
02071 }
02072 }
02073 }
02074 }
02075 }
02076
02077 return ndat ;
02078 }
02079
02080
02081
02082
02083
02084
02085
02086 int NI_size_column( NI_rowtype *rt , int col_len , void *cpt )
02087 {
02088 char *dat = (char *)cpt ;
02089 int ii , ndat ;
02090
02091 if( rt == NULL || col_len <= 0 )
02092 return 0;
02093 if( !ROWTYPE_is_varsize(rt) || dat == NULL )
02094 return (col_len*rt->psiz);
02095
02096
02097
02098 ndat = 0 ;
02099 for( ii=0 ; ii < col_len ; ii++ )
02100 ndat += NI_rowtype_vsize( rt , dat + ii*rt->size ) ;
02101
02102 return ndat ;
02103 }