#include "dbinc.h"
/*****************************************************************************
*                                                                            *
*      COMMON OCEANOGRAPHIC DATA ACCESS SYSTEM (CODAS)                       *
*                                                                            *
*      WRITTEN BY:  RAMON CABRERA, ERIC FIRING, and JULIE RANADA             *
*                   JOINT INSTITUTE FOR MARINE AND ATMOSPHERIC RESEARCH      *
*                   1000 POPE ROAD  MSB 424                                  *
*                   HONOLULU, HI 96822                                       *
*                                                                            *
*      VERSION:     3.10                                                     *
*                                                                            *
*      DATE:        APRIL 1989, AUGUST 1995                                  *
*                                                                            *
*****************************************************************************/
/*

       FILE:  dbadd_f.c

              SYSTEM FUNCTIONS FOR ADDING SCALED DATA IN A DATABASE

*/
/*-----------------------------------------------------------------------------

   FUNCTION:  DBADD_F

      It automatically rescales and converts floating point data to the
      standard units and data types used in the database system and
      adds these to the database.

   PARAMETERS:

      type = pointer to data type

      data = address of user buffer

      nv = pointer to number of values in user buffer

      nbad = pointer to number of values set to BAD because of rescaling/
             conversion to a value outside range

      ierr = pointer to error code

   RETURNS:  void

*/
#if PROTOTYPE_ALLOWED
void DBADD_F(int *type, FLOAT data[],
             unsigned int *nv, unsigned int *nbad,
             int *ierr)
#else
void DBADD_F(type, data, nv, nbad, ierr)
int *type, *ierr;
FLOAT data[];
unsigned int *nv, *nbad;
#endif
{
   if (*nv == 0)
   {
      *ierr = INVALID_BUFFER_SIZE;
      return;
   }
/*
  ---> PROFILE DATA (types 0 - 99)
*/
   if ((*type >= 0) & (*type < (int)db->block_hdr.data_list_nentries))
   {
      if ((*ierr = dbadd_flags()) != 0)
         return;
      if (addf_profile_data(type, data, nv, nbad, ierr))
         goto error_found;
   }
   else
      *ierr = INVALID_TYPE_REQUEST;  /* use DBADD for types 100 - 300 */
   return;

   error_found:
      report_db_error("DBADD_F");
      *ierr = db->error_code * 1000 - db->error_data;
}

/*-----------------------------------------------------------------------------

   FUNCTION:  addf_profile_data

      It rescales and converts floating point data to the units and
      data type used as a standard in the database system, before
      adding these to a profile.

   PARAMETERS:

      type = pointer to user-defined data type
   
      data = address of user buffer where data to be added is located

      nv = pointer to number of values in the user buffer

      nbad = pointer to number of values set to BAD because of rescaling/
             conversion to a value outside range

      ierr = pointer to error code

   RETURNS:  0 if okay
             db->error_code otherwise

*/
#if PROTOTYPE_ALLOWED
int addf_profile_data(int *type, FLOAT data[],
                      unsigned int *nv, unsigned int *nbad,
                      int *ierr)
#else
int addf_profile_data(type, data, nv, nbad, ierr)
int *type, *ierr;
FLOAT data[];
unsigned int *nv, *nbad;
#endif
{
   char *conv_data;
   int ind;
   unsigned int nb;

   if ((db->data_list[*type].access_type == PROFILE_VAR_ACCESS_CODE) ||
      (db->data_list[*type].access_type == BLOCK_VAR_ACCESS_CODE))
      nb = (*nv) * VALUE_SIZE[db->data_list[*type].value_type];
   else
   {
      *ierr = INVALID_TYPE_REQUEST;
      return(0);
   }
   set_access_param(type, nb, &ind, ierr);
   if (*ierr)
      return(0);
   if (nb)
   {
      if ((conv_data = malloc(nb)) == NULL)
      {
         db->error_code = INSUFFICIENT_MEMORY;
         goto error_found;
      }
      *ierr = (*scale[db->data_list[*type].value_type])
        (conv_data, data, &(db->data_list[*type].scale),
        &(db->data_list[*type].offset), nv, nbad);
      if (!(*ierr))
         if (add_profile_aux(type, conv_data, nb, ind))
         {
            free(conv_data);
            goto error_found;
         }
      free(conv_data);
   }
   return(0);

   error_found:
      report_db_error("addf_profile_data");
      return(db->error_code);
}

