/* * This file is records.h * * This software and its documentation are in the public domain * and are furnished "as is." The United States government, * its instrumentalities, officers, employees, and agents make * no warranty, express or implied, as to the usefulness of the * software and documentation for any purpose. They assume no * responsibility (1) for the use of the software and * documentation; or (2) to provide technical support to users. * * This file contains definitions that define the location of bytes in * the header portion of an EBUFR record, as well as definitions of * the routines supplied in records.c. Should the format of an EBUFR * header change, or should the use of the EBUFR record routines be * extended (for example to include GRIB), the appropriate changes * should be made to this file. I have attempted as much as possible * to abstract the definition of EBUFR header quantities, so that the * remainder of the EBUFR code in this directory depends directly on * the definitions contained in this file. David Casperson (16 Nov * 1991). */ #ifndef __records__ #define __records__ #include "standard.h" /* added 16 Nov 1991 */ /* * The first set of definitions give the location of various pieces of * information in EBUFR records of types 0--3, 6--9. * */ /* * Maximum size of an EBUFR record. This is 9995 rather than 9999 to * allow for the extra 4 bytes required when producing ANSI standard * tape files with variable size logical records. */ #define EBUFRMAXSIZE 9995 /* size of the EBUFR header in bytes. */ #define EBHsize 22 /* location of the byte specifying the type for all types of EBUFR records */ #define TypeLoc 0 /* * The following four definitions tell how to get the X value from the * header of a type 6 record. The first two definitions say that the * X value is stored in bytes 1 and 8 of the header of a type 6 * record. The offset and mask define how the value is stored in the * byte. The X value of a type 6 record can be got by * (header[XLocRec6]>>XOffsetRec6) & XMaskRec6 * or * (header[XLoc2Rec6]>>XOffsetRec6) & XMaskRec6. * In this case the offset and mask aren't required, but the same * mechanism is used in the following definitions. */ #define XLocRec6 1 #define XLoc2Rec6 8 #define XOffsetRec6 0 #define XMaskRec6 0xFF /* F value of record type 7. (See above for a more detailed description.) */ #define FLocRec7 1 #define FLoc2Rec7 8 #define FOffsetRec7 6 #define FMaskRec7 0x3 /* X value of record type 7. (See above for a more detailed description.) */ #define XLocRec7 1 #define XLoc2Rec7 8 #define XOffsetRec7 0 #define XMaskRec7 0x3F /* Y value of record type 7. (See above for a more detailed description.) */ #define YLocRec7 2 #define YLoc2Rec7 9 #define YOffsetRec7 0 #define YMaskRec7 0xFF /* X value of record type 8. (See above for a more detailed description.) */ #define XLocRec8 1 #define XLoc2Rec8 8 #define XOffsetRec8 0 #define XMaskRec8 0xFF /* Y value of record type 8. (See above for a more detailed description.) */ #define YLocRec8 2 #define YLoc2Rec8 9 #define YOffsetRec8 0 #define YMaskRec8 0xFF /* * Code value of record type 8. An offset and mask aren't defined for * this value because it occupies four bytes (3--6 or 10--13). */ #define CodeLocRec8 3 #define CodeLoc2Rec8 10 #define CodeBitsRec8 32 /* * Time location in a type 9 (data) record. The time is actually * stored as follows: * h[1]<<8|h[2] -- year (including century) * h[3] -- month * h[4] -- day * h[5] -- hour (0 -- 23 ) * h[6] -- minute * h[7] -- second */ #define TimeLocRec9 1 #define TimeLengthRec9 7 /* * The latitude and longitude are stored in an EBUFR type 9 header in * a pseudo-BUFR format. The latitude is stored in the first * LatBitsRec9 bits of the four bytes starting at LatLocRec9. Similar * remarks apply to the longitude. See an EBUFR manual for how to * convert this to a standard latitude and longitude. */ #define LatLocRec9 8 #define LatBitsRec9 25 #define LonLocRec9 12 #define LonBitsRec9 26 /* * CLI byte is used for distinguishing between stations at the same * latitude and longitude. */ #define CLILocRec9 16 #define CLIOffsetRec9 0 #define CLIMaskRec9 0xFF /* * The next byte has a confusing definition: If the high bit isn't * set, then this record is the first record in an entity, and the low * seven bits give a number which is one less than the number of * records in the entity. If the high bit is set, then this record is * a continuation record of a multi-record entity, and the low seven * bits plus two give the sequence number of the record in the entity. * A three record entity would have this byte consecutively filled * with 2, 128, 129. */ #define RecNumLoc 17 #define RecNumMask 0x3F #define RecNumOffset 0 #define IsContLoc 17 #define IsContOffset 7 #define IsContMask 0x1 /* * The remaining four bytes give the size of the variable part of this * EBUFR record expressed in %04.4d format. Thus theoretically the * largest value that can be stored in this field is 9999, but I * believe that the largest occuring value should be 9999-22-4. */ #define VSizeLoc 18 #define VSizeLength 4 /* * The following macros abstract the above information even further, * by giving a format independent way of accessing values of Packed * Header records. */ #define TypeOf(h) ((h)[TypeLoc]) #define XOfRec6(h) (XMaskRec6 & (((h)[XLocRec6])>>XOffsetRec6)) #define XOfRec7(h) (XMaskRec7 & (((h)[XLocRec7])>>XOffsetRec7)) #define XOfRec8(h) (XMaskRec8 & (((h)[XLocRec8])>>XOffsetRec8)) #define YOfRec6(h) (YMaskRec6 & (((h)[YLocRec6])>>YOffsetRec6)) #define YOfRec7(h) (YMaskRec7 & (((h)[YLocRec7])>>YOffsetRec7)) #define YOfRec8(h) (YMaskRec8 & (((h)[YLocRec8])>>YOffsetRec8)) #define FOfRec7(h) (FMaskRec7 & (((h)[FLocRec7])>>FOffsetRec7)) /* * macro for getting a 32-bit number starting at a given byte * location. I don't want to try casting tricks here because of * possible alignment problems. For this macro to work correctly 'h' * must be of unsigned character type. */ #define Val32bit(h,a) \ ( \ ( ( (unsigned long) (h)[a+0] ) << (3*8) ) | \ ( ( (unsigned long) (h)[a+1] ) << (2*8) ) | \ ( ( (unsigned long) (h)[a+2] ) << (1*8) ) | \ ( ( (unsigned long) (h)[a+3] ) << (0*8) ) \ ) #define CodeOfRec8(h) (Val32bit((h),CodeLocRec8)>>(32-CodeBitsRec8)) #define LatOfRec9(h) ((Val32bit(h,LatLocRec9))>>(32-LatBitsRec9)) #define LonOfRec9(h) ((Val32bit(h,LonLocRec9))>>(32-LonBitsRec9)) #define CLIOfRec9(h) ((h)[CLILocRec9]>>CLIOffsetRec9 & CLIMaskRec9) #define RecNumOf(h) (RecNumMask & ( (h)[RecNumLoc] >> RecNumOffset)) #define IsContxx(h) (IsContMask & ( (h)[IsContLoc] >> IsContOffset)) #define IsContOf(h) (IsContxx(h) ? True : False) #define VSizeOf(h) \ ( (unsigned int) \ ( ( (h)[VSizeLoc+0] - '0' ) * 1000 ) + \ ( ( (h)[VSizeLoc+1] - '0' ) * 100 ) + \ ( ( (h)[VSizeLoc+2] - '0' ) * 10 ) + \ ( ( (h)[VSizeLoc+3] - '0' ) * 1 ) \ ) typedef unsigned char EBHeaderPacked_t[EBHsize] ; extern void copyEntity(/* EBHeaderPacked_t Header; FILE *In ; FILE *Out ; */) ; extern void skipEntity(/* EBHeaderPacked_t Header; FILE *In ; */) ; extern void copyRecord(/* EBHeaderPacked_t Header; FILE *In ; FILE *Out ; */) ; extern void skipRecord(/* EBHeaderPacked_t Header; FILE *In ; */) ; extern void copyBytes(/* unsigned int n ; FILE *In ; FILE *Out ; */) ; extern void skipBytes(/* unsigned int n ; FILE *In ; */) ; extern Boolean readHeader(/* EBHeaderPacked_t h ; FILE *In ; */) ; extern void writeHeader(/* EBHeaderPacked_t h ; FILE *Out ; */) ; extern Boolean isEbufrCtn(/* EBHeaderPacked_t h1, h2 ; int recno ; */) ; extern void readEntity(/* EBHeaderPacked_t Header ; char **VPart ; int *VSize ; FILE *In ; */) ; extern void writeEntity(/* EBHeaderPacked_t Header ; char *Body ; int Size ; FILE *Out ; */) ; extern int nextRecordType(/* FILE *In ; */) ; #endif /* ifndef __records__ */