Example #1
0
NITFPRIV(NITF_BOOL) basicHasNext(nitf_TREEnumerator** it)
{
    nitf_TRECursor* cursor = it && *it ? (nitf_TRECursor*)(*it)->data : NULL;
    if (cursor && nitf_TRECursor_isDone(cursor))
    {
        nitf_TRECursor_cleanup(cursor);
        NITF_FREE(cursor);
        NITF_FREE(*it);
        *it = NULL;
        return NITF_FAILURE; /* maybe 0 is better */
    }
    return cursor != NULL ? NITF_SUCCESS : NITF_FAILURE;
}
Example #2
0
NITFAPI(NITF_BOOL) nitf_TRECursor_isDone(nitf_TRECursor * tre_cursor)
{
    nitf_Error error;
    int isDone = (tre_cursor->desc_ptr == tre_cursor->end_ptr);

    /* check if the passed in cursor is not at the beginning */
    if (!isDone && tre_cursor->index >= 0)
    {
        nitf_TRECursor dolly = nitf_TRECursor_clone(tre_cursor, &error);
        /* if iterate returns 0, we are done */
        isDone = !nitf_TRECursor_iterate(&dolly, &error);
        isDone = isDone || (dolly.desc_ptr == dolly.end_ptr);
        nitf_TRECursor_cleanup(&dolly);
    }
    return isDone;
}
Example #3
0
NITFAPI(int) nitf_TREUtils_computeLength(nitf_TRE * tre)
{
    int length = 0;
    int tempLength;
    nitf_Error error;
    nitf_Pair *pair; /* temp nitf_Pair */
    nitf_Field *field; /* temp nitf_Field */
    nitf_TRECursor cursor;

    /* get out if TRE is null */
    if (!tre)
        return -1;

    cursor = nitf_TRECursor_begin(tre);
    while (!nitf_TRECursor_isDone(&cursor))
    {
        if (nitf_TRECursor_iterate(&cursor, &error) == NITF_SUCCESS)
        {
            tempLength = cursor.length;
            if (tempLength == NITF_TRE_GOBBLE)
            {
                /* we don't have any other way to know the length of this
                 * field, other than to see if the field is in the hash
                 * and use the length defined when it was created.
                 * Otherwise, we don't add any length.
                 */
                tempLength = 0;
                pair = nitf_HashTable_find(
                        ((nitf_TREPrivateData*)tre->priv)->hash, cursor.tag_str);
                if (pair)
                {
                    field = (nitf_Field *) pair->data;
                    if (field)
                        tempLength = field->length;
                }
            }
            length += tempLength;
        }
    }
    nitf_TRECursor_cleanup(&cursor);
    return length;
}
Example #4
0
NITFAPI(NITF_BOOL) nitf_TREUtils_isSane(nitf_TRE * tre)
{
    int status = 1;
    nitf_Error error;
    nitf_TRECursor cursor;

    /* get out if TRE is null */
    if (!tre)
        return NITF_FAILURE;

    cursor = nitf_TRECursor_begin(tre);
    while (!nitf_TRECursor_isDone(&cursor) && status)
    {
        if (nitf_TRECursor_iterate(&cursor, &error) == NITF_SUCCESS)
            if (!nitf_TRE_exists(tre, cursor.tag_str))
                status = !status;
    }
    nitf_TRECursor_cleanup(&cursor);
    return status;
}
Example #5
0
NITFAPI(int) nitf_TREUtils_print(nitf_TRE * tre, nitf_Error * error)
{
    nitf_Pair *pair; /* temp pair */
    int status = NITF_SUCCESS;
    nitf_TRECursor cursor;

    /* get out if TRE is null */
    if (!tre)
    {
        nitf_Error_init(error, "print -> invalid tre object",
                NITF_CTXT, NITF_ERR_INVALID_PARAMETER);
        return NITF_FAILURE;
    }

    cursor = nitf_TRECursor_begin(tre);
    while (!nitf_TRECursor_isDone(&cursor) && (status == NITF_SUCCESS))
    {
        if ((status = nitf_TRECursor_iterate(&cursor, error)) == NITF_SUCCESS)
        {
            pair = nitf_HashTable_find(
                    ((nitf_TREPrivateData*)tre->priv)->hash, cursor.tag_str);
            if (!pair || !pair->data)
            {
                nitf_Error_initf(error, NITF_CTXT, NITF_ERR_UNK,
                "Unable to find tag, '%s', in TRE hash for TRE '%s'", cursor.tag_str, tre->tag);
                status = NITF_FAILURE;
            }
            else
            {
                printf("%s (%s) = [",
                cursor.desc_ptr->label == NULL ?
                "null" : cursor.desc_ptr->label, cursor.tag_str);
                nitf_Field_print((nitf_Field *) pair->data);
                printf("]\n");
            }
        }
    }
    nitf_TRECursor_cleanup(&cursor);
    return status;
}
Example #6
0
NITFAPI(NITF_BOOL) nitf_TREUtils_fillData(nitf_TRE * tre,
        const nitf_TREDescription* descrip,
        nitf_Error * error)
{
    nitf_TRECursor cursor;

    /* set the description so the cursor can use it */
    ((nitf_TREPrivateData*)tre->priv)->description =
        (nitf_TREDescription*)descrip;

    /* loop over the description, and add blank fields for the
     * "normal" fields... any special case fields (loops, conditions)
     * won't be added here
     */
    cursor = nitf_TRECursor_begin(tre);
    while (!nitf_TRECursor_isDone(&cursor))
    {
        if (nitf_TRECursor_iterate(&cursor, error))
        {
            nitf_Pair* pair = nitf_HashTable_find(
                    ((nitf_TREPrivateData*)tre->priv)->hash, cursor.tag_str);

            if (!pair || !pair->data)
            {
                nitf_Field* field = NULL;
                int fieldLength = cursor.length;

                /* If it is a GOBBLE length, there isn't really a standard
                 * on how long it can be... therefore we'll just throw in
                 * a field of size 1, just to have something...
                 */
                if (fieldLength == NITF_TRE_GOBBLE)
                {
                    fieldLength = 1;
                }

                field = nitf_Field_construct(fieldLength,
                        cursor.desc_ptr->data_type,
                        error);

                /* set the field to be resizable later on */
                if (cursor.length == NITF_TRE_GOBBLE)
                    field->resizable = 1;

                /* special case if BINARY... must set Raw Data */
                if (cursor.desc_ptr->data_type == NITF_BINARY)
                {
                    char* tempBuf = (char *) NITF_MALLOC(fieldLength);
                    if (!tempBuf)
                    {
                        nitf_Field_destruct(&field);
                        nitf_Error_init(error, NITF_STRERROR(NITF_ERRNO),
                                NITF_CTXT, NITF_ERR_MEMORY);
                        goto CATCH_ERROR;
                    }

                    memset(tempBuf, 0, fieldLength);
                    nitf_Field_setRawData(field, (NITF_DATA *) tempBuf,
                            fieldLength, error);
                }
                else if (cursor.desc_ptr->data_type == NITF_BCS_N)
                {
                    /* this will get zero/blank filled by the function */
                    nitf_Field_setString(field, "0", error);
                }
                else
                {
                    /* this will get zero/blank filled by the function */
                    nitf_Field_setString(field, " ", error);
                }

                /* add to hash if there wasn't an entry yet */
                if (!pair)
                {
                    nitf_HashTable_insert(
                            ((nitf_TREPrivateData*)tre->priv)->hash,
                            cursor.tag_str, field, error);
                }
                /* otherwise, just set the data pointer */
                else
                {
                    pair->data = (NITF_DATA *) field;
                }
            }
        }
    }
    nitf_TRECursor_cleanup(&cursor);

    /* no problems */
    /*    return tre->descrip; */
    return NITF_SUCCESS;

  CATCH_ERROR:
    return NITF_FAILURE;
}
Example #7
0
NITFAPI(NITF_BOOL) nitf_TREUtils_setValue(nitf_TRE * tre,
                                          const char *tag,
                                          NITF_DATA * data,
                                          size_t dataLength, 
                                          nitf_Error * error)
{
    nitf_Pair *pair;
    nitf_Field *field = NULL;
    nitf_TRECursor cursor;
    NITF_BOOL done = 0;
    NITF_BOOL status = 1;
    nitf_FieldType type = NITF_BCS_A;

    /* used temporarily for storing the length */
    int length;

    /* get out if TRE is null */
    if (!tre)
    {
        nitf_Error_init(error, "setValue -> invalid tre object",
                NITF_CTXT, NITF_ERR_INVALID_PARAMETER);
        return NITF_FAILURE;
    }

    /* If the field already exists, get it and modify it */
    if (nitf_HashTable_exists(((nitf_TREPrivateData*)tre->priv)->hash, tag))
    {
        pair = nitf_HashTable_find(
                ((nitf_TREPrivateData*)tre->priv)->hash, tag);
        field = (nitf_Field *) pair->data;

        if (!field)
        {
            nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER,
                    "setValue -> invalid field object: %s", tag);
            return NITF_FAILURE;
        }

        /* check to see if the data passed in is too large or too small */
        if ((dataLength > field->length && !field->resizable) || dataLength < 1)
        {
            nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER,
                    "setValue -> invalid dataLength for field: %s", tag);
            return NITF_FAILURE;
        }

        if (!nitf_Field_setRawData
            (field, (NITF_DATA *) data, dataLength, error))
        {
            return NITF_FAILURE;
        }
