NCBI C++ ToolKit
table_printer.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: table_printer.cpp 72358 2016-05-03 17:12:04Z ivanov $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Michael Kornbluh
27  *
28  * File Description: Prints out neatly-aligned ASCII tables.
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
34 #include <iterator>
35 
36 #include <util/table_printer.hpp>
37 
39 
41  const string & sColName,
42  Uint4 iColWidth,
43  EJustify eJustify,
44  EDataTooLong eDataTooLong )
45 {
46  m_colInfoVec.push_back(SColInfo(
47  sColName,
48  iColWidth,
49  eJustify,
50  eDataTooLong));
51 }
52 
54  const SColInfoVec & vecColInfo,
55  ostream & ostrm,
56  const string & sColumnSeparator)
58  m_vecColInfo(vecColInfo), m_ostrm(ostrm), m_iNextCol(0),
59  m_sColumnSeparator(sColumnSeparator)
60 {
61  // if any column width is less than the length of the name of the column,
62  // expand it
65  {
66  col_it->m_iColWidth =
67  max<Uint4>(col_it->m_iColWidth, (Uint4)col_it->m_sColName.length());
68  }
69 }
70 
72 {
73  switch(m_eState) {
74  case eState_Initial:
75  // nothing written, so nothing to finish
76  break;
78  // close rows with dashes
79  x_PrintDashes();
81  break;
82  default:
83  NCBI_USER_THROW_FMT("Bad state: " << static_cast<int>(m_eState));
84  }
85 }
86 
88  const string * pSep = &kEmptyStr;
89  ITERATE(
91  {
92  m_ostrm << *pSep;
93  pSep = &m_sColumnSeparator;
94 
95  m_ostrm << string(col_it->m_iColWidth, '-');
96  }
97  m_ostrm << endl;
98 }
99 
101  const string * pSep = &kEmptyStr;
102  ITERATE(
104  {
105  m_ostrm << *pSep;
106  pSep = &m_sColumnSeparator;
107 
108  m_ostrm << setw(col_it->m_iColWidth) << left
109  << col_it->m_sColName;
110  }
111  m_ostrm << endl;
112 }
113 
115  const string & sValue)
116 {
117  if( m_eState == eState_Initial ) {
118  x_PrintDashes();
120  x_PrintDashes();
122  }
123 
124  const SColInfo & colInfo =
126 
127  // write the value
128  m_ostrm << setw(colInfo.m_iColWidth)
129  << ( colInfo.m_eJustify == eJustify_Left ? left : right);
130  if( sValue.length() > colInfo.m_iColWidth ) {
131  // handle a cell value that's too long
132  switch(colInfo.m_eDataTooLong) {
134  static const char kErrMsg[] = "**ERROR**";
135  static const size_t kErrMsgLen = sizeof(kErrMsg) - 1;
136  if( colInfo.m_iColWidth >= kErrMsgLen ) {
137  m_ostrm << kErrMsg;
138  } else {
139  m_ostrm << string(colInfo.m_iColWidth, '?');
140  }
141  break;
142  }
144  const static string kEllipses = "...";
145 
146  if( colInfo.m_iColWidth > kEllipses.length() ) {
147  string::const_iterator value_end_it = sValue.end();
148  value_end_it -= kEllipses.length();
149  m_ostrm << setw(1);
150  copy( sValue.begin(), value_end_it,
151  ostream_iterator<char>(m_ostrm) );
152  m_ostrm << kEllipses;
153  } else {
154  // even ellipses won't fit
155  m_ostrm << string(colInfo.m_iColWidth, '?');
156  }
157  break;
158  }
159 
161  // recklessly print the whole string, regardless of how
162  // it may corrupt this row's formatting and regardless of
163  // how long it might be.
164  m_ostrm << sValue;
165  break;
167  default:
169  "CTablePrinter cannot fit cell data into allotted space. "
170  "Column name: " << colInfo.m_sColName
171  << ", Column width: " << colInfo.m_iColWidth
172  << ", Length of oversized data: " << sValue.length()
173  << "Oversized data starts with: "
174  << sValue.substr(0, colInfo.m_iColWidth) << "...[snip]...");
175  }
176  } else {
177  // no problem, so just write it
178  m_ostrm << sValue;
179  }
180 
181  // go to the next column
182  ++m_iNextCol;
183  if( m_iNextCol >= m_vecColInfo.m_colInfoVec.size() ) {
184  m_iNextCol = 0;
185  m_ostrm << endl;
186  } else {
188  }
189 }
190 
192 
CTablePrinter(const SColInfoVec &vecColInfo, ostream &ostrm, const string &sColumnSeparator=" ")
SColInfoVec m_vecColInfo
The info about columns of the table.
const string m_sColumnSeparator
The text that separates columns (both in the header as well as dat).
Uint4 m_iNextCol
The 0-based index of the column that the next AddCell will use.
void FinishTable(void)
If the table is not already finished, this finishes it by writing the closing row (which is usually a...
EDataTooLong
controls how table should behave when a data cell is too long to fit into its column.
@ eDataTooLong_ShowErrorInColumn
The data will be replaced with some sort of error message, or at least question marks if the error me...
@ eDataTooLong_ShowWholeData
This recklessly prints the whole table data, regardless of formatting corruption and regardless of ho...
@ eDataTooLong_TruncateWithEllipses
The data is truncated with ellipses (that is, "...").
@ eDataTooLong_ThrowException
Throws an exception when the data won't fit.
void x_PrintDashes(void)
This writes a row of dashes which starts the table, separates the header from the data,...
void x_PrintColumnNames(void)
This prints the column names, appropriately spaced and separated.
ostream & m_ostrm
The ostream to which the table is written.
EState m_eState
This keeps track of the state of the table writer.
@ eState_PrintingRows
This means the header row HAS been printed, and data rows are being printed.
@ eState_Initial
This means the header row has NOT been printed yet.
EJustify
controls how the data in each column is justified.
void x_AddCellValue(const string &sValue)
This is the underlying logic to add another cell to the table data.
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
string
Definition: cgiapp.hpp:687
#define NCBI_USER_THROW_FMT(message)
Throw a "user exception" with message processed as output to ostream.
Definition: ncbiexpt.hpp:724
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
Definition: njn_matrix.hpp:613
This holds the info about all columns for the table.
vector< SColInfo > TColInfoVec
void AddCol(const string &sColName, Uint4 iColWidth=0, EJustify eJustify=eJustify_Left, EDataTooLong eDataTooLong=eDataTooLong_Default)
TColInfoVec m_colInfoVec
The underlying column info vector for which SColInfoVec is a wrapper.
This structure contains info about a given column.
EJustify m_eJustify
Justification of data cells in this column (the name of the column is always left-justified,...
EDataTooLong m_eDataTooLong
How data cells should behave in this column behave when there is too much data to fit in them.
string m_sColName
The name of the column, which is shown in the header.
Uint4 m_iColWidth
How many characters wide the column is.
Modified on Wed Jun 12 11:10:58 2024 by modify_doxy.py rev. 669887