13 # include <vcl_msvc_warnings.h> 30 return length_definition;
37 return tag_definition;
43 return length_formatter;
56 else return "<Unknown>";
62 else return "<unknown>";
68 if (record->read(input)) {
82 std::cerr <<
"Error reading extension tag at offset " << input.
tell() <<
".\n";
92 std::cerr <<
"Error reading extension length for tag " << cetag <<
".\n";
103 if (record_definition ==
nullptr) {
104 VIL_NITF2_LOG(log_info) <<
"Skipping unknown record " << cetag <<
".\n";
120 if (input.
tell() != expected_pos) {
121 std::cerr <<
"vil_nitf2_tagged_record::read(): Read " << input.
tell() - record_data_start_pos
122 <<
" bytes instead of " <<
m_length <<
" as expected in "<<cetag<<
".\n";
125 input.
seek(expected_pos);
188 #define VIL_NITF2_TAGGED_RECORD_GET_VALUES(T) \ 189 bool vil_nitf2_tagged_record::get_values(std::string tag, const vil_nitf2_index_vector& indexes, \ 190 std::vector<T>& out_values, bool clear_out_values) const \ 191 { return m_field_sequence->get_values(tag, indexes, out_values, clear_out_values); } \ 192 bool vil_nitf2_tagged_record::get_values(std::string tag, std::vector<T>& out_values) const \ 193 { return m_field_sequence->get_values(tag, out_values); } 208 : m_length_field(nullptr), m_tag_field(nullptr), m_length(0), m_definition(nullptr), m_field_sequence(nullptr)
216 const char* test_tre_tag =
"@TEST@";
224 .
field(
"SQUINT_ANGLE",
"Squint Angle",
NITF_DBL(6, 2,
true),
true)
226 .
field(
"TGT_CAT",
"Target Classification Category",
228 .value(
"H",
"Helicopter")
229 .value(
"T",
"Tracked")
230 .value(
"U",
"Unknown")
231 .value(
"W",
"Wheeled")
232 .value(
"TOO LONG",
"Too long value test")
233 .value(
"T",
"Duplicate value test")))
236 .field(
"TGT_n_SPEED",
"Target Estimated Ground Speed",
NITF_INT(4),
true)
237 .field(
"TGT_n_CAT",
"Target Classification Category",
239 .value(
"H",
"Helicopter")
240 .value(
"T",
"Tracked")
241 .value(
"U",
"Unknown")
242 .value(
"W",
"Wheeled")),
248 .
field(
"CLASS",
"Security Classification",
250 .value(
"T",
"Top Secret")
251 .value(
"S",
"Secret")
252 .value(
"C",
"Confindential")
253 .value(
"R",
"Restricted")
254 .value(
"U",
"Unclassified")),
255 true,
nullptr,
nullptr)
262 .
field(
"XBANDS",
"Large number of bands",
NITF_INT(2),
false,
267 .field(
"BAND_LTR",
"Band Description",
NITF_CHAR(),
true,
270 .
field(
"EXP_TEST",
"Exponential format test",
NITF_EXP(6,1))
275 .field(
"A",
"Test repeat A",
NITF_INT(1))
277 .field(
"S",
"Test repeat S",
NITF_STR(3)))
284 .field(
"D",
"Test fixed repeat",
NITF_INT(1))
288 std::string testFieldsStr =
293 "+89.111111-159.222222" 294 "890102.33N0091122.00W" 335 std::stringstream test_stream;
336 test_stream << test_tre_tag;
337 test_stream << std::setw(5) << std::setfill(
'0') << testFieldsStr.length();
338 test_stream << testFieldsStr;
339 std::string read_string = test_stream.str();
342 vs->write(read_string.c_str(), read_string.length());
349 std::cerr << *record <<
'\n';
351 std::cerr <<
"\nOriginal string:\n" << read_string
352 <<
"\nWrite() output:\n";
356 char* buf =
new char[(
unsigned int)bufsize + 1];
358 vs2->
read(buf, bufsize);
360 std::string write_string = std::string(buf);
361 std::cerr << write_string <<
'\n';
362 if (read_string != write_string) {
363 std::cerr <<
"\nWrite failed!\n";
367 std::cerr <<
"Testing get_value:\n";
369 if (!record->get_value(
"MTI_DP", mti_dp) || mti_dp!=2) {
370 std::cerr <<
"Get value failed!\n";
374 std::cerr <<
"MTI_DP = " << mti_dp <<
'\n';
378 tgt_speed[0] != 2222 ||
381 tgt_speed[2] != 4444) {
382 std::cerr <<
"Get vector value test failed!\n";
386 std::cerr <<
"TGT_2_SPEED = " << tgt_speed[2] <<
'\n';
390 std::cerr <<
"Get fixed repeat count test failed!\n";
394 std::cerr <<
"Testing get_values (all values)...\n";
395 std::vector<std::string> c_values;
396 if (!record->get_values(
"C", c_values) ||
397 c_values.size() != 5 ||
398 c_values[0]!=
"C000" ||
399 c_values[1]!=
"C100" ||
400 c_values[2]!=
"C101" ||
401 c_values[3]!=
"C110" ||
402 c_values[4]!=
"C111") {
403 std::cerr <<
"failed!\n\n";
407 std::cerr <<
"Get values (partial index)...\n";
409 std::vector<int> a_values;
410 indexes.push_back(1);
411 if (!record->get_values(
"A", indexes, a_values) ||
412 a_values.size() != 1 ||
414 std::cerr <<
"failed!\n\n";
418 if (!record->get_values(
"C", indexes, c_values) ||
419 c_values.size() != 4 ||
420 c_values[0]!=
"C100" ||
421 c_values[1]!=
"C101" ||
422 c_values[2]!=
"C110" ||
425 std::cerr <<
"failed!\n\n";
429 std::cerr <<
"Didn't create record!\n";
433 std::cerr <<
"Output of vector field C:\n" 437 std::cerr <<
"Error undefining TRE.\n";
445 os <<
"CETAG: " <<
name() <<
'\n' 446 <<
"CELEN: " <<
length() << std::endl;
451 if (!field_def)
break;
453 os << field_def->
tag <<
": ";
455 os << *field << std::endl;
458 os <<
"(undefined)" << std::endl;
481 return length_written == expected_length;
495 if (!field_def)
break;
497 if (field_def->
tag == tag) {
517 skipped_node->
columns.emplace_back(
"CEDATA" );
518 skipped_node->columns.emplace_back(
"<skipped unknown TRE>" );
519 tr->
children.push_back( skipped_node );
527 first_child->
columns.emplace_back(
"CEL" );
528 first_child->columns.emplace_back(
"Extension Length" );
529 std::stringstream len_stream;
531 first_child->columns.push_back( len_stream.str() );
545 os << seq.size() <<
" TRE's:" << std::endl;
546 vil_nitf2_tagged_record_sequence::const_iterator it;
547 for (it = seq.begin(); it != seq.end(); ++it) {
548 os << *it << std::endl;
Functor vil_nitf2_field_value_one_of defines a predicate that sets its out parameter to true iff the ...
vxl_int_32 vil_nitf2_long
Functor vil_nitf2_field_value defines a function that sets its out parameter to a value of a field fr...
#define VIL_NITF2_TAGGED_RECORD_GET_VALUES(T)
virtual vil_streampos tell() const =0
Return file pointer.
bool read(vil_nitf2_istream &input, const vil_nitf2_field_definitions *field_defs=nullptr, const vil_nitf2_index_vector &indexes=vil_nitf2_index_vector())
virtual ~vil_nitf2_tagged_record()
std::vector< std::string > columns
#define NITF_STR_BCSA(LEN)
std::ostream & output(std::ostream &) const
void end()
Declares that definition is finished, preventing further invocations of field() or repeat().
vil_nitf2_field * get_field(std::string tag) const
vil_nitf2_tagged_record_definition & field(std::string field_name, std::string pretty_name, vil_nitf2_field_formatter *formatter, bool blanks_ok=false, vil_nitf2_field_functor< int > *width_functor=nullptr, vil_nitf2_field_functor< bool > *condition_functor=nullptr, std::string units="", std::string description="")
Define a field. Assumes ownership of pointer arguments.
virtual void seek(vil_streampos position)=0
Goto file pointer.
#define VIL_NITF2_LOG(LEVEL)
virtual vil_streampos read(void *buf, vil_streampos n)=0
Read n bytes into buf. Returns number of bytes read.
static vil_nitf2_field_definition & s_length_definition()
std::string m_pretty_name
vil_nitf2_field_definition * find_field_definition(const std::string &tag)
vil_nitf2_tagged_record_definition * m_definition
vil_nitf2_tagged_record()
bool write(vil_nitf2_ostream &output, int variable_width=-1) const
static vil_nitf2_tagged_record_definition & define(std::string name, std::string pretty_name)
Factory method. Assumes ownership of optional pointer argument.
std::string pretty_name() const
virtual bool write(vil_nitf2_ostream &, const vil_nitf2_field_definitions *field_defs=nullptr, vil_nitf2_index_vector indexes=vil_nitf2_index_vector())
virtual bool value(int &) const
Stream interface for VIL image loaders.
const vil_nitf2_field_definitions & field_definitions() const
Return field definitions.
static vil_nitf2_field_definition & s_tag_definition()
vil_nitf2_scalar_field * m_tag_field
vil_nitf2_field_sequence * m_field_sequence
make a section of a vil_stream behave like a vil_stream.
static vil_nitf2_integer_formatter & s_length_formatter()
vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of Stellar Science Ltd.
bool get_value(std::string tag, int &out_value) const
vil_nitf2_scalar_field * m_length_field
bool read(vil_nitf2_istream &input)
vil_nitf2_tagged_record_definition defines a particular tagged record extension (TRE).
static bool undefine(const std::string &name)
Undefines a TRE. Returns whether TRE with specified name was found.
An in-core vil_stream implementation.
virtual bool ok() const =0
Return false if the stream is broken.
const vil_nitf2_field_definitions * m_field_definitions
virtual vil_nitf2_field::field_tree * get_tree() const
Functor vil_nitf2_choose_field_value defines a function that sets its out parameter to a value of one...
std::vector< field_tree * > children
virtual vil_streampos file_size() const =0
Amount of data in the stream.
make a section of a vil_stream behave like a vil_stream
static vil_nitf2_tagged_record_definition * find(const std::string &name)
Look up a record definition.
std::ostream & operator<<(std::ostream &os, const vil_nitf2_tagged_record &record)
bool get_value(std::string tag, int &out_value) const
vil_nitf2_tagged_record_definition & repeat(vil_nitf2_field_functor< int > *repeat_functor, vil_nitf2_field_definitions &field_definitions)
Define a repeat node. Assumes ownership of pointer argument.
virtual vil_nitf2_field::field_tree * get_tree(vil_nitf2_field::field_tree *tr=nullptr) const
Functor vil_nitf2_field_value_greater_than defines a comparison predicate that sets its out parameter...
vil_nitf2_field_definition * field_definition()
static vil_nitf2_scalar_field * read(vil_nitf2_istream &input, vil_nitf2_field_definition *definition, int variable_width=-1, bool *error=nullptr)
virtual bool write(vil_nitf2_ostream &)
An in-core vil_stream implementation.
static vil_nitf2_string_formatter & s_tag_formatter()
static vil_nitf2_tagged_record * create(vil_nitf2_istream &input)
vil_nitf2_field_definitions * m_field_definitions