core/vil/file_formats/vil_nitf2_array_field.h
Go to the documentation of this file.
00001 //:
00002 // \file
00003 // vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of
00004 // Stellar Science Ltd. Co. (stellarscience.com) for
00005 // Air Force Research Laboratory, 2005.
00006 
00007 #ifndef VIL_NITF2_ARRAY_FIELD_H
00008 #define VIL_NITF2_ARRAY_FIELD_H
00009 
00010 #include <vcl_map.h>
00011 #include <vcl_string.h>
00012 #include "vil_nitf2_field.h"
00013 #include "vil_nitf2_index_vector.h"
00014 
00015 class vil_nitf2_field_definition;
00016 class vil_nitf2_location;
00017 class vil_nitf2_date_time;
00018 
00019 //: Abstract class for array fields, i.e., fields that occur within a repeat loop.
00020 // Since repeat loops can be nested, this field can be multi-dimensional.
00021 // Its row dimensions don't even need to be same. One instance of this
00022 // class "collects" all the values associated with a tag, even though they
00023 // may be interleaved among other values in the NITF file. This class
00024 // provides dimensional information and implements methods common to the
00025 // type-specific subclasses.
00026 
00027 class vil_nitf2_array_field : public vil_nitf2_field
00028 {
00029  public:
00030   // Constructor
00031   vil_nitf2_array_field(vil_nitf2_field_definition* definition, int num_dimensions)
00032     : vil_nitf2_field(definition), m_num_dimensions(num_dimensions) {}
00033 
00034   // Destructor
00035   virtual ~vil_nitf2_array_field() {}
00036 
00037   //: Number of dimensions.
00038   // \returns this vector's number of dimensions, which equals
00039   // its "repeat" nesting level.
00040   int num_dimensions() const;
00041 
00042   //: Given a partial index vector, set the value of the next dimension.
00043   // Length of indexes must be less than num_dimensions(). See comment
00044   // for member m_dimensions_map, below; indexes is its key. For example,
00045   // if indexes is empty, the first dimension is set.
00046   void set_next_dimension(const vil_nitf2_index_vector& indexes, int bound);
00047 
00048   //: Given a partial index vector, return value of next dimension (or zero if none).
00049   // Length of indexes must be less than num_dimensions(). See comment
00050   // for member m_dimensions_map, below; indexes is its key. For
00051   // example, if indexes is empty, the first dimension is retrieved.
00052   int next_dimension(const vil_nitf2_index_vector& indexes) const;
00053 
00054   //: Compares index vector against value dimensions.
00055   bool check_index(const vil_nitf2_index_vector& indexes) const;
00056 
00057   //: Reads from input stream the scalar value at specified index.
00058   // check_index(indexes) must be true, or this will emit an error.
00059   // \returns success.
00060   virtual bool read_vector_element(vil_nitf2_istream& input,
00061                                    const vil_nitf2_index_vector& indexes,
00062                                    int variable_width) = 0;
00063 
00064   //: Writes to output stream the scalar value at specified index.
00065   // check_index(indexes) must be true, of this will emit an error.
00066   // Returns success.  Arg variable_width, if non-negative, overrides
00067   // formatter's field_width.
00068   virtual bool write_vector_element(vil_nitf2_ostream& output,
00069                                     const vil_nitf2_index_vector& indexes,
00070                                     int variable_width) const = 0;
00071 
00072   virtual field_tree* get_tree() const;
00073 
00074   //:
00075   // Sets out_value to the value of the element selected by specified
00076   // index vector, which must satisfy check_index(). Returns true iff the
00077   // value is defined. Note that this may return false because the value
00078   // is unspecified (i.e., blank), even if the index is valid.
00079   //
00080   // Subclasses overload the appropriate method to set out parameter and
00081   // return true. The implementation here return false. These methods are
00082   // defined here for the convenience of my callers, so they don't have to
00083   // downcast to the specific field type.
00084 #if VXL_HAS_INT_64
00085   virtual bool value(const vil_nitf2_index_vector&, vil_nitf2_long& ) const { return false; }
00086 #endif
00087   virtual bool value(const vil_nitf2_index_vector&, int& ) const { return false; }
00088   virtual bool value(const vil_nitf2_index_vector&, double& ) const { return false; }
00089   virtual bool value(const vil_nitf2_index_vector&, char& ) const { return false; }
00090   virtual bool value(const vil_nitf2_index_vector&, void*& ) const { return false; }
00091   virtual bool value(const vil_nitf2_index_vector&, vcl_string& ) const { return false; }
00092   virtual bool value(const vil_nitf2_index_vector&, vil_nitf2_location*& ) const { return false; }
00093   virtual bool value(const vil_nitf2_index_vector&, vil_nitf2_date_time& ) const { return false; }
00094 
00095  protected:
00096   void do_dimension( const vil_nitf2_index_vector& index,
00097                      vil_nitf2_field::field_tree* tr ) const;
00098   vcl_string get_value_string(const vil_nitf2_index_vector& in_indices) const;
00099 
00100 
00101   //: Dimensionality of vector field
00102   int m_num_dimensions;
00103 
00104   //:
00105   // Because a repeating field's dimension can depend on the value of
00106   // another repeating field, slices of a multi-dimensional vector field
00107   // can have varying dimensions (for an example test case, see method
00108   // vil_nitf2_tagged_record::test()). Dimensions are therefore stored
00109   // here as follows:
00110   //   - m_dimensions_map[vector()] holds the first dimension;
00111   //   - m_dimensions_map[vector(i)] holds the second dimension of
00112   //     row i of a 2-or-more-dimensional vector;
00113   //   - m_dimensions_map[vector(i,j)] holds the third dimension of
00114   //     plane (i,j) of a 3-or-more-dimensional vector;
00115   // and so on, according dimensionality of the field.
00116   vcl_map<vil_nitf2_index_vector, int> m_dimensions_map;
00117 };
00118 
00119 #endif // VIL_NITF2_ARRAY_FIELD_H