Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #ifndef VIL_NITF2_TYPED_ARRAY_FIELD_H
00008 #define VIL_NITF2_TYPED_ARRAY_FIELD_H
00009
00010 #include <vcl_map.h>
00011 #include <vcl_iosfwd.h>
00012
00013 #include "vil_nitf2_array_field.h"
00014 #include "vil_nitf2.h"
00015
00016 class vil_nitf2_index_vector;
00017
00018
00019
00020
00021 template<class T>
00022 class vil_nitf2_typed_array_field : public vil_nitf2_array_field
00023 {
00024 public:
00025
00026 vil_nitf2_typed_array_field(int num_dimensions, vil_nitf2_field_definition* field_definition)
00027 : vil_nitf2_array_field(field_definition, num_dimensions) {}
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 bool value(const vil_nitf2_index_vector& indexes, T& out_value) const;
00039
00040
00041
00042
00043 bool read_vector_element(vil_nitf2_istream& input,
00044 const vil_nitf2_index_vector& indexes,
00045 int variable_width);
00046
00047
00048
00049
00050
00051 bool write_vector_element(vil_nitf2_ostream& output,
00052 const vil_nitf2_index_vector& indexes,
00053 int variable_width) const;
00054
00055
00056
00057 virtual vcl_ostream& output(vcl_ostream& os) const;
00058
00059
00060 ~vil_nitf2_typed_array_field() {}
00061
00062 protected:
00063
00064
00065
00066 void output_dimension_iterate(vcl_ostream& os, vil_nitf2_index_vector indexes,
00067 bool& output_yet) const;
00068
00069 private:
00070
00071
00072
00073
00074
00075
00076 vcl_map<vil_nitf2_index_vector, T> m_value_map;
00077 };
00078
00079
00080
00081
00082
00083 #include "vil_nitf2_index_vector.h"
00084 #include "vil_nitf2_field_formatter.h"
00085 #include "vil_nitf2_typed_field_formatter.h"
00086 #include "vil_nitf2_field_definition.h"
00087
00088 template<class T>
00089 bool vil_nitf2_typed_array_field<T>::value(
00090 const vil_nitf2_index_vector& indexes, T& out_value) const
00091 {
00092 if ((int)indexes.size() != m_num_dimensions) {
00093 vcl_cerr << "vil_nitf2_typed_array_field index vector wrong length\n";
00094 return false;
00095 }
00096 typename vcl_map<vil_nitf2_index_vector, T>::const_iterator element = m_value_map.find(indexes);
00097 if (element != m_value_map.end()) {
00098 out_value = element->second;
00099 return true;
00100 } else return false;
00101 }
00102
00103 template<class T>
00104 bool vil_nitf2_typed_array_field<T>::
00105 read_vector_element(vil_nitf2_istream& input, const vil_nitf2_index_vector& indexes,
00106 int variable_width)
00107 {
00108 VIL_NITF2_LOG(log_debug) << "Reading " << tag() << indexes << ": ";
00109 bool is_blank;
00110 if (!check_index(indexes)) {
00111 VIL_NITF2_LOG(log_debug) << "invalid index!" << vcl_endl;
00112 return false;
00113 }
00114 vil_nitf2_field_formatter* formatter = m_definition->formatter;
00115
00116 vil_nitf2_typed_field_formatter<T>* typed_formatter = (vil_nitf2_typed_field_formatter<T>*)formatter;
00117
00118 int saved_field_width = typed_formatter->field_width;
00119 if (variable_width > 0) {
00120 typed_formatter->field_width = variable_width;
00121 }
00122 T val;
00123 bool value_read = typed_formatter->read(input, val, is_blank);
00124 typed_formatter->field_width = saved_field_width;
00125 if (value_read) {
00126 VIL_NITF2_LOG(log_debug) << val << vcl_endl;
00127 m_value_map[indexes] = val;
00128 } else if (is_blank && !m_definition->blanks_ok) {
00129 VIL_NITF2_LOG(log_debug) << "not specified, but required!" << vcl_endl;
00130 } else if (is_blank) {
00131 VIL_NITF2_LOG(log_debug) << "(unspecified)" << vcl_endl;
00132 } else {
00133 VIL_NITF2_LOG(log_debug) << "failed!" << vcl_endl;
00134 return false;
00135 }
00136 return true;
00137 }
00138
00139 template<class T>
00140 bool vil_nitf2_typed_array_field<T>::
00141 write_vector_element(vil_nitf2_ostream& output, const vil_nitf2_index_vector& indexes,
00142 int variable_width) const
00143 {
00144 VIL_NITF2_LOG(log_debug) << "Writing tag " << tag() << indexes << ' ';
00145 if (!check_index(indexes)) {
00146 VIL_NITF2_LOG(log_debug) << ": invalid index!" << vcl_endl;
00147 return false;
00148 }
00149 T val;
00150
00151 vil_nitf2_typed_field_formatter<T>* typed_formatter =
00152 (vil_nitf2_typed_field_formatter<T>*)m_definition->formatter;
00153 if (variable_width > 0) typed_formatter->field_width = variable_width;
00154 bool value_defined = value(indexes, val);
00155 if (value_defined) {
00156 VIL_NITF2_LOG(log_debug) << vcl_endl;
00157 return typed_formatter->write(output, val);
00158 } else {
00159 if (!m_definition->blanks_ok) {
00160 VIL_NITF2_LOG(log_debug) << ": required value undefined at this index; writing blanks." << vcl_endl;
00161 }
00162 return typed_formatter->write_blank(output);
00163 }
00164 }
00165
00166 template<class T>
00167 vcl_ostream& vil_nitf2_typed_array_field<T>::output(vcl_ostream& os) const
00168 {
00169 bool output_yet = false;
00170 output_dimension_iterate(os, vil_nitf2_index_vector(), output_yet);
00171 return os;
00172 }
00173
00174 template<class T>
00175 void vil_nitf2_typed_array_field<T>::output_dimension_iterate(
00176 vcl_ostream& os, vil_nitf2_index_vector indexes, bool& output_yet) const
00177 {
00178 if ((int)indexes.size()==m_num_dimensions) {
00179 T val;
00180 if (value(indexes, val)) {
00181
00182
00183 if (output_yet) {
00184 os << ", ";
00185 } else {
00186 output_yet = true;
00187 }
00188 os << indexes << ' ' << val;
00189 }
00190 } else {
00191 int dim = next_dimension(indexes);
00192 for (int i=0; i < dim; ++i) {
00193 vil_nitf2_index_vector next_indexes(indexes);
00194 next_indexes.push_back(i);
00195 output_dimension_iterate(os, next_indexes, output_yet);
00196 }
00197 os << vcl_endl;
00198 output_yet = false;
00199 }
00200 }
00201
00202 template<class T>
00203 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_typed_array_field<T>& field)
00204 {
00205 return field->output(os);
00206 };
00207
00208
00209 template<>
00210 inline vil_nitf2_typed_array_field<void*>::~vil_nitf2_typed_array_field()
00211 {
00212 for (vcl_map<vil_nitf2_index_vector, void*>::iterator it = m_value_map.begin();
00213 it != m_value_map.end(); ++it)
00214 {
00215
00216 delete[] (char*) it->second;
00217 }
00218 m_value_map.clear();
00219 }
00220
00221 template<>
00222 inline vil_nitf2_typed_array_field<vil_nitf2_location*>::~vil_nitf2_typed_array_field()
00223 {
00224 for (vcl_map<vil_nitf2_index_vector, vil_nitf2_location*>::iterator it = m_value_map.begin();
00225 it != m_value_map.end(); ++it)
00226 {
00227 delete it->second;
00228 }
00229 m_value_map.clear();
00230 }
00231
00232 #endif // VIL_NITF2_TYPED_ARRAY_FIELD_H