You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							584 lines
						
					
					
						
							19 KiB
						
					
					
				
			
		
		
	
	
							584 lines
						
					
					
						
							19 KiB
						
					
					
				| /*
 | |
|  * Copyright (c) 1994 Sandia Corporation. Under the terms of Contract
 | |
|  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Governement
 | |
|  * retains certain rights in this software.
 | |
|  * 
 | |
|  * Redistribution and use in source and binary forms, with or without
 | |
|  * modification, are permitted provided that the following conditions are
 | |
|  * met:
 | |
|  * 
 | |
|  *     * Redistributions of source code must retain the above copyright
 | |
|  *       notice, this list of conditions and the following disclaimer.
 | |
|  * 
 | |
|  *     * Redistributions in binary form must reproduce the above
 | |
|  *       copyright notice, this list of conditions and the following
 | |
|  *       disclaimer in the documentation and/or other materials provided
 | |
|  *       with the distribution.  
 | |
|  * 
 | |
|  *     * Neither the name of Sandia Corporation nor the names of its
 | |
|  *       contributors may be used to endorse or promote products derived
 | |
|  *       from this software without specific prior written permission.
 | |
|  * 
 | |
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 | |
|  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 | |
|  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 | |
|  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 | |
|  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 | |
|  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 | |
|  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 | |
|  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 | |
|  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 | |
|  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 | |
|  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  * 
 | |
|  */
 | |
| /*****************************************************************************
 | |
| *
 | |
| * exutils - exodus utilities
 | |
| *
 | |
| * author - James A. Schutt - 8 byte float and standard C definitions
 | |
| *          Vic Yarberry    - Added headers and error logging
 | |
| *          
 | |
| * environment - UNIX
 | |
| *
 | |
| * entry conditions - 
 | |
| *
 | |
| * exit conditions - 
 | |
| *
 | |
| * revision history - 
 | |
| *
 | |
| *  $Id: ex_conv.c,v 1.1 2005/07/17 15:43:59 andy Exp $
 | |
| *
 | |
| *****************************************************************************/
 | |
| 
 | |
| #include <stdlib.h>
 | |
| #include "exodusII.h"
 | |
| #include "exodusII_int.h"
 | |
| 
 | |
| typedef int convert_task;
 | |
| 
 | |
| /* this file contains code needed to support the various floating point word
 | |
|  * size combinations for computation and i/o that applications might want to
 | |
|  * use.  the following discussion uses the C type names "float" and "double".
 | |
|  *
 | |
|  * netCDF supports two floating point word sizes for its files:
 | |
|  *      NC_FLOAT  - 32 bit IEEE (in XDR parlance, XDR_FLOAT)
 | |
|  *      NC_DOUBLE - 64 bit IEEE (in XDR parlance, XDR_DOUBLE)
 | |
|  * now, if you want to write an array of NC_FLOATs, netCDF expects as input
 | |
|  * an array of native floats; NC_DOUBLEs require an input array of native
 | |
|  * doubles.
 | |
|  *
 | |
|  * so, suppose you're computing using variables declared double, but you want
 | |
|  * to write a netCDF file using NC_FLOATs.  you need to copy your array into
 | |
|  * a buffer array declared as float, which truncates your data from double to
 | |
|  * float (type conversion).  then you can pass the buffer array to netCDF 
 | |
|  * routines for output as NC_FLOATs, and everything will work OK.  similarly,
 | |
|  * if you are computing in floats but want to write NC_DOUBLEs, you need to 
 | |
|  * copy your data into a buffer array declared as double, which promotes it
 | |
|  * from float to double, and then call the netCDF routine with the buffer array.
 | |
|  *
 | |
|  * these routines are designed to do this type conversion, based on information
 | |
|  * given in the ex_open or ex_create calls.  thus, except for when the file is
 | |
|  * opened, the user is relieved of the burden of caring about compute word size
 | |
|  * (the size of floating point variables used in the application program, and
 | |
|  * passed into the EXODUS II calls) and i/o word size (the size of floating
 | |
|  * point data as written in the netCDF file).
 | |
|  *
 | |
|  * this code is supposed to be general enough to handle weird cases like the
 | |
|  * cray, where in C (and C++) both floats and doubles are 8 byte quantities.
 | |
|  * thus the same array can be passed into a netCDF routine to write either
 | |
|  * NC_FLOATs or NC_DOUBLEs.
 | |
|  *
 | |
|  * note: 16 byte floating point values, such as might be obtained from an ANSI C
 | |
|  *       "long double", are specifically not handled.  Also, I don't know how
 | |
|  *       the vanilla netCDF interface handles double precision on a CRAY, which
 | |
|  *       gives 16 byte values, but these routines as written won't be able to
 | |
|  *       handle it.
 | |
|  *
 | |
|  * author: j. a. schutt, sandia national laboratories, department 1425
 | |
|  */
 | |
