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); }
/** * 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; }