Beispiel #1
0
NITFPRIV(NITF_BOOL) defaultSetField(nitf_TRE * tre,
                                    const char *tag,
                                    NITF_DATA * data,
                                    size_t dataLength, nitf_Error * error)
{
	nitf_Field* field = NULL;

	if (strcmp(tag, NITF_TRE_RAW))
	{
        nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Invalid param [%s]", tag);
        return NITF_FAILURE;
	}

	field = nitf_Field_construct(dataLength, NITF_BINARY, error);
    if (!field)
        return NITF_FAILURE;

    /* TODO -- likely inefficient, since we end up copying the raw data here */
    if (!nitf_Field_setRawData(field, (NITF_DATA *) data, dataLength, error))
        return NITF_FAILURE;

	if (nitf_HashTable_exists(((nitf_TREPrivateData*)tre->priv)->hash, tag))
	{
        nitf_Field* oldValue;
        nitf_Pair* pair = nitf_HashTable_find(
                ((nitf_TREPrivateData*)tre->priv)->hash, tag);
        oldValue = (nitf_Field*)pair->data;
        nitf_Field_destruct(&oldValue);
        pair->data = field;
        return NITF_SUCCESS;
	}

	/* reset the lengths in two places */
	((nitf_TREPrivateData*)tre->priv)->length = dataLength;
	((nitf_TREPrivateData*)tre->priv)->description[0].data_count = dataLength;

	return nitf_HashTable_insert(((nitf_TREPrivateData*)tre->priv)->hash,
	        tag, field, error);
}
Beispiel #2
0
/*!
 *  Clone this object.  This is a deep copy operation.
 *
 *  \param source The source object
 *  \param error  An error to populate upon failure
 *  \return A new object that is identical to the old
 */
NITFAPI(nitf_Field *) nitf_Field_clone(nitf_Field * source,
                                       nitf_Error * error)
{
    nitf_Field *field = NULL;

    if (source)
    {
        /* construct new one */
        field = nitf_Field_construct(source->length, source->type, error);
        if (field)
        {
            field->resizable = source->resizable;
            /* set the data */
            if (!nitf_Field_setRawData
                    (field, (NITF_DATA *) source->raw, source->length, error))
            {
                nitf_Field_destruct(&field);
                field = NULL;
            }
        }
    }
    return field;
}
Beispiel #3
0
 //! set the value
 void set(NITF_DATA* inval, size_t length) throw(nitf::NITFException)
 {
     NITF_BOOL x = nitf_Field_setRawData(getNativeOrThrow(), inval, length, &error);
     if (!x)
         throw nitf::NITFException(&error);
 }
Beispiel #4
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;
}
Beispiel #5
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;

}
Beispiel #6
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;
}
Beispiel #7
0
NITFPRIV(int) defaultRead(nitf_IOInterface *io, 
                          nitf_Uint32 length, nitf_TRE * tre,
                          struct _nitf_Record* record, 
                          nitf_Error * error)
{
    nitf_Field *field = NULL;
    nitf_TREDescription *descr = NULL;
    char *data = NULL;
    NITF_BOOL success;

    if (!tre)
    {
        /* set error ??? */
        goto CATCH_ERROR;
    }

    /*  malloc the space for the raw data */
    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);

    descr =
        (nitf_TREDescription *) NITF_MALLOC(2 *
                                            sizeof(nitf_TREDescription));
    if (!descr)
    {
        nitf_Error_init(error, NITF_STRERROR(NITF_ERRNO),
                        NITF_CTXT, NITF_ERR_MEMORY);
        goto CATCH_ERROR;
    }

    descr[0].data_type = NITF_BINARY;
    descr[0].data_count = length;
    descr[0].label = _NITF_DEFAULT_TRE_LABEL;
    descr[0].tag = NITF_TRE_RAW;
    descr[1].data_type = NITF_END;
    descr[1].data_count = 0;
    descr[1].label = NULL;
    descr[1].tag = NULL;

    tre->priv = nitf_TREPrivateData_construct(error);
    if (!tre->priv)
        goto CATCH_ERROR;

    ((nitf_TREPrivateData*)tre->priv)->length = length;
    ((nitf_TREPrivateData*)tre->priv)->description = descr;

    /*  Read the data extension into the tre  */
    success = nitf_TREUtils_readField(io, data, (int) length, error);
    if (!success)
        goto CATCH_ERROR;

    field = nitf_Field_construct(length, NITF_BINARY, error);
    if (field == NULL)
    {
        goto CATCH_ERROR;
    }
    /* TODO -- likely inefficient, since we end up copying the raw data here */
    if (!nitf_Field_setRawData
            (field, (NITF_DATA *) data, length, error))
    {
        goto CATCH_ERROR;
    }
    nitf_HashTable_insert(((nitf_TREPrivateData*)tre->priv)->hash,
            NITF_TRE_RAW, field, error);

    NITF_FREE(data);

