Example #1
0
/*
 * Returns a new upstream filter.
 *
 * Arguments:
 *      upFilter        Pointer to pointer to returned upstream filter.  Must
 *                      not be NULL.  Set on and only on success.
 * Returns:
 *      NULL            Success.
 *      else            Failure error object.
 */
ErrorObj*
upFilter_new(
    UpFilter** const    upFilter)
{
    ErrorObj*            errObj;
    size_t              nbytes = sizeof(UpFilter);
    UpFilter* const     filt = (UpFilter*)malloc(nbytes);

    if (NULL == filt) {
        errObj = ERR_NEW2(0, NULL, "Couldn't allocate %lu-bytes: %s",
            (unsigned long)nbytes, strerror(errno));
    }
    else {
        StringBuf* const strBuf = strBuf_new(132);

        if (NULL == strBuf) {
            errObj = ERR_NEW(0, NULL, strBuf_strerror(strBuf));

            free(filt);
        }
        else {
            filt->strBuf = strBuf;
            filt->head = NULL;
            filt->stringOutOfDate = 1;
            filt->count = 0;
            *upFilter = filt;
            errObj = NULL;              /* success */
        }
    }                                   /* "filt" allocated */

    return errObj;
}
Example #2
0
/**
 * Sets an LDM product-identifier from a GRIB message.
 *
 * Not Atomic,
 * Idempotent,
 * Thread-safe
 *
 * @param[out] ident      Product-identifier buffer.
 * @param[in]  identSize  Size of product-identifier buffer in bytes.
 * @param[in]  decoded    Decoded GRIB message.
 * @param[in]  wmoHead    WMO header associated with the GRIB message.
 * @retval     0          Success. \c *ident is set.
 * @retval     1          GRIB message has no data.
 * @retval     3          System error.
 */
static int setIdent(
    char* const            ident,
    const size_t           identSize,
    DecodedGrib2Msg* const decoded,
    const char* const      wmoHead)
{
    const size_t   numFields = g2d_getNumFields(decoded);
    int            status;

    if (0 == numFields) {
        log_add("GRIB message has no fields");
        status = 1;
    }
    else {
        StringBuf* const prods = strBuf_new(127); /* initially empty */

        if (NULL == prods) {
            log_add_syserr("Couldn't allocate string-buffer for products");
            log_flush_error();
            status = 3;
        }
        else {
            Gribmsg          gribMsg;
            Geminfo          gemInfo;
            int              modelId;

            status = appendParameterNames(prods, decoded, &gribMsg, &gemInfo);

            if (0 == status) {
                status = getModelId(decoded, &modelId);

                if (0 == status)
                    composeIdent(ident, identSize, decoded, &gribMsg, &gemInfo,
                            prods, wmoHead, modelId);
            }

            strBuf_free(prods);
        } /* "prods" allocated */
    } /* numFields > 0 */

    return status;
}
Example #3
0
/**
 * Returns a new instance of a child-map.
 *
 * @retval NULL         Failure. \c log_start() called.
 * @retval !NULL        Pointer to a new instance.
 */
ChildMap* cm_new(void)
{
    ChildMap*   map = (ChildMap*)malloc(sizeof(ChildMap));

    if (NULL == map) {
        LOG_SERROR0("Couldn't allocate new child-map");
    }
    else {
        map->root = NULL;
        map->count = 0;
        map->buf = strBuf_new(132);

        if (NULL == map->buf) {
            LOG_SERROR0("Couldn't allocate command-line buffer");
            free(map);

            map = NULL;
        }
    }

    return map;
}
Example #4
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
}