vil_nitf2_typed_field_formatter.h
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 #ifndef VIL_NITF2_TYPED_FIELD_FORMATTER_H
6 #define VIL_NITF2_TYPED_FIELD_FORMATTER_H
7 
8 #include <iosfwd>
9 #include <string>
10 #include <sstream>
13 
14 #include <cassert>
15 #ifdef _MSC_VER
16 # include <vcl_msvc_warnings.h>
17 #endif
18 
19 // All subclasses of NITF field formatter derive from this template
20 // The template handles both scalars and vectors of type T.
21 //
22 template<typename T>
24 {
25  public:
26  // Constructor
29 
30  // Destructor
31  ~vil_nitf2_typed_field_formatter() override = default;
32 
33  // Returns a std::vector field of specified dimensionality.
35  int num_dimensions, vil_nitf2_field_definition* field_definition) override;
36 
37  // Returns a new field, read from stream.
38  vil_nitf2_scalar_field* read_field(vil_nitf2_istream& input, bool& out_blank) override;
39 
40  // Writes scalar field to the specified stream.
41  bool write_field(vil_nitf2_ostream& output, const vil_nitf2_scalar_field* field) override;
42 
43  // Attempts to read one instance of field from vil_nitf2_istream into value.
44  // Returns whether value is valid. Sets out_blank to indicate whether the
45  // input read consisted entirely of blanks (in which case false is the
46  // return value). The default implementation converts to a std::stringstream
47  // and calls read(std::istream&). Subclasses either need to overload
48  // this method or read(vil_nitf2_istream&).
49  virtual bool read(vil_nitf2_istream& input, T& out_value, bool& out_blank);
50 
51  // Same as above, but reads value from a std::istream (which, unlike a
52  // vil_nitf2_istream, supports formatted I/O).
53  virtual bool read_vcl_stream(std::istream& input, T& out_value, bool& out_blank);
54 
55  // Write value to a vil_nitf2_ostream. Return success. The default
56  // implementation calls write(std::ostream&). Subclasses need to either
57  // overload this method or define write(std::ostream&). Returns success.
58  virtual bool write(vil_nitf2_ostream& output, const T& value);
59 
60  // Same as above, but writes value to a std::ostream (which, unlike
61  // vil_nitf2_ostream, supports formatted I/O).
62  virtual bool write_vcl_stream(std::ostream& output, const T& value);
63 };
64 
65 //=============================================================================
66 // vil_nitf2_typed_field_formatter implementation
67 //=============================================================================
68 
71 #include "vil_nitf2_index_vector.h"
72 
73 template<typename T>
75  int num_dimensions, vil_nitf2_field_definition* field_definition)
76 {
77  return new vil_nitf2_typed_array_field<T>(num_dimensions, field_definition);
78 }
79 
80 template<typename T>
82  vil_nitf2_istream& input, bool& out_blank)
83 {
84  T value;
85  if (read( input, value, out_blank )) {
86  return new vil_nitf2_typed_scalar_field<T>(value, nullptr);
87  }
88  return nullptr;
89 }
90 
91 template<typename T>
93  vil_nitf2_ostream& output, const vil_nitf2_scalar_field* field)
94 {
95  if (field) {
96  T val;
97  if (field->value(val)) {
98  return write(output, val);
99  }
100  }
101  return false;
102 }
103 
104 template<typename T>
106  vil_nitf2_istream& input, T& out_value, bool& out_blank)
107 {
108  //hackery for non-binary data (convert to string and create a stringstream from it)
109  std::string str = vil_nitf2_field_formatter::read_string(input, field_width);
110  std::stringstream s(str);
111  return read_vcl_stream( s, out_value, out_blank );
112 }
113 
114 template<typename T>
116  std::istream& /* input */, T& /* out_value */, bool& /* out_blank */)
117 {
118  assert(0);
119  return false;
120 }
121 
122 template<typename T>
124  std::ostream& /* output */, const T& /* value */)
125 {
126  assert( 0 );
127  return false;
128 }
129 
130 template<typename T>
132  vil_nitf2_ostream& output, const T& value)
133 {
134  std::stringstream strstr;
135  write_vcl_stream(strstr, value);
136  std::string str = strstr.str();
137  output.write(str.c_str(), str.length());
138  return output.ok();
139 }
140 
141 //=============================================================================
142 // vil_nitf2_type_field_formatter subclasses
143 //=============================================================================
144 
145 // Reads and writes an integer field, with or without sign.
146 //
148 {
149  public:
151 
152  vil_nitf2_field_formatter* copy() const override;
153 
154  // partially overridden read/write methods
157  bool read_vcl_stream(std::istream& input, int& out_value, bool& out_blank) override;
158  bool write_vcl_stream(std::ostream& output, const int& value) override;
159 
160  bool show_sign;
161 };
162 
164 {
165  public:
167 
168  vil_nitf2_field_formatter* copy() const override;
169 
170  // partially overridden read/write methods
173  bool read_vcl_stream(std::istream& input, vil_nitf2_long& out_value, bool& out_blank) override;
174  bool write_vcl_stream(std::ostream& output, const vil_nitf2_long& value) override;
175 
176  bool show_sign;
177 };
178 
179 // Reads and writes a fixed point field, with or without sign, and with
180 // specified precision.
181 //
183 {
184  public:
186 
187  vil_nitf2_field_formatter* copy() const override;
188 
189  // partially overridden read/write methods
192  bool read_vcl_stream(std::istream& input, double& out_value, bool& out_blank) override;
193  bool write_vcl_stream(std::ostream& output, const double& value) override;
194 
196  bool show_sign;
197 };
198 
199 // Reads and writes a floating point field in exponential format: sign, digit,
200 // decimal point, mantissa digits, 'E', sign, exponent digits;
201 // e.g., "+3.1416E+00", which has mantissa width 4 and exponent width 2.
202 //
204 {
205  public:
207 
208  vil_nitf2_field_formatter* copy() const override;
209 
210  // partially overridden read/write methods
213  bool read_vcl_stream(std::istream& input, double& out_value, bool& out_blank) override;
214  bool write_vcl_stream(std::ostream& output, const double& value) override;
215 
218 };
219 
220 // Reads and writes a character field. (I know this seems like overkill,
221 // but it's part of an inheritance hierarchy.)
222 //
224 {
225  public:
227 
228  vil_nitf2_field_formatter* copy() const override;
229 
230  // partially overridden read/write methods
233  bool read_vcl_stream(std::istream& input, char& out_value, bool& out_blank) override;
234  bool write_vcl_stream(std::ostream& output, const char& value) override;
235 };
236 
237 // Reads and writes a binary data field
238 //
240 {
241  public:
242  vil_nitf2_binary_formatter(int width_bytes);
243 
244  vil_nitf2_field_formatter* copy() const override;
245 
246  // partially overridden read/write methods
249 
250  // Overload read() instead of read_vcl_stream() to read binary data without
251  // converting to string, because zero data would prematurely null-terminate
252  // the stringstream.
253  bool read( vil_nitf2_istream& input, void*& out_value, bool& out_blank ) override;
254 
255  /// Overload to write() instead of write_vcl_stream() to write binary data
256  // (see preceding comment).
257  bool write(vil_nitf2_ostream& output, void*const& value) override;
258 };
259 
260 // Reads and writes a std::string field.
261 //
263 {
264  public:
265  // Character sets
267 
268  // Constructor
270 
271  vil_nitf2_field_formatter* copy() const override;
272 
273  // Destructor
274  ~vil_nitf2_string_formatter() override = default;
275 
276  // partially overridden read/write methods
279  bool read_vcl_stream(std::istream& input, std::string& out_value, bool& out_blank ) override;
280  bool write_vcl_stream(std::ostream& output, const std::string& value) override;
281 
282  virtual bool is_valid(std::string value) const;
283 
284  // Member variable
286 };
287 
288 // Helper class for vil_nitf2_enum_string_formatter. Represents a std::string enumeration.
289 //
290 class vil_nitf2_enum_values : public std::map<std::string, std::string>
291 {
292  public:
293  vil_nitf2_enum_values& value(std::string token, std::string pretty_name = "");
294 };
295 
296 // Reads and writes an enumerated std::string field.
297 // To Do: Reimplement this to represent its value using a new class
298 // NitfEnum_value, that outputs its pretty_name by default.
299 //
301 {
302  public:
303  // Constructor
305 
306  vil_nitf2_field_formatter* copy() const override;
307 
308  // Is specified value valid?
309  bool is_valid_value(const std::string& value) const;
310 
311  private:
312  void validate_value_map();
314 };
315 
316 // Reads and write a date/time field.
317 //
319 {
320  public:
321  // Constructor
323 
324  vil_nitf2_field_formatter* copy() const override;
325 
326  // partially overridden read/write methods
329  bool read_vcl_stream(std::istream& input, vil_nitf2_date_time& out_value, bool& out_blank) override;
330  bool write_vcl_stream(std::ostream& output, const vil_nitf2_date_time& value) override;
331 };
332 
333 // Reads and writes a location field.
334 //
336 {
337  public:
338  // Constructor
340 
341  vil_nitf2_field_formatter* copy() const override;
342 
343  // partially overridden read/write methods
346  bool read_vcl_stream(std::istream& input, vil_nitf2_location*& out_value, bool& out_blank) override;
347  bool write_vcl_stream(std::ostream& output, vil_nitf2_location*const& value) override;
348 
349  // Converts overall field width to seconds precision for DMSH formatted
350  // field, ddmmss.sssHdddmmss.sssH
351  static int sec_precision(int field_width) { return (field_width-17)/2; }
352 
353  // Converts overall field width to degrees precision for degrees formatted
354  // field, +dd.ddd+ddd.ddd
355  static int deg_precision(int field_width) { return (field_width-9)/2; }
356 };
357 
358 // Reads and writes a TRE sequence field
359 //
361  public vil_nitf2_typed_field_formatter<vil_nitf2_tagged_record_sequence>
362 {
363  public:
364  // Constructor
366 
367  vil_nitf2_field_formatter* copy() const override;
368 
369  // partially overridden read/write methods
372 
373  // Overload read() instead of read_vcl_stream() to read binary data without
374  // converting to string, because zero data would prematurely null-terminate
375  // the stringstream.
376  bool read( vil_nitf2_istream& input, vil_nitf2_tagged_record_sequence& out_value, bool& out_blank ) override;
377 
378  /// Overload to write() instead of write_vcl_stream() to write binary data
379  // (see preceding comment).
380  bool write(vil_nitf2_ostream& output, const vil_nitf2_tagged_record_sequence& value) override;
381 };
382 
383 #endif // VIL_NITF2_TYPED_FIELD_FORMATTER_H
vil_nitf2_field_formatter * copy() const override
vxl_int_32 vil_nitf2_long
Definition: vil_nitf2.h:26
vil_nitf2_integer_formatter(int field_width, bool show_sign=false)
bool write(vil_nitf2_ostream &output, void *const &value) override
Overload to write() instead of write_vcl_stream() to write binary data.
static std::string read_string(std::istream &input, int length)
vil_nitf2_field_formatter * copy() const override
vil_nitf2_field_formatter * copy() const override
bool write_vcl_stream(std::ostream &output, const vil_nitf2_date_time &value) override
bool read(vil_nitf2_istream &input, vil_nitf2_tagged_record_sequence &out_value, bool &out_blank) override
bool read_vcl_stream(std::istream &input, vil_nitf2_long &out_value, bool &out_blank) override
vil_nitf2_field_formatter * copy() const override
vil_nitf2_exponential_formatter(int mantissa_width, int exponent_width)
vil_nitf2_string_formatter(int field_width, enum_char_set char_set=ECS)
bool write_vcl_stream(std::ostream &output, const double &value) override
vil_nitf2_field_formatter * copy() const override
virtual vil_streampos write(void const *buf, vil_streampos n)=0
Write n bytes from buf. Returns number of bytes written.
bool read_vcl_stream(std::istream &input, vil_nitf2_date_time &out_value, bool &out_blank) override
bool write_vcl_stream(std::ostream &output, const int &value) override
virtual bool is_valid(std::string value) const
vil_nitf2_double_formatter(int field_width, int precision, bool show_sign)
bool read_vcl_stream(std::istream &input, int &out_value, bool &out_blank) override
vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of Stellar Science Ltd.
~vil_nitf2_string_formatter() override=default
bool read(vil_nitf2_istream &input, void *&out_value, bool &out_blank) override
vil_nitf2_enum_string_formatter(int field_width, vil_nitf2_enum_values)
vil_nitf2_field_formatter * copy() const override
virtual bool value(int &) const
Stream interface for VIL image loaders.
Definition: vil_stream.h:21
bool write_vcl_stream(std::ostream &output, const std::string &value) override
vil_nitf2_field_formatter * copy() const override
bool write_field(vil_nitf2_ostream &output, const vil_nitf2_scalar_field *field) override
bool write_vcl_stream(std::ostream &output, const vil_nitf2_long &value) override
vil_nitf2_array_field * create_array_field(int num_dimensions, vil_nitf2_field_definition *field_definition) override
enum_field_type
Definition: vil_nitf2.h:36
bool write_vcl_stream(std::ostream &output, const char &value) override
vil_nitf2_field_formatter * copy() const override
vil_nitf2_field_formatter * copy() const override
vil_nitf2_typed_field_formatter(vil_nitf2::enum_field_type field_type, int field_width)
Typed concrete class for array fields.
virtual bool read_vcl_stream(std::istream &input, T &out_value, bool &out_blank)
virtual bool write_vcl_stream(std::ostream &output, const T &value)
bool write(vil_nitf2_ostream &output, const vil_nitf2_tagged_record_sequence &value) override
Overload to write() instead of write_vcl_stream() to write binary data.
vil_nitf2::enum_field_type field_type
bool read_vcl_stream(std::istream &input, char &out_value, bool &out_blank) override
vil_nitf2_scalar_field * read_field(vil_nitf2_istream &input, bool &out_blank) override
bool write_vcl_stream(std::ostream &output, const double &value) override
virtual bool read(vil_nitf2_istream &input, T &out_value, bool &out_blank)
bool write_vcl_stream(std::ostream &output, vil_nitf2_location *const &value) override
virtual bool ok() const =0
Return false if the stream is broken.
Abstract class for array fields, i.e., fields that occur within a repeat loop.
bool read_vcl_stream(std::istream &input, vil_nitf2_location *&out_value, bool &out_blank) override
vil_nitf2_field_formatter * copy() const override
~vil_nitf2_typed_field_formatter() override=default
bool is_valid_value(const std::string &value) const
bool read_vcl_stream(std::istream &input, double &out_value, bool &out_blank) override
bool read_vcl_stream(std::istream &input, std::string &out_value, bool &out_blank) override
virtual bool write(vil_nitf2_ostream &output, const T &value)
bool read_vcl_stream(std::istream &input, double &out_value, bool &out_blank) override
vil_nitf2_field_formatter * copy() const override
vil_nitf2_long_long_formatter(int field_width, bool show_sign=false)
vil_nitf2_enum_values & value(std::string token, std::string pretty_name="")