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 <utility>
6 #include "vil_nitf2_field_sequence.h"
7 #include "vil_nitf2_index_vector.h"
8 #include "vil_nitf2_field_formatter.h"
9 #include "vil_nitf2_field_definition.h"
10 #include "vil_nitf2_scalar_field.h"
11 #include "vil_nitf2_array_field.h"
12 #include "vil_nitf2_compound_field_value.h"
13
14 #ifdef _MSC_VER
15 # include "vcl_msvc_warnings.h"
16 #endif
17
18 vil_nitf2_field::field_tree *
get_tree(vil_nitf2_field::field_tree * tr) const19 vil_nitf2_field_sequence::get_tree(vil_nitf2_field::field_tree * tr) const
20 {
21 vil_nitf2_field::field_tree * t = tr ? tr : new vil_nitf2_field::field_tree;
22 for (auto i : fields_vector)
23 {
24 t->children.push_back(i->get_tree());
25 }
26 return t;
27 }
28
29 void
insert_field(const std::string & str,vil_nitf2_field * field)30 vil_nitf2_field_sequence::insert_field(const std::string & str, vil_nitf2_field * field)
31 {
32 fields.insert(std::make_pair(str, field));
33 fields_vector.push_back(field);
34 }
35
36 bool
create_array_fields(const vil_nitf2_field_definitions * field_defs,int num_dimensions)37 vil_nitf2_field_sequence::create_array_fields(const vil_nitf2_field_definitions * field_defs, int num_dimensions)
38 {
39 for (auto node : *field_defs)
40 {
41 if (node && node->is_field_definition())
42 {
43 vil_nitf2_field_definition * field_def = node->field_definition();
44 vil_nitf2_array_field * field = field_def->formatter->create_array_field(num_dimensions, field_def);
45 if (field)
46 {
47 insert_field(field_def->tag, field);
48 }
49 else
50 {
51 std::cerr << "vil_nitf2_field_sequence:create_array_fields(): Error created required std::vector field "
52 << field_def->tag << "; bailing out.\n";
53 return false;
54 }
55 }
56 else if (node && node->is_repeat_node())
57 {
58 // recursively create nested vector fields
59 vil_nitf2_field_definition_repeat_node * repeat_node = node->repeat_node();
60 if (!create_array_fields(repeat_node->field_definitions, num_dimensions + 1))
61 {
62 return false;
63 }
64 }
65 else
66 {
67 std::cerr << "vil_nitf2_field_sequence::create_array_fields(): unsupported node type!\n";
68 return false;
69 }
70 }
71 return true;
72 }
73
74 void
set_array_fields_dimension(const vil_nitf2_field_definitions * field_defs,const vil_nitf2_index_vector & index,int repeat_count)75 vil_nitf2_field_sequence::set_array_fields_dimension(const vil_nitf2_field_definitions * field_defs,
76 const vil_nitf2_index_vector & index,
77 int repeat_count)
78 {
79 for (auto node : *field_defs)
80 {
81 if (node && node->is_field_definition())
82 {
83 vil_nitf2_field_definition * field_def = node->field_definition();
84 vil_nitf2_array_field * field = get_field(field_def->tag)->array_field();
85 if (field)
86 {
87 VIL_NITF2_LOG(log_debug) << " (Setting tag " << field_def->tag << " dimension " << index << " to "
88 << repeat_count << ".)" << std::endl;
89 field->set_next_dimension(index, repeat_count);
90 }
91 else
92 {
93 std::cerr << "vil_nitf2_field_sequence:set_array_field_dimension(): array field " << field_def->tag
94 << " not found!\n";
95 }
96 }
97 else if (node && node->is_repeat_node())
98 {
99 // recursively set dimension vector fields
100 vil_nitf2_field_definition_repeat_node * repeat_node = node->repeat_node();
101 set_array_fields_dimension(repeat_node->field_definitions, index, repeat_count);
102 }
103 else
104 {
105 std::cerr << "vil_nitf2_field_sequence::set_array_fields_dimension(): unsupported node type!\n";
106 }
107 }
108 }
109
110 bool
read(vil_nitf2_istream & input,const vil_nitf2_field_definitions * field_defs,const vil_nitf2_index_vector & indexes)111 vil_nitf2_field_sequence::read(vil_nitf2_istream & input,
112 const vil_nitf2_field_definitions * field_defs,
113 const vil_nitf2_index_vector & indexes)
114 {
115 if (!field_defs)
116 field_defs = m_field_definitions;
117 if (!field_defs)
118 std::cerr << "vil_nitf2_field_sequence::read() missing field definitions!\n";
119 bool error = false;
120 for (auto node : *field_defs)
121 {
122 if (node && node->is_field_definition())
123 {
124 vil_nitf2_field_definition * field_def = node->field_definition();
125 // The field exists if it is required, or if it is conditional and
126 // the condition is true.
127 bool field_exists;
128 if (field_def->is_required())
129 {
130 field_exists = true;
131 }
132 else
133 {
134 bool condition;
135 bool conditionValid = (*(field_def->condition_functor))(this, indexes, condition);
136 if (conditionValid)
137 {
138 field_exists = condition;
139 }
140 else
141 {
142 // Cannot evaluate condition; therefore I don't know whether this
143 // field exists and cannot reliably parse the rest of the record
144 std::cerr << "vil_nitf2_field_sequence::read(): Cannot evaluate condition for tag " << field_def->tag << '\n';
145 error = true;
146 break;
147 }
148 }
149 if (field_exists)
150 {
151 // Evaluate its width functor, if any.
152 int variable_width = -1;
153 if (field_def->width_functor != nullptr)
154 {
155 bool computed_width = (*(field_def->width_functor))(this, indexes, variable_width);
156 if (!computed_width)
157 {
158 // Cannot evaluate width functor; therefore I don't know the length
159 // of this field and cannot reliably parse the rest of the record
160 std::cerr << "vil_nitf2_field_sequence::read(): Cannot evaluate width functor for tag " << field_def->tag
161 << '\n';
162 error = true;
163 break;
164 }
165 }
166 if (variable_width == 0)
167 {
168 VIL_NITF2_LOG(log_debug) << "Skipping field " << field_def->tag << ", whose length = 0." << std::endl;
169 }
170 else
171 {
172 // Either there is no width functor, in which case variable_width = -1 and will be ignored,
173 // or there is a width functor, and the resulting positive variable_width will be applied.
174 if (indexes.empty())
175 {
176 // read scalar field
177 bool fieldReadError;
178 vil_nitf2_scalar_field * field =
179 vil_nitf2_scalar_field::read(input, field_def, variable_width, &fieldReadError);
180 if (field)
181 {
182 insert_field(field_def->tag, field);
183 }
184 if (fieldReadError)
185 {
186 error = true;
187 break;
188 }
189 }
190 else
191 {
192 // read vector field element
193 bool read_error = true;
194 vil_nitf2_field_definition * field_def = node->field_definition();
195 if (field_def)
196 {
197 vil_nitf2_array_field * field = get_field(field_def->tag)->array_field();
198 if (field)
199 {
200 if (field->read_vector_element(input, indexes, variable_width))
201 {
202 read_error = false;
203 }
204 }
205 }
206 if (read_error)
207 {
208 std::cerr << "vil_nitf2_field_sequence::read(): Couldn't find std::vector field!\n";
209 return false;
210 }
211 }
212 }
213 // TO DO: Check that the expected amount of data was read; if not,
214 // try to recover.
215 }
216 }
217 else if (node && node->is_repeat_node())
218 {
219 vil_nitf2_field_definition_repeat_node * repeat_node = node->repeat_node();
220
221 // Compute how many times it repeats
222 int repeat_count = 0;
223 bool computed_repeat = false;
224 if (repeat_node->repeat_functor != nullptr)
225 {
226 computed_repeat = (*(repeat_node->repeat_functor))(this, indexes, repeat_count);
227 }
228 if (!computed_repeat)
229 {
230 // Cannot evaluate repeat count; therefore I don't know the length
231 // of this field and cannot reliably parse the rest of the record
232 std::cerr << "Cannot evaluate repeat count for repeat node\n";
233 error = true;
234 break;
235 }
236 // On the first call to this method, call create_array_fields to loop
237 // recursively over the field definitions to create all vector fields.
238 // All nested fields need to be defined before any values are read. This is
239 // is so that we can start setting the bounds on outer dimensions of
240 // nested field at the top of each repeat loop.
241 //
242 // For example, for this field sequence:
243 // REPEAT i=1..N
244 // FIELD A(i)
245 // REPEAT j=1..A(i)
246 // FIELD B(i,j)
247 // the following call to create_array_fields sets up fields
248 // A (with 1 dimension) and B (with 2 dimensions).
249 if (indexes.empty())
250 {
251 if (!create_array_fields(repeat_node->field_definitions, 1))
252 {
253 return false;
254 }
255 }
256 // Loop repeat_count times over fields to read the elements
257 std::string nesting_level_indicator((indexes.size() + 1) * 2, '-');
258 VIL_NITF2_LOG(log_debug) << nesting_level_indicator << "Repeating fields " << repeat_count
259 << " times:" << std::endl;
260 for (int i = 0; i < repeat_count; ++i)
261 {
262 // The first time through the repeat loop, set the dimension
263 // bounds of all fields, including repeated fields. So, for the
264 // example above, during the first call to this method read(),
265 // the invocation of set_fields_bounds() will set:
266 // A.dimension(vector()) = N
267 // B.dimension(vector()) = N
268 // During the recursive calls to read(), the two invocations of
269 // set_field_bounds() will set:
270 // B.dimension(vector(1)) = A(1)
271 // B.dimension(vector(2)) = A(2)
272 // Actually, the indexes are zero-based, but this gives the general
273 // idea.
274 if (i == 0)
275 {
276 set_array_fields_dimension(repeat_node->field_definitions, indexes, repeat_count);
277 }
278
279 // Now call myself recursively to read the vector field elements
280 vil_nitf2_index_vector nested_indexes(indexes);
281 nested_indexes.push_back(i);
282 if (!read(input, repeat_node->field_definitions, nested_indexes))
283 {
284 return false;
285 }
286 }
287 VIL_NITF2_LOG(log_debug) << nesting_level_indicator << "End repeating fields." << std::endl;
288 }
289 else
290 {
291 std::cerr << "vil_nitf2_tagged_record::read(): unsupported node.\n";
292 }
293 }
294 return !error;
295 }
296
297 bool
write(vil_nitf2_ostream & output,const vil_nitf2_field_definitions * field_defs,vil_nitf2_index_vector indexes)298 vil_nitf2_field_sequence::write(vil_nitf2_ostream & output,
299 const vil_nitf2_field_definitions * field_defs,
300 vil_nitf2_index_vector indexes)
301 {
302 if (!field_defs)
303 field_defs = m_field_definitions;
304 if (!field_defs)
305 std::cerr << "vil_nitf2_field_sequence::write(): Missing field definitions!\n";
306 for (auto node : *field_defs)
307 {
308 if (node && node->is_field_definition())
309 {
310 vil_nitf2_field_definition * field_def = node->field_definition();
311 if (!field_def)
312 {
313 std::cerr << "vil_nitf2_field_sequence::write(): Missing field definition!\n";
314 return false;
315 }
316 vil_nitf2_field * field = get_field(field_def->tag);
317
318 // Determine whether the field is required or is a conditional field
319 // whose condition is satisfied
320 bool expected = field_def->is_required();
321 if (!expected)
322 {
323 bool condition;
324 if ((*field_def->condition_functor)(this, indexes, condition))
325 {
326 expected |= condition;
327 }
328 else
329 {
330 std::cerr << "vil_nitf2_field_sequence::write(): Cound not evaluate condition for field " << field_def->tag
331 << std::endl;
332 // Cannot evaluate condition, therefore I can't tell whether this
333 // field should exist.
334 return false;
335 }
336 }
337 if (field && !expected)
338 {
339 std::cerr << "vil_nitf2_field_sequence::write(): Field " << field_def->tag
340 << " is being ignored because its condition is not satisfied.\n";
341 }
342 else
343 {
344 // Will emit field. Evaluate its width functor, if any.
345 int variable_width = -1;
346 if (field_def->width_functor != nullptr)
347 {
348 bool computed_width = (*(field_def->width_functor))(this, indexes, variable_width);
349 if (!computed_width)
350 {
351 // Cannot evaluate width functor; therefore I don't know the length
352 // of this field and cannot reliably parse the rest of the record
353 std::cerr << "vil_nitf2_field_sequence::write(): Cannot evaluate width functor for tag " << field_def->tag
354 << std::endl;
355 return false;
356 }
357 }
358 if (variable_width == 0)
359 {
360 VIL_NITF2_LOG(log_debug) << "Skipping field " << field_def->tag << ", whose length = 0." << std::endl;
361 }
362 else
363 {
364 // Either there is no width functor, in which case variable_width = -1 and will be ignored,
365 // or there is a width functor, and the resulting positive variable_width will be applied.
366 if (!field && expected)
367 {
368 if (!field_def->blanks_ok)
369 {
370 std::cerr << "vil_nitf2_field_sequence::write(): Field " << field_def->tag
371 << " is unspecified; writing blanks.\n";
372 }
373 if (variable_width > 0)
374 field_def->formatter->field_width = variable_width;
375 field_def->formatter->write_blank(output);
376 }
377 else if (field)
378 {
379 if (field->scalar_field())
380 {
381 field->scalar_field()->write(output, variable_width);
382 }
383 else
384 {
385 field->array_field()->write_vector_element(output, indexes, variable_width);
386 }
387 }
388 }
389 }
390 }
391 else if (node && node->is_repeat_node())
392 {
393 vil_nitf2_field_definition_repeat_node * repeat_node = node->repeat_node();
394 // Compute how many times it repeats
395 int repeat_count = 0;
396 bool computed_repeat = false;
397 if (repeat_node->repeat_functor != nullptr)
398 {
399 computed_repeat = (*(repeat_node->repeat_functor))(this, indexes, repeat_count);
400 }
401 if (!computed_repeat)
402 {
403 // Cannot evaluate repeat count; therefore I don't know the length
404 // of this field.
405 std::cerr << "vil_nitf2_field_sequence::write(): Cannot evaluate repeat count for repeat node\n";
406 return false;
407 }
408 if (repeat_node->field_definitions)
409 {
410 for (int i = 0; i < repeat_count; ++i)
411 {
412 vil_nitf2_index_vector nested_indexes(indexes);
413 nested_indexes.push_back(i);
414 this->write(output, repeat_node->field_definitions, nested_indexes);
415 }
416 }
417 }
418 else
419 {
420 std::cerr << "vil_nitf2_field_sequence::write(): Ignoring unsupported node.\n";
421 }
422 }
423 return true;
424 }
425
~vil_nitf2_field_sequence()426 vil_nitf2_field_sequence::~vil_nitf2_field_sequence()
427 {
428 // Delete fields, which I own
429 for (auto & field_map_entry : fields)
430 {
431 vil_nitf2_field * field = field_map_entry.second;
432 delete field;
433 }
434 }
435
436 vil_nitf2_field *
get_field(const std::string & tag) const437 vil_nitf2_field_sequence::get_field(const std::string & tag) const
438 {
439 auto field_map_entry = fields.find(tag);
440 if (field_map_entry == fields.end())
441 return nullptr;
442 return field_map_entry->second;
443 }
444
445 // Who needs templated functions when we have macros!
446 #define NITF_FIELD_SEQ_GET_VALUE(T) \
447 bool vil_nitf2_field_sequence::get_value(std::string tag, T & out_value) const \
448 { \
449 vil_nitf2_field * field = get_field(tag); \
450 vil_nitf2_scalar_field * scalar_field = field ? field->scalar_field() : 0; \
451 if (!scalar_field) \
452 { \
453 /*std::cerr << "vil_nitf2_field_sequence::get_value(" << tag << "): scalar field not found.\n";*/ \
454 return false; \
455 } \
456 if (!scalar_field->value(out_value)) \
457 { \
458 std::cerr << "vil_nitf2_field_sequence::get_value(" << tag << ") called with wrong type.\n"; \
459 return false; \
460 } \
461 return true; \
462 }
463
464 NITF_FIELD_SEQ_GET_VALUE(int)
465 NITF_FIELD_SEQ_GET_VALUE(double)
466 NITF_FIELD_SEQ_GET_VALUE(char)
467 NITF_FIELD_SEQ_GET_VALUE(void *)
468 NITF_FIELD_SEQ_GET_VALUE(std::string)
469 NITF_FIELD_SEQ_GET_VALUE(vil_nitf2_location *)
470 NITF_FIELD_SEQ_GET_VALUE(vil_nitf2_date_time)
471 NITF_FIELD_SEQ_GET_VALUE(vil_nitf2_tagged_record_sequence)
472
473 #define NITF_FIELD_SEQ_GET_ARRAY_VALUE(T) \
474 bool vil_nitf2_field_sequence::get_value( \
475 std::string tag, const vil_nitf2_index_vector & indexes, T & out_value, bool ignore_extra_indexes) const \
476 { \
477 vil_nitf2_field * field = get_field(tag); \
478 if (!field) \
479 { \
480 /*std::cerr << "vil_nitf2_field_sequence::get_value(" << tag << ", const vil_nitf2_index_vector&): tag not \
481 * found.\n"; */ \
482 return false; \
483 } \
484 vil_nitf2_index_vector trimmed_indexes(indexes); \
485 if (ignore_extra_indexes && (int)indexes.size() > field->num_dimensions()) \
486 { \
487 trimmed_indexes.resize(field->num_dimensions()); \
488 } \
489 if (trimmed_indexes.size() == 0) \
490 { \
491 return field->scalar_field() && field->scalar_field()->value(out_value); \
492 } \
493 else \
494 { \
495 return field->array_field()->value(trimmed_indexes, out_value); \
496 } \
497 }
498
499 NITF_FIELD_SEQ_GET_ARRAY_VALUE(int) // expanded below for debugging
500 NITF_FIELD_SEQ_GET_ARRAY_VALUE(double)
501 NITF_FIELD_SEQ_GET_ARRAY_VALUE(char)
502 NITF_FIELD_SEQ_GET_ARRAY_VALUE(void *)
503 NITF_FIELD_SEQ_GET_ARRAY_VALUE(std::string)
504 NITF_FIELD_SEQ_GET_ARRAY_VALUE(vil_nitf2_location *)
505 NITF_FIELD_SEQ_GET_ARRAY_VALUE(vil_nitf2_date_time)
506
507 // Macro to generate overloads of get_values(), since VXL coding
508 // standards forbid using templated member functions.
509 //
510 #define NITF_FIELD_SEQ_GET_VALUES(T) \
511 bool vil_nitf2_field_sequence::get_values( \
512 std::string tag, const vil_nitf2_index_vector & indexes, std::vector<T> & out_values, bool clear_out_values) const \
513 { \
514 vil_nitf2_field * field = get_field(tag); \
515 if (!field) \
516 { \
517 /*std::cerr << "vil_nitf2_field_sequence::get_value(" << tag << ", const vil_nitf2_index_vector&): tag not \
518 * found.\n"; */ \
519 return false; \
520 } \
521 if (clear_out_values) \
522 { \
523 out_values.clear(); \
524 } \
525 int num_dims = field->num_dimensions(); \
526 if (num_dims == (int)indexes.size()) \
527 { \
528 /* get single value */ \
529 T value; \
530 if (get_value(tag, indexes, value, false)) \
531 { \
532 out_values.push_back(value); \
533 return true; \
534 } \
535 else \
536 { \
537 return false; \
538 } \
539 } \
540 else \
541 { \
542 vil_nitf2_array_field * array_field = field->array_field(); \
543 if (!array_field) \
544 { \
545 /* indexes is too long */ \
546 return false; \
547 } \
548 /* traverse value tree depth-first, collecting values into out_values */ \
549 int dimension = array_field->next_dimension(indexes); \
550 for (int index = 0; index < dimension; ++index) \
551 { \
552 vil_nitf2_index_vector next_indexes = indexes; \
553 next_indexes.push_back(index); \
554 if (!get_values(tag, next_indexes, out_values, false)) \
555 { \
556 return false; \
557 } \
558 } \
559 return true; \
560 } \
561 } \
562 \
563 bool vil_nitf2_field_sequence::get_values(std::string tag, std::vector<T> & out_values) const \
564 { \
565 return get_values(tag, vil_nitf2_index_vector(), out_values, true); \
566 }
567
568 NITF_FIELD_SEQ_GET_VALUES(int)
569 NITF_FIELD_SEQ_GET_VALUES(double)
570 NITF_FIELD_SEQ_GET_VALUES(char)
571 NITF_FIELD_SEQ_GET_VALUES(void *)
572 NITF_FIELD_SEQ_GET_VALUES(std::string)
573 NITF_FIELD_SEQ_GET_VALUES(vil_nitf2_location *)
574 NITF_FIELD_SEQ_GET_VALUES(vil_nitf2_date_time)
575
576 #if VXL_HAS_INT_64
577 // if not VXL_HAS_INT_64 isn't defined the vil_nitf2_long is the same as just plain 'int'
578 // and this function will be a duplicate of that get_value
579 NITF_FIELD_SEQ_GET_VALUE(vil_nitf2_long)
580 NITF_FIELD_SEQ_GET_ARRAY_VALUE(vil_nitf2_long)
581 NITF_FIELD_SEQ_GET_VALUES(vil_nitf2_long)
582 #endif
583