NITFPRIV(nitf_Field*) defaultGetField(nitf_TRE* tre, const char* tag) { nitf_Pair* pair = nitf_HashTable_find( ((nitf_TREPrivateData*)tre->priv)->hash, tag); if (!pair) return NULL; return (nitf_Field*)pair->data; }
void findInExtensions(nitf_Extensions* ext) { /* These iterators are for going through the image segments */ nitf_ListIterator iter; nitf_ListIterator end; nitf_List* list; assert( ext ); list = nitf_Extensions_get(ext, "ACFTB"); if (list) { /* Set the iterator to traverse the list of image segments */ iter = nitf_List_begin(list); /* And set this one to the end, so we'll know when we're done! */ end = nitf_List_end(list); /* While we are not done... */ while ( nitf_ListIterator_notEqualTo(&iter, &end) ) { nitf_TRE* tre; printf("Found ACFTB instance\n"); /* Get the image segment as its proper object */ tre = (nitf_TRE*)nitf_ListIterator_get(&iter); if ( nitf_HashTable_exists( tre->hash, "raw_data" ) ) { printf("Your plugin for ACFTB was not loaded so the data is contained in the RAW section\n"); } else { nitf_Pair* mission = nitf_HashTable_find( tre->hash, "ACMSNID" ); if (! mission ) { printf("Error: no Mission ID available\n"); nitf_HashTable_print( tre->hash ); } else { nitf_Field* field = (nitf_Field*)mission->data; printf("Mission ID: [%.*s]\n", field->length, field->raw); } } /* Increment the iterator so we can continue */ nitf_ListIterator_increment(&iter); } } else { printf("No ACFTB\n"); } }
NITFAPI(nitf_Field*) nitf_TREUtils_basicGetField(nitf_TRE* tre, const char* tag) { nitf_Pair* pair = nitf_HashTable_find( ((nitf_TREPrivateData*)tre->priv)->hash, tag); if (!pair) return NULL; return (nitf_Field*)pair->data; }
nitf::Pair nitf::HashTable::find(const std::string& key) throw(except::NoSuchKeyException) { if (key.length() == 0) throw except::NoSuchKeyException(Ctxt("Empty key value")); nitf_Pair* x = nitf_HashTable_find(getNative(), key.c_str()); if (!x) throw except::NoSuchKeyException(Ctxt(key)); return nitf::Pair(x); }
NITFPRIV(nitf_Pair*) defaultIncrement(nitf_TREEnumerator* it, nitf_Error* error) { if (it && it->data) { nitf_Pair* data = nitf_HashTable_find( ((nitf_TREPrivateData*)it->data)->hash, NITF_TRE_RAW); if (data) { it->data = NULL; /* set to NULL, since we only have one value */ return data; } } nitf_Error_init(error, "Null iterator!", NITF_CTXT, NITF_ERR_INVALID_OBJECT); return NULL; }
NITFPRIV(nitf_TREEnumerator*) defaultBegin(nitf_TRE* tre, nitf_Error* error) { nitf_TREEnumerator* it = (nitf_TREEnumerator*)NITF_MALLOC(sizeof(nitf_TREEnumerator)); /* Check rv here */ it->next = defaultIncrement; it->hasNext = defaultHasNext; it->getFieldDescription = defaultGetFieldDescription; it->data = tre->priv; if (!it->data || !nitf_HashTable_find( ((nitf_TREPrivateData*)it->data)->hash, NITF_TRE_RAW)) { nitf_Error_init(error, "No raw_data in default!", NITF_CTXT, NITF_ERR_INVALID_OBJECT); return NITF_FAILURE; } return it; }
NITFPRIV(NITF_BOOL) defaultWrite(nitf_IOInterface* io, struct _nitf_TRE* tre, struct _nitf_Record* record, nitf_Error* error) { nitf_Field* field; nitf_Pair* pair = nitf_HashTable_find( ((nitf_TREPrivateData*)tre->priv)->hash, NITF_TRE_RAW); if (pair == NULL) { nitf_Error_init(error, "No raw_data in default!", NITF_CTXT, NITF_ERR_INVALID_OBJECT); return NITF_FAILURE; } field = (nitf_Field*)pair->data; if (!nitf_IOInterface_write(io, field->raw, field->length, error)) return NITF_FAILURE; return NITF_SUCCESS; }
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; }
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; }
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(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; }