| 
 | |
| #define NC_FLOAT_WORDSIZE 4
 | |
| #define NC_DOUBLE_WORDSIZE 8
 | |
| 
 | |
| enum conv_action { NO_CONVERSION, CONVERT_UP, CONVERT_DOWN };
 | |
| typedef int conv_action;
 | |
| 
 | |
| struct file_item {
 | |
|   int                   file_id;
 | |
|   conv_action           rd_conv_action;
 | |
|   conv_action           wr_conv_action;
 | |
|   nc_type               netcdf_type_code;
 | |
|   int                   user_compute_wordsize;
 | |
|   struct file_item*     next;
 | |
| };
 | |
| 
 | |
| struct file_item* file_list = NULL;
 | |
| 
 | |
| /*
 | |
|  * Now recognized at more locations worldwide in this file...
 | |
|  */
 | |
| 
 | |
| static int cur_len = 0;                       /* in bytes! */
 | |
| static void* buffer_array = NULL;
 | |
| static int do_conversion = 0; /* Do any files do a conversion? */
 | |
| 
 | |
| #define FIND_FILE(ptr,id) { ptr = file_list;                    \
 | |
|                             while(ptr) {                        \
 | |
|                               if( ptr->file_id == id ) break;   \
 | |
|                               ptr = ptr->next;                  \
 | |
|                             }                                   \
 | |
|                           }
 | |
| 
 | |
| /*............................................................................*/
 | |
| /*............................................................................*/
 | |
| 
 | |
| int ex_conv_ini( int  exoid,
 | |
|                   int* comp_wordsize,
 | |
|                   int* io_wordsize,
 | |
|                   int  file_wordsize )
 | |
