Format.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "Format.hh"
18 #include "Format.ih"
19 
20 // Custom includes
21 #include <cmath>
22 #include <boost/io/ios_state.hpp>
23 #include <iomanip>
24 #include <sstream>
25 
26 //#include "Format.mpp"
27 #define prefix_
28 //-/////////////////////////////////////////////////////////////////////////////////////////////////
29 
30 namespace {
31 
32  char const SIPrefix[] = { 'y', 'z', 'a', 'f', 'p', 'n', 'u', 'm',
33  ' ',
34  'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y' };
35  unsigned const SIScales = 8;
36 
37 }
38 
39 prefix_ std::ostream & senf::format::operator<<(std::ostream & os, eng const & v_)
40 {
41  boost::io::ios_base_all_saver ibas (os);
42  boost::io::ios_fill_saver ifs (os);
43 
44  os.setf(v_.flags_, v_.mask_);
45  if (v_.havePrecision_)
46  os.precision(v_.precision_);
47  if (v_.haveWidth_)
48  os.width(v_.width_);
49  if (v_.haveFill_)
50  os.fill(v_.fill_);
51 
52  unsigned prec (os.precision());
53  if (prec < 4)
54  prec = 4;
55  unsigned w (os.width());
56  char fill (os.fill());
57  unsigned minw (prec+2+((os.flags() & std::ios_base::showbase) ? 1 : 4));
58  std::ios_base::fmtflags flags (os.flags());
59  std::ios_base::fmtflags align (flags & std::ios_base::adjustfield);
60  if (! std::isnan(v_.d_))
61  minw += prec+3;
62 
63  float ref (std::fabs(v_.v_));
64  float v (v_.v_);
65  float d (0.0);
66  if (! std::isnan(v_.d_)) d = std::fabs(v_.d_);
67  int scale (0);
68 
69  if (d > ref) ref = d;
70  while (ref >= 1000.0f) {
71  ref /= 1000.0f;
72  v /= 1000.0f;
73  d /= 1000.0f;
74  scale += 3;
75  }
76  while (ref > 0 && ref < 1) {
77  ref *= 1000.0f;
78  v *= 1000.0f;
79  d *= 1000.0f;
80  scale -= 3;
81  }
82 
83  os << std::dec << std::setprecision(prec-3) << std::fixed;
84  if (w > 0) {
85  if ((align == 0 || align == std::ios_base::right || align == std::ios_base::internal))
86  os << std::setw(prec+2+(w>minw ? w-minw : 0));
87  else
88  os << std::right << std::setfill(' ') << std::setw(prec+2);
89  }
90  else
91  os << std::right;
92  os << v;
93 
94  os << std::setfill('0') << std::noshowpos;
95  if (! std::isnan(v_.d_)) {
96  os << "+-";
97  if (w > 0)
98  os << std::setw(prec+1);
99  os << d;
100  }
101 
102  if ((flags & std::ios_base::showbase) && unsigned(std::abs(scale/3)) <= SIScales) {
103  if (w > 0 || scale != 0)
104  os << SIPrefix[scale/3+SIScales];
105  }
106  else if ((flags & std::ios_base::showpoint) || scale != 0)
107  os << ((flags & std::ios_base::uppercase)?'E':'e')
108  << std::showpos << std::internal << std::setw(3) << scale;
109  else if (w > 0)
110  os << " ";
111  if (w > minw && align == std::ios_base::left)
112  os << std::setfill(fill) << std::setw(w-minw) << "";
113 
114  return os;
115 }
116 
117 prefix_ std::string senf::format::detail::dumpintSigned(long long v, unsigned bits)
118 {
119  if (v<0) return dumpintUnsigned(-v,bits,-1);
120  else return dumpintUnsigned(v,bits,+1);
121 }
122 
123 prefix_ std::string senf::format::detail::dumpintUnsigned(unsigned long long v, unsigned bits,
124  int sign)
125 {
126  int bytes ((bits+7)/8);
127  int digs (int(2.4*bytes)+1);
128  std::stringstream ss;
129  ss << (sign ? (sign<0 ? "-" : " ") : "")
130  << "0x" << std::setw(2*bytes) << std::setfill('0') << std::hex
131  << 1u*v
132  << " (" << std::setw(digs+(sign ? 1 : 0)) << std::setfill(' ') << std::dec;
133  if (sign)
134  ss << sign*static_cast<long long>(v);
135  else
136  ss << 1u*v;
137  ss << ") (";
138  for (int i (bytes-1); i>=0; --i) {
139  char c ((v>>(8*i))&0xff);
140  ss << ((c>=32 && c<=126) ? c : '.');
141  }
142  ss << ')';
143  return ss.str();
144 }
145 
146 unsigned int senf::format::IndentHelper::static_level = 0;
147 
148 
149 //-/////////////////////////////////////////////////////////////////////////////////////////////////
150 #undef prefix_
151 //#include "Format.mpp"
152 
153 
154 // Local Variables:
155 // mode: c++
156 // fill-column: 100
157 // comment-column: 40
158 // c-file-style: "senf"
159 // indent-tabs-mode: nil
160 // ispell-local-dictionary: "american"
161 // compile-command: "scons -u test"
162 // End:
std::ostream & operator<<(std::ostream &os, Packet const &packet)
PacketParserBase::size_type bytes(Parser const &p)
Format public header.
streamable_type eng(float v, float d=NAN)
Format value in engineering representation.
#define prefix_
Definition: Format.cc:27