<HTML> <BODY BGCOLOR=#ccccdd LINK=#0000aa VLINK=#0000ff ALINK=#ff0000 ><BASE TARGET="bottom_target"><PRE>
/*C$$$ SUBPROGRAM DOCUMENTATION BLOCK
C
C SUBPROGRAM: CREAD
C PRGMMR: WOOLLEN ORG: NP20 DATE: 2012-09-15
C
C ABSTRACT: CREAD IS A PACKAGE OF C LANGUAGE I/O ROUTINES WHICH
C ARE DESIGNED TO OPERATE BUFRLIB INPUT AND OUTPUT
C FUNCTIONS IN A LESS RESTRICTIVE WAY COMPARED TO
C THOSE AVAILABLE IN STANDARD FORTRAN IMPLEMENTATIONS.
C THE PACKAGE CONSISTS OF THREE FILE OPEN ROUTINES,
C ONE FILE CLOSE ROUTINE, TWO FILE POSITIONING
C ROUTINES, ONE READ BUFR AND ONE WRITE BUFR ROUTINE.
C ARRAYS OF FILE CONNECTION DESCRIPTORS AND FILE
C POSITION POINTERS PROVIDE THE CONNECTION TO THE
C BUFRLIB INTERNAL FILE STATUS INDICATORS. THE
C BUFRLIB FILE CONNECTION INDEX LUN, OBTAINED BY
C CALLS TO STATUS, IS USED TO REFERENCE THE CREAD
C DESCRIPTOR AND POINTER ARRAYS.
C
C PROGRAM HISTORY LOG:
C 2012-09-15 J. WOOLLEN -- ORIGINAL AUTHOR
C
C USAGE: CALL openrb(nfile,ufile) - open ufile for binary reading
C CALL openwb(nfile,ufile) - open ufile for binary writing
C CALL openab(nfile,ufile) - open ufile for binary appending
C CALL backbufr(nfile) - backspace file nfile 1 message
C CALL cewind(nfile) - rewind file nfile to beginning
C CALL closfb(nfile) - disconnect file nfile from c
C CALL crdbufr(nfile,bufr,maxbyt) - read next bufr message from file nfile into bufr
C CALL cwrbufr(nfile,bufr,nwrd) - write bufr message from bufr into file nfile
C
C INPUT ARGUMENTS:
c nfile - integer bufrlib file connection index
C ufile - full file path/filename
c bufr - in crdbufr: char array to read a bufr message into
c maxbyt - in crdbufr: maximum number of bytes allowed to read
c bufr - in cwrbufr: integer array to write a bufr message from
c nwrd - in cwrbufr: number of words to write for bufr message
C
C OUTPUT ARGUMENTS:
c crdbufr - return code from reading
c -3 - sec0 message length > maxbyt
c -2 - error reading bufr message
c -1 - no more more messages in file
c 0 - read a bufr message
C
C REMARKS:
C THIS ROUTINE CALLS: IUPBS01
C
C THIS ROUTINE IS CALLED BY:
C
C ATTRIBUTES:
C LANGUAGE: C
C MACHINE: PORTABLE TO ALL PLATFORMS
C
C$$$*/
#include "bufrlib.h"
/* The following arrays are dimensioned one larger than NFILES because of the difference in array
indexing between Fortran and C. In each of the following C functions, the value passed in for
nfile will a be Fortran index ranging from 1 to NFILES, so we need to allow for this same range
of values in C, which would otherwise expect the array indices to range from 0 to NFILES-1. */
FILE *pb[NFILES+1]; fpos_t lstpos[NFILES+1];
void openrb (nfile,ufile) f77int *nfile; char *ufile; { pb[*nfile] = fopen( ufile , "rb " ); }
void openwb (nfile,ufile) f77int *nfile; char *ufile; { pb[*nfile] = fopen( ufile , "wb " ); }
void openab (nfile,ufile) f77int *nfile; char *ufile; { pb[*nfile] = fopen( ufile , "a+b" ); }
void backbufr (nfile ) f77int *nfile; { fsetpos(pb[*nfile],&lstpos[*nfile]);}
void cewind (nfile ) f77int *nfile; { rewind(pb[*nfile]); }
void closfb (nfile ) f77int *nfile; { fclose(pb[*nfile]); }
f77int crdbufr (nfile,bufr,mxbyt)
f77int *nfile; f77int *mxbyt; char *bufr;
{ f77int nbyt; f77int nb; f77int wkint[2]; fpos_t nxtpos;
fgetpos(pb[*nfile],&lstpos[*nfile]);
nb = sizeof(*bufr); bufr[0]=bufr[1];
while ( strncmp(bufr,"BUFR",4)!=0)
{ memmove(bufr,&bufr[1],3);
if(fread(bufr+3,nb,1,pb[*nfile])!=1) return -1;
}
fgetpos(pb[*nfile],&nxtpos); if(fread(bufr+4,nb,4,pb[*nfile])!=4) return -1;
memcpy(wkint,bufr,8); nbyt=iupbs01
(wkint,"LENM",4)-8;
if(nbyt+8>*mxbyt) {fsetpos(pb[*nfile],&nxtpos);return -3;};
if(fread(bufr+8,nb,nbyt,pb[*nfile])!=nbyt) {fsetpos(pb[*nfile],&nxtpos);return -2;};
if(strncmp(bufr+nbyt+4,"7777",4)!=0) {fsetpos(pb[*nfile],&nxtpos);return -2;};
return 0;
}
void cwrbufr (nfile,bufr,nwrd)
f77int *nfile; f77int *nwrd; f77int *bufr;
{ f77int nb; nb = sizeof(*bufr);
fwrite(bufr,nb,*nwrd,pb[*nfile]);
}