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 || !msglen || !version || !discipline || !fieldnum)
82 LOG((4,
"g2c_start_index_record rw_flag %d", rw_flag));
87 fieldnum1 = *fieldnum + 1;
119 *fieldnum = fieldnum1 - 1;
152 size_t *pds,
size_t *drs,
size_t *bms,
size_t *data,
size_t *msglen,
153 unsigned char *version,
unsigned char *discipline,
short *fieldnum)
159 LOG((4,
"g2c_start_index_record_lf rw_flag %d", rw_flag));
162 if (!f || !reclen || !msg || !local || !gds || !pds || !drs || !bms || !data || !msglen || !version || !discipline || !fieldnum)
168 fieldnum1 = *fieldnum + 1;
200 *fieldnum = fieldnum1 - 1;
239 unsigned int *b2_gds,
unsigned int *b2_bms,
unsigned int *b2_bds,
240 unsigned int *msglen,
unsigned char *version,
unsigned char *pds_val,
241 unsigned char *gds_val,
unsigned char *bms_val,
unsigned char *bds_val,
242 unsigned char *pds_val2,
unsigned char *pds_val3,
unsigned char *gds_val2)
248 if (!f || !b2_msg || !b2_pds || !b2_gds || !b2_bms || !b2_bds ||
324 if (!msg || fieldnum < 0 || !sec3 || !sec4 || !sec5 || !sec6 || !sec7)
328 for (s4 = msg->
sec; s4; s4 = s4->
next)
333 if (s4info->field_num == fieldnum)
341 for (s3 = s4->
prev; s3; s3 = s3->
prev)
349 for (s5 = s4->
next; s5; s5 = s5->
next)
357 for (s6 = s5->
next; s6; s6 = s6->
next)
372 for (s7 = s5->
next; s7; s7 = s7->
next)
436 time_t t = time(NULL);
437 struct tm tm = *localtime(&t);
438 size_t items_written;
441 int total_index_size = 0;
442 int index_version = 1;
452 LOG((2,
"g2c_write_index g2cid %d mode %d index_file %s", g2cid, mode,
459 if ((f = fopen(index_file,
"r")))
471 if (!(f = fopen(index_file,
"wb+")))
484 "!GFHDR! 1 1 162 %4.4u-%2.2u-%2.2u %2.2u:%2.2u:%2.2u %s hfe08 grb2index\n",
485 (tm.tm_year + 1900), (tm.tm_mon + 1), tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
501 for (fieldnum = 0; fieldnum < msg->
num_fields; fieldnum++)
511 total_index_size += reclen;
512 LOG((4,
"fieldnum %d reclen %d total_index_size %d", fieldnum, reclen, total_index_size));
525 sprintf(h2,
"IX%dFORM: 162 %6d %6ld %s \n", index_version, total_index_size,
526 g2c_file[g2cid].num_messages, my_path);
527 LOG((5,
"header 2: %s", h2));
542 for (fieldnum = 0; fieldnum < msg->
num_fields; fieldnum++)
545 int bs3, bs4, bs5, bs6, bs7;
546 size_t bs3_8, bs4_8, bs5_8, bs6_8, bs7_8;
547 unsigned char sec_num;
566 LOG((4,
"fieldnum %d reclen %d", fieldnum, reclen));
569 if (index_version == 2)
684read_hdr_rec1(FILE *f,
int *ip,
int *jp,
int *kp,
char *date_str,
char *time_str)
703 sscanf(line,
"%s %d %d %d %s %s GB2IX1", long_str1, &i, &j, &k, long_date_str, long_time_str);
711 LOG((4,
"str1 %s i %d j %d k %d date_str %s time_str %s", str1, i, j, k, date_str,
754 char *basename,
int *index_version)
759 int total_len, num_rec;
769 sscanf(line,
"IX%dFORM: %d %d %d %s", index_version, &skip, &total_len,
770 &num_rec, long_basename);
779 *total_lenp = total_len;
806 int skip, total_len, num_rec;
821 LOG((2,
"g2c_open_index1 index_file %s", index_file));
827 if (!(f = fopen(index_file,
"rb")))
831 if ((ret =
read_hdr_rec1(f, &i, &j, &k, date_str, time_str)))
833 LOG((4,
"i %d j %d k %d date_str %s time_str %s", i, j, k, date_str, time_str));
836 if ((ret =
read_hdr_rec2(f, &skip, &total_len, &num_rec, basename, &index_version)))
838 LOG((4,
"skip %d total_len %d num_rec %d basename %s", skip, total_len, num_rec, basename));
842 for (rec = 0; rec < num_rec; rec++)
844 unsigned int b2_msg, b2_gds, b2_pds, b2_bms, b2_bds, msglen;
845 unsigned char version;
848 if (fseek(f, file_pos, SEEK_SET))
855 LOG((4,
"reading index1 record at file position %ld", ftell(f)));
857 &b2_bms, &b2_bds, &msglen, &version, pds_val,
858 gds_val, bms_val, bds_val, NULL, NULL, NULL)))
861 LOG((4,
"b2_msg %d b2_pds %d b2_gds %d b2_bms %d b2_bds %d msglen %d version %d",
862 b2_msg, b2_gds, b2_pds, b2_bms, b2_bds, msglen, version));
863 printf(
"b2_msg %d b2_pds %d b2_gds %d b2_bms %d b2_bds %d msglen %d version %d\n",
864 b2_msg, b2_gds, b2_pds, b2_bms, b2_bds, msglen, version);
867 file_pos += total_len;
910 if (!index_file || !data_file || !g2cid)
915 LOG((2,
"g2c_open_index index_file %s", index_file));
918 if (!(f = fopen(index_file,
"rb")))
933 int skip, total_len, num_rec;
948 sscanf(line,
"%s %d %d %d %s %s GB2IX1", long_str1, &i, &j, &k, long_date_str, long_time_str);
956 LOG((1,
"str1 %s i %d j %d k %d date_str %s time_str %s", str1, i, j, k, date_str,
966 sscanf(line,
"IX%dFORM: %d %d %d %s", &index_version, &skip, &total_len,
967 &num_rec, long_basename);
971 LOG((1,
"skip %d total_len %d num_rec %d basename %s", skip, total_len, num_rec, basename));
974 for (rec = 0; rec < num_rec; rec++)
976 int reclen, msgint, local, gds, pds, drs, bms, data;
977 size_t local8, gds8, pds8, drs8, bms8, data8;
979 unsigned char version, discipline;
983 if (fseek(f, file_pos, SEEK_SET))
990 LOG((4,
"reading index record at file position %ld, index_version %d",
991 ftell(f), index_version));
992 if (index_version == 1)
995 &drs, &bms, &data, &msglen, &version, &discipline, &fieldnum)))
1008 &drs8, &bms8, &data8, &msglen, &version, &discipline, &fieldnum)))
1012 LOG((1,
"reclen %d msg %ld local8 %d gds8 %d pds8 %d drs8 %d bms8 %d data8 %d "
1013 "msglen %ld version %d discipline %d fieldnum %d",
1014 reclen, msg, local8, gds8, pds8, drs8, bms8, data8, msglen,
1015 version, discipline, fieldnum));
1020 unsigned int sec_len;
1021 unsigned char sec_num;
1042 LOG((4,
"reading section info at file position %ld", ftell(f)));
1045 for (s = 3; s < 8 && !sec8_found; s++)
1047 size_t bytes_to_sec = gds8;
1065 LOG((4,
"seeking to section 7 in data file, position msgp->bytes_to_msg %ld data %ld",
1076 LOG((4,
"read section 7 info from data file. sec_len %d sec_num %d",
1083 bytes_to_sec = pds8;
1084 else if (sec_num == 5)
1085 bytes_to_sec = drs8;
1086 else if (sec_num == 6)
1087 bytes_to_sec = bms8;
1088 else if (sec_num == 7)
1089 bytes_to_sec = data8;
1090 else if (sec_num == 8)
1094 if (s < 6 && sec_num != s)
1109 LOG((4,
"about to add_section sec_id %d sec_len %d bytes_to_sec %ld sec_num %d",
1110 sec_id, sec_len, bytes_to_sec, sec_num));
1111 if ((ret =
add_section(f, msgp, sec_id++, sec_len, bytes_to_sec, sec_num)))
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_index_record_lf(FILE *f, int rw_flag, int *reclen, size_t *msg, size_t *local, size_t *gds, size_t *pds, size_t *drs, size_t *bms, size_t *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_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.
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.
size_t 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.
#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.
size_t bytes_to_bms
Number of bytes in the message to the bitmap section.
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.
size_t bytes_to_data
Number of bytes in the message to the (first) data 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.