#ifdef NITF_PRINT_TRES
    printf
    ("------------------------------------------------------------\n");
    printf("[%s] length %d (unknown TRE default handler)\n", tre->tag,
           length);
    printf
    ("------------------------------------------------------------\n");
    printf("\n");
#endif

    return NITF_SUCCESS;

    /* Handle any errors */
CATCH_ERROR:
    if (descr) NITF_FREE(descr);
    if (tre && tre->priv)
        nitf_TREPrivateData_destruct((nitf_TREPrivateData**)&tre->priv);
    return NITF_FAILURE;
}
Beispiel #8
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;
}
Beispiel #9
0
NITFAPI(NITF_BOOL) nitf_Field_setReal(nitf_Field * field,
                                      const char *type, NITF_BOOL plus,
                                      double value, nitf_Error *error)
{
    nitf_Uint32 precision;     /* Format precision */
    nitf_Uint32 bufferLen;     /* Length of buffer */
    char *buffer;              /* Holds intermediate and final results */
    char fmt[64];              /* Format used */

    /*  Check type */

    if (
        (strcmp(type, "f") != 0)
        && (strcmp(type, "e") != 0)
        && (strcmp(type, "E") != 0))
    {
        nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER,
                         "Invalid conversion type %s", type);
        return(NITF_FAILURE);
    }

    /* Allocate buffer used to build value */

    /* The 64 covers the puncuation and exponent and is overkill */
    bufferLen = field->length * 2 + 64;
    buffer = NITF_MALLOC(bufferLen + 1);
    if (buffer == NULL)
    {
        nitf_Error_init(error, NITF_STRERROR(NITF_ERRNO),
                        NITF_CTXT, NITF_ERR_MEMORY);
        return(NITF_FAILURE);
    }

    /*
      Try a precision that will be too large and then adjust it based on the
      length of what you get. This results in a left justified string with the
      maximum number of decmal places. What you are actually figuring is the
      number of digits in the whole part of the number.
    */

    precision = field->length;   /* Must be too big */
    if (plus)
        NITF_SNPRINTF(fmt, 64, "%%+-1.%dl%s", precision, type);
    else
        NITF_SNPRINTF(fmt, 64, "%%-1.%dl%s", precision, type);
    NITF_SNPRINTF(buffer, bufferLen + 1, fmt, value);

    bufferLen = strlen(buffer);

    /* if it's resizable and a different length, we resize */
    if (field->resizable && bufferLen != field->length)
    {
        if (!nitf_Field_resizeField(field, bufferLen, error))
            return NITF_FAILURE;
    }

    if (bufferLen > field->length)
    {
        if (precision > bufferLen - field->length)
            precision -= bufferLen - field->length;
        else
            precision = 0;

        if (plus)
            NITF_SNPRINTF(fmt, 64, "%%+-1.%dl%s", precision, type);
        else
            NITF_SNPRINTF(fmt, 64, "%%-1.%dl%s", precision, type);
        NITF_SNPRINTF(buffer, bufferLen + 1, fmt, value);
    }

    if (!nitf_Field_setRawData(field, buffer, field->length, error))
    {
        NITF_FREE(buffer);
        return(NITF_FAILURE);
    }

    NITF_FREE(buffer);
    return(NITF_SUCCESS);
}