Beispiel #1
0
static const char *
pds_ident(const char *cp)
{
	/* log_assert (pdsp + 28) is valid, accessable memory */
	const unsigned char *pdsp = (const unsigned char *)cp -1;
					/* -1 trick for 1 based indexing */
	static char idb[80];
	memset(idb, 0, sizeof(idb));	

	sprintf(idb, " /m%s",
		s_pds_model(*(pdsp + PDS_CENTER), *(pdsp + PDS_MODEL)));
	return idb;
}
Beispiel #2
0
static void composeIdent(
    char* const            ident,
    size_t const           identSize,
    DecodedGrib2Msg* const decoded,
    Gribmsg* const         gribMsg,
    Geminfo* const         gemField,
    StringBuf* const       prods,
    const char* const      wmoHead,
    int const              modelId)
{
    g2int originatingCenter = g2d_getOriginatingCenter(decoded);

    snprintf(ident, identSize, "grib2/%s/%s/#%03d/%s/%s/%s\0",
            s_pds_center(originatingCenter,
                    g2d_getOriginatingSubCenter(decoded)),
            s_pds_model(originatingCenter, modelId),
            grid_id,
            fdats,
            prods,
            levelstmp);
}
Beispiel #3
0
/**
 * Generates an LDM product-identifier from a GRIB edition 2 message.
 *
 * Atomic,
 * Idempotent,
 * Not thread-safe
 *
 * @param[in]  data             Pointer to the GRIB message.
 * @param[in]  sz               Length of the GRIB message in bytes.
 * @param[in]  wmohead          Pointer to the associated WMO header string.
 * @param[out] ident            Pointer to a buffer to receive the LDM
 *                              product-identifier.
 * @param[in]  identSize        Size of the \c ident buffer in bytes.
 * @retval     0                Success. \c ident is set and NUL-terminated.
 * @retval     1                Invalid GRIB message.
 * @retval     2                GRIB message isn't edition 2.
 * @retval     3                System error.
 */
