core/vil/file_formats/vil_nitf2_field_sequence.cxx
Go to the documentation of this file.
00001 // vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of
00002 // Stellar Science Ltd. Co. (stellarscience.com) for
00003 // Air Force Research Laboratory, 2005.
00004 
00005 #include "vil_nitf2_field_sequence.h"
00006 #include "vil_nitf2_index_vector.h"
00007 #include "vil_nitf2_field_formatter.h"
00008 #include "vil_nitf2_field_definition.h"
00009 #include "vil_nitf2_scalar_field.h"
00010 #include "vil_nitf2_array_field.h"
00011 #include "vil_nitf2_compound_field_value.h"
00012 
00013 #include <vcl_utility.h>
00014 
00015 vil_nitf2_field::field_tree*
00016 vil_nitf2_field_sequence::get_tree( vil_nitf2_field::field_tree* tr ) const
00017 {
00018   vil_nitf2_field::field_tree* t = tr ? tr : new vil_nitf2_field::field_tree;
00019   for ( unsigned int i = 0 ; i < fields_vector.size() ; i++ ) {
00020     t->children.push_back( fields_vector[i]->get_tree() );
00021   }
00022   return t;
00023 }
00024 
00025 void vil_nitf2_field_sequence::insert_field( const vcl_string& str, vil_nitf2_field* field )
00026 {
00027   fields.insert(vcl_make_pair(str, field));
00028   fields_vector.push_back(field);
00029 }
00030 
00031 bool vil_nitf2_field_sequence::
00032 create_array_fields(const vil_nitf2_field_definitions* field_defs,
00033                     int num_dimensions)
00034 {
00035   for (vil_nitf2_field_definitions::const_iterator node = field_defs->begin();
00036        node != field_defs->end(); ++node)
00037   {
00038     if ((*node) && (*node)->is_field_definition()) {
00039       vil_nitf2_field_definition* field_def = (*node)->field_definition();
00040       vil_nitf2_array_field* field = field_def->formatter->create_array_field(num_dimensions, field_def);
00041       if (field) {
00042         insert_field(field_def->tag, field);
00043       } else {
00044         vcl_cerr << "vil_nitf2_field_sequence:create_array_fields(): Error created required vcl_vector field "
00045                  << field_def->tag << "; bailing out.\n";
00046         return false;
00047       }
00048     } else if ((*node) && (*node)->is_repeat_node()) {
00049       // recursively create nested vector fields
00050       vil_nitf2_field_definition_repeat_node* repeat_node = (*node)->repeat_node();
00051       if (!create_array_fields(repeat_node->field_definitions, num_dimensions+1)) {
00052         return false;
00053       }
00054     } else {
00055       vcl_cerr << "vil_nitf2_field_sequence::create_array_fields(): unsupported node type!\n";
00056       return false;
00057     }
00058   }
00059   return true;
00060 }
00061 
00062 void vil_nitf2_field_sequence::set_array_fields_dimension(
00063   const vil_nitf2_field_definitions* field_defs,
00064   const vil_nitf2_index_vector& index, int repeat_count)
00065 {
00066   for (vil_nitf2_field_definitions::const_iterator node = field_defs->begin();
00067        node != field_defs->end(); ++node)
00068   {
00069     if ((*node) && (*node)->is_field_definition()) {
00070       vil_nitf2_field_definition* field_def = (*node)->field_definition();
00071       vil_nitf2_array_field* field = get_field(field_def->tag)->array_field();
00072       if (field) {
00073         VIL_NITF2_LOG(log_debug) << "  (Setting tag " << field_def->tag << " dimension "
00074                                  << index << " to " << repeat_count << ".)" << vcl_endl;
00075         field->set_next_dimension(index, repeat_count);
00076       } else {
00077         vcl_cerr << "vil_nitf2_field_sequence:set_array_field_dimension(): array field "
00078                  << field_def->tag << " not found!\n";
00079       }
00080     } else if ((*node) && (*node)->is_repeat_node()) {
00081       // recursively set dimension vector fields
00082       vil_nitf2_field_definition_repeat_node* repeat_node = (*node)->repeat_node();
00083       set_array_fields_dimension(repeat_node->field_definitions, index, repeat_count);
00084     } else {
00085       vcl_cerr << "vil_nitf2_field_sequence::set_array_fields_dimension(): unsupported node type!\n";
00086     }
00087   }
00088 }
00089 
00090 bool vil_nitf2_field_sequence::read(vil_nitf2_istream& input,
00091                                     const vil_nitf2_field_definitions* field_defs,
00092                                     vil_nitf2_index_vector indexes)
00093 {
00094   if (!field_defs)
00095     field_defs = m_field_definitions;
00096   if (!field_defs)
00097     vcl_cerr << "vil_nitf2_field_sequence::read() missing field definitions!\n";
00098   bool error = false;
00099   for (vil_nitf2_field_definitions::const_iterator node = field_defs->begin();
00100        node != field_defs->end(); ++node)
00101   {
00102     if ((*node) && (*node)->is_field_definition())
00103     {
00104       vil_nitf2_field_definition* field_def = (*node)->field_definition();
00105       // The field exists if it is required, or if it is conditional and
00106       // the condition is true.
00107       bool field_exists;
00108       if (field_def->is_required()) {
00109         field_exists = true;
00110       } else {
00111         bool condition;
00112         bool conditionValid = (*(field_def->condition_functor))(this, indexes, condition);
00113         if (conditionValid) {
00114           field_exists = condition;
00115         } else {
00116           // Cannot evaluate condition; therefore I don't know whether this
00117           // field exists and cannot reliably parse the rest of the record
00118           vcl_cerr << "vil_nitf2_field_sequence::read(): Cannot evaluate condition for tag " << field_def->tag << '\n';
00119           error = true;
00120           break;
00121         }
00122       }
00123       if (field_exists)
00124       {
00125         // Evaluate its width functor, if any.
00126         int variable_width = -1;
00127         if (field_def->width_functor != 0) {
00128           bool computed_width = (*(field_def->width_functor))(this, indexes, variable_width);
00129           if (!computed_width) {
00130             // Cannot evaluate width functor; therefore I don't know the length
00131             // of this field and cannot reliably parse the rest of the record
00132             vcl_cerr << "vil_nitf2_field_sequence::read(): Cannot evaluate width functor for tag " << field_def->tag << '\n';
00133             error = true;
00134             break;
00135           }
00136         }
00137         if (variable_width == 0) {
00138           VIL_NITF2_LOG(log_debug) << "Skipping field " << field_def->tag << ", whose length = 0." << vcl_endl;
00139         }
00140         else
00141         {
00142           // Either there is no width functor, in which case variable_width = -1 and will be ignored,
00143           // or there is a width functor, and the resulting positive variable_width will be applied.
00144           if (indexes.size()==0) {
00145             // read scalar field
00146             bool fieldReadError;
00147             vil_nitf2_scalar_field* field = vil_nitf2_scalar_field::read(input, field_def, variable_width, &fieldReadError);
00148             if (field) {
00149               insert_field(field_def->tag, field);
00150             }
00151             if ( fieldReadError ){
00152               error = true;
00153               break;
00154             }
00155 
00156           } else {
00157             // read vector field element
00158             bool read_error = true;
00159             vil_nitf2_field_definition* field_def = (*node)->field_definition();
00160             if (field_def) {
00161               vil_nitf2_array_field* field = get_field(field_def->tag)->array_field();
00162               if (field) {
00163                 if (field->read_vector_element(input, indexes, variable_width)) {
00164                   read_error = false;
00165                 }
00166               }
00167             }
00168             if (read_error) {
00169               vcl_cerr << "vil_nitf2_field_sequence::read(): Couldn't find vcl_vector field!\n";
00170               return false;
00171             }
00172           }
00173         }
00174         // TO DO: Check that the expected amount of data was read; if not,
00175         // try to recover.
00176       }
00177     }
00178     else if ((*node) && (*node)->is_repeat_node())
00179     {
00180       vil_nitf2_field_definition_repeat_node* repeat_node = (*node)->repeat_node();
00181 
00182       // Compute how many times it repeats
00183       int repeat_count = 0;
00184       bool computed_repeat = false;
00185       if (repeat_node->repeat_functor != 0) {
00186         computed_repeat = (*(repeat_node->repeat_functor))(this, indexes, repeat_count);
00187       }
00188       if (!computed_repeat) {
00189         // Cannot evaluate repeat count; therefore I don't know the length
00190         // of this field and cannot reliably parse the rest of the record
00191         vcl_cerr << "Cannot evaluate repeat count for repeat node\n";
00192         error = true;
00193         break;
00194       }
00195       // On the first call to this method, call create_array_fields to loop
00196       // recursively over the field definitions to create all vector fields.
00197       // All nested fields need to be defined before any values are read. This is
00198       // is so that we can start setting the bounds on outer dimensions of
00199       // nested field at the top of each repeat loop.
00200       //
00201       // For example, for this field sequence:
00202       //   REPEAT i=1..N
00203       //     FIELD A(i)
00204       //     REPEAT j=1..A(i)
00205       //       FIELD B(i,j)
00206       // the following call to create_array_fields sets up fields
00207       // A (with 1 dimension) and B (with 2 dimensions).
00208       if (indexes.size() == 0) {
00209         if (!create_array_fields(repeat_node->field_definitions, 1)) {
00210           return false;
00211         }
00212       }
00213       // Loop repeat_count times over fields to read the elements
00214       vcl_string nesting_level_indicator((indexes.size()+1)*2, '-');
00215       VIL_NITF2_LOG(log_debug) << nesting_level_indicator
00216                                << "Repeating fields " << repeat_count << " times:" << vcl_endl;
00217       for (int i=0; i<repeat_count; ++i)
00218       {
00219         // The first time through the repeat loop, set the dimension
00220         // bounds of all fields, including repeated fields. So, for the
00221         // example above, during the first call to this method read(),
00222         // the invocation of set_fields_bounds() will set:
00223         //   A.dimension(vector()) = N
00224         //   B.dimension(vector()) = N
00225         // During the recursive calls to read(), the two invocations of
00226         // set_field_bounds() will set:
00227         //   B.dimension(vector(1)) = A(1)
00228         //   B.dimension(vector(2)) = A(2)
00229         // Actually, the indexes are zero-based, but this gives the general
00230         // idea.
00231         if (i==0) {
00232           set_array_fields_dimension(repeat_node->field_definitions, indexes, repeat_count);
00233         }
00234 
00235         // Now call myself recursively to read the vector field elements
00236         vil_nitf2_index_vector nested_indexes(indexes);
00237         nested_indexes.push_back(i);
00238         if (!read(input, repeat_node->field_definitions, nested_indexes)) {
00239           return false;
00240         }
00241       }
00242       VIL_NITF2_LOG(log_debug) << nesting_level_indicator << "End repeating fields." << vcl_endl;
00243     }
00244     else {
00245       vcl_cerr << "vil_nitf2_tagged_record::read(): unsupported node.\n";
00246     }
00247   }
00248   return !error;
00249 }
00250 
00251 bool vil_nitf2_field_sequence::write(vil_nitf2_ostream& output,
00252                                      const vil_nitf2_field_definitions* field_defs,
00253                                      vil_nitf2_index_vector indexes)
00254 {
00255   if (!field_defs)
00256     field_defs = m_field_definitions;
00257   if (!field_defs)
00258     vcl_cerr << "vil_nitf2_field_sequence::write(): Missing field definitions!\n";
00259   for (vil_nitf2_field_definitions::const_iterator node = field_defs->begin();
00260        node != field_defs->end(); ++node)
00261   {
00262     if ((*node) && (*node)->is_field_definition())
00263     {
00264       vil_nitf2_field_definition* field_def = (*node)->field_definition();
00265       if (!field_def) {
00266         vcl_cerr << "vil_nitf2_field_sequence::write(): Missing field definition!\n";
00267         return false;
00268       }
00269       vil_nitf2_field* field = get_field(field_def->tag);
00270 
00271       // Determine whether the field is required or is a conditional field
00272       // whose condition is satisfied
00273       bool expected = field_def->is_required();
00274       if (!expected) {
00275         bool condition;
00276         if ((*field_def->condition_functor)(this, indexes, condition)) {
00277           expected |= condition;
00278         } else {
00279           vcl_cerr << "vil_nitf2_field_sequence::write(): Cound not evaluate condition for field "
00280                    << field_def->tag << vcl_endl;
00281           // Cannot evaluate condition, therefore I can't tell whether this
00282           // field should exist.
00283           return false;
00284         }
00285       }
00286       if (field && !expected) {
00287         vcl_cerr << "vil_nitf2_field_sequence::write(): Field " << field_def->tag
00288                  << " is being ignored because its condition is not satisfied.\n";
00289       }
00290       else
00291       {
00292         // Will emit field. Evaluate its width functor, if any.
00293         int variable_width = -1;
00294         if (field_def->width_functor != 0) {
00295           bool computed_width = (*(field_def->width_functor))(this, indexes, variable_width);
00296           if (!computed_width) {
00297             // Cannot evaluate width functor; therefore I don't know the length
00298             // of this field and cannot reliably parse the rest of the record
00299             vcl_cerr << "vil_nitf2_field_sequence::write(): Cannot evaluate width functor for tag " << field_def->tag << vcl_endl;
00300             return false;
00301           }
00302         }
00303         if (variable_width == 0) {
00304           VIL_NITF2_LOG(log_debug) << "Skipping field " << field_def->tag << ", whose length = 0." << vcl_endl;
00305         } else {
00306           // Either there is no width functor, in which case variable_width = -1 and will be ignored,
00307           // or there is a width functor, and the resulting positive variable_width will be applied.
00308           if (!field && expected) {
00309             if (!field_def->blanks_ok) {
00310               vcl_cerr << "vil_nitf2_field_sequence::write(): Field " << field_def->tag
00311                        << " is unspecified; writing blanks.\n";
00312             }
00313             if (variable_width > 0)
00314               field_def->formatter->field_width = variable_width;
00315             field_def->formatter->write_blank(output);
00316           } else if (field) {
00317             if (field->scalar_field()) {
00318               field->scalar_field()->write(output, variable_width);
00319             } else {
00320               field->array_field()->write_vector_element(output, indexes, variable_width);
00321             }
00322           }
00323         }
00324       }
00325     }
00326     else if ((*node) && (*node)->is_repeat_node())
00327     {
00328       vil_nitf2_field_definition_repeat_node* repeat_node = (*node)->repeat_node();
00329       // Compute how many times it repeats
00330       int repeat_count = 0;
00331       bool computed_repeat = false;
00332       if (repeat_node->repeat_functor != 0) {
00333         computed_repeat = (*(repeat_node->repeat_functor))(this, indexes, repeat_count);
00334       }
00335       if (!computed_repeat) {
00336         // Cannot evaluate repeat count; therefore I don't know the length
00337         // of this field.
00338         vcl_cerr << "vil_nitf2_field_sequence::write(): Cannot evaluate repeat count for repeat node\n";
00339         return false;
00340       }
00341       if (repeat_node->field_definitions) {
00342         for (int i=0; i < repeat_count; ++i) {
00343           vil_nitf2_index_vector nested_indexes(indexes);
00344           nested_indexes.push_back(i);
00345           this->write(output, repeat_node->field_definitions, nested_indexes);
00346         }
00347       }
00348     } else {
00349       vcl_cerr << "vil_nitf2_field_sequence::write(): Ignoring unsupported node.\n";
00350     }
00351   }
00352   return true;
00353 }
00354 
00355 vil_nitf2_field_sequence::~vil_nitf2_field_sequence()
00356 {
00357   // Delete fields, which I own
00358   for (field_map::iterator field_map_entry = fields.begin();
00359        field_map_entry != fields.end(); ++field_map_entry)
00360   {
00361     vil_nitf2_field* field = field_map_entry->second;
00362     delete field;
00363   }
00364 }
00365 
00366 vil_nitf2_field* vil_nitf2_field_sequence::get_field(vcl_string tag) const
00367 {
00368   vcl_map<vcl_string, vil_nitf2_field*>::const_iterator field_map_entry = fields.find(tag);
00369   if (field_map_entry == fields.end())
00370     return 0;
00371   return field_map_entry->second;
00372 }
00373 
00374 // Who needs templated functions when we have macros!
00375 #define NITF_FIELD_SEQ_GET_VALUE(T) \
00376 bool vil_nitf2_field_sequence::get_value(vcl_string tag, T& out_value) const { \
00377   vil_nitf2_field* field = get_field(tag); \
00378   vil_nitf2_scalar_field* scalar_field = field ? field->scalar_field() : 0; \
00379   if (!scalar_field) { \
00380     /*vcl_cerr << "vil_nitf2_field_sequence::get_value(" << tag << "): scalar field not found.\n";*/ \
00381     return false; \
00382   } \
00383   if (!scalar_field->value(out_value)) { \
00384     vcl_cerr << "vil_nitf2_field_sequence::get_value(" << tag << ") called with wrong type.\n"; \
00385     return false; \
00386   } \
00387   return true; \
00388 }
00389 
00390 NITF_FIELD_SEQ_GET_VALUE(int)
00391 NITF_FIELD_SEQ_GET_VALUE(double)
00392 NITF_FIELD_SEQ_GET_VALUE(char)
00393 NITF_FIELD_SEQ_GET_VALUE(void*)
00394 NITF_FIELD_SEQ_GET_VALUE(vcl_string)
00395 NITF_FIELD_SEQ_GET_VALUE(vil_nitf2_location*)
00396 NITF_FIELD_SEQ_GET_VALUE(vil_nitf2_date_time)
00397 NITF_FIELD_SEQ_GET_VALUE(vil_nitf2_tagged_record_sequence)
00398 
00399 #define NITF_FIELD_SEQ_GET_ARRAY_VALUE(T) \
00400 bool vil_nitf2_field_sequence::get_value(vcl_string tag, \
00401                                          const vil_nitf2_index_vector& indexes, \
00402                                          T& out_value, \
00403                                          bool ignore_extra_indexes) const { \
00404   vil_nitf2_field* field = get_field(tag); \
00405   if (!field) { \
00406     /*vcl_cerr << "vil_nitf2_field_sequence::get_value(" << tag << ", const vil_nitf2_index_vector&): tag not found.\n"; */\
00407     return false; \
00408   } \
00409   vil_nitf2_index_vector trimmed_indexes(indexes); \
00410   if (ignore_extra_indexes && (int)indexes.size() > field->num_dimensions()) { \
00411      trimmed_indexes.resize(field->num_dimensions()); \
00412   } \
00413   if (trimmed_indexes.size()==0) { \
00414     return field->scalar_field() && field->scalar_field()->value(out_value); \
00415   } else { \
00416     return field->array_field()->value(trimmed_indexes, out_value); \
00417   } \
00418 }
00419 
00420 NITF_FIELD_SEQ_GET_ARRAY_VALUE(int) // expanded below for debugging
00421 NITF_FIELD_SEQ_GET_ARRAY_VALUE(double)
00422 NITF_FIELD_SEQ_GET_ARRAY_VALUE(char)
00423 NITF_FIELD_SEQ_GET_ARRAY_VALUE(void*)
00424 NITF_FIELD_SEQ_GET_ARRAY_VALUE(vcl_string)
00425 NITF_FIELD_SEQ_GET_ARRAY_VALUE(vil_nitf2_location*)
00426 NITF_FIELD_SEQ_GET_ARRAY_VALUE(vil_nitf2_date_time)
00427 
00428 // Macro to generate overloads of get_values(), since VXL coding
00429 // standards forbid using templated member functions.
00430 //
00431 #define NITF_FIELD_SEQ_GET_VALUES(T) \
00432 bool vil_nitf2_field_sequence::get_values(vcl_string tag, \
00433                                           const vil_nitf2_index_vector& indexes, \
00434                                           vcl_vector<T>& out_values, \
00435                                           bool clear_out_values) const \
00436 { \
00437   vil_nitf2_field* field = get_field(tag); \
00438   if (!field) { \
00439     /*vcl_cerr << "vil_nitf2_field_sequence::get_value(" << tag << ", const vil_nitf2_index_vector&): tag not found.\n"; */\
00440     return false; \
00441   } \
00442   if (clear_out_values) { \
00443     out_values.clear(); \
00444   } \
00445   int num_dims = field->num_dimensions(); \
00446   if (num_dims == (int)indexes.size()) { \
00447     /* get single value */\
00448     T value; \
00449     if (get_value(tag, indexes, value, false)) { \
00450       out_values.push_back(value); \
00451       return true; \
00452     } else { \
00453       return false; \
00454     } \
00455   } else { \
00456     vil_nitf2_array_field* array_field = field->array_field(); \
00457     if (!array_field) { \
00458       /* indexes is too long */\
00459       return false; \
00460     } \
00461     /* traverse value tree depth-first, collecting values into out_values */\
00462     int dimension = array_field->next_dimension(indexes); \
00463     for (int index=0; index < dimension; ++index) { \
00464       vil_nitf2_index_vector next_indexes = indexes; \
00465       next_indexes.push_back(index); \
00466       if (!get_values(tag, next_indexes, out_values, false)) { \
00467         return false; \
00468       } \
00469     } \
00470     return true; \
00471   } \
00472 } \
00473 \
00474 bool vil_nitf2_field_sequence::get_values(vcl_string tag, vcl_vector<T>& out_values) const \
00475 { \
00476   return get_values(tag, vil_nitf2_index_vector(), out_values, true); \
00477 }
00478 
00479 NITF_FIELD_SEQ_GET_VALUES(int)
00480 NITF_FIELD_SEQ_GET_VALUES(double)
00481 NITF_FIELD_SEQ_GET_VALUES(char)
00482 NITF_FIELD_SEQ_GET_VALUES(void*)
00483 NITF_FIELD_SEQ_GET_VALUES(vcl_string)
00484 NITF_FIELD_SEQ_GET_VALUES(vil_nitf2_location*)
00485 NITF_FIELD_SEQ_GET_VALUES(vil_nitf2_date_time)
00486 
00487 #if VXL_HAS_INT_64
00488 //if not VXL_HAS_INT_64 isn't defined the vil_nitf2_long is the same as just plain 'int'
00489 //and this function will be a duplicate of that get_value
00490 NITF_FIELD_SEQ_GET_VALUE(vil_nitf2_long)
00491 NITF_FIELD_SEQ_GET_ARRAY_VALUE(vil_nitf2_long)
00492 NITF_FIELD_SEQ_GET_VALUES(vil_nitf2_long)
00493 #endif