NCEPLIBS-g2c 2.0.0
Loading...
Searching...
No Matches
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
40int
41g2c_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
229int
230g2c_file_io_int(FILE *f, int write, int *var)
231{
232 return g2c_file_io(f, write, G2C_INT, var);
233}
234
250int
251g2c_file_io_uint(FILE *f, int write, unsigned int *var)
252{
253 return g2c_file_io(f, write, G2C_UINT, var);
254}
255
272int
273g2c_file_io_short(FILE *f, int write, short *var)
274{
275 return g2c_file_io(f, write, G2C_SHORT, var);
276}
277
293int
294g2c_file_io_ushort(FILE *f, int write, unsigned short *var)
295{
296 return g2c_file_io(f, write, G2C_USHORT, var);
297}
298
315int
316g2c_file_io_byte(FILE *f, int write, char *var)
317{
318 return g2c_file_io(f, write, G2C_BYTE, var);
319}
320
336int
337g2c_file_io_ubyte(FILE *f, int write, unsigned char *var)
338{
339 return g2c_file_io(f, write, G2C_UBYTE, var);
340}
341
358int
359g2c_file_io_longlong(FILE *f, int write, long long *var)
360{
361 return g2c_file_io(f, write, G2C_INT64, var);
362}
363
379int
380g2c_file_io_ulonglong(FILE *f, int write, unsigned long long *var)
381{
382 return g2c_file_io(f, write, G2C_UINT64, var);
383}
384
407int
408g2c_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:262
#define G2C_USHORT
unsigned 2-byte int
Definition grib2.h:267
#define G2C_EFILE
File I/O error.
Definition grib2.h:482
#define G2C_INT64
signed 8-byte int
Definition grib2.h:269
#define G2C_EINVAL
Invalid input.
Definition grib2.h:481
#define G2C_UINT64
unsigned 8-byte int
Definition grib2.h:270
#define G2C_BYTE
signed 1 byte integer
Definition grib2.h:260
#define G2C_EBADTEMPLATE
Template problem.
Definition grib2.h:498
#define G2C_INT
signed 4 byte integer
Definition grib2.h:263
#define G2C_UINT
unsigned 4-byte int
Definition grib2.h:268
#define G2C_UBYTE
unsigned 1 byte int
Definition grib2.h:266
#define G2C_NOERROR
No error.
Definition grib2.h:476
#define G2C_EBADTYPE
Type not found.
Definition grib2.h:501
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:125
#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:129