/*****************************************************************************
*                                                                            *
*      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 312                                  *
*                   HONOLULU, HI 96822                                       *
*                                                                            *
*      VERSION:     3.10                                                     *
*                                                                            *
*      DATE:        APRIL 1989, AUGUST 1995                                  *
*                                                                            *
*****************************************************************************/

/*
       FILE:  DBINC.H

              INCLUDE FILE FOR COMPILING CODAS SOURCE CODE

              The structures and constants declared in this file are
              applicable only to the database system's internal functions.
*/
#ifndef dbinc_included
#define dbinc_included

#ifndef geninc_included
#include "geninc.h"     /* HOST_ENVIRONMENT, typedef's */
#endif
/*
       DATABASE DEFINITIONS
*/
#define DATABASE_SYSTEM_VERSION      "0300"   /**jr: change long to string **/
#define MAX_OPEN_DATABASES            5
#define MAX_BLOCK_DIR_SIZE          512
#define MAX_PROFILE_DIR_SIZE        512
#define MAX_DATA_LIST_SIZE          100
#define MAX_STRUCT_DEF_SOURCE        10
#define MAX_STRUCTURE_LIST_SIZE     100

#if (HOST_ENVIRONMENT == PC_COMPATIBLE_HOST || HOST_ENVIRONMENT == UNKNOWN_HOST)
#define MAX_DBNAME_LENGTH             5
#endif
#if (HOST_ENVIRONMENT == VAXD_COMPATIBLE_HOST)
#define MAX_DBNAME_LENGTH             6
#endif
#if (HOST_ENVIRONMENT == SUN3_COMPATIBLE_HOST)
#define MAX_DBNAME_LENGTH            11
#endif

/*
       BLOCK DIRECTORY HEADER STRUCTURE

         ** 144 BYTES
         ** RANGES REFER TO ALL DATA IN WORKING DATABASE
*/
typedef struct
{
   CHAR   db_version[4];            /* database system version             */
   DATASET_ID_TYPE  dataset_id;     /* dataset identification              */
   ULONG  time1,                    /* time range (packed block times)     */
          time2;
   LONG   lon1,                     /* latitude/longitude range            */
          lon2,                     /* (packed positions)                  */
          lat1,
          lat2;
   SHORT  depth1,                   /* depth range                         */
          depth2;                   /* (in meters positive down)           */
   ULONG  dir_type;
   USHORT dir_entry_nbytes,         /* sizes  of entries in directory      */
          dir_nentries;             /* number of entries in directory      */
   ULONG  next_seq_number;          /* next file sequence number available */
   CHAR   block_file_template[40];  /* format template for names of block_files (40 bytes)         */
   ULONG  data_mask,                /* data range                          */
          data_proc_mask;           /* data proc range                     */
   ULONG  unused1,                  /* reserved for future use             */
          unused2,
          unused3,
          unused4;
   CHAR   ms_code[4];               /* modified 95/07 JR */
} BLOCK_DIR_HDR_TYPE;

#define BLOCK_DIR_HDR_SIZE   sizeof(BLOCK_DIR_HDR_TYPE)
#define EXPECTED_BLOCK_DIR_HDR_SIZE   144 /* 18 x 8 */

/*
       BLOCK DIRECTORY ENTRY STRUCTURE

          ** 80 BYTES PER ENTRY
          ** RANGES REFER TO ALL DATA IN BLOCK
*/
typedef struct
{
   PRODUCER_ID_TYPE producer_id;        /* producer identification            */
   ULONG            time1,              /* time range (packed block times)    */
                    time2;
   LONG             lon1,               /* latitude/longitude range           */
                    lon2,               /* (packed positions)                 */
                    lat1,
                    lat2;
   SHORT            depth1,             /* depth range (in meters)            */
                    depth2;
   ULONG            block_nbytes;       /* block size in bytes                */
   LONG             file_id;            /* sequence number of BLOCK file      */
   ULONG            data_mask,          /* data present in block              */
                    data_proc_mask;     /* processing stage of data           */
   LONG             unassigned;         /* padding to 8-byte multiple         */
} BLOCK_DIR_ENTRY_TYPE;

#define BLOCK_DIR_ENTRY_SIZE   sizeof(BLOCK_DIR_ENTRY_TYPE)
#define EXPECTED_BLOCK_DIR_ENTRY_SIZE   80
#define MAX_BLOCK_DIR_ENTRY_SIZE   sizeof(BLOCK_DIR_ENTRY_TYPE)
#define MAX_BLOCK_DIR_NBYTES  (MAX_BLOCK_DIR_SIZE * MAX_BLOCK_DIR_ENTRY_SIZE)

