/************************************************************************** * *N vpf_dump_doc_table * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Dump the contents of a narrative-style .DOC VPF table into an * ASCII file as a series of text strings. This function checks * to make sure that the given table is a real narrative file * (two fields: ID and TEXT). If not, it displays it as a normal * VPF table. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * tablename <input> == (char *) narrative-style .DOC VPF table to dump. * outname <input> == (char *) name of ASCII dump file. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels DOS Turbo C *E *************************************************************************/ void vpf_dump_doc_table( char *tablename, char *outname ) { vpf_table_type table; long int i,n; char *buf; row_type row; FILE *fp; fp = fopen(outname,"w"); table = vpf_open_table(tablename,disk,"rb",NULL); /* Check header to make sure the table is a narrative table */ if ((ossim_strcasecmp(table.header[1].name,"TEXT") != 0) || (table.nfields != 2)) { /* Not a real narrative table -> normal VPF table dump */ vpf_close_table(&table); vpf_dump_table(tablename,outname); return; } fprintf(fp,"%s\n%s\n\n",tablename,table.description); for (i=1;i<=table.nrows;i++) { row = read_next_row(table); buf = (char *)get_table_element(1,row,table,NULL,&n); fprintf(fp,"%s\n",buf); free(buf); free_row(row,table); } fclose(fp); vpf_close_table( &table ); }
/************************************************************************** * *N related_row * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Return the related row of table2 based upon the value of table 1's key * Table 2 must be the '1' side of an n:1 relationship -- If it isn't, * use 'related_rows()'. * Supported data types - I and T<n>. * Binary search supported only for data type I. (column must be sorted) *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels DOS Turbo C *E *************************************************************************/ long int related_row( void *keyval1, vpf_table_type table2, char *key2, int sort_flag ) { long int rowid, i, ival, kval, n; row_type row; int KEY2_; char cval, *tval; if (ossim_strcasecmp(key2,"ID")==0) { memcpy( &rowid, keyval1, sizeof(rowid) ); return rowid; } rowid = 0; KEY2_ = table_pos(key2,table2); if ((table2.header[KEY2_].type != 'I')&& (table2.header[KEY2_].type != 'T')) return rowid; if ((table2.header[KEY2_].type == 'I')&& (table2.header[KEY2_].count != 1)) return rowid; if ((table2.header[KEY2_].type == 'T')&&(sort_flag)) sort_flag = 0; if (table2.header[KEY2_].type == 'I') memcpy(&kval,keyval1,sizeof(kval)); if (!sort_flag) { /* Sequential search */ for (i=1;i<=table2.nrows;i++) { row = get_row(i,table2); if (table2.header[KEY2_].type == 'I') { get_table_element(KEY2_,row,table2,&ival,&n); if (ival == kval) rowid = i; } else { if (table2.header[KEY2_].count==1) { get_table_element(KEY2_,row,table2,&cval,&n); if (memcmp(&cval,keyval1,sizeof(ival))==0) rowid = i; } else { tval = (char*)get_table_element(KEY2_,row,table2,NULL,&n); if (strcmp(tval,(char *)keyval1)==0) rowid = i; } } free_row(row,table2); if (rowid > 0) break; } } else { /* Binary search */ memcpy(&kval,keyval1,sizeof(kval)); rowid = vpf_binary_search( kval, KEY2_, table2 ); } return rowid; }
/************************************************************************* * *N table_pos * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function returns the column offset of the specified field name *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * field_name <input> == (char *) field name. * table <input> == (vpf_table_type) VPF table structure. * table_pos <output> == (ossim_int32) returned column number. * UNIX returns -1 if not exists *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels May 1991 DOS Turbo C *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ ossim_int32 table_pos( const char* field_name, vpf_table_type table ) { register ossim_int32 i; ossim_int32 col; char altfn[256]; col = -1; for (i = 0; i < table.nfields; i++) { strcpy(altfn, ",:"); strcat(altfn, field_name); if (ossim_strcasecmp(field_name,table.header[i].name) == 0 || ossim_strcasecmp(altfn,table.header[i].name) == 0) { col = i; break; } } return col; }
/************************************************************************* * *N parse_data_def * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function parses a table's data definition and creates a header * in memory that is associated with the table. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * table <inout> == (vpf_table_type *) vpf table structure. * ddlen <input> == (ossim_int32) length of the table's data definition. * * return value is the record length if all items are fixed length, or * -1 if the record contains variable length items *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels April 1991 DOS Turbo C * Mody Buchbinder May 1991 - Modified for new table header. * Dave Flinn July 1991 - updated for UNIX *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * External Variables: *X * None *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Functions Called: *F * void *vpfmalloc() VPFMISC.C *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Portability: *O * This module should be ANSI C compatible. *E *************************************************************************/ ossim_int32 parse_data_def( vpf_table_type *table ) { register ossim_int32 n,i; ossim_int32 p, k; char *buf,*des,*nar,*vdt, *tdx, *doc, byte ;/*temporary storage */ char end_of_rec; int status; ossim_int32 ddlen; ossim_int32 reclen = 0; #if UNIX /* just for backward compat check */ ossim_int32 bkcompat = 1 ; #endif if ( table->mode == Read ) { fread(&ddlen,sizeof(ddlen),1,table->fp); /* Check the next byte to see if the byte order is specified */ fread(&byte,1,1,table->fp); p=0; table->byte_order = LEAST_SIGNIFICANT; /* default */ switch (toupper(byte)) { case 'L': p++; break; case 'M': table->byte_order = MOST_SIGNIFICANT; p++; break; } if (MACHINE_BYTE_ORDER != table->byte_order) { k = ddlen; swap_four((char *)&k,(char *)&ddlen); } if ( ddlen < 0 ) { return (ossim_int32)0 ; } STORAGE_BYTE_ORDER = table->byte_order; /* header without first 4 bytes */ table->ddlen = ddlen + sizeof (ossim_int32) ; buf = (char *)vpfmalloc((ddlen+3)*sizeof(char)); buf[0] = byte; /* already have the first byte of the buffer */ Read_Vpf_Char(&buf[1],table->fp,ddlen-1) ; } else { table->ddlen = (long)strlen ( table->defstr ) ; ddlen = table->ddlen ; buf = (char *)vpfmalloc((ddlen+3)*sizeof(char)); strncpy ( buf, table->defstr, ddlen ) ; p=0; table->byte_order = LEAST_SIGNIFICANT; /* default */ byte = buf[0]; switch (toupper(byte)) { case 'L': p++; break; case 'M': table->byte_order = MOST_SIGNIFICANT; p++; break; } STORAGE_BYTE_ORDER = table->byte_order; } buf[ddlen-1] = '\0'; /* mark end of string for reading functions */ if ( buf[p] == ';' ) p++; /* buf[p] is semi-colon */ des = get_string(&p,buf,COMPONENT_SEPERATOR ); strncpy(table->description,des,80); free(des); nar = get_string(&p,buf,COMPONENT_SEPERATOR ); strncpy(table->narrative ,nar,12); free(nar); n = 0 ; /* get number of fields */ for (i=p; i < ddlen;i++) if ( buf[i] == LINE_CONTINUE ) i++ ; /* skip past line continue, and next character */ else if (buf[i] == END_OF_FIELD ) /* Found end of field */ n++; /* increment nfields */ else if (buf[i] == COMMENT ) /* skip past comments */ while ( buf[i] != LINE_CONTINUE && buf[i] != END_OF_FIELD && buf[i] != '\0') i++ ; /* increment i */ table->nfields = n ; table->header = (header_type)vpfmalloc((n+1)*sizeof(header_cell)); for(i=0;i<n;i++) { end_of_rec = FALSE; table->header[i].name = get_string(&p,buf, FIELD_COUNT); /*****/ rightjust(table->header[i].name); table->header[i].type = toupper(vpf_get_char (&p,buf)); table->header[i].count = get_number(&p,buf,FIELD_SEPERATOR ); if ( i == 0 ) if ( ossim_strcasecmp ( table->header[0].name, "ID" ) ) { free(buf); return (ossim_int32)0 ; } if(table->header[i].count == -1) reclen = -1; /* set reclen to variable len flag */ /* Now set null values and add up record length, if fixed length */ status = 0; switch (table->header[i].type) { case 'I': if ( reclen >= 0 ) reclen += (sizeof(ossim_int32)*table->header[i].count); table->header[i].nullval.Int = NULLINT ; break; case 'S': if ( reclen >= 0 ) reclen += (sizeof(short int)*table->header[i].count); table->header[i].nullval.Short = NULLSHORT ; break; case 'F': if ( reclen >= 0 ) reclen += (sizeof(float)*table->header[i].count); table->header[i].nullval.Float = NULLFLOAT ; break; case 'R': if ( reclen >= 0 ) reclen += (sizeof(double)*table->header[i].count); table->header[i].nullval.Double = NULLDOUBLE ; break; case 'T': if ( reclen >= 0 ) { /* if fixed length */ reclen += (sizeof(char)*table->header[i].count); table->header[i].nullval.Char = (char *) vpfmalloc ( table->header[i].count + 1 ) ; for ( k=0; k < table->header[i].count; k++ ) table->header[i].nullval.Char[k] = NULLCHAR ; table->header[i].nullval.Char[k] = '\0'; } else { /* variable length */ table->header[i].nullval.Char = (char *) vpfmalloc ( VARIABLE_STRING_NULL_LENGTH + 1 ) ; for ( k=0; k < VARIABLE_STRING_NULL_LENGTH ; k++ ) table->header[i].nullval.Char[k] = NULLCHAR ; table->header[i].nullval.Char[k] = '\0'; } break; case 'C': if ( reclen >= 0 ) reclen += (sizeof(coordinate_type)*table->header[i].count); table->header[i].nullval.Other = '\0'; break; case 'Z': if ( reclen >= 0 ) reclen += (sizeof(tri_coordinate_type)*table->header[i].count); table->header[i].nullval.Other = '\0' ; break; case 'B': if ( reclen >= 0 ) reclen += (sizeof(double_coordinate_type)*table->header[i].count); table->header[i].nullval.Other = '\0' ; break; case 'Y': if ( reclen >= 0 ) reclen += (sizeof(double_tri_coordinate_type)*table->header[i].count); table->header[i].nullval.Other ='\0'; break; case 'D': if ( reclen >= 0 ) reclen += ((sizeof(date_type)-1)*table->header[i].count); strcpy ( table->header[i].nullval.Date, NULLDATE ) ; break; case 'K': reclen = -1; table->header[i].nullval.Other = '\0' ; break; case 'X': /* do nothing */ table->header[i].nullval.Other = '\0' ; break ; default: status = 1; break ; } /** switch type **/ if (status) { free(buf); return (ossim_int32)0; } table->header[i].keytype = vpf_get_char (&p,buf); des = get_string(&p,buf, FIELD_SEPERATOR ); rightjust(des); strncpy(table->header[i].description,des,80); free(des); vdt = get_string(&p,buf, FIELD_SEPERATOR ); strncpy(table->header[i].vdt,vdt,12); free(vdt); #if UNIX /* This is for backward compatability qc checking */ if ( bkcompat && buf[p] == END_OF_FIELD ) { bkcompat= 0 ; } #endif tdx = get_string(&p,buf, FIELD_SEPERATOR ) ; if ( ! strcmp ( tdx, "" ) ) { table->header[i].tdx = (char *) NULL ; if (buf[p] == ':') end_of_rec = TRUE; } else { if (strcmp(tdx,"-") != 0) { table->header[i].tdx =(char*) vpfmalloc ( (unsigned long)strlen ( tdx ) +1 ) ; strcpy (table->header[i].tdx, tdx ); } else table->header[i].tdx = (char *)NULL; } free(tdx); if (!end_of_rec) { doc = get_string(&p,buf, FIELD_SEPERATOR ) ; if ( ! strcmp ( doc, "" ) ) { table->header[i].narrative = (char *) NULL ; end_of_rec = TRUE; } else { if (strcmp(doc,"-") != 0) { table->header[i].narrative = (char*)vpfmalloc ( (unsigned long)strlen(doc) +1) ; strcpy (table->header[i].narrative, doc ); } else table->header[i].narrative = (char *)NULL; } free(doc); } else table->header[i].narrative = (char *)NULL; p += 1; /** eat semicolon **/ } free(buf); return reclen; }
/************************************************************************** * *N fc_row_number * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Given the starting row of a feature class relationship, return the * row number of the table at the end of the feature class relate * chain. * If your relate goes from the feature to the primitive, this will * return the primitive id for the given feature row. * If your relate goes from the primitive to the feature, this will * return the feature id of the given primitive row. * * Currently only supports relates on 'I' or 'K' fields. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels DOS Turbo C *E *************************************************************************/ long int fc_row_number( row_type row, fcrel_type fcrel, long int tile ) { row_type relrow; long int count; long int i, rownum, keyval; id_triplet_type triplet_keyval; int KEY1_, KEY_; position_type p; vpf_relate_struct rcell; p = ll_first(fcrel.relate_list); ll_element(p,&rcell); KEY1_ = table_pos(rcell.key1,fcrel.table[0]); get_table_element(0,row,fcrel.table[0],&rownum,&count); if (KEY1_ == 0) { /* "ID" */ keyval = rownum; } else { switch (fcrel.table[0].header[KEY1_].type) { case 'I': get_table_element(KEY1_,row,fcrel.table[0],&keyval,&count); break; case 'K': get_table_element(KEY1_,row,fcrel.table[0],&triplet_keyval, &count); keyval = triplet_keyval.exid; if (tile != triplet_keyval.tile) { return -2; } break; default: keyval = 0; break; } } p = ll_first(fcrel.relate_list); for (i=1;i<(fcrel.nchain-1);i++) { /* Relate through Join table(s) */ rownum = related_row(&keyval,fcrel.table[i],rcell.key2,0); relrow = get_row(rownum,fcrel.table[i]); p = ll_next(p); ll_element(p,&rcell); KEY_ = table_pos(rcell.key1,fcrel.table[i]); if (KEY_ == 0) { /* "ID" */ keyval = rownum; } else { switch (fcrel.table[i].header[KEY_].type) { case 'I': get_table_element(KEY_,relrow,fcrel.table[i],&keyval,&count); break; case 'K': get_table_element(KEY_,relrow,fcrel.table[i],&triplet_keyval, &count); keyval = triplet_keyval.exid; if (tile != triplet_keyval.tile) { return -2; } break; default: keyval = 0; break; } } free_row(relrow,fcrel.table[i]); } if (ossim_strcasecmp(rcell.key2,"ID")==0) rownum = keyval; else rownum = related_row(&keyval,fcrel.table[i],rcell.key2,0); return rownum; }
/************************************************************************** * *N related_rows * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Return the list of related rows of table2 based upon the value of * table 1's key. * Supported data types - I and T<n>. * Binary search supported only for data type I. (column must be sorted) * Thematic index used, if present on key column. * NOTE: A sequential search operation will search the entire * table ...zzz... *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels DOS Turbo C *E *************************************************************************/ linked_list_type related_rows( void *keyval1, vpf_table_type table2, char *key2, int sort_flag, ThematicIndex *idx ) { linked_list_type rowlist; set_type rowset; long int rowid, i, ival, kval, n, start,end; row_type row = 0; int KEY2_; char cval, *tval; rowlist = ll_init(); if (ossim_strcasecmp(key2,"ID")==0) { memcpy( &rowid, keyval1, sizeof(rowid) ); ll_insert(&rowid,sizeof(rowid),rowlist); return rowlist; } KEY2_ = table_pos(key2,table2); if ((table2.header[KEY2_].type != 'I')&& (table2.header[KEY2_].type != 'T')) return rowlist; if ((table2.header[KEY2_].type == 'I')&& (table2.header[KEY2_].count != 1)) return rowlist; if ((table2.header[KEY2_].type == 'T')&&(sort_flag)) sort_flag = 0; if (idx) { if (idx->fp) { rowset = search_thematic_index(idx,(char *)keyval1); start = set_min(rowset); end = set_max(rowset); for (i=start;i<=end;i++) if (set_member(i,rowset)) { ll_insert(&i,sizeof(i),ll_last(rowlist)); } set_nuke(&rowset); return rowlist; } } if (!sort_flag) { /* Sequential search */ for (i=1;i<=table2.nrows;i++) { row = get_row(i,table2); if (table2.header[KEY2_].type == 'I') { get_table_element(KEY2_,row,table2,&ival,&n); if (memcmp(&ival,keyval1,sizeof(ival))==0) ll_insert(&i,sizeof(i),ll_last(rowlist)); } else { if (table2.header[KEY2_].count==1) { get_table_element(KEY2_,row,table2,&cval,&n); if (memcmp(&cval,keyval1,sizeof(ival))==0) ll_insert(&i,sizeof(i),ll_last(rowlist)); } else { tval = (char*)get_table_element(KEY2_,row,table2,NULL,&n); if (strcmp(tval,(char *)keyval1)==0) ll_insert(&i,sizeof(i),ll_last(rowlist)); } } free_row(row,table2); } } else { /* Binary search */ memcpy(&kval,keyval1,sizeof(kval)); rowid = vpf_binary_search( kval, KEY2_, table2 ); if (rowid > 0) { ll_insert(&rowid,sizeof(rowid),ll_last(rowlist)); i = rowid-1L; do { get_row(i,table2); get_table_element(KEY2_,row,table2,&ival,&n); if (ival == kval) ll_insert(&i,sizeof(i),ll_last(rowlist)); i--; } while ((ival==kval)&&(i>0)); i = rowid+1L; do { get_row(i,table2); get_table_element(KEY2_,row,table2,&ival,&n); if (ival == kval) ll_insert(&i,sizeof(i),ll_last(rowlist)); i++; } while ((ival==kval)&&(i<=table2.nrows)); } } return rowlist; }
/************************************************************************** * *N fcs_relate_list * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Read the feature class schema table and create the list of * tables to chain through. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * fcname <input> == (char *) feature class name. * start_table <input> == (char *) table to start from. * end_table <input> == (char *) table to end with. * fcs <input> == (vpf_table_type) feature class schema table. * fcs_relate_list <output> == (linked_list_type) list of tables to * chain through. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels DOS Turbo C *E *************************************************************************/ linked_list_type fcs_relate_list( char *fcname, char *start_table, char *end_table, vpf_table_type fcs ) { linked_list_type rlist; vpf_relate_struct rstruct; set_type fcset, set1, set2; char tablename[255], *buf, expr[255]; row_type row; long int rownum,n; int TABLE1_, KEY1_, TABLE2_, KEY2_; rlist = ll_init(); sprintf(expr,"FEATURE_CLASS = %s",fcname); fcset = query_table(expr,fcs); if (set_empty(fcset)) { set_nuke(&fcset); return rlist; } TABLE1_ = table_pos("TABLE1",fcs); KEY1_ = table_pos("FOREIGN_KEY",fcs); if (KEY1_ < 0) KEY1_ = table_pos("TABLE1_KEY",fcs); TABLE2_ = table_pos("TABLE2",fcs); KEY2_ = table_pos("PRIMARY_KEY",fcs); if (KEY2_ < 0) KEY2_ = table_pos("TABLE2_KEY",fcs); strcpy( tablename, start_table ); while (1) { sprintf(expr,"TABLE1 = %s",tablename); set1 = query_table(expr,fcs); set2 = set_intersection(set1,fcset); set_nuke(&set1); if (set_empty(set2)) { set_nuke(&fcset); set_nuke(&set2); return rlist; } rownum = set_min(set2); set_nuke(&set2); row = get_row(rownum,fcs); buf = (char *)get_table_element(TABLE1_,row,fcs,NULL,&n); strcpy(rstruct.table1,buf); rightjust(rstruct.table1); free(buf); buf = (char *)get_table_element(KEY1_,row,fcs,NULL,&n); strcpy(rstruct.key1,buf); rightjust(rstruct.key1); free(buf); buf = (char *)get_table_element(TABLE2_,row,fcs,NULL,&n); strcpy(rstruct.table2,buf); rightjust(rstruct.table2); free(buf); buf = (char *)get_table_element(KEY2_,row,fcs,NULL,&n); strcpy(rstruct.key2,buf); rightjust(rstruct.key2); free(buf); rstruct.degree = R_ONE; /* Default */ free_row( row, fcs ); if (table_in_list(rstruct.table1, rlist)) break; ll_insert( &rstruct, sizeof(rstruct), ll_last(rlist) ); strcpy( tablename, rstruct.table2 ); if (ossim_strcasecmp(tablename,end_table)==0) break; } set_nuke(&fcset); return rlist; }
/************************************************************************* * *N vpf_display_record * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function displays all of the fields of a particular VPF * record, including the descriptions of the fields and their * values. It accesses the online data dictionary metadata * contained in the specified Value Description Tables. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * row <input> == (row_type) vpf table row structure. * table <input> == (vpf_table_type) vpf table. * fp <input> == (FILE *) pointer to the output file. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels Sept 1991 DOS Turbo C *E *************************************************************************/ void vpf_display_record( row_type row, vpf_table_type table, FILE *fp ) { register int i,j; char *buf,*num, path[128], *tablename; char *attr,*val,*descr, vdtpath[128], fmtdate[40]; vpf_table_type vdt; row_type vdtrow; int found; ossim_int32 l, lval, count, *lptr; short int s,sval,*sptr; float f,*fptr; date_type date; int TABLE_ = 1, ATTR_ = 2, VAL_ = 3, DESCR_ = 4; num = (char *)vpfmalloc(20*sizeof(char)); strcpy( vdtpath, "" ); /* Display all secondary attributes */ for (i=0;i<table.nfields;i++) { switch (table.header[i].type) { case 'T': buf = (char *)get_table_element(i,row,table, NULL,&count); rightjust(buf); if (strcmp( buf, "" ) != 0) { fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); fputs(buf,fp); strcpy( path, table.path ); strcat( path, table.header[i].vdt ); if ( (access(path,4)==0) && (strcmp(table.header[i].vdt,"") != 0) ) { if (strcmp(vdtpath,path) != 0) { if (strcmp(vdtpath,"") != 0) { vpf_close_table(&vdt); } vdt = vpf_open_table( path, disk, "rb", NULL ); } strcpy( vdtpath, path ); for (j=1;j<=vdt.nrows;j++) { vdtrow = read_row( j, vdt ); tablename = (char *)get_table_element( TABLE_, vdtrow, vdt, NULL, &count ); rightjust(tablename); strupr2(tablename); attr = (char *)get_table_element( ATTR_, vdtrow, vdt, NULL, &count ); rightjust(attr); val = (char *)get_table_element( VAL_, vdtrow, vdt, NULL, &count ); rightjust(val); found = FALSE; if ( (strstr(table.name,tablename)) && (ossim_strcasecmp(attr,table.header[i].name)==0) && (ossim_strcasecmp(val,buf)==0) ) { descr = (char *)get_table_element(DESCR_,vdtrow,vdt, NULL, &count); rightjust(descr); fputs(" (",fp); fputs(descr,fp); fputs(")",fp); free(descr); found = TRUE; } free(tablename); free(attr); free(val); free_row( vdtrow, vdt ); if (found) break; } } fputc('\n',fp); } free(buf); break; case 'I': if (table.header[i].count==1) { get_table_element(i,row,table,&l,&count); if (l != NULLINT) { fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); ltoa((int)l,num,10); fputs(num,fp); strcpy( path, table.path ); strcat( path, table.header[i].vdt ); if ( (access(path,4)==0) && (strcmp(table.header[i].vdt,"") != 0) ) { if (strcmp(vdtpath,path) != 0) { if (strcmp(vdtpath,"") != 0) { vpf_close_table(&vdt); } vdt = vpf_open_table( path, disk, "rb", NULL ); } strcpy( vdtpath, path ); for (j=1;j<=vdt.nrows;j++) { vdtrow = read_row( j, vdt ); tablename = (char *)get_table_element( TABLE_, vdtrow, vdt, NULL, &count ); rightjust(tablename); strupr2(tablename); attr = (char *)get_table_element( ATTR_, vdtrow, vdt, NULL, &count ); rightjust(attr); get_table_element( VAL_, vdtrow, vdt, &lval, &count ); found = FALSE; if ( (strstr(table.name,tablename)) && (ossim_strcasecmp(attr,table.header[i].name)==0) && (lval==l) ) { descr = (char *)get_table_element(DESCR_,vdtrow, vdt, NULL, &count); rightjust(descr); fputs(" (",fp); fputs(descr,fp); fputs(")",fp); free(descr); found = TRUE; } free(tablename); free(attr); free_row( vdtrow, vdt ); if (found) break; } } fputc('\n',fp); } } else { get_table_element(i,row,table,&lptr,&count); fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": (",fp); for (j=0;j<count;j++) { ltoa((int)lptr[j],num,10); fputs(num,fp); if (j<count-1) fputs(", ",fp); } fputs(")\n",fp); } break; case 'S': if (table.header[i].count==1) { get_table_element(i,row,table,&s,&count); if (s != NULLSHORT) { fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); itoa(s,num,10); fputs(num,fp); strcpy( path, table.path ); strcat( path, table.header[i].vdt ); if ( (access(path,4)==0) && (strcmp(table.header[i].vdt,"") != 0) ) { if (strcmp(vdtpath,path) != 0) { if (strcmp(vdtpath,"") != 0) { vpf_close_table(&vdt); } vdt = vpf_open_table( path, disk, "rb", NULL ); } strcpy( vdtpath, path ); for (j=1;j<=vdt.nrows;j++) { vdtrow = read_row( j, vdt ); tablename = (char *)get_table_element( TABLE_, vdtrow, vdt, NULL, &count ); rightjust(tablename); strupr2(tablename); attr = (char *)get_table_element( ATTR_, vdtrow, vdt, NULL, &count ); rightjust(attr); get_table_element( VAL_, vdtrow, vdt, &sval, &count ); found = FALSE; if ( (strstr(table.name,tablename)) && (ossim_strcasecmp(attr,table.header[i].name)==0) && (sval==s) ) { descr = (char *)get_table_element(DESCR_,vdtrow, vdt, NULL, &count); rightjust(descr); fputs(" (",fp); fputs(descr,fp); fputs(")",fp); free(descr); found = TRUE; } free(tablename); free(attr); free_row( vdtrow, vdt ); if (found) break; } } fputc('\n',fp); } } else { get_table_element(i,row,table,&sptr,&count); fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": (",fp); for (j=0;j<count;j++) { itoa(sptr[j],num,10); fputs(num,fp); if (j<count-1) fputs(", ",fp); } fputs(")\n",fp); } break; case 'F': if (table.header[i].count==1) { get_table_element(i,row,table,&f,&count); if (!is_vpf_null_float(f)) { fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); #if !defined(__APPLE__) && !defined(__FreeBSD__) gcvt(f,6,num); #endif fputs(num,fp); fputc('\n',fp); } } else { get_table_element(i,row,table,&fptr,&count); fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": (",fp); for (j=0;j<count;j++) { if (is_vpf_null_float(fptr[j])) { fputs("(null)",fp); } else { #if !defined(__APPLE__) && !defined(__FreeBSD__) gcvt(fptr[j],6,num); #endif fputs(num,fp); } if (j<count-1) fputs(", ",fp); } fputs(")\n",fp); } break; case 'D': if (table.header[i].count==1) { get_table_element(i,row,table,date,&count); fputs(table.header[i].name,fp); fputs(" - ",fp); fputs(table.header[i].description,fp); fputs(": ",fp); format_date(date,fmtdate); fputs(fmtdate,fp); fputc('\n',fp); } break; } } if (strcmp(vdtpath,"") != 0) vpf_close_table( &vdt ); free(num); }