int grib2name (
    char* const         data,
    const size_t        sz,
    const char* const   wmohead,
    char* const         ident,
    const size_t        identSize)
{
#if USE_GRIB2_DECODER
    int                 status;
    DecodedGrib2Msg*    decoded;

    if (status = g2d_new(&decoded, (unsigned char*)data, sz)) {
        log_add("Couldn't decode GRIB message");
        status = G2D_INVALID == status
                ? 1
                : G2D_NOT_2
                    ? 2
                    : 3;
    }
    else {
        if (status = setIdent(ident, identSize, decoded, wmohead)) {
            log_add("Couldn't set LDM product-identifier");
            status = 1;
        }

        g2d_free(decoded);
    } /* "decoded" allocated */

    return status;
#else
    static StringBuf*  paramNames;    /* Buffer for parameter name(s) */
    int                iField;        /* GRIB-2 field index */
    int                status;        /* Function return code */
    g2int              listsec0[3];   /* GRIB-2 section 0 parameters */
    g2int              listsec1[13];  /* GRIB-2 section 1 parameters */
    g2int              numlocal;      /* Number of GRIB section 2-s */
    int                model_id;      /* ID of model */
    int                grid_id;       /* ID of grid */
    char               fdats[80];     /* No idea */
    char               levelstmp[80]; /* Level? */
    Gribmsg            g2Msg;         /* GRIB-2 message structure */

    if (paramNames) {
        strBuf_clear(paramNames);
    }
    else {
        paramNames = strBuf_new(127);
        if (NULL == paramNames) {
            log_add("Couldn't allocate buffer for parameter name(s)");
            return 3;
        }
    }

    g2Msg.cgrib2 = (unsigned char*)data;
    g2Msg.mlength = sz;
    g2Msg.gfld = NULL;
    g2Msg.field_tot = 0;

    if ((status = g2_info(g2Msg.cgrib2, g2Msg.mlength, listsec0, listsec1,
            &(g2Msg.field_tot), &numlocal)) != 0)
        return (2 == status) ? 2 : 1;

    if (g2Msg.field_tot <= 0) {
        log_add("GRIB-2 message has no data fields");
        return 1;
    }

    for (iField = 0; iField < g2Msg.field_tot; iField++) {
        static char  g2tables[5][LLMXLN];  /* GRIB tables */
        static char* tbllist[5] = {g2tables[0], g2tables[1], g2tables[2],
                g2tables[3], g2tables[4]}; /* Addresses of GRIB tables */
        Geminfo      gemInfo;              /* GEMPAK structure */
        int const    lastField = iField == g2Msg.field_tot - 1;

        status = g2_getfld(g2Msg.cgrib2, g2Msg.mlength, iField+1, 0, 0,
                &g2Msg.gfld);

        if (status) {
            log_add("Invalid GRIB-2 message: g2_getfld() status=%d", status);
            return (2 == status) ? 2 : 1;
        }

        /* "g2Msg.gfld" is allocated */

        /* Initialize strings in Geminfo structure */
        (void)memset(gemInfo.cproj, 0, sizeof(gemInfo.cproj));
        (void)memset(gemInfo.parm, 0, sizeof(gemInfo.parm));
        (void)memset(gemInfo.gdattm1, 0, sizeof(gemInfo.gdattm1));
        (void)memset(gemInfo.gdattm2, 0, sizeof(gemInfo.gdattm2));

        /*
         * In the original code, the last field determined the model ID.
         */
        if (lastField)
            model_id = g2Msg.gfld->ipdtmpl[4];

        /*
         * This assignment to "grid_id" isn't under the above "lastField"
         * conditional because "decode_g2gnum()" might have side-effects upon
         * which "gb2_2gem()" depends.
         */
        grid_id = (g2Msg.gfld->griddef == 0)
            ? decode_g2gnum(g2Msg.gfld)
            : g2Msg.gfld->griddef;

        gb2_2gem(&g2Msg, &gemInfo, tbllist, &status);

        if (status) {
            log_add("Couldn't decode GRIB2 message. WMO header=\"%s\"",
                    wmohead);
            log_flush_error();

            if (lastField) {
                (void)strcpy(fdats, "FHRS"); /* safe */
                (void)strcpy(levelstmp, "LVL"); /* safe */
            }
        }
        else {
            char g2name[13];          /**< Name of product/parameter */
            int  ilen;                /**< Length of resulting string */

            (void)strcpy(g2name, gemInfo.parm); /* both 13 bytes */
            cst_rmbl(g2name, g2name, &ilen, &status);

            if (iField)
                strBuf_appendString(paramNames, ";");
            strBuf_appendString(paramNames, g2name);

            cst_rxbl(gemInfo.unit, gemInfo.unit, &ilen, &status);
            if (ilen == 0)
                (void)strcpy(gemInfo.unit, "-"); /* safe */

            cst_rmbl(gemInfo.gdattm1, gemInfo.gdattm1, &ilen, &status);
            cst_rmbl(gemInfo.gdattm2, gemInfo.gdattm2, &ilen, &status);

            /*
             * In the original code, the last field determined the following
             * parameters.
             */
            if (lastField) {
                static char  strBuf[5];       /* Holds 4-char string */
                static char* strptr = strBuf; /* For "cst_itoc()" */

                if (ilen > 0)
                    (void)snprintf(fdats, sizeof(fdats), "%s-%s",
                            gemInfo.gdattm1, gemInfo.gdattm2);
                else
                    (void)snprintf(fdats, sizeof(fdats), "%s",
                            gemInfo.gdattm1);

                for (ilen = 1; ilen > 0;
                        cst_rmst(fdats, "/", &ilen, fdats, &status));

                cst_itoc(&gemInfo.vcord, 1, &strptr, &status);

                if (gemInfo.level[1] == -1)
                    (void)snprintf(levelstmp, sizeof(levelstmp), "%d %s %s",
                            gemInfo.level[0], gemInfo.unit, strptr);
                else
                    (void)snprintf(levelstmp, sizeof(levelstmp), "%d-%d %s %s",
                            gemInfo.level[0], gemInfo.level[1], gemInfo.unit,
                            strptr);
            }
        }

        g2_free(g2Msg.gfld);
        g2Msg.gfld = NULL;
    }

    /*
     * See if the WMO header can be used for grid 0 products
     */
    if ((grid_id == 0) && (strlen(wmohead) > 11) && (wmohead[7] == 'K') &&
            (wmohead[8] == 'W')) {
        int wmoGridId = wmo_to_gridid(&wmohead[0], &wmohead[2]);

        if (wmoGridId > 0)
            grid_id = wmoGridId;
    }

    (void)snprintf(ident, identSize, "grib2/%s/%s/#%03d/%s/%s/%s",
            s_pds_center((int)listsec1[0], (int)listsec1[1]),
            s_pds_model((int)listsec1[0], model_id),
            grid_id,
            fdats,
            strBuf_toString(paramNames),
            levelstmp);

    return 0;
#endif
}
void	grib1name ( char *filename, int seqno,  char *data, char *ident )
{
unsigned char model_id,grid_id,parmid,vcordid,center,subcenter;
unsigned char dattim[6],ftim[4],level[2];
int CCYY,YYYY,MM,DD,HH,vtime;
time_t time1, time2;
struct tm tm1, tm2;
char prodtmp[255],prodid[255],levelstmp[255];
char *pos;
static char datyp[]="grib";
static int isinit=!0;

/* Initialize time zone information */
if(isinit)
   {
   isinit = 0;
   putenv("TZ=UTC0");
   tzset();
   }

	model_id = *((unsigned char *)data+13);
        grid_id = *((unsigned char *)data+14);
	center = *((unsigned char *)data+12);
        subcenter = *((unsigned char *)data+33);

        dattim[0] = *((unsigned char *)data+20);
        dattim[1] = *((unsigned char *)data+21);
        dattim[2] = *((unsigned char *)data+22);
        dattim[3] = *((unsigned char *)data+23);
        dattim[4] = *((unsigned char *)data+24);
        dattim[5] = *((unsigned char *)data+32);

        ftim[0] = *((unsigned char *)data+26);
        ftim[1] = *((unsigned char *)data+27);
        ftim[2] = *((unsigned char *)data+28);
        ftim[3] = *((unsigned char *)data+25);

        parmid = *((unsigned char *)data+16);
        vcordid = *((unsigned char *)data+17);
        level[0] = *((unsigned char *)data+18);
        level[1] = *((unsigned char *)data+19);

        if(dattim[0] > 0) dattim[5] = dattim[5] - 1; CCYY = dattim[5]*100 + dattim[0];
        vtime = verf_time((unsigned char *)data+8,&YYYY,&MM,&DD,&HH);

        tm1.tm_year    = CCYY - 1900; tm1.tm_mon     = dattim[1] - 1;
        tm1.tm_mday    = dattim[2]; tm1.tm_hour    = dattim[3];
        tm1.tm_min     = dattim[4]; tm1.tm_sec     = 0;
        tm1.tm_isdst   = -1; time1 = mktime(&tm1);

        tm2.tm_year    = YYYY - 1900; tm2.tm_mon     = MM - 1;
        tm2.tm_mday    = DD; tm2.tm_hour    = HH;
        tm2.tm_min     = 0; tm2.tm_sec     = 0;
        tm2.tm_isdst   = -1; time2 = mktime(&tm2);

        memset(prodtmp,0,255);
        memset(prodid,0,255);
        memset(levelstmp,0,255);

        sprintf(prodid,"%s\0",k5toa((unsigned char *)data+8));
        while((pos = strchr(prodid,' ')) != NULL) pos[0] = '_';

        sprintf(levelstmp,"%s\0",levels((int)vcordid,(int)level[0],(int)level[1]));
        while((pos = strchr(levelstmp,' ')) != NULL) pos[0] = '_';

        sprintf(prodtmp,"%s/%s/%s/#%03d/%04d%02d%02d%02d%02d/F%03d/%s/%s! %06d\0",datyp,
                s_pds_center(center,subcenter),s_pds_model(center,model_id),grid_id,
                CCYY,dattim[1],dattim[2],dattim[3],dattim[4],(time2 - time1)/3600,
                prodid,
                levelstmp,seqno
                /*(char *)PDStimes(ftim[2],ftim[0],ftim[1],ftim[3]),
                YYYY,MM,DD,HH*/);
        if(strlen(filename) < 253)
                {
                strcpy(ident,filename);
                strncat(ident," !",2);
                strncat(ident,prodtmp,253-strlen(filename));
                }
        else
		{
                strncpy(ident,filename,255);
		ident[255] = '\0';
		}
}
void	grib2name ( char *filename, int seqno,  char *data, size_t sz, char *ident )
{
int i, n, ier, ilen;
int unpack=0, expand=0;
g2int  listsec0[3],listsec1[13],numlocal;
int model_id, grid_id;
char g2name[13], fdats[80];
char prodtmp[255];
char levelstmp[80];
char prods[128];
static char datyp[]="grib2", slashstr[]="/";
static int tblinit=0;
static char *strptr[5];

Gribmsg curr_g2;
Geminfo curr_gem;

static char g2tables[5][LLMXLN] = { 0 }, *tbllist[5];

curr_g2.cgrib2 = (unsigned char *)data;
curr_g2.mlength = sz;
curr_g2.gfld = NULL;
curr_g2.field_tot = 0;

if ( !tblinit)
    {
      for (i = 0; i < 5; i++)
        tbllist[i] = g2tables[i];
      tblinit = !0;
    }


/* modify below to pass message size as a failsafe check */
/*if ( ( ier = g2_info ( curr_g2.cgrib2, listsec0,listsec1, &(curr_g2.field_tot), &numlocal) ) != 0 ) */
if ( ( ier = g2_info ( curr_g2.cgrib2, curr_g2.mlength, listsec0,listsec1, &(curr_g2.field_tot), &numlocal) ) != 0 )
	return;

prods[0] = '\0';
for ( n=0; n < curr_g2.field_tot; n++)
   {
   ier=g2_getfld( curr_g2.cgrib2, curr_g2.mlength, n+1, unpack, expand,
           &curr_g2.gfld);

   /* initialize strings in geminfo structure */
   memset ( curr_gem.cproj, 0, sizeof(curr_gem.cproj));
   memset ( curr_gem.parm, 0, sizeof(curr_gem.parm));
   memset ( curr_gem.gdattm1, 0, sizeof(curr_gem.gdattm1));
   memset ( curr_gem.gdattm2, 0, sizeof(curr_gem.gdattm2));
   model_id = curr_g2.gfld->ipdtmpl[4];
   grid_id = curr_g2.gfld->griddef;

   gb2_2gem (&curr_g2, &curr_gem, tbllist, &ier);

   if ( ier != 0 )
      {
      sprintf(g2name,"UNK\0");
      sprintf(levelstmp,"LVL\0");
      sprintf(fdats,"FHRS\0");
      }
   else
      {
      sprintf(g2name,"%s\0",curr_gem.parm);
      cst_rmbl (g2name, g2name, &ilen, &ier );
      if ( n > 0 ) strncat ( prods, ";", 1);
      sprintf(prods+strlen(prods),"%s\0",g2name);

      strptr[0] = (char *)malloc(12);
      cst_itoc ( &curr_gem.vcord, 1, (char **)(&strptr), &ier);
     
      cst_rxbl (curr_gem.unit, curr_gem.unit, &ilen, &ier); 
      if ( ilen == 0 ) sprintf (curr_gem.unit, "-\0"); 
      if ( curr_gem.level[1] == -1 )
	 sprintf(levelstmp,"%d %s %s\0",curr_gem.level[0],curr_gem.unit,strptr[0]);
      else
         sprintf(levelstmp,"%d-%d %s %s\0",curr_gem.level[0],curr_gem.level[1],curr_gem.unit,strptr[0]);

      cst_rmbl (curr_gem.gdattm1, curr_gem.gdattm1, &ilen, &ier );
      cst_rmbl (curr_gem.gdattm2, curr_gem.gdattm2, &ilen, &ier );
      if ( ilen > 0 )
         sprintf(fdats,"%s-%s\0",curr_gem.gdattm1,curr_gem.gdattm2);
      else
         sprintf(fdats,"%s\0",curr_gem.gdattm1);

      ilen = 1;
      while ( ilen > 0 ) cst_rmst(fdats, slashstr, &ilen, fdats, &ier);

      free(strptr[0]);
      }

   g2_free(curr_g2.gfld);
   curr_g2.gfld = NULL;
   }

sprintf(prodtmp,"%s/%s/%s/#%03d/%s/%s/%s! %06d\0",
		datyp,
                s_pds_center((int)listsec1[0],(int)listsec1[1]),
		s_pds_model((int)listsec1[0],model_id),
		grid_id,
		fdats,
                prods,
                levelstmp,seqno);

if(strlen(filename) < 253)
  {
    strcpy(ident,filename);
    strncat(ident," !",2);
    strncat(ident,prodtmp,253-strlen(filename));
  }
else
  {
    strncpy(ident,filename,255);
    ident[255] = '\0';
  }

return;
}