/*
       BLOCK HEADER STRUCTURE

         ** 160 BYTES
         ** RANGES REFER TO ALL DATA IN BLOCK
*/
typedef struct
{
   CHAR             db_version[4],       /* db system version                 */
                    producer_host[4];    /* environment used to create block  */
   DATASET_ID_TYPE  dataset_id;          /* data set identifier               */
   PRODUCER_ID_TYPE producer_id;         /* producer identifier               */
   ULONG            time1,               /* time range (packed block times)   */
                    time2;
   LONG             lon1,                /* latitude/longitude range          */
                    lon2,                /* (packed positions)                */
                    lat1,
                    lat2;
   SHORT            depth1,              /* depth range (in meters)           */
                    depth2;
   ULONG            data_list_ofs,
                    dir_ofs,
                    block_nbytes,
                    dir_type;
   USHORT           data_list_nentries,
                    dir_entry_nbytes,
                    dir_nentries,
                    data_dir_nentries;
   ULONG            data_mask,           /* data present in block             */
                    data_proc_mask;      /* processing stage of data          */
   USHORT           struct_def_nentries;
   CHAR             ms_code[4];
   USHORT           dir_time_flag;
   ULONG            block_ftr_ofs;
   USHORT           unassigned2[8];
} BLOCK_HDR_TYPE;

#define BLOCK_HDR_SIZE   sizeof(BLOCK_HDR_TYPE)
#define EXPECTED_BLOCK_HDR_SIZE   160  /* 20 x 8 */

/*
       DATA LIST ENTRY STRUCTURE
       >>>>>>>>      new version       <<<<<<<<
       The UBYTE elements have been changed to SHORT.  This 
       keeps the ULONG elements aligned at multiples of 4,
       and keeps the length of the structure a multiple of 
       4.
*/
typedef struct
{
   CHAR      name[20],
             units[12];
   SHORT     value_type,
             access_type;
   ULONG     access_0,
             access_1;
   FLOAT     offset,
             scale;
   ULONG     unused;
} DATA_LIST_ENTRY_TYPE;

#define DATA_LIST_ENTRY_SIZE   sizeof(DATA_LIST_ENTRY_TYPE)
#define EXPECTED_DATA_LIST_ENTRY_SIZE   56

/*
       PRODUCER DEFINITION STRUCTURE
*/
typedef struct
{
   DATASET_ID_TYPE        dataset_id;
   PRODUCER_ID_TYPE       producer_id;
   ULONG                  block_dir_type;
   LONG                   profile_dir_type;
   USHORT                 data_list_max_nentries,
                          struct_def_max_nentries,
                          profile_var_max_nentries,
                          dir_time_flag;
} PRODUCER_DEFINITION_TYPE;

#define PRODUCER_DEFINITION_SIZE   sizeof(PRODUCER_DEFINITION_TYPE)

/*
       PROFILE DIRECTORY ENTRY STRUCTURES
*/
/*
 --->  TYPE 0:  POINTER, TIME-KEY
*/
typedef struct
{
   LONG       ofs;                     /* offset of profile in block file    */
   ULONG      time;                    /* time of profile from block time1   */
} PROFILE_DIR_0_ENTRY_TYPE;

#define PROFILE_DIR_0_ENTRY_SIZE  sizeof(PROFILE_DIR_0_ENTRY_TYPE)
#define XPCTD_PROFILE_DIR_0_ENTRY_SIZE  8

/*
 --->  TYPE 1:  POINTER, TIME-KEY, LAT-KEY, LON-KEY
*/
typedef struct
{
   LONG       ofs;                     /* offset of profile in block file    */
   ULONG      time;                    /* time of profile from block time1   */
   SHORT      depth1,                  /* type 1 does not have depth keys--  */
              depth2;                  /* space is reserved for conformity   */
   LONG       spare_key;              /* pad to multiple of 8; may be useful */
   LONG       lon,                     /* profile position in hundredths of  */
              lat;                     /* a second                           */
} PROFILE_DIR_1_ENTRY_TYPE;

#define PROFILE_DIR_1_ENTRY_SIZE  sizeof(PROFILE_DIR_1_ENTRY_TYPE)
#define XPCTD_PROFILE_DIR_1_ENTRY_SIZE  24

/*
 --->  TYPE 2:  POINTER, TIME-KEY, DEPTH1-KEY, DEPTH2-KEY
*/
typedef struct
{
   LONG       ofs;                     /* offset of profile in block file    */
   ULONG      time;                    /* time of profile from block time1   */
   SHORT      depth1,                  /* minimum depth of profile in meters */
              depth2;                  /* maximum depth of profile in meters */
   LONG       spare_key;              /* pad to multiple of 8; may be useful */
} PROFILE_DIR_2_ENTRY_TYPE;