#ifdef NITF_DEBUG
        fprintf(stdout, "Setting (and filling) Field [%s] to TRE [%s]\n",
                tag, tre->tag);
#endif

        /* Now we need to fill our data */
        if (!nitf_TREUtils_fillData(tre,
                                    ((nitf_TREPrivateData*)tre->priv)->description,
                                    error))
            return NITF_FAILURE;

    }
    /* it doesn't exist in the hash yet, so we need to find it */
    else
    {

        cursor = nitf_TRECursor_begin(tre);
        while (!nitf_TRECursor_isDone(&cursor) && !done && status)
        {
            if (nitf_TRECursor_iterate(&cursor, error) == NITF_SUCCESS)
            {
                /* we found it */
                if (strcmp(tag, cursor.tag_str) == 0)
                {
                    if (cursor.desc_ptr->data_type == NITF_BCS_A)
                    {
                        type = NITF_BCS_A;
                    }
                    else if (cursor.desc_ptr->data_type == NITF_BCS_N)
                    {
                        type = NITF_BCS_N;
                    }
                    else if (cursor.desc_ptr->data_type == NITF_BINARY)
                    {
                        type = NITF_BINARY;
                    }
                    else
                    {
                        /* bad type */
                        nitf_Error_init(error,
                                "setValue -> invalid data type",
                                NITF_CTXT,
                                NITF_ERR_INVALID_PARAMETER);
                        return NITF_FAILURE;
                    }

                    length = cursor.length;
                    /* check to see if we should gobble the rest */
                    if (length == NITF_TRE_GOBBLE)
                    {
                        length = dataLength;
                    }

                    /* construct the field */
                    field = nitf_Field_construct(length, type, error);

                    /* now, set the data */
                    nitf_Field_setRawData(field, (NITF_DATA *) data,
                            dataLength, error);

#ifdef NITF_DEBUG
                    fprintf(stdout, "Adding (and filling) Field [%s] to TRE [%s]\n",
                            cursor.tag_str, tre->tag);
#endif

                    /* add to the hash */
                    nitf_HashTable_insert(
                            ((nitf_TREPrivateData*)tre->priv)->hash,
                            cursor.tag_str, field, error);


                    /* Now we need to fill our data */
                    if (!nitf_TREUtils_fillData(tre, ((nitf_TREPrivateData*)tre->priv)->description, error))
                        return NITF_FAILURE;

                    done = 1; /* set, so we break out of loop */
                }
            }
        }
        /* did we find it? */
        if (!done)
        {
            nitf_Error_initf(error, NITF_CTXT, NITF_ERR_UNK,
                    "Unable to find tag, '%s', in TRE hash for TRE '%s'",
                    tag, tre->tag);
            status = 0;
        }
        nitf_TRECursor_cleanup(&cursor);
    }
    return status;

}
Example #8
0
NITFAPI(int) nitf_TREUtils_parse(nitf_TRE * tre,
                                 char *bufptr, 
                                 nitf_Error * error)
{
    int status = 1;
    int iterStatus = NITF_SUCCESS;
    int offset = 0;
    int length;
    nitf_TRECursor cursor;
    nitf_Field *field = NULL;
    nitf_TREPrivateData *privData = NULL;

    /* get out if TRE is null */
    if (!tre)
    {
        nitf_Error_init(error, "parse -> invalid tre object",
                NITF_CTXT, NITF_ERR_INVALID_PARAMETER);
        return NITF_FAILURE;
    }

    privData = (nitf_TREPrivateData*)tre->priv;

    /* flush the hash first, to protect from duplicate entries */
    if (privData)
    {
        nitf_TREPrivateData_flush(privData, error);
    }

    cursor = nitf_TRECursor_begin(tre);
    while (offset < privData->length && status)
    {
        if ((iterStatus = 
             nitf_TRECursor_iterate(&cursor, error)) == NITF_SUCCESS)
        {
            length = cursor.length;
            if (length == NITF_TRE_GOBBLE)
            {
                length = privData->length - offset;
            }

            /* no need to call setValue, because we already know
             * it is OK for this one to be in the hash
             */

            /* construct the field */
            field = nitf_Field_construct(length,
                    cursor.desc_ptr->data_type, error);
            if (!field)
                goto CATCH_ERROR;

            /* first, check to see if we need to swap bytes */
            if (field->type == NITF_BINARY
                    && (length == NITF_INT16_SZ || length == NITF_INT32_SZ))
            {
                if (length == NITF_INT16_SZ)
                {
                    nitf_Int16 int16 =
                        (nitf_Int16)NITF_NTOHS(*((nitf_Int16 *) (bufptr + offset)));
                    status = nitf_Field_setRawData(field,
                            (NITF_DATA *) & int16, length, error);
                }
                else if (length == NITF_INT32_SZ)
                {
                    nitf_Int32 int32 =
                        (nitf_Int32)NITF_NTOHL(*((nitf_Int32 *) (bufptr + offset)));
                    status = nitf_Field_setRawData(field,
                            (NITF_DATA *) & int32, length, error);
                }
            }
            else
            {
                /* check for the other binary lengths ... */
                if (field->type == NITF_BINARY)
                {
                    /* TODO what to do??? 8 bit is ok, but what about 64? */
                    /* for now, just let it go through... */
                }

                /* now, set the data */
                status = nitf_Field_setRawData(field, (NITF_DATA *) (bufptr + offset),
                        length, error);
            }

#ifdef NITF_DEBUG
            {
                fprintf(stdout, "Adding Field [%s] to TRE [%s]\n",
                        cursor.tag_str, tre->tag);
            }
#endif

            /* add to the hash */
            nitf_HashTable_insert(((nitf_TREPrivateData*)tre->priv)->hash,
                    cursor.tag_str, field, error);

            offset += length;
        }
        /* otherwise, the iterate function thinks we are done */
        else
        {
            break;
        }
    }
    nitf_TRECursor_cleanup(&cursor);

    /* check if we still have more to parse, and throw an error if so */
    if (offset < privData->length)
    {
        nitf_Error_init(error, "TRE data is longer than it should be",
                NITF_CTXT, NITF_ERR_INVALID_OBJECT);
        status = NITF_FAILURE;
    }
    return status;

    /* deal with errors here */
    CATCH_ERROR:
    return NITF_FAILURE;
}
Example #9
0
NITFAPI(char *) nitf_TREUtils_getRawData(nitf_TRE * tre, nitf_Uint32* treLength, nitf_Error * error)
{
    int status = 1;
    int offset = 0;
    nitf_Uint32 length;
    int tempLength;

    /* data buffer - Caller must free this */
    char *data = NULL;

    /* temp data buffer */
    char *tempBuf = NULL;

    /* temp nitf_Pair */
    nitf_Pair *pair;
    
    /* temp nitf_Field */
    nitf_Field *field;

    /* the cursor */
    nitf_TRECursor cursor;

    /* get actual length of TRE */
    length = nitf_TREUtils_computeLength(tre);
    *treLength = length;

    if (length <= 0)
    {
        nitf_Error_init(error, "TRE has invalid length",
                NITF_CTXT, NITF_ERR_INVALID_OBJECT);
        return NULL;
    }

    /* allocate the memory - this does not get freed in this function */
    data = (char *) NITF_MALLOC(length + 1);
    if (!data)
    {
        nitf_Error_init(error, NITF_STRERROR(NITF_ERRNO),
                NITF_CTXT, NITF_ERR_MEMORY);
        goto CATCH_ERROR;
    }
    memset(data, 0, length + 1);

    cursor = nitf_TRECursor_begin(tre);
    while (!nitf_TRECursor_isDone(&cursor) && status && offset < length)
    {
        if (nitf_TRECursor_iterate(&cursor, error) == NITF_SUCCESS)
        {
            pair = nitf_HashTable_find(((nitf_TREPrivateData*)tre->priv)->hash,
                    cursor.tag_str);
            if (pair && pair->data)
            {
                tempLength = cursor.length;
                if (tempLength == NITF_TRE_GOBBLE)
                {
                    tempLength = length - offset;
                }
                field = (nitf_Field *) pair->data;

                /* get the raw data */
                tempBuf = NITF_MALLOC(tempLength);
                if (!tempBuf)
                {
                    nitf_Error_init(error, NITF_STRERROR(NITF_ERRNO),
                            NITF_CTXT, NITF_ERR_MEMORY);
                    goto CATCH_ERROR;
                }
                /* get the data as raw buf */
                nitf_Field_get(field, (NITF_DATA *) tempBuf,
                        NITF_CONV_RAW, tempLength, error);

                /* first, check to see if we need to swap bytes */
                if (field->type == NITF_BINARY)
                {
                    if (tempLength == NITF_INT16_SZ)
                    {
                        nitf_Int16 int16 =
                            (nitf_Int16)NITF_HTONS(*((nitf_Int16 *) tempBuf));
                        memcpy(tempBuf, (char*)&int16, tempLength);
                    }
                    else if (tempLength == NITF_INT32_SZ)
                    {
                        nitf_Int32 int32 =
                            (nitf_Int32)NITF_HTONL(*((nitf_Int32 *) tempBuf));
                        memcpy(tempBuf, (char*)&int32, tempLength);
                    }
                    else
                    {
                        /* TODO what to do??? 8 bit is ok, but what about 64? */
                        /* for now, just let it go through... */
                    }
                }

                /* now, memcpy the data */
                memcpy(data + offset, tempBuf, tempLength);
                offset += tempLength;

                /* free the buf */
                NITF_FREE(tempBuf);
            }
            else
            {
                nitf_Error_init(error,
                "Failed due to missing TRE field(s)",
                NITF_CTXT, NITF_ERR_INVALID_OBJECT);
                goto CATCH_ERROR;
            }
        }
    }
    nitf_TRECursor_cleanup(&cursor);
    return data;

  /* deal with errors here */
  CATCH_ERROR:
    if (data)
        NITF_FREE(data);
    return NULL;
}
Example #10
0
/* TODO  This is a cut and paste of nitf_TREUtils_parse() with a little bit
 *       of extra logic for determining the appropriate field type for
 *       engineering data.  Is there a way to reuse more of the other
 *       parse function? */
