예제 #1
0
/*************************************************************************
 *
 *N  write_next_row
 *
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Purpose:
 *P
 *     This function writes the next row of the table.
 *     The parameter row must be initialized prior to this functional, either
 *     by being read in from an existing table or set to valid values.
 *     A row with any empty columns should not be written out.
 *     The parameter table must be a valid table and initialized prior to
 *     this function, by vpf_open_table.  It is assumed that there is
 *     enough free disk space to write to the file. It is also assumed that
 *     the file pointer (table->fp) is already opened for writing. The
 *     variable count, set to the values in row, must be greater than 0,
 *     otherwise, if count is -1 the vpf_write functions will lock up
 *     (row[].count should never have a value of 0). Note that if errorfp
 *     is used, it must be opened prior to this function.
 *
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Parameters:
 *A
 *    row        <input> == (row_type) the row to write to the table.
 *    table      <input> == (vpf_table_type *) vpf table structure.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   History:
 *H
 *    Dave Flinn       July 1991      Based on read_next_row.
 *    Barry Michaels    Oct 1991      Added row as a parameter.
 *    JTB              10/91          guaranteed function always
 *                                    returns a value:
 *                                     0: record written
 *                                    -1: unknown field type
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   External Variables:
 *X
 *    None
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Functions Called:
 *F
 *   None
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Portability:
 *O
 *    This module should be ANSI C compatible.
 *E
 *************************************************************************/
long int write_next_row(row_type row, vpf_table_type * table )
{
   register long int i,
		     j;
   char            * tptr,
		   * output ;
   long int          recordsize = 0;
   long int	     count;
   id_triplet_type * keys;
   unsigned long int pos_for_ndx,
		     length;
   int               retn_val = 0;
   coordinate_type   dummycoord = {0.0,0.0};

   STORAGE_BYTE_ORDER = table->byte_order;

   table->nrows++;
   fseek(table->fp, 0L, SEEK_END);
   pos_for_ndx = ftell(table->fp); /* begining of new row */

   for (i = 0; i < table->nfields; i++) {   /* for each column */

     count = row[i].count ;          /* Retrieve count from row.  Should
					be 0 if variable length null */

     /* In case this column is variable length, write out count */

     if (count == 0) count = 1;

     if ( table->header[i].count < 0 ) {
       Write_Vpf_Int ( &count, table->fp, 1 ) ;
       recordsize += sizeof ( long int ) ;
     }

     /* Now write out the data type */

     switch (table->header[i].type) {

     case 'T':
       if ( count == 0 ) 	/* Assume this is variable length text
				   and don't do anything */
	 break ;

       /* This loop insures that the exact number of characters are written
	  out to disk. */

       output = (char *) vpfmalloc ( count + 1 ) ;  /* include null byte */
       for (j = 0, tptr = (char*)row[i].ptr; j < count; j++, tptr++)
	 if ( *tptr )
	   output[j] = *tptr ;
	 else
	   output[j] = SPACE ;
       output[count] = '\0' ;
       Write_Vpf_Char( output ,table->fp, count) ;
       free ( output ) ;
       recordsize += sizeof ( char ) * count ;
       break;

     case 'I':
       Write_Vpf_Int (row[i].ptr, table->fp, count ) ;
       recordsize += sizeof ( long int ) * count ;
       break;

     case 'S':
       Write_Vpf_Short (row[i].ptr, table->fp, count ) ;
       recordsize += sizeof ( short int ) * count ;
       break;

     case 'F':
       Write_Vpf_Float (row[i].ptr, table->fp, count ) ;
       recordsize += sizeof ( float ) * count ;
       break;

     case 'R':
       Write_Vpf_Double (row[i].ptr, table->fp, count ) ;
       recordsize += sizeof ( double ) * count ;
       break;

     case 'D':	/* date has 21 chars in memory, not on disk */
       Write_Vpf_Date (row[i].ptr, table->fp, count ) ;
       recordsize += ( sizeof ( date_type ) - 1 ) * count ;
       break;

     case 'C':
       if (row[i].ptr) {
	  Write_Vpf_Coordinate(row[i].ptr,table->fp,count);
       } else {
	  for (j=0;j<count;j++)
	     Write_Vpf_Coordinate(&dummycoord,table->fp,count);
       }
       recordsize += sizeof ( coordinate_type ) * count ;
       break;

     case 'B':
       Write_Vpf_DoubleCoordinate(row[i].ptr,table->fp,count);
       recordsize += sizeof ( double_coordinate_type ) * count ;
       break;

     case 'Z':
       Write_Vpf_CoordinateZ(row[i].ptr,table->fp,count);
       recordsize += sizeof ( tri_coordinate_type ) * count ;
       break;

     case 'Y':
       Write_Vpf_DoubleCoordinateZ(row[i].ptr,table->fp,count);
       recordsize += sizeof ( double_tri_coordinate_type ) * count ;
       break;

     case 'K':
       keys = (id_triplet_type *) vpfmalloc (count*sizeof(id_triplet_type)) ;
       memcpy ( keys, row[i].ptr, count*sizeof(id_triplet_type) ) ;
       for (j=0;j<count;j++)
	 recordsize += write_key ( keys[j], table->fp);
       free ( keys ) ;
       break;

     case 'X':
       /* do nothing */
       break;

     default:
       return(-1);
     }
   }

   if ( table->xfp ) {  /* only for variable length columns */
     length = recordsize ;
     fseek( table->xfp, 0, SEEK_END );

     Write_Vpf_Int ( &pos_for_ndx, table->xfp, 1 ) ;
     Write_Vpf_Int ( &length, table->xfp, 1 ) ;
   }

   return retn_val;
}
예제 #2
0
/*************************************************************************
 *
 *N  vpf_open_table
 *
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Purpose:
 *P
 *     This function opens a vpf table and either loads it into RAM or sets
 *     up the structure to read off of disk.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Parameters:
 *A
 *    tablename <input> == (const char *) file name of the table.
 *    storage   <input> == (storage_type) table storage mode -
 *                                        either ram or disk.
 *    mode      <input> == (const char *) file mode for opening the table -
 *                                  same as fopen() mode in C.
 *    defstr    <input> == (char *) table definition string used for
 *                                  creating a writable table.
 *    vpf_open_table <output> == (vpf_table_type) VPF table structure.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   History:
 *H
 *    Barry Michaels   April 1991                   DOS Turbo C
 *    Dave Flinn       July 1991                    UNIX compatable
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   External Variables:
 *X
 *    None
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Functions Called:
 *F
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Portability:
 *O
 *    This module should be ANSI C compatible.
 *E
 *************************************************************************/