#define PROFILE_DIR_2_ENTRY_SIZE  sizeof(PROFILE_DIR_2_ENTRY_TYPE)
#define XPCTD_PROFILE_DIR_2_ENTRY_SIZE  16

/*
 --->  TYPE 3:  POINTER, TIME-KEY, DEPTH1-KEY, DEPTH2-KEY, LAT-KEY, LON-KEY
*/
typedef struct
{
   LONG       ofs;                     /* offset of profile in block file    */
   ULONG      time;                    /* time of profile from block time1   */
   SHORT      depth1,                  /* minimum depth of profile in meters */
              depth2;                  /* maximum depth of profile in meters */
   LONG       spare_key;              /* pad to multiple of 8; may be useful */
   LONG       lon,                     /* profile position in                */
              lat;                     /* hundredths of a second             */
} PROFILE_DIR_3_ENTRY_TYPE;

#define PROFILE_DIR_3_ENTRY_SIZE  sizeof(PROFILE_DIR_3_ENTRY_TYPE)
#define XPCTD_PROFILE_DIR_3_ENTRY_SIZE  24

#define MAX_PROFILE_DIR_ENTRY_SIZE  sizeof(PROFILE_DIR_3_ENTRY_TYPE)
#define MAX_PROFILE_DIR_NBYTES  \
   (MAX_PROFILE_DIR_SIZE * MAX_PROFILE_DIR_ENTRY_SIZE)

/*
       DATA DIR STRUCTURE
       Here the USHORT is changed to LONG, to relax the
       limitation on profile and array size.
*/
typedef struct
{
   ULONG  ofs,
          nbytes;
} DATA_DIR_ENTRY_TYPE;

#define DATA_DIR_ENTRY_SIZE  sizeof(DATA_DIR_ENTRY_TYPE)
#define EXPECTED_DATA_DIR_ENTRY_SIZE  8

/*
       DATABASE ACCESS DEFINITION
*/
typedef struct
{
   FILE_NAME_TYPE               block_dir_file,
                                block_file,
                                producer_def_file;
   char                         temporary_data_file[L_tmpnam];
   int                          path_nchar;

   FILE                        *fpblkdir,
                               *fpblkdata,
                               *fptmpdata,
                               *fpprddef;

   int                          error_code,
                                error_data,
                                db_is_open,
                                block_dir_is_open,
                                block_is_open,
                                profile_is_open,
                                new_block_is_open,
                                new_profile_is_open,
                                access_mode,
                                create_mode,
                                memory_directory,
                                block_dir_loaded,
                                data_list_loaded,
                                block_strdef_loaded,
                                profile_dir_loaded,
                                producer_loaded,
                                block_dir_in_memory,
                                profile_dir_in_memory,
                                producer_in_memory,
                                block_modified,
                                block_dir_modified,
                                block_dir_host, /* from block_dir_hdr ms_code */
                                block_host, /* from block hdr ms_code */
                                dbint_sd_concatenated, /* internal SDs concatenated to db->struct_def? */
                                formats_matched; /* jr+ indicates if format list
                                             has been matched to block_strdef */
   PRODUCER_DEFINITION_TYPE    *producer;
   BLOCK_DIR_HDR_TYPE           block_dir_hdr;
   char                        *block_dir;
   BLOCK_DIR_ENTRY_TYPE         block_dir_entry;
   BLOCK_DIR_ENTRY_TYPE        *block_dir_entry_ptr;
   int                          block_dir_index;
   BLOCK_HDR_TYPE               block_hdr;
   DATA_LIST_ENTRY_TYPE         data_list[MAX_DATA_LIST_SIZE];
   STRUCT_DEF_HDR_TYPE         *struct_def;
   STRUCT_DEF_HDR_TYPE         *prev_strdef;
   STRUCT_DEF_HDR_TYPE         *block_strdef;
   STRUCT_DEF_HDR_TYPE         *next_strdef;
   FORMAT_HDR_TYPE             *format_list;
   STRUCT_DEF_ELEM_TYPE        data_def;
   char                        *profile_dir;
   PROFILE_DIR_3_ENTRY_TYPE     profile_dir_entry;
   PROFILE_DIR_3_ENTRY_TYPE    *profile_dir_entry_ptr;
   int                          profile_dir_index;
   DATA_DIR_ENTRY_TYPE          data_dir[MAX_DATA_LIST_SIZE];
   char                        *block_ftr;
   ULONG                        temp_data_ofs;
   YMDHMS_TIME_TYPE             block_base_time,
                                block_last_time,
                                profile_time;
} DATABASE_TYPE;

#define DATABASE_SIZE  sizeof(DATABASE_TYPE)

#include "dbglo.h"

#endif /* ifndef dbinc_included */