NITFPRIV(int) ENGRDA_parse(nitf_TRE * tre,
                           char *bufptr,
                           nitf_Error * error)
{
    int status = 1;
    int iterStatus = NITF_SUCCESS;
    int offset = 0;
    int length;
    nitf_TRECursor cursor;
    nitf_Field *field = NULL;
    nitf_TREPrivateData *privData = NULL;
    nitf_FieldType prevValueType;
    nitf_FieldType fieldType;

    /* get out if TRE is null */
    if (!tre)
    {
        nitf_Error_init(error, "parse -> invalid tre object",
                NITF_CTXT, NITF_ERR_INVALID_PARAMETER);
        return NITF_FAILURE;
    }

    privData = (nitf_TREPrivateData*)tre->priv;

    /* flush the hash first, to protect from duplicate entries */
    if (privData)
    {
        nitf_TREPrivateData_flush(privData, error);
    }

    cursor = nitf_TRECursor_begin(tre);
    prevValueType = NITF_BINARY;
    while (offset < privData->length && status)
    {
        if ((iterStatus =
             nitf_TRECursor_iterate(&cursor, error)) == NITF_SUCCESS)
        {
            length = cursor.length;
            if (length == NITF_TRE_GOBBLE)
            {
                length = privData->length - offset;
            }

            /* no need to call setValue, because we already know
             * it is OK for this one to be in the hash
             */

            /* for engineering data, the TREDescription specifies the type as
             * binary but in reality it's based on the value type field.  this
             * will be saved off for us below.  it's also critical to set this
             * correctly so that string types don't get endian swapped. */
            fieldType =
                !strncmp(cursor.tag_str, "ENGDATA", 7) ?
                    prevValueType : cursor.desc_ptr->data_type;

            /* construct the field */
            field = nitf_Field_construct(length, fieldType, error);
            if (!field)
                goto CATCH_ERROR;

            /* first, check to see if we need to swap bytes */
            if (field->type == NITF_BINARY
                    && (length == NITF_INT16_SZ || length == NITF_INT32_SZ))
            {
                if (length == NITF_INT16_SZ)
                {
                    nitf_Int16 int16 =
                        (nitf_Int16)NITF_NTOHS(*((nitf_Int16 *) (bufptr + offset)));
                    status = nitf_Field_setRawData(field,
                            (NITF_DATA *) & int16, length, error);
                }
                else if (length == NITF_INT32_SZ)
                {
                    nitf_Int32 int32 =
                        (nitf_Int32)NITF_NTOHL(*((nitf_Int32 *) (bufptr + offset)));
                    status = nitf_Field_setRawData(field,
                            (NITF_DATA *) & int32, length, error);
                }
            }
            else
            {
                /* check for the other binary lengths ... */
                if (field->type == NITF_BINARY)
                {
                    /* TODO what to do??? 8 bit is ok, but what about 64? */
                    /* for now, just let it go through... */
                }

                /* now, set the data */
                status = nitf_Field_setRawData(field, (NITF_DATA *) (bufptr + offset),
                        length, error);
            }

            /* when we see the value type, save it off
             * we'll eventually read this when we get to the engineering data
             * itself */
            if (!strncmp(cursor.tag_str, "ENGTYP", 6) &&
                field->type == NITF_BCS_A &&
                field->length == 1)
            {
                prevValueType = (field->raw[0] == 'A') ?
                    NITF_BCS_A : NITF_BINARY;
            }

#ifdef NITF_DEBUG
            {
                fprintf(stdout, "Adding Field [%s] to TRE [%s]\n",
                        cursor.tag_str, tre->tag);
            }
#endif

            /* add to the hash */
            nitf_HashTable_insert(((nitf_TREPrivateData*)tre->priv)->hash,
                    cursor.tag_str, field, error);

            offset += length;
        }
        /* otherwise, the iterate function thinks we are done */
        else
        {
            break;
        }
    }
    nitf_TRECursor_cleanup(&cursor);

    /* check if we still have more to parse, and throw an error if so */
    if (offset < privData->length)
    {
        nitf_Error_init(error, "TRE data is longer than it should be",
                NITF_CTXT, NITF_ERR_INVALID_OBJECT);
        status = NITF_FAILURE;
    }
    return status;

    /* deal with errors here */
    CATCH_ERROR:
    return NITF_FAILURE;
}