1 /*
2  * Copyright (C) 2011-2019 Daniel Scharrer
3  *
4  * This software is provided 'as-is', without any express or implied
5  * warranty.  In no event will the author(s) be held liable for any damages
6  * arising from the use of this software.
7  *
8  * Permission is granted to anyone to use this software for any purpose,
9  * including commercial applications, and to alter it and redistribute it
10  * freely, subject to the following restrictions:
11  *
12  * 1. The origin of this software must not be misrepresented; you must not
13  *    claim that you wrote the original software. If you use this software
14  *    in a product, an acknowledgment in the product documentation would be
15  *    appreciated but is not required.
16  * 2. Altered source versions must be plainly marked as such, and must not be
17  *    misrepresented as being the original software.
18  * 3. This notice may not be removed or altered from any source distribution.
19  */
20 
21 /*!
22  * \file
23  *
24  * Terminal output functions: colors, progress bar.
25  */
26 #ifndef INNOEXTRACT_UTIL_CONSOLE_HPP
27 #define INNOEXTRACT_UTIL_CONSOLE_HPP
28 
29 #include <stddef.h>
30 #include <ostream>
31 #include <iomanip>
32 #include <sstream>
33 
34 #include <boost/date_time/posix_time/ptime.hpp>
35 #include <boost/cstdint.hpp>
36 
37 namespace color {
38 
39 /*!
40  * Object that can be written to the console to change the output color.
41  */
42 struct shell_command {
43 	const char * command;
44 };
45 
46 //! Reset the output color to the original value.
47 extern shell_command reset;
48 
49 extern shell_command black;
50 extern shell_command red;
51 extern shell_command green;
52 extern shell_command yellow;
53 extern shell_command blue;
54 extern shell_command magenta;
55 extern shell_command cyan;
56 extern shell_command white;
57 
58 extern shell_command dim_black;
59 extern shell_command dim_red;
60 extern shell_command dim_green;
61 extern shell_command dim_yellow;
62 extern shell_command dim_blue;
63 extern shell_command dim_magenta;
64 extern shell_command dim_cyan;
65 extern shell_command dim_white;
66 
67 //! The last set output color.
68 extern shell_command current;
69 
operator <<(std::ostream & os,shell_command command)70 inline std::ostream & operator<<(std::ostream & os, shell_command command) {
71 	color::current = command;
72 	return os << command.command;
73 }
74 
75 enum is_enabled {
76 	enable,
77 	disable,
78 	automatic
79 };
80 
81 /*!
82  * Initilize console output functions.
83  *
84  * \param color    Enable or disable color output.
85  * \param progress Enable or disable progress bar output.
86  */
87 void init(is_enabled color = automatic, is_enabled progress = automatic);
88 
89 } // namespace color
90 
91 enum ClearMode {
92 	FullClear,    //!< Perform a full clear.
93 	FastClear,    //!< Perform a full clear if it is cheap, otherwise only reset the cursor.
94 	DeferredClear //!< Perform a full clear if it is cheap, otherwise leave the line as-is,
95 	              //!< but insert new writes before it until the next full/fast clear.
96 };
97 
98 //! A text-based progress bar for terminals.
99 class progress {
100 
101 	boost::uint64_t max;
102 	boost::uint64_t value;
103 	bool show_rate;
104 
105 	boost::posix_time::ptime start_time;
106 
107 	float last_status;
108 	boost::uint64_t last_time;
109 
110 	float last_rate;
111 	std::ostringstream label;
112 
113 public:
114 
115 	/*!
116 	 * \param max_value       Maximumum progress values.
117 	 *                        If this value is \c 0, the progress bar will be unbounded.
118 	 * \param show_value_rate Display the rate at which the progress changes.
119 	 */
120 	progress(boost::uint64_t max_value = 0, bool show_value_rate = true);
121 
122 	/*!
123 	 * Update the progress bar.
124 	 *
125 	 * \param delta Value to add to the progress. When the total progress value reaches the
126 	 *              maximum set in the constructor, the bar will be full.
127 	 * \param force Force updating the progress bar. Normally, the progress bar. Otherwise,
128 	 *              updates are rate-limited and small deltas are not displayed immediately.
129 	 *
130 	 * \return true if the progres bar was updated
131 	 */
132 	bool update(boost::uint64_t delta = 0, bool force = false);
133 
134 	/*!
135 	 * Draw a bounded progress bar (with a maximum).
136 	 *
137 	 * \param value The progress value, between \c 0.f and \c 1.f.
138 	 * \param label A label to draw next to the progress bar.
139 	 */
140 	static void show(float value, const std::string & label = std::string());
141 
142 	/*!
143 	 * Draw an unbounded progress bar (without a maximum).
144 	 *
145 	 * \param value The progress value, between \c 0.f and \c 1.f.
146 	 * \param label A label to draw next to the progress bar.
147 	 */
148 	static void show_unbounded(float value, const std::string & label = std::string());
149 
150 	/*!
151 	 * Clear any progress bar to make way for other output.
152 	 *
153 	 * \param mode The clear mode to perform.
154 	 */
155 	static void clear(ClearMode mode = FullClear);
156 
157 	//! Enable or disable the progress bar.
158 	static void set_enabled(bool enable);
159 
160 	static bool is_enabled();
161 
162 };
163 
164 #endif // INNOEXTRACT_UTIL_CONSOLE_HPP
165