Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

vil_nitf2_typed_field_formatter.cxx

Go to the documentation of this file.
00001 // vil_nitf2: Written by Harry Voorhees (hlv@) and Rob Radtke (rob@) of
00002 // Stellar Science Ltd. Co. (stellarscience.com) for
00003 // Air Force Research Laboratory, 2005.
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> //for VCL_WIN32
00012 
00013 #include <vcl_cerrno.h>
00014 
00015 //==============================================================================
00016 // Class vil_nitf2_date_time_formatter
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 // Class vil_nitf2_location_formatter
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 // Class vil_nitf2_integer_formatter
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   //Assuming that int is 32 bits, then it can't represent a value higher than
00085   // (10^32)/2 ... that is 2147483648.
00086   //assert( field_width < 10 );
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 // processed all chars
00108          && errno==0              // with no errors
00109          && sign_ok;              // sign shown as expected
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 // Class vil_nitf2_long_long_formatter
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;   // processed all chars
00157 #elif defined VCL_BORLAND
00158   out_value = _atoi64( cstr );
00159   conversion_ok = true;                       //no error checking available
00160 #else
00161   out_value = ::strtoll(cstr, &endp, 10);     // in Standard C Library
00162   conversion_ok = (endp-cstr)==field_width;   // processed all chars
00163 #endif
00164 
00165 #else //VXL_HAS_INT_64
00166   out_value = strtol(cstr, &endp, 10);
00167   conversion_ok = (endp-cstr)==field_width;   // processed all chars
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              // with no errors
00174          && sign_ok;              // sign shown as expected
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 // Class vil_nitf2_double_formatter
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  // processed all chars
00219      && errno==0              // with no errors
00220      && decimal_ok            // decimal point in right place
00221      && sign_ok;              // sign shown as expected
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 // Class vil_nitf2_exponential_formatter
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   // Check locations of non-digits in format: +d.dddddE+dd
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   // processed all chars
00275      && errno==0               // read a number with no errors
00276      && base_sign_ok           // base sign in right place
00277      && decimal_ok             // decimal point in right place
00278      && e_ok                   // 'E' in right place
00279      && exp_sign_ok;           // exponent sign in right place
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   // Can't control the width of exponent (it's 3) so write it to a buffer first
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   // Write everything up to the exponent sign
00296   output << buffer_string.substr(0,length-3);
00297   // Write exponent digits, padding or unpadding them to desired width
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 // Class vil_nitf2_binary_formatter
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; //no such thing as 'blank' binary data
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 // Class vil_nitf2_char_formatter
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   //int numRead = input.read(&out_value, 1);
00344   out_blank = (out_value == ' ');
00345   return !input.fail();
00346   //return numRead == 1;
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 // Class vil_nitf2_string_formatter
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 /*value*/) const
00395 {
00396   // to do: check char set
00397   return true;
00398 }
00399 
00400 //==============================================================================
00401 // Class vil_nitf2_enum_string_formatter
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   //field_type = Nitf::Enum;
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       // Should probably remove it so that is_valid() doesn't match it.
00426       // On the other hand, this class will never read a token of this
00427       // length, so don't worry about it.
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 // Class vil_nitf2_enum_values
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 // Class vil_nitf2_tre_sequence_formatter
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 /* ignored */)
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); // out_value assumes ownership of record
00478     }
00479     error_reading_tre &= !record;
00480   }
00481   if (input.tell() != end) { // TO DO: what does end equal at EOF?
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& /*output*/, vil_nitf2_tagged_record_sequence& /*value*/ )
00495 { 
00496   return false; 
00497 }

Generated on Thu Jan 10 14:40:00 2008 for core/vil by  doxygen 1.4.4