vil_nitf2_array_field.cxx
Go to the documentation of this file.
1 // vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of
2 // Stellar Science Ltd. Co. (stellarscience.com) for
3 // Air Force Research Laboratory, 2005.
4 
5 #include <cstddef>
6 #include <sstream>
7 #include <cstdlib>
10 #include "vil_nitf2_index_vector.h"
11 
12 #ifdef _MSC_VER
13 # include <vcl_msvc_warnings.h>
14 #endif
15 #include <vil/vil_stream_core.h>
16 
18 {
19  return m_num_dimensions;
20 }
21 
24 {
25  auto dimension_bounds_entry = m_dimensions_map.find(index);
26  if (dimension_bounds_entry != m_dimensions_map.end()) {
27  return dimension_bounds_entry->second;
28  } else {
29  return 0;
30  }
31 }
32 
35 {
36  if ((int)index.size() >= m_num_dimensions) {
37  std::cerr << "vil_nitf2_array_field::set_next_dimension"
38  << index << ": invalid partial index!\n";
39  return;
40  }
41  if (next_dimension(index) > 0) {
42  std::cerr << "vil_nitf2_array_field::set_next_dimension"
43  << index << ": bound previously set!\n";
44  }
45  m_dimensions_map[index] = bound;
46 }
47 
49 check_index(const vil_nitf2_index_vector& indexes) const
50 {
51  if ((int)indexes.size() != m_num_dimensions) {
52  std::cerr << "index length does not match value dimensions!\n";
53  return false;
54  }
55  // Remove the last element from index and look it up in the dimensions map.
56  // Then check if the removed element is less than the returned dimension bound.
57  // If no dimension bound is found, then one of the other index values is
58  // invalid.
59  vil_nitf2_index_vector dimension_index;
60  for (int dim=0; dim < m_num_dimensions-1; ++dim) {
61  dimension_index.push_back(indexes[dim]);
62  }
63  int dimension_bound = next_dimension(dimension_index);
64  int last_index = indexes[indexes.size()-1];
65  if (last_index < dimension_bound) {
66  return true;
67  } else {
68  std::cerr << "Tag " << tag() << indexes << ": index out of bounds!\n";
69  return false;
70  }
71 }
72 
73 std::string int_to_string( int i )
74 {
75  std::stringstream s;
76  s << i;
77  return s.str();
78 }
79 
80 std::string index_string( const vil_nitf2_index_vector& indices )
81 {
82  std::string ret_val = "";
83  for ( unsigned int i = 0 ; i < indices.size() ; i++ ){
84  ret_val += "[" + int_to_string( indices[i] ) + "]";
85  }
86  return ret_val;
87 }
88 
90 {
91  auto* str = new vil_stream_core;
92  write_vector_element( *str, in_indices, -1 );
93  vil_streampos num_to_read = str->tell();
94  str->seek( 0 );
95  char* buffer;
96  buffer = (char*)std::malloc( (std::size_t) num_to_read+1 );
97  str->read( (void*)buffer, num_to_read );
98  buffer[(std::size_t) num_to_read] = 0;
99  return std::string( buffer );
100 }
101 
103  vil_nitf2_field::field_tree* inTree ) const
104 {
105  int dim = next_dimension( in_indices );
106  for ( int i = 0 ; i < dim ; i++ )
107  {
108  //this is the index list we're dealing with in this loop
109  vil_nitf2_index_vector curr_indices = in_indices;
110  curr_indices.push_back( i );
111  //create our tree node and add it to inTree's child list
112  auto* tr = new vil_nitf2_field::field_tree;
113  std::string tag_str = tag();
114  std::string index_str = index_string( curr_indices );
115  std::string p_name;
116  if ( index_str == "" ) p_name = pretty_name();
117  else p_name = "";
118  tr->columns.push_back( tag_str + index_str );
119  tr->columns.push_back( p_name );
120  if( check_index( curr_indices ) ) {
121  tr->columns.push_back( get_value_string( curr_indices ) );
122  }
123  inTree->children.push_back( tr );
124  //recursive call
125  do_dimension( curr_indices, tr );
126  }
127 }
128 
130 {
133  return tr;
134 }
virtual field_tree * get_tree() const
int next_dimension(const vil_nitf2_index_vector &indexes) const
Given a partial index vector, return value of next dimension (or zero if none).
void do_dimension(const vil_nitf2_index_vector &index, vil_nitf2_field::field_tree *tr) const
std::string tag() const
vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of Stellar Science Ltd.
std::string int_to_string(int i)
bool check_index(const vil_nitf2_index_vector &indexes) const
Compares index vector against value dimensions.
An in-core vil_stream implementation.
virtual bool write_vector_element(vil_nitf2_ostream &output, const vil_nitf2_index_vector &indexes, int variable_width) const =0
Writes to output stream the scalar value at specified index.
std::vector< field_tree * > children
vxl_int_32 vil_streampos
Definition: vil_stream.h:16
std::string get_value_string(const vil_nitf2_index_vector &in_indices) const
std::string pretty_name() const
void set_next_dimension(const vil_nitf2_index_vector &indexes, int bound)
Given a partial index vector, set the value of the next dimension.
std::string index_string(const vil_nitf2_index_vector &indices)
field_tree * get_tree() const override
int m_num_dimensions
Dimensionality of vector field.
An in-core vil_stream implementation.
int num_dimensions() const override
Number of dimensions.
std::map< vil_nitf2_index_vector, int > m_dimensions_map
Because a repeating field's dimension can depend on the value of another repeating field,...