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