| {
 | |
|   char errmsg[MAX_ERR_LENGTH];
 | |
|   struct file_item* new_file;
 | |
| 
 | |
| /* ex_conv_ini() initializes the floating point conversion process.
 | |
|  *
 | |
|  * exoid                an integer uniquely identifying the file of interest.
 | |
|  *
 | |
|  * word size parameters are specified in bytes. valid values are 0, 4, and 8:
 | |
|  *
 | |
|  * comp_wordsize        compute floating point word size in the user's code.
 | |
|  *                      a zero value indicates that the user is requesting the 
 | |
|  *                      default float size for the machine. The appropriate 
 | |
|  *                      value is chosen and returned in comp_wordsize, and used
 | |
|  *                      in subsequent conversions.  a valid but inappropriate 
 | |
|  *                      for this parameter cannot be detected.
 | |
|  *
 | |
|  * io_wordsize          the desired floating point word size for a netCDF file.
 | |
|  *                      for an existing file, if this parameter doesn't match
 | |
|  *                      the word size of data already stored in the file, a
 | |
|  *                      fatal error is generated.  a value of 0 for an existing
 | |
|  *                      file indicates that the word size of the file was not
 | |
|  *                      known a priori, so use whatever is in the file.  a value
 | |
|  *                      of 0 for a new file means to use the default size, an
 | |
|  *                      NC_FLOAT (4 bytes).  when a value of 0 is specified the
 | |
|  *                      actual value used is returned in io_wordsize.
 | |
|  *
 | |
|  * file_wordsize        floating point word size in an existing netCDF file.
 | |
|  *                      a value of 0 should be passed in for a new netCDF file.
 | |
|  */
 | |
| 
 | |
| /* check to make sure machine word sizes aren't weird (I'm paranoid) */
 | |
| 
 | |
|   if ((sizeof(float)  != 4 && sizeof(float)  != 8) ||
 | |
|       (sizeof(double) != 4 && sizeof(double) != 8 ) )
 | |
|   {
 | |
|     sprintf(errmsg,"Error: unsupported compute word size for file id: %d",
 | |
|             exoid);
 | |
|     ex_err("ex_conv_ini",errmsg,EX_FATAL);
 | |
|     return(EX_FATAL);
 | |
|   }
 | |
| 
 | |
| /* check to see if requested word sizes are valid */
 | |
| 
 | |
|   if (!*io_wordsize )
 | |
|   {
 | |
|     if (!file_wordsize )
 | |
|       *io_wordsize = NC_FLOAT_WORDSIZE;
 | |
|     else
 | |
|       *io_wordsize = file_wordsize;
 | |
|   }
 | |
|   else if (*io_wordsize != 4 && *io_wordsize != 8 )
 | |
|   {
 | |
|     sprintf(errmsg,"Error: unsupported I/O word size for file id: %d",exoid);
 | |
|     ex_err("ex_conv_ini",errmsg,EX_FATAL);
 | |
|     return(EX_FATAL);
 | |
|   }
 | |
|   else if (file_wordsize && *io_wordsize != file_wordsize )
 | |
|   {
 | |
|     *io_wordsize = file_wordsize;
 | |
|     sprintf(errmsg,
 | |
|            "Error: invalid I/O word size specified for existing file id: %d",
 | |
|             exoid);
 | |
|     ex_err("ex_conv_ini",errmsg,EX_MSG);
 | |
|     ex_err("ex_conv_ini",
 | |
|            "       Requested I/O word size overridden.",
 | |
|             EX_MSG);
 | |
|   }
 | |
| 
 | |
|   if (!*comp_wordsize )
 | |
|   {
 | |
|       *comp_wordsize = sizeof(float);
 | |
|   }
 | |
|   else if (*comp_wordsize != 4 && *comp_wordsize != 8 )
 | |
|   {
 | |
|     ex_err("ex_conv_ini","Error: invalid compute wordsize specified",EX_FATAL);
 | |
|     return(EX_FATAL);
 | |
|   }
 | |
| 
 | |
| /* finally, set up conversion action */
 | |
| 
 | |
|   new_file = malloc(sizeof(struct file_item));
 | |
| 
 | |
|   new_file->file_id = exoid;
 | |
|   new_file->user_compute_wordsize = *comp_wordsize;
 | |
|   new_file->next = file_list;
 | |
|   file_list = new_file;
 | |
| 
 | |
| /* crays writing NC_FLOATs always hit this case first since on a cray
 | |
|  * sizeof(float) = sizeof(double)
 | |
|  */
 | |
|   if( *comp_wordsize == sizeof(float) &&
 | |
|       *io_wordsize   == NC_FLOAT_WORDSIZE ) {
 | |
| 
 | |
|     new_file->rd_conv_action = NO_CONVERSION;
 | |
|     new_file->wr_conv_action = NO_CONVERSION;
 | |
|     new_file->netcdf_type_code = NC_FLOAT;
 | |
|   }
 | |
| /* crays writing NC_DOUBLEs always hit this case first since on a cray
 | |
|  * sizeof(float) = sizeof(double)
 | |
|  */
 | |
|   else if( *comp_wordsize == sizeof(double) &&
 | |
|            *io_wordsize   == NC_DOUBLE_WORDSIZE ) {
 | |
| 
 | |
|     new_file->rd_conv_action = NO_CONVERSION;
 | |
|     new_file->wr_conv_action = NO_CONVERSION;
 | |
|     new_file->netcdf_type_code = NC_DOUBLE;
 | |
|   }
 | |
|   else if( *comp_wordsize == sizeof(double) &&
 | |
|            *io_wordsize   == NC_FLOAT_WORDSIZE ) {
 | |
| 
 | |
|     new_file->rd_conv_action = CONVERT_UP;
 | |
|     new_file->wr_conv_action = CONVERT_DOWN;
 | |
|     new_file->netcdf_type_code = NC_FLOAT;
 | |
|     do_conversion = 1;
 | |
|   }
 | |
|   else if( *comp_wordsize == sizeof(float) &&
 | |
|            *io_wordsize   == NC_DOUBLE_WORDSIZE ) {
 | |
| 
 | |
|     new_file->rd_conv_action = CONVERT_DOWN;
 | |
|     new_file->wr_conv_action = CONVERT_UP;
 | |
|     new_file->netcdf_type_code = NC_DOUBLE;
 | |
|     do_conversion = 1;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Invalid compute or io wordsize: i.e. 4 byte compute word on Cray */
 | |
|     sprintf(errmsg,"Error: invalid compute (%d) or io (%d) wordsize specified",
 | |
|                     *comp_wordsize, *io_wordsize);
 | |
|     ex_err("ex_conv_ini", errmsg, EX_FATAL);
 | |
|     return(EX_FATAL);
 | |
|   }
 | |
|     
 | |
|   return(EX_NOERR);
 | |
| 
 | |
| }
 | |
