NCEPLIBS-g2c  1.8.0
g2cio.c
Go to the documentation of this file.
1 
7 #include "grib2_int.h"
8 
9 #define BITSHIFT_7 7
10 #define BITSHIFT_15 15
11 #define BITSHIFT_31 31
12 #define BITSHIFT_63 63
40 int
41 g2c_file_io(FILE *f, int write, int g2ctype, void *var)
42 {
43  void *void_be;
44  char *bvar = NULL;
45  short *svar = NULL;
46  int *ivar = NULL;
47  long long int *i64var = NULL;
48  unsigned long long int int64_be, int64_tmp;
49  unsigned int int_be, int_tmp;
50  unsigned short short_be, short_tmp;
51  unsigned char byte_be, byte_tmp;
52  int type_len;
53 
54  /* Check inputs. */
55  if (!f || !var || g2ctype < G2C_BYTE || g2ctype > G2C_UINT64)
56  return G2C_EINVAL;
57 
58  switch (g2ctype)
59  {
60  case G2C_BYTE:
61  case G2C_UBYTE:
62  type_len = ONE_BYTE;
63  bvar = var;
64  void_be = &byte_be;
65  if (write)
66  {
67  /* Are we writing a negative number? */
68  if (g2ctype == G2C_BYTE && *bvar < 0)
69  {
70  byte_tmp = -1 * *bvar; /* Store as positive. */
71  byte_tmp |= 1UL << BITSHIFT_7; /* Set sign bit. */
72  }
73  else
74  byte_tmp = *bvar;
75 
76  /* Convert result to big-endian. */
77  byte_be = byte_tmp;
78  }
79  break;
80  case G2C_SHORT:
81  case G2C_USHORT:
82  type_len = TWO_BYTES;
83  svar = var;
84  void_be = &short_be;
85  if (write)
86  {
87  /* Are we writing a negative number? */
88  if (g2ctype == G2C_SHORT && *svar < 0)
89  {
90  short_tmp = -1 * *svar; /* Store as positive. */
91  short_tmp |= 1UL << BITSHIFT_15; /* Set sign bit. */
92  }
93  else
94  short_tmp = *svar;
95 
96  /* Convert result to big-endian. */
97  short_be = ntohs(short_tmp);
98  }
99  break;
100  case G2C_INT:
101  case G2C_UINT:
102  type_len = FOUR_BYTES;
103  ivar = var;
104  void_be = &int_be;
105  if (write)
106  {
107  /* Are we writing a negative number? */
108  if (g2ctype == G2C_INT && *ivar < 0)
109  {
110  int_tmp = -1 * *ivar; /* Store as positive. */
111  int_tmp |= 1UL << BITSHIFT_31; /* Set sign bit. */
112  }
113  else
114  int_tmp = *ivar;
115 
116  /* Convert result to big-endian. */
117  int_be = ntohl(int_tmp);
118  }
119  break;
120  case G2C_INT64:
121  case G2C_UINT64:
122  type_len = EIGHT_BYTES;
123  i64var = var;
124  void_be = &int64_be;
125  if (write)
126  {
127  /* Are we writing a negative number? */
128  if (g2ctype == G2C_INT64 && *i64var < 0)
129  {
130  int64_tmp = -1 * *i64var; /* Store as positive. */
131  int64_tmp |= 1ULL << BITSHIFT_63; /* Set sign bit. */
132  }
133  else
134  int64_tmp = *i64var;
135 
136  /* Convert result to big-endian. */
137  int64_be = ntoh64(int64_tmp);
138  }
139  break;
140  default:
141  return G2C_EBADTYPE;
142  }
143 
144  if (write)
145  {
146  if ((fwrite(void_be, type_len, 1, f)) != 1)
147  return G2C_EFILE;
148  }
149  else
150  {
151  /* Read from the file. */
152  if ((fread(void_be, type_len, 1, f)) != 1)
153  return G2C_EFILE;
154 
155  switch (g2ctype)
156  {
157  case G2C_BYTE:
158  case G2C_UBYTE:
159  /* No conversion needed for one-byte values. */
160  *bvar = byte_be;
161 
162  /* Did we read a negative number? Check the sign bit... */
163  if (g2ctype == G2C_BYTE && *bvar & 1 << BITSHIFT_7)
164  {
165  *bvar &= ~(1UL << BITSHIFT_7); /* Clear sign bit. */
166  *bvar *= -1; /* Make it negative. */
167  }
168  break;
169  case G2C_SHORT:
170  case G2C_USHORT:
171  /* Convert from big-endian. */
172  *svar = htons(short_be);
173 
174  /* Did we read a negative number? Check the sign bit... */
175  if (g2ctype == G2C_SHORT && *svar & 1 << BITSHIFT_15)
176  {
177  *svar &= ~(1UL << BITSHIFT_15); /* Clear sign bit. */
178  *svar *= -1; /* Make it negative. */
179  }
180  break;
181  case G2C_INT:
182  case G2C_UINT:
183  /* Convert from big-endian. */
184  *ivar = htonl(int_be);
185 
186  /* Did we read a negative number? Check the sign bit... */
187  if (g2ctype == G2C_INT && *ivar & 1 << BITSHIFT_31)
188  {
189  *ivar &= ~(1UL << BITSHIFT_31); /* Clear sign bit. */
190  *ivar *= -1; /* Make it negative. */
191  }
192  break;
193  case G2C_INT64:
194  case G2C_UINT64:
195  /* Convert from big-endian. */
196  *i64var = hton64(int64_be);
197 
198  /* Did we read a negative number? Check the sign bit... */
199  if (g2ctype == G2C_INT64 && *i64var & 1ULL << BITSHIFT_63)
200  {
201  *i64var &= ~(1ULL << BITSHIFT_63); /* Clear sign bit. */
202  *i64var *= -1; /* Make it negative. */
203  }
204  break;
205  default:
206  return G2C_EBADTYPE;
207  }
208  }
209 
210  return G2C_NOERROR;
211 }
212 
229 int
230 g2c_file_io_int(FILE *f, int write, int *var)
231 {
232  return g2c_file_io(f, write, G2C_INT, var);
233 }
234 
250 int
251 g2c_file_io_uint(FILE *f, int write, unsigned int *var)
252 {
253  return g2c_file_io(f, write, G2C_UINT, var);
254 }
255 
272 int
273 g2c_file_io_short(FILE *f, int write, short *var)
274 {
275  return g2c_file_io(f, write, G2C_SHORT, var);
276 }
277 
293 int
294 g2c_file_io_ushort(FILE *f, int write, unsigned short *var)
295 {
296  return g2c_file_io(f, write, G2C_USHORT, var);
297 }
298 
315 int
316 g2c_file_io_byte(FILE *f, int write, char *var)
317 {
318  return g2c_file_io(f, write, G2C_BYTE, var);
319 }
320 
336 int
337 g2c_file_io_ubyte(FILE *f, int write, unsigned char *var)
338 {
339  return g2c_file_io(f, write, G2C_UBYTE, var);
340 }
341 
358 int
359 g2c_file_io_longlong(FILE *f, int write, long long *var)
360 {
361  return g2c_file_io(f, write, G2C_INT64, var);
362 }
363 
379 int
380 g2c_file_io_ulonglong(FILE *f, int write, unsigned long long *var)
381 {
382  return g2c_file_io(f, write, G2C_UINT64, var);
383 }
384 
407 int
408 g2c_file_io_template(FILE *f, int rw_flag, int map, long long int *template_value)
409 {
410  int ret;
411 
412  /* Take the absolute value of map[t] because some of the
413  * numbers are negative - used to indicate that the
414  * cooresponding fields can contain negative data (needed for
415  * unpacking). */
416  switch(abs(map))
417  {
418  case ONE_BYTE:
419  if (map < 0)
420  {
421  char my_byte;
422  if (rw_flag)
423  my_byte = *template_value;
424  if ((ret = g2c_file_io_byte(f, rw_flag, &my_byte)))
425  return ret;
426  if (!rw_flag)
427  *template_value = my_byte;
428  }
429  else
430  {
431  unsigned char my_ubyte;
432  if (rw_flag)
433  my_ubyte = *template_value;
434  if ((ret = g2c_file_io_ubyte(f, rw_flag, &my_ubyte)))
435  return ret;
436  if (!rw_flag)
437  *template_value = my_ubyte;
438  }
439  /* FILE_BE_INT1P(f, rw_flag, template_value); */
440  break;
441  case TWO_BYTES:
442  if (map < 0)
443  {
444  short my_short;
445  if (rw_flag)
446  my_short = *template_value;
447  if ((ret = g2c_file_io_short(f, rw_flag, &my_short)))
448  return ret;
449  if (!rw_flag)
450  *template_value = my_short;
451  }
452  else
453  {
454  unsigned short my_ushort;
455  if (rw_flag)
456  my_ushort = *template_value;
457  if ((ret = g2c_file_io_ushort(f, rw_flag, &my_ushort)))
458  return ret;
459  if (!rw_flag)
460  *template_value = my_ushort;
461  }
462  /* FILE_BE_INT2P(f, rw_flag, template_value); */
463  break;
464  case FOUR_BYTES:
465  if (map < 0)
466  {
467  int my_int;
468  if (rw_flag)
469  my_int = *template_value;
470  if ((ret = g2c_file_io_int(f, rw_flag, &my_int)))
471  return ret;
472  if (!rw_flag)
473  *template_value = my_int;
474  }
475  else
476  {
477  unsigned int my_uint;
478  if (rw_flag)
479  my_uint = *template_value;
480  if ((ret = g2c_file_io_uint(f, rw_flag, &my_uint)))
481  return ret;
482  if (!rw_flag)
483  *template_value = my_uint;
484  }
485  break;
486  default:
487  return G2C_EBADTEMPLATE;
488  }
489 
490  return G2C_NOERROR;
491 }
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
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
#define BITSHIFT_7
7 bits.
Definition: g2cio.c:9
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
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
#define BITSHIFT_15
15 bits.
Definition: g2cio.c:10
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
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
#define BITSHIFT_63
63 bits.
Definition: g2cio.c:12
#define BITSHIFT_31
31 bits.
Definition: g2cio.c:11
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
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
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
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
#define G2C_SHORT
signed 2 byte integer
Definition: grib2.h:278
#define G2C_USHORT
unsigned 2-byte int
Definition: grib2.h:283
#define G2C_EFILE
File I/O error.
Definition: grib2.h:497
#define G2C_INT64
signed 8-byte int
Definition: grib2.h:285
#define G2C_EINVAL
Invalid input.
Definition: grib2.h:496
#define G2C_UINT64
unsigned 8-byte int
Definition: grib2.h:286
#define G2C_BYTE
signed 1 byte integer
Definition: grib2.h:276
#define G2C_EBADTEMPLATE
Template problem.
Definition: grib2.h:513
#define G2C_INT
signed 4 byte integer
Definition: grib2.h:279
#define G2C_UINT
unsigned 4-byte int
Definition: grib2.h:284
#define G2C_UBYTE
unsigned 1 byte int
Definition: grib2.h:282
#define G2C_NOERROR
No error.
Definition: grib2.h:491
#define G2C_EBADTYPE
Type not found.
Definition: grib2.h:516
Header file with internal function prototypes NCEPLIBS-g2c library.
#define FOUR_BYTES
Four bytes.
Definition: grib2_int.h:52
#define ntoh64(y)
Byte swap 64-bit ints.
Definition: grib2_int.h:123
#define TWO_BYTES
Two bytes.
Definition: grib2_int.h:51
#define ONE_BYTE
One byte.
Definition: grib2_int.h:50
#define EIGHT_BYTES
Eight bytes.
Definition: grib2_int.h:53
#define hton64(y)
Byte swap 64-bit ints.
Definition: grib2_int.h:127