Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vil_nitf2_array_field.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_array_field.h"
00006 #include "vil_nitf2_field_definition.h"
00007 #include "vil_nitf2_index_vector.h"
00008 
00009 #include <vcl_cstddef.h> // for size_t
00010 #include <vcl_sstream.h>
00011 #include <vil/vil_stream_core.h>
00012 
00013 int vil_nitf2_array_field::num_dimensions() const
00014 {
00015   return m_num_dimensions;
00016 }
00017 
00018 int vil_nitf2_array_field::
00019 next_dimension(const vil_nitf2_index_vector& index) const
00020 {
00021   vcl_map<vil_nitf2_index_vector,int>::const_iterator dimension_bounds_entry = m_dimensions_map.find(index);
00022   if (dimension_bounds_entry != m_dimensions_map.end()) {
00023     return dimension_bounds_entry->second;
00024   } else {
00025     return 0;
00026   }
00027 }
00028 
00029 void vil_nitf2_array_field::
00030 set_next_dimension(const vil_nitf2_index_vector& index, int bound)
00031 {
00032   if ((int)index.size() >= m_num_dimensions) {
00033     vcl_cerr << "vil_nitf2_array_field::set_next_dimension"
00034              << index << ": invalid partial index!\n";
00035     return;
00036   }
00037   if (next_dimension(index) > 0) {
00038     vcl_cerr << "vil_nitf2_array_field::set_next_dimension"
00039              << index << ": bound previously set!\n";
00040   }
00041   m_dimensions_map[index] = bound;
00042 }
00043 
00044 bool vil_nitf2_array_field::
00045 check_index(const vil_nitf2_index_vector& indexes) const
00046 {
00047   if ((int)indexes.size() != m_num_dimensions) {
00048     vcl_cerr << "index length does not match value dimensions!\n";
00049     return false;
00050   }
00051   // Remove the last element from index and look it up in the dimensions map.
00052   // Then check if the removed element is less than the returned dimension bound.
00053   // If no dimension bound is found, then one of the other index values is
00054   // invalid.
00055   vil_nitf2_index_vector dimension_index;
00056   for (int dim=0; dim < m_num_dimensions-1; ++dim) {
00057     dimension_index.push_back(indexes[dim]);
00058   }
00059   int dimension_bound = next_dimension(dimension_index);
00060   int last_index = indexes[indexes.size()-1];
00061   if (last_index < dimension_bound) {
00062     return true;
00063   } else {
00064     vcl_cerr << "Tag " << tag() << indexes << ": index out of bounds!\n";
00065     return false;
00066   }
00067 }
00068 
00069 vcl_string int_to_string( int i )
00070 {
00071   vcl_stringstream s;
00072   s << i;
00073   return s.str();
00074 }
00075 
00076 vcl_string index_string( const vil_nitf2_index_vector& indices )
00077 {
00078   vcl_string ret_val = "";
00079   for ( unsigned int i = 0 ; i < indices.size() ; i++ ){
00080     ret_val += "[" + int_to_string( indices[i] ) + "]";
00081   }
00082   return ret_val;
00083 }
00084 
00085 vcl_string vil_nitf2_array_field::get_value_string(const vil_nitf2_index_vector& in_indices) const
00086 {
00087   vil_stream_core* str = new vil_stream_core;
00088   write_vector_element( *str, in_indices, -1 );
00089   vil_streampos num_to_read = str->tell();
00090   str->seek( 0 );
00091   char* buffer;
00092   buffer = (char*)malloc( (vcl_size_t) num_to_read+1 );
00093   str->read( (void*)buffer, num_to_read );
00094   buffer[(vcl_size_t) num_to_read] = 0;
00095   return vcl_string( buffer );
00096 }
00097 
00098 void vil_nitf2_array_field::do_dimension( const vil_nitf2_index_vector& in_indices,
00099                                           vil_nitf2_field::field_tree* inTree ) const
00100 {
00101   int dim = next_dimension( in_indices );
00102   for ( int i = 0 ; i < dim ; i++ )
00103   {
00104     //this is the index list we're dealing with in this loop
00105     vil_nitf2_index_vector curr_indices = in_indices;
00106     curr_indices.push_back( i );
00107     //create our tree node and add it to inTree's child list
00108     vil_nitf2_field::field_tree* tr = new vil_nitf2_field::field_tree;
00109     vcl_string tag_str = tag();
00110     vcl_string index_str = index_string( curr_indices );
00111     vcl_string p_name;
00112     if ( index_str == "" ) p_name = pretty_name();
00113     else p_name = "";
00114     tr->columns.push_back( tag_str + index_str );
00115     tr->columns.push_back( p_name );
00116     if( check_index( curr_indices ) ) {
00117       tr->columns.push_back( get_value_string( curr_indices ) );
00118     }
00119     inTree->children.push_back( tr );
00120     //recursive call
00121     do_dimension( curr_indices, tr );
00122   }
00123 }
00124 
00125 vil_nitf2_field::field_tree* vil_nitf2_array_field::get_tree() const
00126 {
00127   field_tree* tr = vil_nitf2_field::get_tree();
00128   do_dimension( vil_nitf2_index_vector(), tr );
00129   return tr;
00130 }

Generated on Thu Jan 10 14:39:59 2008 for core/vil by  doxygen 1.4.4