NITFPRIV(nitf_Pair*) basicIncrement(nitf_TREEnumerator* it, nitf_Error* error) { /* get the next value, and increment the cursor */ nitf_TRECursor* cursor = it ? (nitf_TRECursor*)it->data : NULL; nitf_Pair* data; if (!cursor || !nitf_TRECursor_iterate(cursor, error)) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_OBJECT, "Invalid cursor, or error iterating..."); return NULL; } if (!nitf_TRE_exists(cursor->tre, cursor->tag_str)) goto CATCH_ERROR; data = nitf_HashTable_find(((nitf_TREPrivateData*)cursor->tre->priv)->hash, cursor->tag_str); if (!data) goto CATCH_ERROR; return data; CATCH_ERROR: nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_OBJECT, "Couldnt retrieve tag [%s]", cursor->tag_str); return NULL; }
NITF_BOOL decodePadValue(imgInfo *info, char *string, nitf_Uint8 *value, nitf_Error *error) { char *str; /* Pointer into the string */ size_t len; /* Current length of the value string */ nitf_Uint32 nValues; /* Number of byte values in pad value */ nitf_Uint32 i; str = string; len = strlen(str); nValues = (len - 2) / 2; if ( (len <= 2) /* Must be more that 2 characters */ || ((len & 1) != 0) /* String length must be even */ || (nValues > (MAX_PAD - 1)) /* Specifcation is too long */ ) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Error decoding pad value: %s", string); return (NITF_FAILURE); } if ((str[0] != '0') || ((str[1] != 'x') && (str[1] != 'X'))) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Error decoding pad value: %s", string); return (NITF_FAILURE); } str += 2; len -= 2; for (i = 0;i < nValues;i++) { int currentByte; /* Current byte in value */ char val[3]; /* Current byte as characters */ val[0] = tolower(*str); str += 1; val[1] = tolower(*str); str += 1; val[2] = 0; if (sscanf(val, "%x", ¤tByte) != 1) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Error decoding pad value: %s", string); return (NITF_FAILURE); } *(value++) = currentByte; } return(NITF_SUCCESS); }
NITFPRIV(NITF_BOOL) toUint(nitf_Field * field, NITF_DATA * outData, size_t length, nitf_Error * error) { /* First we have to figure out what we are storing... See, its okay to convert a BCS-N to an int, and... its also okay to maintain a binary int... */ NITF_BOOL status = NITF_FAILURE; if (field->type == NITF_BINARY) { switch (field->length) { case 2: status = toUint16(field, (nitf_Uint16 *) outData, error); break; case 4: status = toUint32(field, (nitf_Uint32 *) outData, error); break; case 8: status = toUint64(field, (nitf_Uint64 *) outData, error); break; default: nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Unexpected field size for uint [%d]", field->length); } } else { status = fromStringToUint(field, outData, length, error); } return status; }
NITFPRIV(const char **) doInit(nitf_DLL * dll, const char *prefix, nitf_Error * error) { NITF_PLUGIN_INIT_FUNCTION init; const char **ident; char name[NITF_MAX_PATH]; memset(name, 0, NITF_MAX_PATH); NITF_SNPRINTF(name, NITF_MAX_PATH, "%s%s", prefix, NITF_PLUGIN_INIT_SUFFIX); init = (NITF_PLUGIN_INIT_FUNCTION) nitf_DLL_retrieve(dll, name, error); if (!init) { nitf_Error_print(error, stdout, "Invalid init hook in DSO"); return NULL; } /* Else, call it */ ident = (*init)(error); if (!ident) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_OBJECT, "The plugin [%s] is not retrievable", prefix); return NULL; } return ident; }
nitf_PluginRegistry_retrieveCompConstructor(nitf_PluginRegistry * reg, const char *ident, int *hadError, nitf_Error * error) { /* We get back a pair from the hash table */ nitf_Pair *pair; /* No error has occurred (yet) */ *hadError = 0; if (!nitf_HashTable_exists(reg->compressionHandlers, ident)) { *hadError = 1; nitf_Error_init(error, "Compression handlers not set", NRT_CTXT, NRT_ERR_COMPRESSION); return NULL; } pair = nitf_HashTable_find(reg->compressionHandlers, ident); /* If nothing is there, we don't have a handler, plain and simple */ if (!pair) { nitf_Error_initf(error, NRT_CTXT, NRT_ERR_COMPRESSION, "Don't have a handler for '%s'", ident); return NULL; } return (NITF_PLUGIN_COMPRESSION_CONSTRUCT_FUNCTION) pair->data; }
NITFPRIV(NITF_BOOL) isBCSN(const char *str, nitf_Uint32 len, nitf_Error * error) { char *strp; /* Pointer into string */ nitf_Uint32 i; strp = (char*)str; /* Look for + or minus which must be the first character */ if ((*strp == '+') || (*strp == '-')) { strp += 1; len -= 1; } for (i = 0; i < len; i++) { /* * Some TRE's allow for all minus signs to represent * BCSN if number not known (e.g. BANDSB) */ if (!isdigit(*strp) && (*strp != '-')) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Invalid character %c in BCS_N string", *strp); return (NITF_FAILURE); } strp += 1; } return (NITF_SUCCESS); }
NITF_BOOL nitf::DirectBlockSource::nextBlock(void* callback, void* buf, const void* block, nitf_Uint32 blockNumber, nitf_Uint64 blockSize, nitf_Error * error) { nitf::DirectBlockSource* const cb = reinterpret_cast<nitf::DirectBlockSource*>(callback); if (!callback) { nitf_Error_init(error, "Null pointer reference", NITF_CTXT, NITF_ERR_INVALID_OBJECT); return NITF_FAILURE; } try { cb->nextBlock(buf, block, blockNumber, blockSize); } catch (const except::Exception &ex) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_READING_FROM_FILE, ex.getMessage().c_str()); return NITF_FAILURE; } catch (const std::exception &ex) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_READING_FROM_FILE, ex.what()); return NITF_FAILURE; } catch (...) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_READING_FROM_FILE, "Unknown exception"); return NITF_FAILURE; } return NITF_SUCCESS; }
NITFPRIV(NITF_BOOL) insertPlugin(nitf_PluginRegistry * reg, const char **ident, nitf_DLL * dll, nitf_Error * error) { nitf_HashTable *hash = NULL; int i; int ok; const char* suffix = NULL; /* Load the DLL */ if (!nitf_List_pushBack(reg->dsos, dll, error)) { return NITF_FAILURE; } if (strcmp(ident[0], NITF_PLUGIN_TRE_KEY) == 0) { hash = reg->treHandlers; suffix = NITF_PLUGIN_HOOK_SUFFIX; } else if (strcmp(ident[0], NITF_PLUGIN_COMPRESSION_KEY) == 0) { hash = reg->compressionHandlers; suffix = NITF_PLUGIN_CONSTRUCT_SUFFIX; } else if (strcmp(ident[0], NITF_PLUGIN_DECOMPRESSION_KEY) == 0) { hash = reg->decompressionHandlers; suffix = NITF_PLUGIN_CONSTRUCT_SUFFIX; } else { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_OBJECT, "The identity [%s] is not supported", ident[0]); return NITF_FAILURE; } /* Go through each identity and add it as a creator */ for (i = 1;; i++) { const char *key = ident[i]; if (key == NULL) break; /* no more */ ok = insertCreator(dll, hash, key, suffix, error); if (!ok) { return NITF_FAILURE; } } return NITF_SUCCESS; }
NITFPRIV(NITF_BOOL) fromStringToUint(nitf_Field * field, NITF_DATA * outData, size_t length, nitf_Error * error) { char buffer[256]; if (field->length > 256) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Field length too long for string conversion [%d]", field->length); return NITF_FAILURE; } memcpy(buffer, field->raw, field->length); buffer[field->length] = 0; switch (length) { case 2: { nitf_Uint16 *int16 = (nitf_Uint16 *) outData; *int16 = (nitf_Uint16) NITF_ATO32(buffer); } break; case 4: { nitf_Uint32 *int32 = (nitf_Uint32 *) outData; *int32 = (nitf_Uint32) NITF_ATOU32(buffer); } break; case 8: { nitf_Uint64 *int64 = (nitf_Uint64 *) outData; #if defined(__aix__) sscanf(buffer, "%lld", int64); #else *int64 = (nitf_Uint64) NITF_ATO64(buffer); #endif } break; default: nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Unsupported length [%d]", length); return NITF_FAILURE; } return NITF_SUCCESS; }
NITF_BOOL nitf::RowSource::nextRow(void* algorithm, nitf_Uint32 band, NITF_DATA* buffer, nitf_Error* error) { nitf::RowSourceCallback* const callback = reinterpret_cast<nitf::RowSourceCallback*>(algorithm); if (!callback) { nitf_Error_init(error, "Null pointer reference", NITF_CTXT, NITF_ERR_INVALID_OBJECT); return NITF_FAILURE; } try { callback->nextRow(band, (char*)buffer); } catch (const except::Exception &ex) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_READING_FROM_FILE, ex.getMessage().c_str()); return NITF_FAILURE; } catch (const std::exception &ex) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_READING_FROM_FILE, ex.what()); return NITF_FAILURE; } catch (...) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_READING_FROM_FILE, "Unknown exception"); return NITF_FAILURE; } return NITF_SUCCESS; }
NITFAPI(NITF_BOOL) nitf_Field_resizeField(nitf_Field *field, size_t newLength, nitf_Error *error) { char fill = 0; /* it must be resizable */ if (!field->resizable) return NITF_FAILURE; if (field && newLength != field->length) { if (field->raw) NITF_FREE(field->raw); field->raw = NULL; /* re-malloc */ field->raw = (char *) NITF_MALLOC(newLength + 1); if (!field->raw) { nitf_Error_init(error, NITF_STRERROR(NITF_ERRNO), NITF_CTXT, NITF_ERR_MEMORY); goto CATCH_ERROR; } /* set the new length */ field->length = newLength; field->raw[newLength] = 0; /* terminating null byte */ switch (field->type) { case NITF_BCS_A: fill = ' '; break; case NITF_BCS_N: fill = '0'; break; case NITF_BINARY: fill = 0; break; default: nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Invalid type [%d]", field->type); goto CATCH_ERROR; } memset(field->raw, fill, field->length); } return NITF_SUCCESS; CATCH_ERROR: return NITF_FAILURE; }
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); }
/* We may want to rethink this function a bit. * The NITF spec. has many fields with a BINARY_INTEGER type * This could mean that the field contains 3 8-bit binary integers * For that example, the length of the field is 3, which isn't an integer size * Thus, that wouldn't work here if we just assumed BINARY_INTEGER has ONE integer in the field */ NITFPRIV(NITF_BOOL) fromIntToString(nitf_Field * field, char *outValue, size_t length, nitf_Error * error) { char buffer[256]; size_t actualLength = 0; /* These are all two-step processes 1) get native int 2) NITF_SNPRINTF */ switch (field->length) { case 2: { nitf_Int16 int16; if (!toInt16(field, &int16, error)) goto CATCH_ERROR; actualLength = NITF_SNPRINTF(buffer, 256, "%d", int16); } break; case 4: { nitf_Int32 int32; if (!toInt32(field, &int32, error)) goto CATCH_ERROR; actualLength = NITF_SNPRINTF(buffer, 256, "%ld", (long) int32); } break; case 8: { nitf_Int64 int64; if (!toInt64(field, &int64, error)) goto CATCH_ERROR; actualLength = NITF_SNPRINTF(buffer, 256, "%lld", int64); } break; default: { /* otherwise, it must not be an integer value */ return fromStringToString(field, outValue, length, error); } } if (actualLength > length) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Out value too small [%d] size required", strlen(buffer)); return NITF_FAILURE; } strcpy(outValue, buffer); return NITF_SUCCESS; CATCH_ERROR: return NITF_FAILURE; }
NITFPRIV(NITF_BOOL) toRaw(nitf_Field * field, char *outValue, size_t length, nitf_Error * error) { NITF_BOOL status = NITF_SUCCESS; if (length && length <= field->length) { memcpy(outValue, field->raw, length); } else { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Length [%d] is longer than field width [%d]", length, field->length); status = NITF_FAILURE; } return status; }
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; }
NITFAPI(nitf_ImageSegment *) nitf_ImageSegment_clone(nitf_ImageSegment * source, nitf_Error * error) { nitf_ImageSegment *segment = NULL; if (source) { segment = (nitf_ImageSegment *) NITF_MALLOC(sizeof(nitf_ImageSegment)); if (!segment) { nitf_Error_init(error, NITF_STRERROR(NITF_ERRNO), NITF_CTXT, NITF_ERR_MEMORY); return NULL; } /* Just in case we self-destruct */ segment->subheader = NULL; /* The image offset in the file */ segment->imageOffset = source->imageOffset; /* The image end (offset + length image) */ segment->imageEnd = source->imageEnd; segment->subheader = nitf_ImageSubheader_clone(source->subheader, error); if (!segment->subheader) { nitf_ImageSegment_destruct(&segment); return NULL; } } else { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_OBJECT, "Trying to clone NULL pointer"); } /* Yes! We have a success */ return segment; }
NITFPRIV(NITF_BOOL) isBCSA(const char *str, nitf_Uint32 len, nitf_Error * error) { nitf_Uint8 *strp; /* Pointer into string */ nitf_Uint32 i; strp = (nitf_Uint8 *) str; for (i = 0; i < len; i++) { if ((*strp < 0x20) || (*strp > 0x7e)) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Invalid character %c in BCS_N string", *strp); return (NITF_FAILURE); } strp += 1; } return (NITF_SUCCESS); }
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_Field *) nitf_Field_construct(size_t length, nitf_FieldType type, nitf_Error * error) { nitf_Field *field = NULL; if (length == 0) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Cannot create field of size 0"); goto CATCH_ERROR; } field = (nitf_Field *) NITF_MALLOC(sizeof(nitf_Field)); if (!field) { nitf_Error_init(error, NITF_STRERROR(NITF_ERRNO), NITF_CTXT, NITF_ERR_MEMORY); goto CATCH_ERROR; } field->type = type; field->raw = NULL; field->length = 0; /* this gets set by resizeField */ field->resizable = 1; /* set to 1 so we can use the resize code */ if (!nitf_Field_resizeField(field, length, error)) goto CATCH_ERROR; field->resizable = 0; /* set to 0 - the default value */ return field; CATCH_ERROR: if (field) nitf_Field_destruct(&field); return NULL; }
nitf_PluginRegistry_internalLoadDir(nitf_PluginRegistry * reg, const char *dirName, nitf_Error * error) { const char *name; size_t sizePath; nitf_Directory *dir = NULL; if (!dirName) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_OPENING_FILE, "Null directory name"); return NITF_FAILURE; } dir = nitf_Directory_construct(error); if (!dir) { return NITF_FAILURE; } sizePath = strlen(dirName); if (nitf_Directory_exists(dirName)) { name = nitf_Directory_findFirstFile(dir, dirName); if (name) { do { char *end; char fullName[NITF_MAX_PATH]; int pathSize = sizePath; memset(fullName, 0, NITF_MAX_PATH); memcpy(fullName, dirName, sizePath); if (!isDelimiter(dirName[pathSize - 1])) fullName[pathSize++] = DIR_DELIMITER; memcpy(fullName + pathSize, name, strlen(name)); /* See if we have .so or .dll extensions */ if ((end = (char *) strstr(name, NITF_DLL_EXTENSION)) != NULL) { if (!nitf_PluginRegistry_loadPlugin(fullName, error)) { #ifdef NITF_DEBUG_PLUGIN_REG printf("Warning: plugin [%s] failed to load!\n", name); #endif } } else { #ifdef NITF_DEBUG_PLUGIN_REG printf("Skipping directory [%s]\n", name); #endif } name = nitf_Directory_findNextFile(dir); } while (name); } else { printf("Error: %s\n", NITF_STRERROR(NITF_ERRNO)); } } else { #ifdef NITF_DEBUG_PLUGIN_REG fprintf(stdout, "Could not open plug-in directory '%s'. " "You may have forgotten to set your NITF_PLUGIN_PATH environment " "variable : continuing without plugins...\n", dirName); #endif } nitf_Directory_destruct(&dir); return NITF_SUCCESS; }
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); }
NITFPROT(NITF_BOOL) nitf_Field_resetLength(nitf_Field * field, size_t newLength, NITF_BOOL keepData, nitf_Error * error) { size_t diff; size_t oldLength; char *raw; if (newLength > 0) { /* remember old data */ raw = field->raw; field->raw = (char *) NITF_MALLOC(newLength + 1); if (!field->raw) { field->raw = raw; nitf_Error_init(error, NITF_STRERROR(NITF_ERRNO), NITF_CTXT, NITF_ERR_MEMORY); return 0; } field->raw[newLength] = 0; /* terminating null byte */ oldLength = field->length; field->length = newLength; /* ignore old data */ if (!keepData) { if (field->type == NITF_BCS_N) memset(field->raw, '0', newLength); else if (field->type == NITF_BCS_A) memset(field->raw, ' ', newLength); else memset(field->raw, 0, newLength); } /* copy the old data */ else { diff = newLength - field->length; if (field->type == NITF_BCS_N) copyAndFillZeros(field, raw, diff < 0 ? newLength : oldLength, error); else if (field->type == NITF_BCS_A) copyAndFillSpaces(field, raw, diff < 0 ? newLength : oldLength, error); else { memset(field->raw, 0, newLength); memcpy(field->raw, raw, diff < 0 ? newLength : oldLength); } } /* free the old memory */ NITF_FREE(raw); } else { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_PARAMETER, "Invalid length specified"); return 0; } return 1; }
NITFAPI(NITF_BOOL) nitf_TREUtils_basicInit(nitf_TRE * tre, const char* id, nitf_Error * error) { nitf_TREDescriptionSet* set = NULL; nitf_TREDescriptionInfo* descInfo = NULL; nitf_TREPrivateData *priv = NULL; NITF_BOOL found = 0; assert(tre); set = (nitf_TREDescriptionSet*)tre->handler->data; /* create a new private data struct */ priv = nitf_TREPrivateData_construct(error); if (!priv) return NITF_FAILURE; /* search for the description with the given ID - if one was provided */ if (id) { descInfo = set->descriptions; while(descInfo && descInfo->name && !found) { if (strcmp(descInfo->name, id) == 0) { /* we have a match! */ found = 1; } else { descInfo++; } } /* if we couldn't find it, we get out of here... */ if (!found) { nitf_Error_initf(error, NITF_CTXT, NITF_ERR_INVALID_OBJECT, "No matching id '%s' found!", id); return NITF_FAILURE; } } else { /* otherwise, if no ID was given, we'll just use the first description. * in most cases, this will be the only description. */ descInfo = set->descriptions; } /* set the name */ if (!nitf_TREPrivateData_setDescriptionName( priv, descInfo->name, error)) { nitf_TREPrivateData_destruct(&priv); tre->priv = NULL; return NITF_FAILURE; } /* assign it to the TRE */ tre->priv = priv; /* try to fill the TRE */ if (nitf_TREUtils_fillData(tre, descInfo->description, error)) return NITF_SUCCESS; else { nitf_TRE_destruct(&tre); 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; }
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; }