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 }
00101 else return false;
00102 }
00103
00104 template<class T>
00105 bool vil_nitf2_typed_array_field<T>::
00106 read_vector_element(vil_nitf2_istream& input, const vil_nitf2_index_vector& indexes,
00107 int variable_width)
00108 {
00109 VIL_NITF2_LOG(log_debug) << "Reading " << tag() << indexes << ": ";
00110 bool is_blank;
00111 if (!check_index(indexes)) {
00112 VIL_NITF2_LOG(log_debug) << "invalid index!" << vcl_endl;
00113 return false;
00114 }
00115 vil_nitf2_field_formatter* formatter = m_definition->formatter;
00116
00117 vil_nitf2_typed_field_formatter<T>* typed_formatter = (vil_nitf2_typed_field_formatter<T>*)formatter;
00118
00119 int saved_field_width = typed_formatter->field_width;
00120 if (variable_width > 0) {
00121 typed_formatter->field_width = variable_width;
00122 }
00123 T val;
00124 bool value_read = typed_formatter->read(input, val, is_blank);
00125 typed_formatter->field_width = saved_field_width;
00126 if (value_read) {
00127 VIL_NITF2_LOG(log_debug) << val << vcl_endl;
00128 m_value_map[indexes] = val;
00129 }
00130 else if (is_blank && !m_definition->blanks_ok) {
00131 VIL_NITF2_LOG(log_debug) << "not specified, but required!" << vcl_endl;
00132 }
00133 else if (is_blank) {
00134 VIL_NITF2_LOG(log_debug) << "(unspecified)" << vcl_endl;
00135 }
00136 else {
00137 VIL_NITF2_LOG(log_debug) << "failed!" << vcl_endl;
00138 return false;
00139 }
00140 return true;
00141 }
00142
00143 template<class T>
00144 bool vil_nitf2_typed_array_field<T>::
00145 write_vector_element(vil_nitf2_ostream& output, const vil_nitf2_index_vector& indexes,
00146 int variable_width) const
00147 {
00148 VIL_NITF2_LOG(log_debug) << "Writing tag " << tag() << indexes << ' ';
00149 if (!check_index(indexes)) {
00150 VIL_NITF2_LOG(log_debug) << ": invalid index!" << vcl_endl;
00151 return false;
00152 }
00153 T val;
00154
00155 vil_nitf2_typed_field_formatter<T>* typed_formatter =
00156 (vil_nitf2_typed_field_formatter<T>*)m_definition->formatter;
00157 if (variable_width > 0) typed_formatter->field_width = variable_width;
00158 bool value_defined = value(indexes, val);
00159 if (value_defined) {
00160 VIL_NITF2_LOG(log_debug) << vcl_endl;
00161 return typed_formatter->write(output, val);
00162 }
00163 else {
00164 if (!m_definition->blanks_ok) {
00165 VIL_NITF2_LOG(log_debug) << ": required value undefined at this index; writing blanks." << vcl_endl;
00166 }
00167 return typed_formatter->write_blank(output);
00168 }
00169 }
00170
00171 template<class T>
00172 vcl_ostream& vil_nitf2_typed_array_field<T>::output(vcl_ostream& os) const
00173 {
00174 bool output_yet = false;
00175 output_dimension_iterate(os, vil_nitf2_index_vector(), output_yet);
00176 return os;
00177 }
00178
00179 template<class T>
00180 void vil_nitf2_typed_array_field<T>::output_dimension_iterate(
00181 vcl_ostream& os, vil_nitf2_index_vector indexes, bool& output_yet) const
00182 {
00183 if ((int)indexes.size()==m_num_dimensions) {
00184 T val;
00185 if (value(indexes, val)) {
00186
00187
00188 if (output_yet) {
00189 os << ", ";
00190 }
00191 else {
00192 output_yet = true;
00193 }
00194 os << indexes << ' ' << val;
00195 }
00196 }
00197 else {
00198 int dim = next_dimension(indexes);
00199 for (int i=0; i < dim; ++i) {
00200 vil_nitf2_index_vector next_indexes(indexes);
00201 next_indexes.push_back(i);
00202 output_dimension_iterate(os, next_indexes, output_yet);
00203 }
00204 os << vcl_endl;
00205 output_yet = false;
00206 }
00207 }
00208
00209 template<class T>
00210 vcl_ostream& operator << (vcl_ostream& os, const vil_nitf2_typed_array_field<T>& field)
00211 {
00212 return field->output(os);
00213 };
00214
00215
00216 template<>
00217 inline vil_nitf2_typed_array_field<void*>::~vil_nitf2_typed_array_field()
00218 {
00219 for (vcl_map<vil_nitf2_index_vector, void*>::iterator it = m_value_map.begin();
00220 it != m_value_map.end(); ++it)
00221 {
00222
00223 delete[] (char*) it->second;
00224 }
00225 m_value_map.clear();
00226 }
00227
00228 template<>
00229 inline vil_nitf2_typed_array_field<vil_nitf2_location*>::~vil_nitf2_typed_array_field()
00230 {
00231 for (vcl_map<vil_nitf2_index_vector, vil_nitf2_location*>::iterator it = m_value_map.begin();
00232 it != m_value_map.end(); ++it)
00233 {
00234 delete it->second;
00235 }
00236 m_value_map.clear();
00237 }
00238
00239 #endif // VIL_NITF2_TYPED_ARRAY_FIELD_H