| 
 | |
| /*............................................................................*/
 | |
| /*............................................................................*/
 | |
| 
 | |
| void ex_conv_exit( int exoid )
 | |
| {
 | |
| /* ex_conv_exit() takes the structure identified by "exoid" out of the linked
 | |
|  * list which describes the files that ex_conv_array() knows how to convert.
 | |
|  *
 | |
|  * NOTE: it is absolutely necessary for ex_conv_array() to be called after
 | |
|  *       ncclose(), if the parameter used as "exoid" is the id returned from
 | |
|  *       an ncopen() or nccreate() call, as netCDF reuses file ids!
 | |
|  *       the best place to do this is ex_close(), which is where I did it.
 | |
|  *
 | |
|  * "exoid" is some integer which uniquely identifies the file of interest.
 | |
|  */
 | |
| 
 | |
|   char errmsg[MAX_ERR_LENGTH];
 | |
|   struct file_item* file = file_list;
 | |
|   struct file_item* prev = NULL;
 | |
| 
 | |
|   exerrval = 0; /* clear error code */
 | |
|   while( file )
 | |
|   {
 | |
|     if (file->file_id == exoid ) break;
 | |
| 
 | |
|     prev = file;
 | |
|     file = file->next;
 | |
|   }
 | |
| 
 | |
|   if (!file )
 | |
|   {
 | |
|     sprintf(errmsg,"Warning: failure to clear file id %d - not in list.",exoid);
 | |
|     ex_err("ex_conv_exit",errmsg,EX_MSG);
 | |
|     exerrval = EX_BADFILEID;
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (prev )
 | |
|     prev->next = file->next;
 | |
|   else
 | |
|     file_list = file->next;
 | |
| 
 | |
|   free( file );
 | |
| 
 | |
|   /*
 | |
|    * If no other files are opened, any buffer arrays for float/double 
 | |
|    * conversion ought to be cleaned up.
 | |
|    */
 | |
|   if ( !file_list )
 | |
|   {
 | |
|     if ( cur_len > 0 )
 | |
|       {
 | |
|         free(buffer_array);     /* Better not be null if condition true! */
 | |
|         buffer_array = NULL;
 | |
|         cur_len = 0;
 | |
|       }
 | |
|     do_conversion = 0;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /*............................................................................*/
 | |
| /*............................................................................*/
 | |
| 
 | |
| nc_type nc_flt_code( int exoid )
 | |
| {
 | |
| /* nc_flt_code() returns either NC_FLOAT or NC_DOUBLE, based on the parameters
 | |
|  * with which ex_conv_ini() was called.  nc_flt_code() is used as the nc_type
 | |
|  * parameter on ncvardef() calls that define floating point variables.
 | |
|  *
 | |
|  * "exoid" is some integer which uniquely identifies the file of interest.
 | |
|  */
 | |
| 
 | |
|   char errmsg[MAX_ERR_LENGTH];
 | |
|   struct file_item* file;
 | |
| 
 | |
|   exerrval = 0; /* clear error code */
 | |
|   FIND_FILE( file, exoid );
 | |
| 
 | |
|   if (!file )
 | |
|   {
 | |
|     exerrval = EX_BADFILEID;
 | |
|     sprintf(errmsg,"Error: unknown file id %d for nc_flt_code().",exoid);
 | |
|     ex_err("nc_flt_code",errmsg,exerrval);
 | |
|     return (nc_type) -1;
 | |
|   }
 | |
| 
 | |
|   return file->netcdf_type_code;
 | |
| }
 | |
| 
 | |
| /*............................................................................*/
 | |
| /*............................................................................*/
 | |
| 
 | |
| int ex_comp_ws( int exoid )
 | |
| {
 | |
| /* "exoid" is some integer which uniquely identifies the file of interest.
 | |
|  *
 | |
|  * ex_comp_ws() returns 4 (i.e. sizeof(float)) or 8 (i.e. sizeof(double)),
 | |
|  * depending on the value of floating point word size used to initialize
 | |
|  * the conversion facility for this file id (exoid).
 | |
|  */
 | |
| 
 | |
|   char errmsg[MAX_ERR_LENGTH];
 | |
|   struct file_item* file;
 | |
| 
 | |
|   exerrval = 0; /* clear error code */
 | |
|   FIND_FILE( file, exoid );
 | |
| 
 | |
|   if (!file )
 | |
|   {
 | |
|     exerrval = EX_BADFILEID;
 | |
|     sprintf(errmsg,"Error: unknown file id %d",exoid);
 | |
|     ex_err("ex_comp_ws",errmsg,exerrval);
 | |
|     return(EX_FATAL);
 | |
|   }
 | |
| 
 | |
|   return file->user_compute_wordsize;
 | |
| }
 | |
| 
 | |
| /*............................................................................*/
 | |
| /*............................................................................*/
 | |
| 
 | |
| /* some utility routines for use only by ex_conv_array() */
 | |
| 
 | |
| #define BUFFER_SIZE_UNIT 8192   /* should be even multiple of sizeof(double) */
 | |
| 
 | |
| void* resize_buffer( void* buffer,
 | |
|                      int   new_len )            /* in bytes! */
 | |
| {
 | |
|   /*
 | |
|    * Broaden the scope of this puppy to aid cleanup in ex_conv_exit().
 | |
|    */
 | |
| 
 | |
|   /* static int cur_len = 0;                       in bytes! */
 | |
| 
 | |
|   exerrval = 0; /* clear error code */
 | |
|   if( new_len > cur_len )
 | |
|   {
 | |
| 
 | |
|     cur_len = BUFFER_SIZE_UNIT * ( new_len/BUFFER_SIZE_UNIT + 1 );
 | |
|   
 | |
|     if( buffer ) free( buffer );
 | |
|     buffer = malloc( cur_len );
 | |
| 
 | |
|     if (!buffer )
 | |
|     {
 | |
|       exerrval = EX_MEMFAIL;
 | |
|       ex_err("ex_conv_array","couldn't allocate buffer space",exerrval);
 | |
|       return (NULL);
 | |
|     }
 | |
|   }
 | |
|   return buffer;
 | |
| }
 | |
| 
 | |
| void flt_to_dbl( float*  in_vec,
 | |
|                  int     len,
 | |
|                  double* out_vec )
 | |
| {
 | |
|   int i;
 | |
| 
 | |
|   for( i=0; i<len; i++ ) out_vec[i] = (double)(in_vec[i]);
 | |
| }
 | |
| 
 | |
| void dbl_to_flt( double* in_vec,
 | |
|                  int     len,
 | |
|                  float*  out_vec )
 | |
| {
 | |
|   int i;
 | |
| 
 | |
|   for( i=0; i<len; i++ ) out_vec[i] = (float)(in_vec[i]);
 | |
| }
 | |
| 
 | |
| 
 | |
| /*............................................................................*/
 | |
| /*............................................................................*/
 | |
| 
 | |
| void* ex_conv_array( int          exoid,
 | |
|                      convert_task task,
 | |
|                      const void*  usr_array,
 | |
|                      int          usr_length )
 | |
| {
 | |
| /* ex_conv_array() actually performs the floating point size conversion.
 | |
|  *
 | |
|  * "exoid" is some integer which uniquely identifies the file of interest.
 | |
|  *
 | |
|  * for reads, in conjunction with ncvarget()/ncvarget1(), ex_conv_array() must
 | |
|  * be called twice per read.  the first call must be before ncvarget(), and
 | |
|  * should be something like ex_conv_array( id, RTN_ADDRESS, usr_array, len ),
 | |
|  * where "usr_array" is the address of the user's data array, and "len" is
 | |
|  * the number of floating point values to convert.  this call returns an
 | |
|  * address which should be passed as a parameter in the subsequent ncvarget()
 | |
|  * call.  after ncvarget(), call ex_conv_array() again with something like
 | |
|  * ex_conv_array( ID, READ_CONVERT, usr_array, len ).  here ex_conv_array()
 | |
|  * should return NULL.
 | |
|  *
 | |
|  * for writes, in conjunction with ncvarput()/ncvarput1(), ex_conv_array() need
 | |
|  * only be called once, before the call to ncvarput().  the call should be
 | |
|  * something like ex_conv_array( id, WRITE_CONVERT, usr_array, len ), and
 | |
|  * returns an address that should be passed in the subsequent ncvarput() call.
 | |
|  */
 | |
| 
 | |
| 
 | |
|   char errmsg[MAX_ERR_LENGTH];
 | |
|   /*  static void* buffer_array = NULL; -- now global! */
 | |
|   struct file_item* file;
 | |
|   int len_bytes;
 | |
| 
 | |
|   exerrval = 0; /* clear error code */
 | |
|   if (do_conversion == 0) {
 | |
|     switch( task ) {
 | |
| 
 | |
|     case RTN_ADDRESS:
 | |
|       return (void*)usr_array;
 | |
|       break;
 | |
|     case READ_CONVERT:
 | |
|       return NULL;
 | |
|       break;
 | |
|     case WRITE_CONVERT:
 | |
|       return (void*)usr_array;
 | |
|       break;
 | |
|     default:
 | |
|       /* Fall through if other task is specified */
 | |
|       ;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   FIND_FILE( file, exoid );
 | |
| 
 | |
|   if( !file )
 | |
|   {
 | |
|     exerrval = EX_BADFILEID;
 | |
|     sprintf(errmsg,"Error: unknown file id %d",exoid);
 | |
|     ex_err("ex_conv_array",errmsg,exerrval);
 | |
|     return (NULL);
 | |
|   }
 | |
| 
 | |
| 
 | |
|   switch( task ) {
 | |
| 
 | |
|   case RTN_ADDRESS:
 | |
| 
 | |
|     switch( file->rd_conv_action ) {
 | |
|     case NO_CONVERSION:
 | |
|       return (void*)usr_array;
 | |
|     case CONVERT_UP: /* file ws: 4 byte, CPU ws: 8 byte */
 | |
|       len_bytes = usr_length * sizeof(float);
 | |
|       buffer_array = resize_buffer( buffer_array, len_bytes );
 | |
|       return buffer_array;
 | |
|     case CONVERT_DOWN: /* file ws: 8 byte, CPU ws: 4 byte */
 | |
|       len_bytes = usr_length * sizeof(double);
 | |
|       buffer_array = resize_buffer( buffer_array, len_bytes );
 | |
|       return buffer_array;
 | |
|     }
 | |
|     break;
 | |
| 
 | |
|   case READ_CONVERT:
 | |
| 
 | |
|     switch( file->rd_conv_action ) {
 | |
|     case NO_CONVERSION:
 | |
|       break;
 | |
|     case CONVERT_UP:
 | |
|       flt_to_dbl( buffer_array, usr_length, (void*)usr_array );
 | |
|       break;
 | |
|     case CONVERT_DOWN:
 | |
|       dbl_to_flt( buffer_array, usr_length, (void*)usr_array );
 | |
|       break;
 | |
|     }
 | |
|     return NULL;
 | |
| 
 | |
|   case WRITE_CONVERT:
 | |
| 
 | |
|     switch( file->wr_conv_action ) {
 | |
|     case NO_CONVERSION:
 | |
|       return (void*)usr_array;
 | |
|     case CONVERT_UP:
 | |
|       len_bytes = usr_length * sizeof(double);
 | |
|       buffer_array = resize_buffer( buffer_array, len_bytes );
 | |
|       flt_to_dbl( (void*)usr_array, usr_length, buffer_array );
 | |
|       return buffer_array;
 | |
|     case CONVERT_DOWN:
 | |
|       len_bytes = usr_length * sizeof(float);
 | |
|       buffer_array = resize_buffer( buffer_array, len_bytes );
 | |
|       dbl_to_flt( (void*)usr_array, usr_length, buffer_array );
 | |
|       return buffer_array;
 | |
|     }
 | |
|     break;
 | |
| 
 | |
|   case WRITE_CONVERT_DOWN:
 | |
| 
 | |
|     len_bytes = usr_length * sizeof(float);
 | |
|     buffer_array = resize_buffer( buffer_array, len_bytes );
 | |
|     dbl_to_flt( (void*)usr_array, usr_length, buffer_array );
 | |
|     return buffer_array;
 | |
| 
 | |
|   case WRITE_CONVERT_UP:
 | |
| 
 | |
|     len_bytes = usr_length * sizeof(double);
 | |
|     buffer_array = resize_buffer( buffer_array, len_bytes );
 | |
|     flt_to_dbl( (void*)usr_array, usr_length, buffer_array );
 | |
|     return buffer_array;
 | |
| 
 | |
|   }
 | |
| 
 | |
|   exerrval = EX_FATAL;
 | |
|   sprintf(errmsg,
 | |
|        "Error: unknown task code %d specified for converting float array",task);
 | |
|   ex_err("ex_conv_array",errmsg,exerrval);
 | |
|   return NULL;
 | |
| }
 | |
| 
 |