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 }
1.4.4