17#define G2C_INDEX_HEADER_LEN 81
20#define G2C_INDEX_BASENAME_LEN 40
23#define G2C_INDEX_BITMAP_BYTES 6
26#define G2C_INDEX_FIXED_LEN 44
29#define G2C_INDEX_FIXED_LEN_2 48
32#define G2C_INDEX_DATE_STR_LEN 10
35#define G2C_INDEX_TIME_STR_LEN 8
38#define G2C_INDEX_STR1_LEN 7
71 int *pds,
int *drs,
int *bms,
int *data,
size_t *msglen,
72 unsigned char *version,
unsigned char *discipline,
short *fieldnum)
79 if (!f || !reclen || !msg || !local || !gds || !pds || !drs || !bms || !data
80 || !msglen || !version || !discipline || !fieldnum)
83 LOG((4,
"g2c_start_index_record rw_flag %d", rw_flag));
88 fieldnum1 = *fieldnum + 1;
120 *fieldnum = fieldnum1 - 1;
153 int *pds,
int *drs,
int *bms,
int *data,
size_t *msglen,
154 unsigned char *version,
unsigned char *discipline,
short *fieldnum)
160 LOG((4,
"g2c_start_index_record_lf rw_flag %d", rw_flag));
163 if (!f || !reclen || !msg || !local || !gds || !pds || !drs || !bms || !data
164 || !msglen || !version || !discipline || !fieldnum)
170 fieldnum1 = *fieldnum + 1;
202 *fieldnum = fieldnum1 - 1;
241 unsigned int *b2_gds,
unsigned int *b2_bms,
unsigned int *b2_bds,
242 unsigned int *msglen,
unsigned char *version,
unsigned char *pds_val,
243 unsigned char *gds_val,
unsigned char *bms_val,
unsigned char *bds_val,
244 unsigned char *pds_val2,
unsigned char *pds_val3,
unsigned char *gds_val2)
250 if (!f || !b2_msg || !b2_pds || !b2_gds || !b2_bms || !b2_bds ||
326 if (!msg || fieldnum < 0 ||!sec3 || !sec4 || !sec5 || !sec6 || !sec7)
330 for (s4 = msg->
sec; s4; s4 = s4->
next)
335 if (s4info->field_num == fieldnum)
343 for (s3 = s4->
prev; s3; s3 = s3->
prev)
351 for (s5 = s4->
next; s5; s5 = s5->
next)
359 for (s6 = s5->
next; s6; s6 = s6->
next)
374 for (s7 = s5->
next; s7; s7 = s7->
next)
438 time_t t = time(NULL);
439 struct tm tm = *localtime(&t);
440 size_t items_written;
443 int total_index_size = 0;
444 int index_version = 1;
454 LOG((2,
"g2c_write_index g2cid %d mode %d index_file %s", g2cid, mode,
461 if ((f = fopen(index_file,
"r")))
473 if (!(f = fopen(index_file,
"wb+")))
486 "!GFHDR! 1 1 162 %4.4u-%2.2u-%2.2u %2.2u:%2.2u:%2.2u %s hfe08 grb2index\n",
487 (tm.tm_year + 1900), (tm.tm_mon + 1), tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
503 for (fieldnum = 0; fieldnum < msg->
num_fields; fieldnum++)
513 total_index_size += reclen;
514 LOG((4,
"fieldnum %d reclen %d total_index_size %d", fieldnum, reclen, total_index_size));
527 sprintf(h2,
"IX%dFORM: 162 %6d %6ld %s \n", index_version, total_index_size,
528 g2c_file[g2cid].num_messages, my_path);
529 LOG((5,
"header 2: %s", h2));
544 for (fieldnum = 0; fieldnum < msg->
num_fields; fieldnum++)
547 int bs3, bs4, bs5, bs6, bs7;
548 unsigned char sec_num;
562 LOG((4,
"fieldnum %d reclen %d", fieldnum, reclen));
565 if (index_version == 2)
677read_hdr_rec1(FILE *f,
int *ip,
int *jp,
int *kp,
char *date_str,
char *time_str)
696 sscanf(line,
"%s %d %d %d %s %s GB2IX1", long_str1, &i, &j, &k, long_date_str, long_time_str);
704 LOG((4,
"str1 %s i %d j %d k %d date_str %s time_str %s", str1, i, j, k, date_str,
747 char *basename,
int *index_version)
752 int total_len, num_rec;
762 sscanf(line,
"IX%dFORM: %d %d %d %s", index_version, &skip, &total_len,
763 &num_rec, long_basename);
772 *total_lenp = total_len;
799 int skip, total_len, num_rec;
814 LOG((2,
"g2c_open_index1 index_file %s", index_file));
820 if (!(f = fopen(index_file,
"rb")))
824 if ((ret =
read_hdr_rec1(f, &i, &j, &k, date_str, time_str)))
826 LOG((4,
"i %d j %d k %d date_str %s time_str %s", i, j, k, date_str, time_str));
829 if ((ret =
read_hdr_rec2(f, &skip, &total_len, &num_rec, basename, &index_version)))
831 LOG((4,
"skip %d total_len %d num_rec %d basename %s", skip, total_len, num_rec, basename));
835 for (rec = 0; rec < num_rec; rec++)
837 unsigned int b2_msg, b2_gds, b2_pds, b2_bms, b2_bds, msglen;
838 unsigned char version;
841 if (fseek(f, file_pos, SEEK_SET))
848 LOG((4,
"reading index1 record at file position %ld", ftell(f)));
850 &b2_bms, &b2_bds, &msglen, &version, pds_val,
851 gds_val, bms_val, bds_val, NULL, NULL, NULL)))
854 LOG((4,
"b2_msg %d b2_pds %d b2_gds %d b2_bms %d b2_bds %d msglen %d version %d",
855 b2_msg, b2_gds, b2_pds, b2_bms, b2_bds, msglen, version));
856 printf(
"b2_msg %d b2_pds %d b2_gds %d b2_bms %d b2_bds %d msglen %d version %d\n",
857 b2_msg, b2_gds, b2_pds, b2_bms, b2_bds, msglen, version);
860 file_pos += total_len;
903 if (!index_file || !data_file || !g2cid)
908 LOG((2,
"g2c_open_index index_file %s", index_file));
911 if (!(f = fopen(index_file,
"rb")))
926 int skip, total_len, num_rec;
941 sscanf(line,
"%s %d %d %d %s %s GB2IX1", long_str1, &i, &j, &k, long_date_str, long_time_str);
949 LOG((1,
"str1 %s i %d j %d k %d date_str %s time_str %s", str1, i, j, k, date_str,
959 sscanf(line,
"IX%dFORM: %d %d %d %s", &index_version, &skip, &total_len,
960 &num_rec, long_basename);
964 LOG((1,
"skip %d total_len %d num_rec %d basename %s", skip, total_len, num_rec, basename));
967 for (rec = 0; rec < num_rec; rec++)
969 int reclen, msgint, local, gds, pds, drs, bms, data;
971 unsigned char version, discipline;
975 if (fseek(f, file_pos, SEEK_SET))
982 LOG((4,
"reading index record at file position %ld, index_version %d",
983 ftell(f), index_version));
984 if (index_version == 1)
987 &drs, &bms, &data, &msglen, &version, &discipline, &fieldnum)))
994 &drs, &bms, &data, &msglen, &version, &discipline, &fieldnum)))
998 LOG((1,
"reclen %d msg %ld local %d gds %d pds %d drs %d bms %d data %d "
999 "msglen %ld version %d discipline %d fieldnum %d",
1000 reclen, msg, local, gds, pds, drs, bms, data, msglen,
1001 version, discipline, fieldnum));
1006 unsigned int sec_len;
1007 unsigned char sec_num;
1027 LOG((4,
"reading section info at file position %ld", ftell(f)));
1030 for (s = 3; s < 8; s++)
1032 size_t bytes_to_sec = gds;
1059 LOG((4,
"read section 7 info from data file. sec_len %d sec_num %d",
1072 bytes_to_sec = data;
1075 if (s < 6 && sec_num != s)
1090 if ((ret =
add_section(f, msgp, sec_id++, sec_len, bytes_to_sec, s)))
int add_msg(G2C_FILE_INFO_T *file, int msg_num, size_t bytes_to_msg, size_t bytes_in_msg, int read_file, G2C_MESSAGE_INFO_T **msg)
Add new message to linked list.
int add_section(FILE *f, G2C_MESSAGE_INFO_T *msg, int sec_id, unsigned int sec_len, size_t bytes_to_sec, unsigned char sec_num)
Add metadata about a new section 3, 4, 5, 6, or 7.
int g2c_rw_section5_metadata(FILE *f, int rw_flag, G2C_SECTION_INFO_T *sec)
Read or write the metadata from section 5 (Data Representation Section) of a GRIB2 message.
int g2c_rw_section1_metadata(FILE *f, int rw_flag, G2C_MESSAGE_INFO_T *msg)
Read Section 1.
int g2c_add_file(const char *path, int mode, int *g2cid)
Open a GRIB2 file and add it to the list of open files.
int g2c_rw_section3_metadata(FILE *f, int rw_flag, G2C_SECTION_INFO_T *sec)
Read the metadata from section 3 (Grid Definition Section) of a GRIB2 message.
int g2c_rw_section4_metadata(FILE *f, int rw_flag, G2C_SECTION_INFO_T *sec)
Read or write the metadata from section 4 (Product Definition Section) of a GRIB2 message.
#define G2C_INDEX_FIXED_LEN_2
Length of beginning of index record for large files.
int g2c_open_index(const char *data_file, const char *index_file, int mode, int *g2cid)
Open a GRIB2 file with the help of an index file.
int g2c_start_index1_record(FILE *f, int rw_flag, unsigned int *b2_msg, unsigned int *b2_pds, unsigned int *b2_gds, unsigned int *b2_bms, unsigned int *b2_bds, unsigned int *msglen, unsigned char *version, unsigned char *pds_val, unsigned char *gds_val, unsigned char *bms_val, unsigned char *bds_val, unsigned char *pds_val2, unsigned char *pds_val3, unsigned char *gds_val2)
Read or write the start of a version 1 index record.
int g2c_open_index1(const char *index_file)
Open a GRIB1 index file and read the contents.
static int read_hdr_rec2(FILE *f, int *skipp, int *total_lenp, int *num_recp, char *basename, int *index_version)
Read the second header record of an index file.
static int read_hdr_rec1(FILE *f, int *ip, int *jp, int *kp, char *date_str, char *time_str)
Read the header record apparently named after Steve Lord.
#define G2C_INDEX_BITMAP_BYTES
Length of bitmap section included in the index record.
#define G2C_INDEX_HEADER_LEN
Length of the two header lines at the top of the index file.
int g2c_start_index_record_lf(FILE *f, int rw_flag, int *reclen, size_t *msg, int *local, int *gds, int *pds, int *drs, int *bms, int *data, size_t *msglen, unsigned char *version, unsigned char *discipline, short *fieldnum)
Read or write the start of a version 2 index record for large file.
G2C_FILE_INFO_T g2c_file[G2C_MAX_FILES+1]
Global file information.
int g2c_start_index_record(FILE *f, int rw_flag, int *reclen, int *msg, int *local, int *gds, int *pds, int *drs, int *bms, int *data, size_t *msglen, unsigned char *version, unsigned char *discipline, short *fieldnum)
Read or write the start of a version 2 index record.
int g2c_write_index(int g2cid, int mode, const char *index_file)
Create an index file from a GRIB2 file, just like those created by the grb2index utility.
#define G2C_INDEX_FIXED_LEN
Length of beginning of index record.
#define G2C_INDEX_DATE_STR_LEN
Length of date string in index record.
#define G2C_INDEX_STR1_LEN
Length of str1 string in index record.
#define G2C_INDEX_TIME_STR_LEN
Length of time string in index record.
int g2c_get_prod_sections(G2C_MESSAGE_INFO_T *msg, int fieldnum, G2C_SECTION_INFO_T **sec3, G2C_SECTION_INFO_T **sec4, G2C_SECTION_INFO_T **sec5, G2C_SECTION_INFO_T **sec6, G2C_SECTION_INFO_T **sec7)
Given a pointer to a message, and a field number, return pointers to all relevent section structs for...
#define G2C_INDEX_BASENAME_LEN
Length of the basename in header record 2.
int g2c_file_io_ulonglong(FILE *f, int write, unsigned long long *var)
Read or write a big-endian unsigned long long to an open GRIB2 file, with conversion between native a...
int g2c_file_io_short(FILE *f, int write, short *var)
Read or write a big-endian signed short to an open GRIB2 file, with conversion between native and big...
int g2c_file_io_ubyte(FILE *f, int write, unsigned char *var)
Read or write a big-endian unsigned byte to an open GRIB2 file, with conversion between native and bi...
int g2c_file_io_uint(FILE *f, int write, unsigned int *var)
Read or write a big-endian 4-byte unsigned int to an open GRIB2 file, with conversion between native ...
int g2c_log_section1(G2C_MESSAGE_INFO_T *msg)
Log section 0 information.
#define G2C_MAX_FILES
Maximum number of open files.
#define G2C_NOCLOBBER
Don't destroy existing file.
#define G2C_ENAMETOOLONG
Name too long.
#define G2C_ENOSECTION
Cannot find section.
#define G2C_EFILE
File I/O error.
#define G2C_LARGE_FILE_INDEX
Create a large file index.
#define G2C_MAX_NAME
Maximum length of a name.
#define G2C_EINVAL
Invalid input.
#define G2C_EBADSECTION
Invalid section number.
#define G2C_EBADID
Bad ID.
#define G2C_NOERROR
No error.
Header file with internal function prototypes NCEPLIBS-g2c library.
#define G2C_FILE_READ
Read.
int bytes_to_local
Number of bytes in the message before the (first) local section.
#define G2C_INDEX1_BDS_VAL_LEN
Length of the binary data section (bds) in index file.
#define G2C_FILE_WRITE
Write.
struct g2c_section_info * next
Pointer to next in list.
struct g2c_section_info * sec
List of section metadata.
unsigned char master_version
GRIB master tables version number.
#define MUTEX_UNLOCK(m)
Pthreads not enabled, so do nothing.
#define G2C_INDEX1_GDS_VAL_LEN
Length of the grid definition section (gds) in index file.
int bytes_to_data
Number of bytes in the message to the (first) data section.
#define G2C_INDEX1_BMS_VAL_LEN
Length of the bitmap section (bms) in index file.
unsigned char discipline
Discipline from section 0.
size_t bytes_in_msg
Number of bytes in this message.
struct g2c_section_info * prev
Pointer to previous in list.
int num_fields
Number of fields in the message.
unsigned char sec_num
Section number.
#define G2C_INDEX1_PDS_VAL_LEN
Length of the product definition section (pds) in index file.
void * sec_info
Pointer to struct specific for section 3, 4, 5, 6, or 7.
unsigned int sec_len
Length of the section (in bytes).
size_t bytes_to_sec
Number of bytes from start of message to this section.
#define ONE_BYTE
One byte.
#define LOG(e)
Ignore logging to stdout.
FILE * f
FILE pointer to open file.
int bytes_to_bms
Number of bytes in the message to the bitmap section.
size_t bytes_to_msg
Number of bytes to skip in the file, to get to this message.
#define MUTEX_LOCK(m)
Pthreads not enabled, so do nothing.
#define EXTERN_MUTEX(m)
Pthreads not enabled, so do nothing.
int sec1_len
Length of section 1.
struct g2c_message_info * next
Pointer to next in list.
struct g2c_file_info * file
Pointer to containing file.
This is the information about each open file.
This is the information about each message.
Information about Section 4 PRODUCT DEFINITION SECTION.
Information about a section 3 through 7 in a GRIB2 message.