void nitf::HashTable::insert(const std::string& key, NITF_DATA* data) throw(nitf::NITFException) { if (key.length() == 0) throw except::NoSuchKeyException(Ctxt("Empty key value")); NITF_BOOL x = nitf_HashTable_insert(getNative(), key.c_str(), data, &error); if (!x) throw nitf::NITFException(&error); }
NITFPRIV(NITF_BOOL) insertCreator(nitf_DLL* dso, nitf_HashTable* hash, const char* ident, const char* suffix, nitf_Error* error) { /* We are trying to find tre_main */ NITF_DLL_FUNCTION_PTR dsoMain = NULL; /* Get the name of the handler */ char name[NITF_MAX_PATH]; char* p = NULL; if (!nitf_DLL_isValid(dso)) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "DSO is not valid for [%s]", ident); } memset(name, 0, NITF_MAX_PATH); NITF_SNPRINTF(name, NITF_MAX_PATH, "%s%s", ident, suffix); nitf_Utils_replace(name, ' ', '_'); /* No error has occurred (yet) */ #if NITF_DEBUG_PLUGIN_REG printf("Loading function [%s] in dso at [%p]\n", name, dso); #endif /* Retrieve the main */ dsoMain = nitf_DLL_retrieve(dso, name, error); if (!dsoMain) { /* If it didnt work, we are done */ return NITF_FAILURE; } #if NITF_DEBUG_PLUGIN_REG if (nitf_HashTable_exists(hash, ident)) { printf("Warning, overriding [%s] hook", ident); } #endif return nitf_HashTable_insert(hash, ident, dsoMain, error); }
nitf_PluginRegistry_registerTREHandler(NITF_PLUGIN_INIT_FUNCTION init, NITF_PLUGIN_TRE_HANDLER_FUNCTION handle, nitf_Error * error) { nitf_PluginRegistry* reg = nitf_PluginRegistry_getInstance(error); const char** ident; int i = 1; int ok = 1; if (!reg) { return NITF_FAILURE; } if ( (ident = (*init)(error)) == NULL) { return NITF_FAILURE; } if (!ident[0] || (strcmp(ident[0], NITF_PLUGIN_TRE_KEY) != 0)) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_OBJECT, "Expected a TRE identity"); return NITF_FAILURE; } for (; ident[i] != NULL; ++i) { #ifdef NITF_DEBUG_PLUGIN_REG if (nitf_HashTable_exists(reg->treHandlers, ident[i])) { printf("Warning, static handler overriding [%s] hook\n", ident[i]); } #endif ok &= nitf_HashTable_insert(reg->treHandlers, ident[i], (NITF_DATA*)handle, error); } return ok; }
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); }
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; }
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; }
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; }
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; }
nitf_TREPrivateData_clone(nitf_TREPrivateData *source, nitf_Error * error) { nitf_TREPrivateData *priv = NULL; /* temporary nitf_List pointer */ nitf_List *lPtr; /* temporary nitf_Field pointer */ nitf_Field *field; /* temporary nitf_Pair pointer */ nitf_Pair *pair; /* iterator to front of list */ nitf_ListIterator iter; /* iterator to back of list */ nitf_ListIterator end; /* used for iterating */ int i; if (source) { priv = nitf_TREPrivateData_construct(error); if (!priv) goto CATCH_ERROR; if (!nitf_TREPrivateData_setDescriptionName( priv, source->descriptionName, error)) { goto CATCH_ERROR; } /* Copy the entire contents of the hash */ for (i = 0; i < source->hash->nbuckets; i++) { /* Foreach chain in the hash table... */ lPtr = source->hash->buckets[i]; iter = nitf_List_begin(lPtr); end = nitf_List_end(lPtr); /* And while they are different... */ while (nitf_ListIterator_notEqualTo(&iter, &end)) { /* Retrieve the field at the iterator... */ pair = (nitf_Pair *) nitf_ListIterator_get(&iter); /* Cast it back to a field... */ field = (nitf_Field *) pair->data; /* clone the field */ field = nitf_Field_clone(field, error); /* If that failed, we need to destruct */ if (!field) goto CATCH_ERROR; /* Yes, now we can insert the new field! */ if (!nitf_HashTable_insert(priv->hash, pair->key, field, error)) { goto CATCH_ERROR; } nitf_ListIterator_increment(&iter); } } } else { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_OBJECT, "Trying to clone NULL pointer"); } return priv; CATCH_ERROR: if (priv) nitf_TREPrivateData_destruct(&priv); return NULL; }
/* 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; }