USGS

Isis 3.0 Application Source Code Reference

Home

WriteTabular.cpp
Go to the documentation of this file.
1 /**
2  * @file
3  * $Revision: 1.1 $
4  * $Date: 2007/08/09 18:24:24 $
5  *
6  * Unless noted otherwise, the portions of Isis written by the USGS are public
7  * domain. See individual third-party library and package descriptions for
8  * intellectual property information,user agreements, and related information.
9  *
10  * Although Isis has been used by the USGS, no warranty, expressed or implied,
11  * is made by the USGS as to the accuracy and functioning of such software
12  * and related material nor shall the fact of distribution constitute any such
13  * warranty, and no responsibility is assumed by the USGS in connection
14  * therewith.
15  *
16  * For additional information, launch
17  * $ISISROOT/doc//documents/Disclaimers/Disclaimers.html in a browser or see
18  * the Privacy & Disclaimers page on the Isis website,
19  * http://isis.astrogeology.usgs.gov, and the USGS privacy and disclaimers on
20  * http://www.usgs.gov/privacy.html.
21  */
22 
23 #include <fstream>
24 #include <iomanip>
25 #include <iostream>
26 #include <sstream>
27 
28 #include "WriteTabular.h"
29 #include "IString.h"
30 #include "Message.h"
31 #include "IException.h"
32 #include "SpecialPixel.h"
33 
34 using std::stringstream;
35 
36 namespace Isis {
37 
38  /**
39  * Constructor
40  * @param filename The name of the file where the table will be written
41  */
42  WriteTabular::WriteTabular(std::ostream &strm) : p_outfile(strm) {
43  p_rows = 0;
44  p_delimiter = ",";
45  p_curCol = 0;
46  }
47 
48  /**
49  * Constructor
50  * @param filename The name of the target file to contain the table, once
51  * formatted
52  * @param cols The Column headers, containing information about the Columns
53  */
54  WriteTabular::WriteTabular(std::ostream &strm, std::vector<Column> cols) : p_outfile(strm) {
55  p_rows = 0;
56  p_delimiter = ",";
57  p_curCol = 0;
58  SetColumns(cols);
59  }
60 
61  /**
62  * Sets the vector of Columns and writes out the first row of the file.
63  *
64  * @param cols A vector of Columns, setting the format of the table
65  */
66  void WriteTabular::SetColumns(std::vector <Column> cols) {
67  for(unsigned int index = 0; index < cols.size(); index++) {
68  Column thisCol = cols[index];
69  QString thisTitle = thisCol.Name();
70 
71  if((int)thisTitle.length() > (int)thisCol.Width()) {
72  QString message = "Column header [" + thisTitle + "] is wider " +
73  "than the set width for column [" + toString((int)index) + "]";
74  throw IException(IException::User, message, _FILEINFO_);
75  }
76 
77  int iteration = 0;
78  while((int)thisTitle.length() < (int)thisCol.Width()) {
79  if(thisCol.Alignment() == Column::Left) {
80  thisTitle += " ";
81  }
82  else if(thisCol.Alignment() == Column::Right ||
83  thisCol.Alignment() == Column::Decimal) {
84  thisTitle = " " + thisTitle;
85  }
86  else {
87  QString message = "Alignment is improperly set";
88  throw IException(IException::User, message, _FILEINFO_);
89  }
90  iteration++;
91  }//end while
92 
93  p_cols.push_back(thisCol);
94  p_outfile << thisTitle;
95  if(index < (cols.size() - 1)) {
96  p_outfile << p_delimiter;
97  }
98  }//end for
99  p_outfile << "\n";
100  }//end function
101 
102  /**
103  * Writes a blank space in the next column in the current row
104  */
106  Column thisCol = p_cols[p_curCol];
107 
108  QString item = "";
109 
110  stringstream tempStream;
111  tempStream.width(thisCol.Width());
112  tempStream.fill(' ');
113  tempStream << item;
114  item = tempStream.str().c_str();
115 
116  if(p_curCol == 0) {
117  p_rows++;
118  }
119 
120  if(p_curCol < (p_cols.size() - 1)) {
121  item += p_delimiter;
122  p_curCol++;
123  }
124  else {
125  item += "\n";
126  p_curCol = 0;
127  }
128  p_outfile << item;
129  }
130 
131  /**
132  * Add an integer value to the next column in this row
133  *
134  * @param item The integer value to put in this column.
135  */
136  void WriteTabular::Write(int item) {
137  Column thisCol = p_cols[p_curCol];
138  if(thisCol.DataType() != Column::Integer &&
139  thisCol.DataType() != Column::Pixel) {
140  if(thisCol.DataType() == Column::Real ||
141  thisCol.DataType() == Column::Pixel) {
142  Write((double)item);
143  return;
144  }
145  QString message = "Wrong data type for this Column";
146  throw IException(IException::User, message, _FILEINFO_);
147  }
148  QString thisItem(toString(item));
149  if(thisItem.length() > (int)thisCol.Width()) {
150  thisItem = "*";
151  while(thisItem.length() < (int)thisCol.Width()) {
152  thisItem += "*";
153  }
154  }
155  stringstream tempStream;
156  tempStream.width(thisCol.Width());
157  tempStream.fill(' ');
158 
159  if(thisCol.Alignment() == Column::Left) {
160  tempStream.setf(std::ios::left);
161  }
162  else tempStream.setf(std::ios::right);
163 
164  tempStream << thisItem;
165  thisItem = tempStream.str().c_str();
166 
167  if(p_curCol == 0) {
168  p_rows++;
169  }
170 
171  if(p_curCol < (p_cols.size() - 1)) {
172  thisItem += p_delimiter;
173  p_curCol++;
174  }
175  else {
176  thisItem += "\n";
177  p_curCol = 0;
178  }
179  p_outfile << thisItem;
180  }
181 
182  /**
183  * Writes a string to the next column in the current row
184  *
185  * @param item The string to write out
186  */
187  void WriteTabular::Write(const char *itemCStr) {
188  Column thisCol = p_cols[p_curCol];
189  if(thisCol.DataType() != Column::String &&
190  thisCol.DataType() != Column::Pixel) {
191  QString message = "Wrong data type for this Column";
192  throw IException(IException::User, message, _FILEINFO_);
193  }
194 
195  QString item(itemCStr);
196  if(item.length() > (int)thisCol.Width()) {
197  item = "*";
198  while(item.length() < (int)thisCol.Width()) {
199  item += "*";
200  }
201  }
202  stringstream tempStream;
203  tempStream.width(thisCol.Width());
204  tempStream.fill(' ');
205 
206  if(thisCol.Alignment() == Column::Left) {
207  tempStream.setf(std::ios::left);
208  }
209  else tempStream.setf(std::ios::right);
210 
211  tempStream << item;
212  item = tempStream.str().c_str();
213 
214  if(p_curCol == 0) {
215  p_rows++;
216  }
217 
218  if(p_curCol < (p_cols.size() - 1)) {
219  item += p_delimiter;
220  p_curCol++;
221  }
222  else {
223  item += "\n";
224  p_curCol = 0;
225  }
226  p_outfile << item;
227  }
228 
229  /**
230  * Writes a floating-point value out to the next column in the current row
231  *
232  * @param item The value to be printed out
233  */
234  void WriteTabular::Write(double item) {
235  Column thisCol = p_cols[p_curCol];
236  if(thisCol.DataType() != Column::Real &&
237  thisCol.DataType() != Column::Pixel) {
238  QString message = "Wrong data type for this Column";
239  throw IException(IException::User, message, _FILEINFO_);
240  }
241 
242  //Check for special pixels, if it's a pixel column
243  if(thisCol.DataType() == Column::Pixel && IsSpecial(item)) {
244  if(IsNullPixel(item)) {
245  Write("Null");
246  return;
247  }
248  if(IsHisPixel(item)) {
249  Write("His");
250  return;
251  }
252  if(IsHrsPixel(item)) {
253  Write("Hrs");
254  return;
255  }
256  if(IsLisPixel(item)) {
257  Write("Lis");
258  return;
259  }
260  if(IsLrsPixel(item)) {
261  Write("Lrs");
262  return;
263  }
264  }
265 
266  QString thisItem(toString(item));
267 
268 
269  if(thisCol.Alignment() == Column::Decimal) {
270 
271  //Format and round the number
272 
273  //First, split the number at the decimal point
274  QStringList tempString = thisItem.split(".");
275  QString intPart = tempString.takeFirst();
276 
277  //Make the fractional portion appear as such, so the iomanipulators
278  //handle it properly
279  if(!tempString.isEmpty()) {
280  tempString.prepend("0");
281  }
282  else {
283  tempString.append("0");
284  tempString.append("0");
285  }
286 
287  //Put the fractional portion into a stringstream, and use
288  //stream manipulators to round it properly
289  stringstream b;
290  b << std::showpoint
291  << std::setprecision(thisCol.Precision())
292  << toDouble(tempString.join("."));
293 
294  //if the rounding causes a rollover (i.e. the decimal portion is greater
295  //than 0.95) increment the integer portion
296  if(toDouble(QString(b.str().c_str())) >= 1) {
297  intPart = toString(toInt(intPart) + 1);
298  }
299 
300  //Put it back into an QString, for easier manipulation
301  QString tempString2 = b.str().c_str();
302  tempString2.remove(QRegExp("[^.]*\\."));
303  //Add any zeros necessary to pad the number
304  while(tempString2.size() < (int)thisCol.Precision()) {
305  tempString2 += "0";
306  }
307 
308  //Put the number back together, adding the decimal point in the right location
309  thisItem = intPart + "." + tempString2;
310  }
311  stringstream tempStream;
312  tempStream.width(thisCol.Width());
313  tempStream.fill(' ');
314 
315  if(thisCol.Alignment() == Column::Left) {
316  tempStream.setf(std::ios::left);
317  }
318  else tempStream.setf(std::ios::right);
319 
320  tempStream << thisItem;
321  thisItem = tempStream.str().c_str();
322 
323  if(p_curCol == 0) {
324  p_rows++;
325  }
326 
327  //If the number is too wide for the column, replace with a string of stars
328  if(thisItem.length() > (int)thisCol.Width()) {
329  thisItem = "*";
330  while(thisItem.length() < (int)thisCol.Width()) {
331  thisItem += "*";
332  }
333  }
334 
335  if(p_curCol < (p_cols.size() - 1)) {
336  thisItem += p_delimiter;
337  p_curCol++;
338  }
339  else {
340  thisItem += "\n";
341  p_curCol = 0;
342  }
343  p_outfile << thisItem;
344 
345  }
346 
347  /**
348  * Sets the string to be put between columns for this table
349  *
350  * @param delim The string to separate columns
351  */
352  void WriteTabular::SetDelimiter(QString delim) {
353  p_delimiter = delim;
354  }
355 
356 }
uint8 left[]
Definition: pmain.cpp:64
WriteTabular(std::ostream &strm, std::vector< Column > cols)
Constructor.
void Write()
Writes a blank space in the next column in the current row.
void SetDelimiter(QString delim)
Sets the string to be put between columns for this table.
double toDouble(const T &value)
Helper function to convert values to doubles.
Definition: MdisCalUtils.h:49
uint8 right[]
Definition: pmain.cpp:65
void SetColumns(std::vector< Column > cols)
Sets the vector of Columns and writes out the first row of the file.