vpf_table_type vpf_open_table( const char * tablename,
			       storage_type   storage ,
			       const char * mode,
			       char         * defstr )
{
   vpf_table_type   table;
   char             tablepath[255],
		  * idxname;
   ossim_int32         i,
		    j;
   ossim_int32         tablesize,
		    idxsize,
		    memsize;
   ossim_uint32 ulval;
   char            * diskname = "VPF data disc";

   strcpy(tablepath,tablename);
   rightjust(tablepath);

   /* Parse out name and path */
   j = -1;
   i=(long)strlen(tablepath);
   while (i>0) {
#ifdef __MSDOS__
      if (tablepath[i] == '\\') {
#else
      if (tablepath[i] == '/') {
#endif
	 j = i;
	 break;
      }
      i--;
   }
   strncpy(table.name,&(tablepath[j+1]),12);
   rightjust(table.name);
   strupr(table.name);
   table.path = (char *)vpfmalloc(((unsigned long)strlen(tablepath)+5)*(unsigned long)sizeof(char));
   strcpy(table.path, tablepath);
   table.path[j+1] = '\0';

 /* Establish a read or write table operation */

   if ( mode[0] == 'r' )
     table.mode = Read ;
   else
     table.mode = Write ;

   /*fprintf(stderr, "vpf_open_table opening %s\n", tablepath);*/
   table.fp = vpfopencheck(tablepath,mode,diskname);
   if (table.fp == NULL) {
      perror(tablepath);
/*
#if __MSDOS__
      perror(tablepath);
      getch();
      if (getgraphmode() >= 0) closegraph();
      exit(0);
#endif
*/
      free(table.path);
      if (table.fp) {
	fclose(table.fp);
	table.fp = NULL;
      } 
      return table;
   }

   /* If file is to be created, copy the def string ptr into header for now */

   if ( table.mode == Write )
     table.defstr = defstr ;

#ifdef __MSDOS__
   tablesize = (filelength(fileno(table.fp)));
#else
   {  /* UNIX doesn't have a filelength function, so this is the best */
     struct stat statbuf ;
     if ( stat ( tablepath, &statbuf ) < 0 ) {
       fprintf (stderr, "vpf_open_table: can't stat file\n" ) ;
       free(table.path);
       fclose(table.fp);
       table.fp = NULL;
       return table;
     }
     tablesize = statbuf.st_size ;
   }
#endif

   /* Populate table structure with correct data, either for read or write */

   table.reclen = parse_data_def(&table);

   if ( table.mode == Write ) {   /* write out header */
     rewind ( table.fp ) ;
     Write_Vpf_Int ( &table.ddlen, table.fp, 1 ) ;
     Write_Vpf_Char ( table.defstr, table.fp, table.ddlen ) ;
     free ( table.defstr ) ;
     table.defstr = (char *) NULL ;
     table.nrows = 0 ;
   }

   if (table.reclen > 0) {      /* Index file */
      table.xstorage = (storage_type)COMPUTE;
      if (table.mode != Write)
	 table.nrows = (tablesize - table.ddlen)/table.reclen;
      table.xfp = (FILE *) NULL ;
   } else {
      idxname = strdup( tablepath );
#ifdef __MSDOS__
      idxname[strlen(tablepath)-1] = 'x';
#else
      if (idxname[strlen(tablepath)-1] == '.')
	idxname[strlen(tablepath)-2] = 'x';
      else
	idxname[strlen(tablepath)-1] = 'x';
#endif
      table.xfp = fopen(idxname, mode);

      if ((!table.xfp) && (table.mode == Read)) {
	 perror(idxname);
         fprintf(stderr, "hit RETURN to continue...");
	 i=getc(stdin);
	 free(idxname);
	 for (i = 0; i < table.nfields; i++)
	   free(table.header[i].name);
	 free(table.header);
	 free(table.path);
         fclose(table.fp);
         table.fp = NULL;
         return table;
      }

      free(idxname);

/*#ifdef __MSDOS__*/
      table.xstorage = (storage_type)DISK;   /* Worst case default */
/*#endif*/

   /* Only read in index if file is read only */

      if (table.xfp && ( table.mode == Read ) ) {
	Read_Vpf_Int (&(table.nrows), table.xfp, 1 ) ;
	Read_Vpf_Int (&ulval, table.xfp, 1 ) ;
	idxsize = table.nrows*sizeof(index_cell) + 10L;

#ifdef __MSDOS__
	if ( (idxsize < (farcoreleft()/2)) && (idxsize < __64K) )
#else
	if (0)
#endif
	  {
	    table.xstorage = (storage_type)RAM;
	    table.index = (index_type)vpfmalloc(idxsize);
	    for (i=0;i<table.nrows;i++) {
	      Read_Vpf_Int (&(table.index[i].pos), table.xfp, 1) ;
	      Read_Vpf_Int (&(table.index[i].length),table.xfp,1 ) ;
	    }
	    fclose(table.xfp);
	  }
      } else if (table.mode == Write) {

     /* Write out dummy header record for index file. vpf_close_table finishes
	the job. */

	 Write_Vpf_Int ( &(table.ddlen), table.xfp, 1 ) ;
	 Write_Vpf_Int ( &(table.ddlen), table.xfp, 1 ) ;
	 table.xstorage = (storage_type)DISK;
	 table.index = (index_type) NULL ;

      }
   }  /* end of if table .reclen */

    table.storage = (storage_type)DISK;
#ifdef __MSDOS__
   memsize = (ossim_int32)min(farcoreleft(),__64K);
#else
   memsize = MAXINT;
#endif

   if ( (storage != disk) && ( table.mode == Read ) ) {
      if (tablesize + table.nrows * table.nfields * HEAP_OVERHEAD < memsize) {
	 fseek(table.fp,index_pos(1,table),SEEK_SET);
	 table.row = (row_type *)vpfmalloc((table.nrows+1)*sizeof(row_type));
	 for (i=0;i<table.nrows;i++) {
	    table.row[i] = read_next_row(table);
	 }
	 fclose(table.fp);
	 table.storage = (storage_type)RAM;
      }
   }
   table.status = OPENED;
   return table;
 }

/*************************************************************************
 *
 *N  vpf_close_table
 *
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Purpose:
 *P
 *     This function frees an entire table from memory.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Parameters:
 *A
 *    table       <inout> == (vpf_table_type) VPF table structure.
 *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
 *************************************************************************/
void vpf_close_table( vpf_table_type *table )
{
   register ossim_int32 i;

   if (table->status != OPENED) {
      return;
   }
   /*fprintf(stderr, "vpf_close_table closing %s%s\n", table->path, table->name);*/

   /* If the table is writable, write out the final record count */

   if ( table->mode == Write && table->xfp ) {
     rewind ( table->xfp ) ;
     Write_Vpf_Int ( &table->nrows, table->xfp, 1 ) ;
     Write_Vpf_Int ( &table->ddlen, table->xfp, 1 ) ;
   }

   for (i=0;i<table->nfields;i++) {
      free(table->header[i].name);
      /* free up null text string */
      if ( table->header[i].type == 'T')
	 free(table->header[i].nullval.Char);
      /* free up index file string */
      if (table->header[i].tdx!=(char *)NULL)
	free ( table->header[i].tdx ) ;
      /* free up narrative table string */
      if (table->header[i].narrative!=(char *)NULL) {
	free ( table->header[i].narrative ) ;
      }
   }
   free(table->header);

   switch (table->storage) {
      case RAM:
	 for (i=0;i<table->nrows;i++) free_row(table->row[i],*table);
	 free(table->row);
	 break;
      case DISK:
	 fclose(table->fp);
	 break;
      default:
	 printf("%s%s: unknown storage flag: %d\n",table->path,table->name,
		table->storage);
	 break;
   }

   switch (table->xstorage) {
      case RAM:
	 free(table->index);
	 break;
      case DISK:
	 fclose(table->xfp);
	 break;
      case COMPUTE:
	 break;
      default:
	 printf("%s%s: unknown index storage flag: %d\n",
		table->path,table->name,table->storage);
	 break;
   }
   table->nfields = 0;
   free(table->path);
   table->status = CLOSED;
}



ossim_int32 is_vpf_table( const char *fname )
{
   FILE *fp;
   ossim_int32 n, ok;

   fp = fopen( fname, "rb" );
   if (!fp) {
      return FALSE;
   }
   Read_Vpf_Int ( &n, fp, 1 ) ;
   fseek( fp, n-1, SEEK_CUR );
   if (fgetc(fp) == ';')
      ok = TRUE;
   else
      ok = FALSE;
   fclose(fp);
   return ok;
}
예제 #3
0
/*************************************************************************
 *
 *N  write_key
 *
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Purpose:
 *P
 *     This function writes an id triplet key from the specified file.
 *     It is assumed that there is enough free disk space to write to the
 *     file. It is also assumed that the file pointer (fp) is already opened
 *     for writing.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Parameters:
 *A
 *    key     <input> == (id_triplet_type) id triplet key.
 *    fp      <input> == (FILE *) input file pointer.
 *    return <output> == (long int) size of the key.
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   History:
 *H
 *    Dave Flinn       July 1991      Based on read_key in vpftable.c
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   External Variables:
 *X
 *    None
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Functions Called:
 *F
 *    None
 *E
 *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 *
 *   Portability:
 *O
 *    This module should be ANSI C compatible.
 *E
 *************************************************************************/
long int write_key( id_triplet_type key, FILE *fp )
{
  long int size = 0 ;	/* to count size of key write */
  unsigned char tint ;
  short int tshort ;

   /* Assume that any count value has been written before this */
   /* Only write one key in this subroutine, do not write more */

  Write_Vpf_Char (&(key.type),fp,1);
  size += sizeof ( char ) ;

   switch (TYPE0(key.type)) {
   case 0:
     break;
   case 1:
     tint = (unsigned char) key.id ;
     Write_Vpf_Char ( &tint, fp, 1 ) ;
     size += sizeof ( char ) ;
     break;
   case 2:
     tshort = (short) key.id ;
     Write_Vpf_Short ( &tshort, fp, 1 ) ;
     size += sizeof ( short int ) ;
     break;
   case 3:
     Write_Vpf_Int (&(key.id), fp, 1 ) ;
     size += sizeof ( long int ) ;
     break;
   }

   switch (TYPE1(key.type)) {
   case 0:
     break;
   case 1:
     tint = (unsigned char) key.tile ;
     Write_Vpf_Char ( &tint, fp, 1 ) ;
     size += sizeof ( char ) ;
     break;
   case 2:
     tshort = (short) key.tile ;
     Write_Vpf_Short ( &tshort, fp, 1 ) ;
     size += sizeof ( short int ) ;
     break;
   case 3:
     Write_Vpf_Int (&(key.tile), fp, 1 ) ;
     size += sizeof ( long int ) ;
     break;
   }

   switch (TYPE2(key.type)) {
   case 0:
     break;
   case 1:
     tint = (unsigned char) key.exid ;
     Write_Vpf_Char ( &tint, fp, 1 ) ;
     size += sizeof ( char ) ;
     break;
   case 2:
     tshort = (short) key.exid ;
     Write_Vpf_Short ( &tshort, fp, 1 ) ;
     size += sizeof ( short int ) ;
     break;
   case 3:
     Write_Vpf_Int (&(key.exid), fp, 1 ) ;
     size += sizeof ( long int ) ;
     break;
   }
  return size ;
}