Loading...
Searching...
No Matches
g2cio.c
Go to the documentation of this file.
#include "grib2_int.h"
#define BITSHIFT_7 7
#define BITSHIFT_15 15
#define BITSHIFT_31 31
#define BITSHIFT_63 63
int
g2c_file_io(FILE *f, int write, int g2ctype, void *var)
{
void *void_be;
signed char *bvar = NULL;
short *svar = NULL;
int *ivar = NULL;
long long int *i64var = NULL;
unsigned long long int int64_be, int64_tmp;
unsigned int int_be, int_tmp;
unsigned short short_be, short_tmp;
unsigned char byte_be, byte_tmp;
int type_len;
/* Check inputs. */
if (!f || !var || g2ctype < G2C_BYTE || g2ctype > G2C_UINT64)
return G2C_EINVAL;
switch (g2ctype)
{
case G2C_BYTE:
case G2C_UBYTE:
type_len = ONE_BYTE;
bvar = var;
void_be = &byte_be;
if (write)
{
/* Are we writing a negative number? */
if (g2ctype == G2C_BYTE && *bvar < 0)
{
byte_tmp = -1 * *bvar; /* Store as positive. */
byte_tmp |= 1UL << BITSHIFT_7; /* Set sign bit. */
}
else
byte_tmp = *bvar;
/* Convert result to big-endian. */
byte_be = byte_tmp;
}
break;
case G2C_SHORT:
case G2C_USHORT:
type_len = TWO_BYTES;
svar = var;
void_be = &short_be;
if (write)
{
/* Are we writing a negative number? */
if (g2ctype == G2C_SHORT && *svar < 0)
{
short_tmp = -1 * *svar; /* Store as positive. */
short_tmp |= 1UL << BITSHIFT_15; /* Set sign bit. */
}
else
short_tmp = *svar;
/* Convert result to big-endian. */
short_be = ntohs(short_tmp);
}
break;
case G2C_INT:
case G2C_UINT:
type_len = FOUR_BYTES;
ivar = var;
void_be = &int_be;
if (write)
{
/* Are we writing a negative number? */
if (g2ctype == G2C_INT && *ivar < 0)
{
int_tmp = -1 * *ivar; /* Store as positive. */
int_tmp |= 1UL << BITSHIFT_31; /* Set sign bit. */
}
else
int_tmp = *ivar;
/* Convert result to big-endian. */
int_be = ntohl(int_tmp);
}
break;
case G2C_INT64:
case G2C_UINT64:
type_len = EIGHT_BYTES;
i64var = var;
void_be = &int64_be;
if (write)
{
/* Are we writing a negative number? */
if (g2ctype == G2C_INT64 && *i64var < 0)
{
int64_tmp = -1 * *i64var; /* Store as positive. */
int64_tmp |= 1ULL << BITSHIFT_63; /* Set sign bit. */
}
else
int64_tmp = *i64var;
/* Convert result to big-endian. */
int64_be = ntoh64(int64_tmp);
}
break;
default:
return G2C_EBADTYPE;
}
if (write)
{
if ((fwrite(void_be, type_len, 1, f)) != 1)
return G2C_EFILE;
}
else
{
/* Read from the file. */
if ((fread(void_be, type_len, 1, f)) != 1)
return G2C_EFILE;
switch (g2ctype)
{
case G2C_BYTE:
case G2C_UBYTE:
/* No conversion needed for one-byte values. */
*bvar = byte_be;
/* Did we read a negative number? Check the sign bit... */
if (g2ctype == G2C_BYTE && *bvar & 1 << BITSHIFT_7)
{
*bvar &= ~(1UL << BITSHIFT_7); /* Clear sign bit. */
*bvar *= -1; /* Make it negative. */
}
break;
case G2C_SHORT:
case G2C_USHORT:
/* Convert from big-endian. */
*svar = htons(short_be);
/* Did we read a negative number? Check the sign bit... */
if (g2ctype == G2C_SHORT && *svar & 1 << BITSHIFT_15)
{
*svar &= ~(1UL << BITSHIFT_15); /* Clear sign bit. */
*svar *= -1; /* Make it negative. */
}
break;
case G2C_INT:
case G2C_UINT:
/* Convert from big-endian. */
*ivar = htonl(int_be);
/* Did we read a negative number? Check the sign bit... */
if (g2ctype == G2C_INT && *ivar & 1 << BITSHIFT_31)
{
*ivar &= ~(1UL << BITSHIFT_31); /* Clear sign bit. */
*ivar *= -1; /* Make it negative. */
}
break;
case G2C_INT64:
case G2C_UINT64:
/* Convert from big-endian. */
*i64var = hton64(int64_be);
/* Did we read a negative number? Check the sign bit... */
if (g2ctype == G2C_INT64 && *i64var & 1ULL << BITSHIFT_63)
{
*i64var &= ~(1ULL << BITSHIFT_63); /* Clear sign bit. */
*i64var *= -1; /* Make it negative. */
}
break;
default:
return G2C_EBADTYPE;
}
}
return G2C_NOERROR;
}
int
g2c_file_io_int(FILE *f, int write, int *var)
{
return g2c_file_io(f, write, G2C_INT, var);
}
int
g2c_file_io_uint(FILE *f, int write, unsigned int *var)
{
return g2c_file_io(f, write, G2C_UINT, var);
}
int
g2c_file_io_short(FILE *f, int write, short *var)
{
return g2c_file_io(f, write, G2C_SHORT, var);
}
int
g2c_file_io_ushort(FILE *f, int write, unsigned short *var)
{
return g2c_file_io(f, write, G2C_USHORT, var);
}
int
g2c_file_io_byte(FILE *f, int write, char *var)
{
return g2c_file_io(f, write, G2C_BYTE, var);
}
int
g2c_file_io_ubyte(FILE *f, int write, unsigned char *var)
{
return g2c_file_io(f, write, G2C_UBYTE, var);
}
int
g2c_file_io_longlong(FILE *f, int write, long long *var)
{
return g2c_file_io(f, write, G2C_INT64, var);
}
int
g2c_file_io_ulonglong(FILE *f, int write, unsigned long long *var)
{
return g2c_file_io(f, write, G2C_UINT64, var);
}
int
g2c_file_io_template(FILE *f, int rw_flag, int map, long long int *template_value)
{
int ret;
/* Take the absolute value of map[t] because some of the
* numbers are negative - used to indicate that the
* cooresponding fields can contain negative data (needed for
* unpacking). */
switch (abs(map))
{
case ONE_BYTE:
if (map < 0)
{
char my_byte;
if (rw_flag)
my_byte = *template_value;
if ((ret = g2c_file_io_byte(f, rw_flag, &my_byte)))
return ret;
if (!rw_flag)
*template_value = my_byte;
}
else
{
unsigned char my_ubyte;
if (rw_flag)
my_ubyte = *template_value;
if ((ret = g2c_file_io_ubyte(f, rw_flag, &my_ubyte)))
return ret;
if (!rw_flag)
*template_value = my_ubyte;
}
/* FILE_BE_INT1P(f, rw_flag, template_value); */
break;
case TWO_BYTES:
if (map < 0)
{
short my_short;
if (rw_flag)
my_short = *template_value;
if ((ret = g2c_file_io_short(f, rw_flag, &my_short)))
return ret;
if (!rw_flag)
*template_value = my_short;
}
else
{
unsigned short my_ushort;
if (rw_flag)
my_ushort = *template_value;
if ((ret = g2c_file_io_ushort(f, rw_flag, &my_ushort)))
return ret;
if (!rw_flag)
*template_value = my_ushort;
}
/* FILE_BE_INT2P(f, rw_flag, template_value); */
break;
case FOUR_BYTES:
if (map < 0)
{
int my_int;
if (rw_flag)
my_int = *template_value;
if ((ret = g2c_file_io_int(f, rw_flag, &my_int)))
return ret;
if (!rw_flag)
*template_value = my_int;
}
else
{
unsigned int my_uint;
if (rw_flag)
my_uint = *template_value;
if ((ret = g2c_file_io_uint(f, rw_flag, &my_uint)))
return ret;
if (!rw_flag)
*template_value = my_uint;
}
break;
default:
return G2C_EBADTEMPLATE;
}
return G2C_NOERROR;
}
g2c_file_io_ushort
int g2c_file_io_ushort(FILE *f, int write, unsigned short *var)
Read or write a big-endian unsigned short to an open GRIB2 file, with conversion between native and b...
Definition g2cio.c:294
g2c_file_io_byte
int g2c_file_io_byte(FILE *f, int write, char *var)
Read or write a big-endian signed byte to an open GRIB2 file, with conversion between native and big-...
Definition g2cio.c:316
BITSHIFT_7
#define BITSHIFT_7
7 bits.
Definition g2cio.c:9
g2c_file_io_template
int g2c_file_io_template(FILE *f, int rw_flag, int map, long long int *template_value)
Read or write a big-endian 4-byte int or unsigned int from or to an open file, with conversion betwee...
Definition g2cio.c:408
g2c_file_io_ulonglong
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...
Definition g2cio.c:380
BITSHIFT_15
#define BITSHIFT_15
15 bits.
Definition g2cio.c:10
g2c_file_io
int g2c_file_io(FILE *f, int write, int g2ctype, void *var)
Read or write a big-endian integer type to an open file, with conversion between native and big-endia...
Definition g2cio.c:41
g2c_file_io_short
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...
Definition g2cio.c:273
BITSHIFT_63
#define BITSHIFT_63
63 bits.
Definition g2cio.c:12
BITSHIFT_31
#define BITSHIFT_31
31 bits.
Definition g2cio.c:11
g2c_file_io_ubyte
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...
Definition g2cio.c:337
g2c_file_io_longlong
int g2c_file_io_longlong(FILE *f, int write, long long *var)
Read or write a big-endian signed long long to an open GRIB2 file, with conversion between native and...
Definition g2cio.c:359
g2c_file_io_uint
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 ...
Definition g2cio.c:251
g2c_file_io_int
int g2c_file_io_int(FILE *f, int write, int *var)
Read or write a big-endian 4-byte signed int to an open GRIB2 file, with conversion between native an...
Definition g2cio.c:230
G2C_SHORT
#define G2C_SHORT
signed 2 byte integer
Definition grib2.h:262
G2C_USHORT
#define G2C_USHORT
unsigned 2-byte int
Definition grib2.h:267
G2C_EFILE
#define G2C_EFILE
File I/O error.
Definition grib2.h:496
G2C_INT64
#define G2C_INT64
signed 8-byte int
Definition grib2.h:269
G2C_EINVAL
#define G2C_EINVAL
Invalid input.
Definition grib2.h:495
G2C_UINT64
#define G2C_UINT64
unsigned 8-byte int
Definition grib2.h:270
G2C_BYTE
#define G2C_BYTE
signed 1 byte integer
Definition grib2.h:260
G2C_EBADTEMPLATE
#define G2C_EBADTEMPLATE
Template problem.
Definition grib2.h:512
G2C_INT
#define G2C_INT
signed 4 byte integer
Definition grib2.h:263
G2C_UINT
#define G2C_UINT
unsigned 4-byte int
Definition grib2.h:268
G2C_UBYTE
#define G2C_UBYTE
unsigned 1 byte int
Definition grib2.h:266
G2C_NOERROR
#define G2C_NOERROR
No error.
Definition grib2.h:490
G2C_EBADTYPE
#define G2C_EBADTYPE
Type not found.
Definition grib2.h:515
grib2_int.h
Header file with internal function prototypes NCEPLIBS-g2c library.
FOUR_BYTES
#define FOUR_BYTES
Four bytes.
Definition grib2_int.h:52
ntoh64
#define ntoh64(x)
Byte swap 64-bit ints.
Definition grib2_int.h:125
TWO_BYTES
#define TWO_BYTES
Two bytes.
Definition grib2_int.h:51
ONE_BYTE
#define ONE_BYTE
One byte.
Definition grib2_int.h:50
hton64
#define hton64(x)
Byte swap 64-bit ints.
Definition grib2_int.h:129
EIGHT_BYTES
#define EIGHT_BYTES
Eight bytes.
Definition grib2_int.h:53