NCEPLIBS-bufr  12.0.0
cread.c
Go to the documentation of this file.
1 
18 #include "bufrlib.h"
19 #include "cread.h"
20 
29 void
30 openrb(int nfile, char *ufile) {
31  pb[nfile] = fopen(ufile, "rb ");
32 }
33 
42 void
43 openwb(int nfile, char *ufile) {
44  pb[nfile] = fopen(ufile, "wb ");
45 }
46 
55 void
56 openab(int nfile, char *ufile) {
57  pb[nfile] = fopen(ufile, "a+b");
58 }
59 
67 void
68 backbufr(int nfile) {
69  fsetpos(pb[nfile],&lstpos[nfile]);
70 }
71 
79 void
80 cewind(int nfile) {
81  rewind(pb[nfile]);
82 }
83 
91 void
92 closfb(int nfile) {
93  fclose(pb[nfile]);
94 }
95 
113 int
114 crdbufr(int nfile, int *bufr, int mxwrd) {
115 
116  int nbytrem, nintrem, nbytx, nintx, wkint[2], ii;
117  size_t nb = sizeof(int), nbdi8 = 8/sizeof(int);
118  char wkchr[17] = " ";
119  fpos_t nxtpos;
120 
121  /* Find the start of the next BUFR message within the file. */
122  fgetpos(pb[nfile], &lstpos[nfile]);
123  while (strncmp(wkchr, "BUFR", 4) != 0) {
124  memmove(wkchr, &wkchr[1], 3);
125  if (fread(wkchr + 3, 1, 1, pb[nfile]) != 1)
126  return -1;
127  }
128 
129  /* Save the current location in case we need to restore it later. */
130  fgetpos(pb[nfile], &nxtpos);
131 
132  /* Read the next 4 bytes of the message. */
133  if (fread(wkchr+4, 1, 4, pb[nfile]) != 4)
134  return -1;
135 
136  /* Determine the remaining number of bytes in the message. This doesn't
137  * include the first 8 bytes, because we've already read those in. */
138  memcpy(wkint, wkchr, 8);
139  nbytrem = iupbs01_f(wkint, "LENM") - 8;
140 
141  nintrem = nbytrem / nb;
142  nintx = nbdi8;
143  /* Since nbytrem doesn't include the first 8 bytes of the BUFR message, then
144  * nintrem is at least nintx integers short of the number needed to hold the
145  * entire message. But there may still be one more integer needed beyond
146  * that, depending on whether nbytrem is an exact multiple of nb. */
147  if ( ( nbytx = nbytrem % nb ) > 0 ) {
148  nintx += 1;
149  }
150  /* Make sure the output array is large enough to hold the entire message. */
151  if (nintrem + nintx > mxwrd) {
152  fsetpos(pb[nfile], &nxtpos);
153  return -3;
154  }
155 
156  /* Copy the first 8 bytes of the BUFR message into the output array. */
157  for ( ii = 0; ii < nbdi8; ii++ ) {
158  bufr[ii] = wkint[ii];
159  }
160  /* Continue reading up to the next-to-last integer of the BUFR message,
161  * and copy these into the output array. */
162  if (fread(&bufr[ii], nb, nintrem-1, pb[nfile]) != nintrem-1) {
163  fsetpos(pb[nfile],&nxtpos);
164  return -2;
165  }
166 
167  /* Read the last few bytes of the BUFR message and check for the "7777"
168  * indicator. We want to read the end of the message byte-by-byte
169  * (rather than integer-by-integer) so that we can easily check for the
170  * ending "7777" string. */
171  nbytrem = nb + nbytx;
172  if (fread(wkchr, 1, nbytrem, pb[nfile]) != nbytrem) {
173  fsetpos(pb[nfile], &nxtpos);
174  return -2;
175  }
176  if (strncmp(&wkchr[nbytrem-4], "7777", 4) != 0) {
177  fsetpos(pb[nfile], &nxtpos);
178  return -2;
179  }
180  /* Copy the last few bytes of the BUFR message into the output array. */
181  memcpy(wkint, wkchr, nbytrem);
182  bufr[nintrem + 1] = wkint[0];
183  if ( nbytx > 0 ) bufr[nintrem + 2] = wkint[1];
184 
185  return 0;
186 }
187 
198 void
199 cwrbufr(int nfile, int *bufr, int nwrd) {
200  size_t nb = sizeof(int);
201 
202  fwrite(bufr, nb, nwrd, pb[nfile]);
203 }
int iupbs01_f(int *bufr, char *mnemonic)
Read a data value from Section 0 or Section 1 of a BUFR message.
Enable a number of NCEPLIBS-bufr subprograms to be called from within the C part of the library.
void closfb(int nfile)
Close a previously opened BUFR file.
Definition: cread.c:92
int crdbufr(int nfile, int *bufr, int mxwrd)
Read the next message from a BUFR file that was previously opened for reading.
Definition: cread.c:114
void openab(int nfile, char *ufile)
Open a new file for appending BUFR messages.
Definition: cread.c:56
void cwrbufr(int nfile, int *bufr, int nwrd)
Write a BUFR message into a file that was previously opened for writing.
Definition: cread.c:199
void openwb(int nfile, char *ufile)
Open a new file for writing BUFR messages.
Definition: cread.c:43
void openrb(int nfile, char *ufile)
Open a new file for reading BUFR messages.
Definition: cread.c:30
void backbufr(int nfile)
Backspace a BUFR file by one BUFR message.
Definition: cread.c:68
void cewind(int nfile)
Rewind a BUFR file back to its beginning.
Definition: cread.c:80
Declare variables for reading or writing BUFR messages via a C language interface.
FILE ** pb
File pointers.
fpos_t * lstpos
Byte positions of last successful reads from files corresponding to pb, for files that were opened fo...