|
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 using std::stringstream; 00035 00036 namespace Isis { 00037 00038 /** 00039 * Constructor 00040 * @param filename The name of the file where the table will be written 00041 */ 00042 WriteTabular::WriteTabular(std::ostream &strm) : p_outfile(strm) { 00043 p_rows = 0; 00044 p_delimiter = ","; 00045 p_curCol = 0; 00046 } 00047 00048 /** 00049 * Constructor 00050 * @param filename The name of the target file to contain the table, once 00051 * formatted 00052 * @param cols The Column headers, containing information about the Columns 00053 */ 00054 WriteTabular::WriteTabular(std::ostream &strm, std::vector<Column> cols) : p_outfile(strm) { 00055 p_rows = 0; 00056 p_delimiter = ","; 00057 p_curCol = 0; 00058 SetColumns(cols); 00059 } 00060 00061 /** 00062 * Sets the vector of Columns and writes out the first row of the file. 00063 * 00064 * @param cols A vector of Columns, setting the format of the table 00065 */ 00066 void WriteTabular::SetColumns(std::vector <Column> cols) { 00067 for(unsigned int index = 0; index < cols.size(); index++) { 00068 Column thisCol = cols[index]; 00069 QString thisTitle = thisCol.Name(); 00070 00071 if((int)thisTitle.length() > (int)thisCol.Width()) { 00072 QString message = "Column header [" + thisTitle + "] is wider " + 00073 "than the set width for column [" + toString((int)index) + "]"; 00074 throw IException(IException::User, message, _FILEINFO_); 00075 } 00076 00077 int iteration = 0; 00078 while((int)thisTitle.length() < (int)thisCol.Width()) { 00079 if(thisCol.Alignment() == Column::Left) { 00080 thisTitle += " "; 00081 } 00082 else if(thisCol.Alignment() == Column::Right || 00083 thisCol.Alignment() == Column::Decimal) { 00084 thisTitle = " " + thisTitle; 00085 } 00086 else { 00087 QString message = "Alignment is improperly set"; 00088 throw IException(IException::User, message, _FILEINFO_); 00089 } 00090 iteration++; 00091 }//end while 00092 00093 p_cols.push_back(thisCol); 00094 p_outfile << thisTitle; 00095 if(index < (cols.size() - 1)) { 00096 p_outfile << p_delimiter; 00097 } 00098 }//end for 00099 p_outfile << "\n"; 00100 }//end function 00101 00102 /** 00103 * Writes a blank space in the next column in the current row 00104 */ 00105 void WriteTabular::Write() { 00106 Column thisCol = p_cols[p_curCol]; 00107 00108 QString item = ""; 00109 00110 stringstream tempStream; 00111 tempStream.width(thisCol.Width()); 00112 tempStream.fill(' '); 00113 tempStream << item; 00114 item = tempStream.str().c_str(); 00115 00116 if(p_curCol == 0) { 00117 p_rows++; 00118 } 00119 00120 if(p_curCol < (p_cols.size() - 1)) { 00121 item += p_delimiter; 00122 p_curCol++; 00123 } 00124 else { 00125 item += "\n"; 00126 p_curCol = 0; 00127 } 00128 p_outfile << item; 00129 } 00130 00131 /** 00132 * Add an integer value to the next column in this row 00133 * 00134 * @param item The integer value to put in this column. 00135 */ 00136 void WriteTabular::Write(int item) { 00137 Column thisCol = p_cols[p_curCol]; 00138 if(thisCol.DataType() != Column::Integer && 00139 thisCol.DataType() != Column::Pixel) { 00140 if(thisCol.DataType() == Column::Real || 00141 thisCol.DataType() == Column::Pixel) { 00142 Write((double)item); 00143 return; 00144 } 00145 QString message = "Wrong data type for this Column"; 00146 throw IException(IException::User, message, _FILEINFO_); 00147 } 00148 QString thisItem(toString(item)); 00149 if(thisItem.length() > (int)thisCol.Width()) { 00150 thisItem = "*"; 00151 while(thisItem.length() < (int)thisCol.Width()) { 00152 thisItem += "*"; 00153 } 00154 } 00155 stringstream tempStream; 00156 tempStream.width(thisCol.Width()); 00157 tempStream.fill(' '); 00158 00159 if(thisCol.Alignment() == Column::Left) { 00160 tempStream.setf(std::ios::left); 00161 } 00162 else tempStream.setf(std::ios::right); 00163 00164 tempStream << thisItem; 00165 thisItem = tempStream.str().c_str(); 00166 00167 if(p_curCol == 0) { 00168 p_rows++; 00169 } 00170 00171 if(p_curCol < (p_cols.size() - 1)) { 00172 thisItem += p_delimiter; 00173 p_curCol++; 00174 } 00175 else { 00176 thisItem += "\n"; 00177 p_curCol = 0; 00178 } 00179 p_outfile << thisItem; 00180 } 00181 00182 /** 00183 * Writes a string to the next column in the current row 00184 * 00185 * @param item The string to write out 00186 */ 00187 void WriteTabular::Write(const char *itemCStr) { 00188 Column thisCol = p_cols[p_curCol]; 00189 if(thisCol.DataType() != Column::String && 00190 thisCol.DataType() != Column::Pixel) { 00191 QString message = "Wrong data type for this Column"; 00192 throw IException(IException::User, message, _FILEINFO_); 00193 } 00194 00195 QString item(itemCStr); 00196 if(item.length() > (int)thisCol.Width()) { 00197 item = "*"; 00198 while(item.length() < (int)thisCol.Width()) { 00199 item += "*"; 00200 } 00201 } 00202 stringstream tempStream; 00203 tempStream.width(thisCol.Width()); 00204 tempStream.fill(' '); 00205 00206 if(thisCol.Alignment() == Column::Left) { 00207 tempStream.setf(std::ios::left); 00208 } 00209 else tempStream.setf(std::ios::right); 00210 00211 tempStream << item; 00212 item = tempStream.str().c_str(); 00213 00214 if(p_curCol == 0) { 00215 p_rows++; 00216 } 00217 00218 if(p_curCol < (p_cols.size() - 1)) { 00219 item += p_delimiter; 00220 p_curCol++; 00221 } 00222 else { 00223 item += "\n"; 00224 p_curCol = 0; 00225 } 00226 p_outfile << item; 00227 } 00228 00229 /** 00230 * Writes a floating-point value out to the next column in the current row 00231 * 00232 * @param item The value to be printed out 00233 */ 00234 void WriteTabular::Write(double item) { 00235 Column thisCol = p_cols[p_curCol]; 00236 if(thisCol.DataType() != Column::Real && 00237 thisCol.DataType() != Column::Pixel) { 00238 QString message = "Wrong data type for this Column"; 00239 throw IException(IException::User, message, _FILEINFO_); 00240 } 00241 00242 //Check for special pixels, if it's a pixel column 00243 if(thisCol.DataType() == Column::Pixel && IsSpecial(item)) { 00244 if(IsNullPixel(item)) { 00245 Write("Null"); 00246 return; 00247 } 00248 if(IsHisPixel(item)) { 00249 Write("His"); 00250 return; 00251 } 00252 if(IsHrsPixel(item)) { 00253 Write("Hrs"); 00254 return; 00255 } 00256 if(IsLisPixel(item)) { 00257 Write("Lis"); 00258 return; 00259 } 00260 if(IsLrsPixel(item)) { 00261 Write("Lrs"); 00262 return; 00263 } 00264 } 00265 00266 QString thisItem(toString(item)); 00267 00268 00269 if(thisCol.Alignment() == Column::Decimal) { 00270 00271 //Format and round the number 00272 00273 //First, split the number at the decimal point 00274 QStringList tempString = thisItem.split("."); 00275 QString intPart = tempString.takeFirst(); 00276 00277 //Make the fractional portion appear as such, so the iomanipulators 00278 //handle it properly 00279 if(!tempString.isEmpty()) { 00280 tempString.prepend("0"); 00281 } 00282 else { 00283 tempString.append("0"); 00284 tempString.append("0"); 00285 } 00286 00287 //Put the fractional portion into a stringstream, and use 00288 //stream manipulators to round it properly 00289 stringstream b; 00290 b << std::showpoint 00291 << std::setprecision(thisCol.Precision()) 00292 << toDouble(tempString.join(".")); 00293 00294 //if the rounding causes a rollover (i.e. the decimal portion is greater 00295 //than 0.95) increment the integer portion 00296 if(toDouble(QString(b.str().c_str())) >= 1) { 00297 intPart = toString(toInt(intPart) + 1); 00298 } 00299 00300 //Put it back into an QString, for easier manipulation 00301 QString tempString2 = b.str().c_str(); 00302 tempString2.remove(QRegExp("[^.]*\\.")); 00303 //Add any zeros necessary to pad the number 00304 while(tempString2.size() < (int)thisCol.Precision()) { 00305 tempString2 += "0"; 00306 } 00307 00308 //Put the number back together, adding the decimal point in the right location 00309 thisItem = intPart + "." + tempString2; 00310 } 00311 stringstream tempStream; 00312 tempStream.width(thisCol.Width()); 00313 tempStream.fill(' '); 00314 00315 if(thisCol.Alignment() == Column::Left) { 00316 tempStream.setf(std::ios::left); 00317 } 00318 else tempStream.setf(std::ios::right); 00319 00320 tempStream << thisItem; 00321 thisItem = tempStream.str().c_str(); 00322 00323 if(p_curCol == 0) { 00324 p_rows++; 00325 } 00326 00327 //If the number is too wide for the column, replace with a string of stars 00328 if(thisItem.length() > (int)thisCol.Width()) { 00329 thisItem = "*"; 00330 while(thisItem.length() < (int)thisCol.Width()) { 00331 thisItem += "*"; 00332 } 00333 } 00334 00335 if(p_curCol < (p_cols.size() - 1)) { 00336 thisItem += p_delimiter; 00337 p_curCol++; 00338 } 00339 else { 00340 thisItem += "\n"; 00341 p_curCol = 0; 00342 } 00343 p_outfile << thisItem; 00344 00345 } 00346 00347 /** 00348 * Sets the string to be put between columns for this table 00349 * 00350 * @param delim The string to separate columns 00351 */ 00352 void WriteTabular::SetDelimiter(QString delim) { 00353 p_delimiter = delim; 00354 } 00355 00356 }