Isis 3.0 Application Source Code Reference |
Home |
00001 /** 00002 * @file 00003 * $Revision: 1.1 $ 00004 * $Date: 2007/08/09 18:24:24 $ 00005 * 00006 * Unless noted otherwise, the portions of Isis written by the USGS are public 00007 * domain. See individual third-party library and package descriptions for 00008 * intellectual property information,user agreements, and related information. 00009 * 00010 * Although Isis has been used by the USGS, no warranty, expressed or implied, 00011 * is made by the USGS as to the accuracy and functioning of such software 00012 * and related material nor shall the fact of distribution constitute any such 00013 * warranty, and no responsibility is assumed by the USGS in connection 00014 * therewith. 00015 * 00016 * For additional information, launch 00017 * $ISISROOT/doc//documents/Disclaimers/Disclaimers.html in a browser or see 00018 * the Privacy & Disclaimers page on the Isis website, 00019 * http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on 00020 * http://www.usgs.gov/privacy.html. 00021 */ 00022 00023 #include <fstream> 00024 #include <iomanip> 00025 #include <iostream> 00026 #include <sstream> 00027 00028 #include "WriteTabular.h" 00029 #include "iString.h" 00030 #include "Message.h" 00031 #include "iException.h" 00032 #include "SpecialPixel.h" 00033 00034 namespace Isis { 00035 00036 /** 00037 * Constructor 00038 * @param filename The name of the file where the table will be written 00039 */ 00040 WriteTabular::WriteTabular(std::ostream &strm) : p_outfile(strm) { 00041 p_rows = 0; 00042 p_delimiter = ","; 00043 p_curCol = 0; 00044 } 00045 00046 /** 00047 * Constructor 00048 * @param filename The name of the target file to contain the table, once 00049 * formatted 00050 * @param cols The Column headers, containing information about the Columns 00051 */ 00052 WriteTabular::WriteTabular(std::ostream &strm, std::vector<Column> cols) : p_outfile(strm) { 00053 p_rows = 0; 00054 p_delimiter = ","; 00055 p_curCol = 0; 00056 SetColumns(cols); 00057 } 00058 00059 /** 00060 * Sets the vector of Columns and writes out the first row of the file. 00061 * 00062 * @param cols A vector of Columns, setting the format of the table 00063 */ 00064 void WriteTabular::SetColumns(std::vector <Column> cols) { 00065 for(unsigned int index = 0; index < cols.size(); index++) { 00066 Column thisCol = cols[index]; 00067 std::string thisTitle = thisCol.Name(); 00068 00069 if(thisTitle.length() > thisCol.Width()) { 00070 std::string message = "Column header [" + thisTitle + "] is wider " + 00071 "than the set width for column [" + iString((int)index) + "]"; 00072 throw Isis::iException::Message(Isis::iException::User, message, _FILEINFO_); 00073 } 00074 00075 int iteration = 0; 00076 while(thisTitle.length() < thisCol.Width()) { 00077 if(thisCol.Alignment() == Column::Left) { 00078 thisTitle += " "; 00079 } 00080 else if(thisCol.Alignment() == Column::Right || 00081 thisCol.Alignment() == Column::Decimal) { 00082 thisTitle = " " + thisTitle; 00083 } 00084 else { 00085 std::string message = "Alignment is improperly set"; 00086 throw Isis::iException::Message(Isis::iException::User, message, _FILEINFO_); 00087 } 00088 iteration++; 00089 }//end while 00090 00091 p_cols.push_back(thisCol); 00092 p_outfile << thisTitle; 00093 if(index < (cols.size() - 1)) { 00094 p_outfile << p_delimiter; 00095 } 00096 }//end for 00097 p_outfile << "\n"; 00098 }//end function 00099 00100 /** 00101 * Writes a blank space in the next column in the current row 00102 */ 00103 void WriteTabular::Write() { 00104 Column thisCol = p_cols[p_curCol]; 00105 00106 std::string item = ""; 00107 00108 std::stringstream tempStream; 00109 tempStream.width(thisCol.Width()); 00110 tempStream.fill(' '); 00111 tempStream << item; 00112 item = tempStream.str(); 00113 00114 if(p_curCol == 0) { 00115 p_rows++; 00116 } 00117 00118 if(p_curCol < (p_cols.size() - 1)) { 00119 item += p_delimiter; 00120 p_curCol++; 00121 } 00122 else { 00123 item += "\n"; 00124 p_curCol = 0; 00125 } 00126 p_outfile << item; 00127 } 00128 00129 /** 00130 * Add an integer value to the next column in this row 00131 * 00132 * @param item The integer value to put in this column. 00133 */ 00134 void WriteTabular::Write(int item) { 00135 Column thisCol = p_cols[p_curCol]; 00136 if(thisCol.DataType() != Column::Integer && 00137 thisCol.DataType() != Column::Pixel) { 00138 if(thisCol.DataType() == Column::Real || 00139 thisCol.DataType() == Column::Pixel) { 00140 Write((double)item); 00141 return; 00142 } 00143 std::string message = "Wrong data type for this Column"; 00144 throw Isis::iException::Message(Isis::iException::User, message, _FILEINFO_); 00145 } 00146 iString thisItem(item); 00147 if(thisItem.length() > thisCol.Width()) { 00148 thisItem = "*"; 00149 while(thisItem.length() < thisCol.Width()) { 00150 thisItem += "*"; 00151 } 00152 } 00153 std::stringstream tempStream; 00154 tempStream.width(thisCol.Width()); 00155 tempStream.fill(' '); 00156 00157 if(thisCol.Alignment() == Column::Left) { 00158 tempStream.setf(std::ios::left); 00159 } 00160 else tempStream.setf(std::ios::right); 00161 00162 tempStream << thisItem; 00163 thisItem = tempStream.str(); 00164 00165 if(p_curCol == 0) { 00166 p_rows++; 00167 } 00168 00169 if(p_curCol < (p_cols.size() - 1)) { 00170 thisItem += p_delimiter; 00171 p_curCol++; 00172 } 00173 else { 00174 thisItem += "\n"; 00175 p_curCol = 0; 00176 } 00177 p_outfile << thisItem.c_str(); 00178 } 00179 00180 /** 00181 * Writes a string to the next column in the current row 00182 * 00183 * @param item The string to write out 00184 */ 00185 void WriteTabular::Write(std::string item) { 00186 Column thisCol = p_cols[p_curCol]; 00187 if(thisCol.DataType() != Column::String && 00188 thisCol.DataType() != Column::Pixel) { 00189 std::string message = "Wrong data type for this Column"; 00190 throw Isis::iException::Message(Isis::iException::User, message, _FILEINFO_); 00191 } 00192 if(item.length() > thisCol.Width()) { 00193 item = "*"; 00194 while(item.length() < thisCol.Width()) { 00195 item += "*"; 00196 } 00197 } 00198 std::stringstream tempStream; 00199 tempStream.width(thisCol.Width()); 00200 tempStream.fill(' '); 00201 00202 if(thisCol.Alignment() == Column::Left) { 00203 tempStream.setf(std::ios::left); 00204 } 00205 else tempStream.setf(std::ios::right); 00206 00207 tempStream << item; 00208 item = tempStream.str(); 00209 00210 if(p_curCol == 0) { 00211 p_rows++; 00212 } 00213 00214 if(p_curCol < (p_cols.size() - 1)) { 00215 item += p_delimiter; 00216 p_curCol++; 00217 } 00218 else { 00219 item += "\n"; 00220 p_curCol = 0; 00221 } 00222 p_outfile << item; 00223 } 00224 00225 /** 00226 * Writes a floating-point value out to the next column in the current row 00227 * 00228 * @param item The value to be printed out 00229 */ 00230 void WriteTabular::Write(double item) { 00231 Column thisCol = p_cols[p_curCol]; 00232 if(thisCol.DataType() != Column::Real && 00233 thisCol.DataType() != Column::Pixel) { 00234 std::string message = "Wrong data type for this Column"; 00235 throw Isis::iException::Message(Isis::iException::User, message, _FILEINFO_); 00236 } 00237 00238 //Check for special pixels, if it's a pixel column 00239 if(thisCol.DataType() == Column::Pixel && IsSpecial(item)) { 00240 if(IsNullPixel(item)) { 00241 Write("Null"); 00242 return; 00243 } 00244 if(IsHisPixel(item)) { 00245 Write("His"); 00246 return; 00247 } 00248 if(IsHrsPixel(item)) { 00249 Write("Hrs"); 00250 return; 00251 } 00252 if(IsLisPixel(item)) { 00253 Write("Lis"); 00254 return; 00255 } 00256 if(IsLrsPixel(item)) { 00257 Write("Lrs"); 00258 return; 00259 } 00260 } 00261 00262 iString thisItem(item); 00263 00264 00265 if(thisCol.Alignment() == Column::Decimal) { 00266 00267 //Format and round the number 00268 00269 //First, split the number at the decimal point 00270 iString tempString = thisItem; 00271 iString intPart = tempString.Token("."); 00272 //Make the fractional portion appear as such, so the iomanipulators 00273 //handle it properly 00274 if(tempString != "") { 00275 tempString = "0." + tempString; 00276 } 00277 else tempString = "0.0"; 00278 00279 //Put the fractional portion into a stringstream, and use 00280 //stream manipulators to round it properly 00281 std::stringstream b; 00282 b << std::showpoint 00283 << std::setprecision(thisCol.Precision()) 00284 << tempString.ToDouble(); 00285 00286 //if the rounding causes a rollover (i.e. the decimal portion is greater 00287 //than 0.95) increment the integer portion 00288 if(iString(b.str()).ToDouble() >= 1) { 00289 intPart = iString(intPart.ToInteger() + 1); 00290 } 00291 00292 //Put it back into an iString, for easier manipulation 00293 tempString = b.str(); 00294 tempString.Token("."); 00295 //Add any zeros necessary to pad the number 00296 while(tempString.size() < thisCol.Precision()) { 00297 tempString += "0"; 00298 } 00299 00300 //Put the number back together, adding the decimal point in the right location 00301 thisItem = intPart + "." + tempString; 00302 } 00303 std::stringstream tempStream; 00304 tempStream.width(thisCol.Width()); 00305 tempStream.fill(' '); 00306 00307 if(thisCol.Alignment() == Column::Left) { 00308 tempStream.setf(std::ios::left); 00309 } 00310 else tempStream.setf(std::ios::right); 00311 00312 tempStream << thisItem; 00313 thisItem = tempStream.str(); 00314 00315 if(p_curCol == 0) { 00316 p_rows++; 00317 } 00318 00319 //If the number is too wide for the column, replace with a string of stars 00320 if(thisItem.length() > thisCol.Width()) { 00321 thisItem = "*"; 00322 while(thisItem.length() < thisCol.Width()) { 00323 thisItem += "*"; 00324 } 00325 } 00326 00327 if(p_curCol < (p_cols.size() - 1)) { 00328 thisItem += p_delimiter; 00329 p_curCol++; 00330 } 00331 else { 00332 thisItem += "\n"; 00333 p_curCol = 0; 00334 } 00335 p_outfile << thisItem; 00336 00337 } 00338 00339 /** 00340 * Sets the string to be put between columns for this table 00341 * 00342 * @param delim The string to separate columns 00343 */ 00344 void WriteTabular::SetDelimiter(std::string delim) { 00345 p_delimiter = delim; 00346 } 00347 00348 }