00001
00002
00003
00004
00005 #include "vil_nitf2_typed_field_formatter.h"
00006
00007 #include <vcl_algorithm.h>
00008 #include <vcl_iomanip.h>
00009 #include <vcl_iostream.h>
00010 #include <vcl_utility.h>
00011 #include <vcl_compiler.h>
00012
00013 #include <vcl_cerrno.h>
00014
00015
00016
00017
00018 vil_nitf2_date_time_formatter::vil_nitf2_date_time_formatter(int field_width)
00019 : vil_nitf2_typed_field_formatter<vil_nitf2_date_time>(vil_nitf2::type_date_time, field_width)
00020 {}
00021
00022 vil_nitf2_field_formatter* vil_nitf2_date_time_formatter::copy() const
00023 {
00024 return new vil_nitf2_date_time_formatter(field_width);
00025 }
00026
00027 bool vil_nitf2_date_time_formatter::read_vcl_stream(vcl_istream& input, vil_nitf2_date_time& out_value, bool& out_blank)
00028 {
00029 return out_value.read(input, field_width, out_blank);
00030 }
00031
00032 bool vil_nitf2_date_time_formatter::write_vcl_stream(vcl_ostream& output, const vil_nitf2_date_time& value)
00033 {
00034 return value.write(output, field_width);
00035 }
00036
00037
00038
00039
00040 vil_nitf2_location_formatter::vil_nitf2_location_formatter(int field_width)
00041 : vil_nitf2_typed_field_formatter<vil_nitf2_location*>(vil_nitf2::type_location, field_width)
00042 {}
00043
00044 vil_nitf2_field_formatter* vil_nitf2_location_formatter::copy() const
00045 {
00046 return new vil_nitf2_location_formatter(field_width);
00047 }
00048
00049 bool vil_nitf2_location_formatter::read_vcl_stream(vcl_istream& input,
00050 vil_nitf2_location*& out_value,
00051 bool& out_blank)
00052 {
00053 vcl_streampos tag_start_pos = input.tellg();
00054 vil_nitf2_location* location = new vil_nitf2_location_degrees(deg_precision(field_width));
00055 if (location->read(input, field_width, out_blank)) {
00056 out_value = location;
00057 return true;
00058 } else {
00059 delete location;
00060 input.seekg(tag_start_pos);
00061 location = new vil_nitf2_location_dmsh(sec_precision(field_width));
00062 if (location->read(input, field_width, out_blank)) {
00063 out_value = location;
00064 return true;
00065 } else {
00066 delete location;
00067 out_value = 0;
00068 return false;
00069 }
00070 }
00071 }
00072
00073 bool vil_nitf2_location_formatter::write_vcl_stream(vcl_ostream& output, vil_nitf2_location*const& value)
00074 {
00075 return value->write(output, field_width);
00076 }
00077
00078
00079
00080
00081 vil_nitf2_integer_formatter::vil_nitf2_integer_formatter(int field_width, bool show_sign )
00082 : vil_nitf2_typed_field_formatter<int>(vil_nitf2::type_int, field_width),
00083 show_sign(show_sign)
00084 {
00085
00086
00087
00088 }
00089
00090 vil_nitf2_field_formatter* vil_nitf2_integer_formatter::copy() const
00091 {
00092 return new vil_nitf2_integer_formatter(field_width, show_sign);
00093 }
00094
00095 bool
00096 vil_nitf2_integer_formatter::read_vcl_stream(vcl_istream& input,
00097 int& out_value, bool& out_blank)
00098 {
00099 char* cstr;
00100 if (!read_c_str(input, field_width, cstr, out_blank)) {
00101 delete[] cstr;
00102 return false;
00103 }
00104 char* endp;
00105 errno = 0;
00106 out_value = (int)strtol(cstr, &endp, 10);
00107 bool sign_ok = check_sign(cstr, show_sign);
00108 bool retVal = (endp-cstr)==field_width
00109 && errno==0
00110 && sign_ok;
00111 delete[] cstr;
00112 return retVal;
00113 }
00114
00115 bool vil_nitf2_integer_formatter::write_vcl_stream(vcl_ostream& output, const int& value)
00116 {
00117 output << vcl_setw(field_width) << vcl_right << vcl_setfill('0');
00118 if (show_sign) {
00119 output << vcl_showpos;
00120 } else {
00121 output << vcl_noshowpos;
00122 }
00123 output << value;
00124 return !output.fail();
00125 }
00126
00127
00128
00129
00130 vil_nitf2_long_long_formatter::
00131 vil_nitf2_long_long_formatter(int field_width, bool show_sign)
00132 : vil_nitf2_typed_field_formatter<vil_nitf2_long>(vil_nitf2::type_long_long, field_width),
00133 show_sign(show_sign)
00134 {}
00135
00136 vil_nitf2_field_formatter* vil_nitf2_long_long_formatter::copy() const
00137 {
00138 return new vil_nitf2_long_long_formatter(field_width, show_sign);
00139 }
00140
00141 bool vil_nitf2_long_long_formatter::
00142 read_vcl_stream(vcl_istream& input, vil_nitf2_long& out_value, bool& out_blank)
00143 {
00144 char* cstr;
00145 if (!read_c_str(input, field_width, cstr, out_blank)) {
00146 delete[] cstr;
00147 return false;
00148 }
00149 bool conversion_ok;
00150 char* endp;
00151 errno = 0;
00152
00153 #if VXL_HAS_INT_64
00154
00155 #if defined VCL_VC
00156 out_value = _strtoi64(cstr, &endp, 10);
00157 conversion_ok = (endp-cstr)==field_width;
00158 #elif defined VCL_BORLAND
00159 out_value = _atoi64( cstr );
00160 conversion_ok = true;
00161 #else
00162 out_value = ::strtoll(cstr, &endp, 10);
00163 conversion_ok = (endp-cstr)==field_width;
00164 #endif
00165
00166 #else //VXL_HAS_INT_64
00167 out_value = strtol(cstr, &endp, 10);
00168 conversion_ok = (endp-cstr)==field_width;
00169 #endif //VXL_HAS_INT_64
00170
00171 bool sign_ok = check_sign(cstr, show_sign);
00172 delete[] cstr;
00173 return conversion_ok
00174 && errno==0
00175 && sign_ok;
00176 }
00177
00178 bool vil_nitf2_long_long_formatter::write_vcl_stream(vcl_ostream& output, const vil_nitf2_long& value)
00179 {
00180 output << vcl_setw(field_width) << vcl_right << vcl_setfill('0');
00181 if (show_sign) {
00182 output << vcl_showpos;
00183 } else {
00184 output << vcl_noshowpos;
00185 }
00186 output << value;
00187 return !output.fail();
00188 }
00189
00190
00191
00192
00193 vil_nitf2_double_formatter::
00194 vil_nitf2_double_formatter(int field_width, int precision, bool show_sign)
00195 : vil_nitf2_typed_field_formatter<double>(vil_nitf2::type_double, field_width),
00196 precision(precision),
00197 show_sign(show_sign)
00198 {}
00199
00200 vil_nitf2_field_formatter* vil_nitf2_double_formatter::copy() const
00201 {
00202 return new vil_nitf2_double_formatter(field_width, precision, show_sign);
00203 }
00204
00205 bool vil_nitf2_double_formatter::read_vcl_stream(vcl_istream& input,
00206 double& out_value, bool& out_blank)
00207 {
00208 char* cstr;
00209 if (!read_c_str(input, field_width, cstr, out_blank)) {
00210 delete[] cstr;
00211 return false;
00212 }
00213 char* endp;
00214 errno=0;
00215 out_value = strtod(cstr, &endp);
00216 bool sign_ok = check_sign(cstr, show_sign);
00217 bool decimal_ok = cstr[(field_width-precision)-1]=='.';
00218 bool retVal =
00219 (endp-cstr)==field_width
00220 && errno==0
00221 && decimal_ok
00222 && sign_ok;
00223 delete[] cstr;
00224 return retVal;
00225 }
00226
00227 bool vil_nitf2_double_formatter::write_vcl_stream(vcl_ostream& output, const double& value)
00228 {
00229 output << vcl_setw(field_width) << vcl_fixed;
00230 if (show_sign) {
00231 output << vcl_showpos;
00232 } else {
00233 output << vcl_noshowpos;
00234 }
00235 output << vcl_internal << vcl_setfill('0') << vcl_setprecision(precision)
00236 << value;
00237 return !output.fail();
00238 }
00239
00240
00241
00242
00243 vil_nitf2_exponential_formatter::
00244 vil_nitf2_exponential_formatter(int mantissa_width, int exponent_width)
00245 : vil_nitf2_typed_field_formatter<double>(vil_nitf2::type_double,
00246 mantissa_width + exponent_width + 5),
00247 mantissa_width(mantissa_width),
00248 exponent_width(exponent_width)
00249 {}
00250
00251 vil_nitf2_field_formatter* vil_nitf2_exponential_formatter::copy() const
00252 {
00253 return new vil_nitf2_exponential_formatter(mantissa_width, exponent_width);
00254 }
00255
00256 bool vil_nitf2_exponential_formatter::read_vcl_stream(vcl_istream& input,
00257 double& out_value, bool& out_blank)
00258 {
00259 char* cstr;
00260 if (!read_c_str(input, field_width, cstr, out_blank)) {
00261 delete[] cstr;
00262 return false;
00263 }
00264 char* endp;
00265 errno=0;
00266 out_value = strtod(cstr, &endp);
00267
00268 const char base_sign = cstr[0];
00269 const bool base_sign_ok = base_sign=='+' || base_sign=='-';
00270 const bool decimal_ok = cstr[2]=='.';
00271 const char e_ok = cstr[3+mantissa_width]=='E';
00272 const char exp_sign = cstr[4+mantissa_width];
00273 const bool exp_sign_ok = exp_sign=='+' || exp_sign=='-';
00274 bool retVal =
00275 (endp-cstr)==field_width
00276 && errno==0
00277 && base_sign_ok
00278 && decimal_ok
00279 && e_ok
00280 && exp_sign_ok;
00281 delete[] cstr;
00282 return retVal;
00283 }
00284
00285 bool vil_nitf2_exponential_formatter::write_vcl_stream(vcl_ostream& output,
00286 const double& value)
00287 {
00288
00289 vcl_ostringstream buffer;
00290 buffer << vcl_setw(field_width) << vcl_scientific
00291 << vcl_showpos << vcl_uppercase
00292 << vcl_internal << vcl_setfill('0') << vcl_setprecision(mantissa_width)
00293 << value;
00294 vcl_string buffer_string = buffer.str();
00295 unsigned int length = (unsigned int)(buffer_string.length());
00296
00297 output << buffer_string.substr(0,length-3);
00298
00299 output << vcl_setw(exponent_width) << vcl_setfill('0')
00300 << buffer_string.substr(length-vcl_min(3,exponent_width), vcl_min(3,exponent_width));
00301 return !output.fail();
00302 }
00303
00304
00305
00306
00307 vil_nitf2_binary_formatter::vil_nitf2_binary_formatter(int width_bytes)
00308 : vil_nitf2_typed_field_formatter<void*>(vil_nitf2::type_binary, width_bytes)
00309 {}
00310
00311 vil_nitf2_field_formatter* vil_nitf2_binary_formatter::copy() const
00312 {
00313 return new vil_nitf2_binary_formatter(field_width);
00314 }
00315
00316 bool vil_nitf2_binary_formatter::read(vil_stream& input, void*& out_value,
00317 bool& out_blank)
00318 {
00319 out_value = (void*)(new char[field_width]);
00320 out_blank = false;
00321 return input.read( out_value, field_width ) == field_width;
00322 }
00323
00324 bool vil_nitf2_binary_formatter::write(vil_nitf2_ostream& output, void*const& value)
00325 {
00326 return output.write( value, field_width ) == field_width;
00327 }
00328
00329
00330
00331
00332 vil_nitf2_char_formatter::vil_nitf2_char_formatter()
00333 : vil_nitf2_typed_field_formatter<char>(vil_nitf2::type_char, 1)
00334 {}
00335
00336 vil_nitf2_field_formatter* vil_nitf2_char_formatter::copy() const
00337 {
00338 return new vil_nitf2_char_formatter();
00339 }
00340
00341 bool vil_nitf2_char_formatter::read_vcl_stream(vcl_istream& input, char& out_value, bool& out_blank)
00342 {
00343 input.get(out_value);
00344
00345 out_blank = (out_value == ' ');
00346 return !input.fail();
00347
00348 }
00349
00350 bool vil_nitf2_char_formatter::write_vcl_stream(vcl_ostream& output, const char& value)
00351 {
00352 output << value;
00353 return !output.fail();
00354 }
00355
00356
00357
00358
00359 vil_nitf2_string_formatter::
00360 vil_nitf2_string_formatter(int field_width, enum_char_set char_set)
00361 : vil_nitf2_typed_field_formatter<vcl_string>(vil_nitf2::type_string, field_width),
00362 char_set(char_set)
00363 {}
00364
00365 vil_nitf2_field_formatter* vil_nitf2_string_formatter::copy() const
00366 {
00367 return new vil_nitf2_string_formatter(field_width, char_set);
00368 }
00369
00370 bool vil_nitf2_string_formatter::read_vcl_stream(vcl_istream& input,
00371 vcl_string& out_value,
00372 bool& out_blank)
00373 {
00374 char* cstr;
00375 if (!read_c_str(input, field_width, cstr, out_blank)) {
00376 delete[] cstr;
00377 return false;
00378 }
00379 vcl_string str = vcl_string(cstr);
00380 delete[] cstr;
00381 vcl_string::size_type end_pos = str.find_last_not_of(" ")+1;
00382 if (end_pos == vcl_string::npos) {
00383 out_value = str;
00384 } else {
00385 out_value = str.substr(0, end_pos);
00386 }
00387 return is_valid(out_value);
00388 }
00389
00390 bool vil_nitf2_string_formatter::write_vcl_stream(vcl_ostream& output, const vcl_string& value)
00391 {
00392 output << vcl_setw(field_width) << vcl_left << vcl_setfill(' ') << value;
00393 return !output.fail();
00394 }
00395
00396 bool vil_nitf2_string_formatter::is_valid(vcl_string ) const
00397 {
00398
00399 return true;
00400 }
00401
00402
00403
00404
00405 vil_nitf2_enum_string_formatter::
00406 vil_nitf2_enum_string_formatter(int field_width, const vil_nitf2_enum_values& value_map)
00407 : vil_nitf2_string_formatter(field_width), value_map(value_map)
00408 {
00409
00410 validate_value_map();
00411 }
00412
00413 vil_nitf2_field_formatter* vil_nitf2_enum_string_formatter::copy() const
00414 {
00415 return new vil_nitf2_enum_string_formatter(field_width, value_map);
00416 }
00417
00418 void vil_nitf2_enum_string_formatter::validate_value_map()
00419 {
00420 for (vil_nitf2_enum_values::iterator entry = value_map.begin();
00421 entry != value_map.end(); ++entry)
00422 {
00423 vcl_string token = entry->first;
00424 if (int(token.length()) > field_width) {
00425 vcl_cerr << "vil_nitf2_enum_values: WARNING: Ignoring token "
00426 << token << "; length exceeds declared field width.\n";
00427
00428
00429
00430 }
00431 }
00432 }
00433
00434 bool vil_nitf2_enum_string_formatter::is_valid_value(vcl_string token) const
00435 {
00436 return value_map.find(token) != value_map.end();
00437 }
00438
00439
00440
00441
00442 vil_nitf2_enum_values& vil_nitf2_enum_values::value(vcl_string token, vcl_string pretty_name)
00443 {
00444 if (!insert(vcl_make_pair(token, pretty_name)).second) {
00445 vcl_cerr << "vil_nitf2_enum_values: WARNING: Ignoring definition "
00446 << token << "; token already defined for this enumeration.\n";
00447 }
00448 return *this;
00449 }
00450
00451
00452
00453
00454 #include "vil_nitf2_tagged_record.h"
00455
00456 vil_nitf2_tagged_record_sequence_formatter::vil_nitf2_tagged_record_sequence_formatter()
00457 : vil_nitf2_typed_field_formatter<vil_nitf2_tagged_record_sequence>(
00458 vil_nitf2::type_tagged_record_sequence, 1 )
00459 {}
00460
00461 vil_nitf2_field_formatter*
00462 vil_nitf2_tagged_record_sequence_formatter::copy() const
00463 {
00464 return new vil_nitf2_tagged_record_sequence_formatter();
00465 }
00466
00467 bool vil_nitf2_tagged_record_sequence_formatter::
00468 read( vil_nitf2_istream& input,
00469 vil_nitf2_tagged_record_sequence& out_value, bool& out_blank )
00470 {
00471 if (field_width <= 0) return false;
00472 vil_streampos current = input.tell();
00473 vil_streampos end = current + field_width;
00474 bool error_reading_tre = false;
00475 out_value.clear();
00476 while (input.tell() < end && !error_reading_tre) {
00477 vil_nitf2_tagged_record* record = vil_nitf2_tagged_record::create(input);
00478 if (record) {
00479 out_value.push_back(record);
00480 }
00481 error_reading_tre &= !record;
00482 }
00483 if (input.tell() != end) {
00484 VIL_NITF2_LOG(log_info) << "\nSeeking to end of TRE sequence field.\n";
00485 input.seek(end);
00486 if (input.tell() != end) {
00487 vcl_cerr << "\nSeek to end of TRE sequence field failed.\n";
00488 error_reading_tre = true;
00489 }
00490 }
00491 out_blank = false;
00492 return !error_reading_tre;
00493 }
00494
00495 bool vil_nitf2_tagged_record_sequence_formatter::
00496 write(vil_nitf2_ostream& , vil_nitf2_tagged_record_sequence& )
00497 {
00498 return false;
00499 }