apt  2.2.4
About: Apt (Advanced Package Tool) is a management system for software packages (Debian/Ubuntu). Release series 2.2.
  Fossies Dox: apt-2.2.4.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

progress.cc
Go to the documentation of this file.
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 /* ######################################################################
4 
5  OpProgress - Operation Progress
6 
7  ##################################################################### */
8  /*}}}*/
9 // Include Files /*{{{*/
10 #include <config.h>
11 
12 #include <apt-pkg/configuration.h>
13 #include <apt-pkg/error.h>
14 #include <apt-pkg/progress.h>
15 
16 #include <cmath>
17 #include <chrono>
18 #include <cstring>
19 #include <iostream>
20 #include <string>
21 #include <stdio.h>
22 #include <sys/time.h>
23 
24 #include <apti18n.h>
25  /*}}}*/
26 
27 using namespace std;
28 
29 // OpProgress::OpProgress - Constructor /*{{{*/
30 // ---------------------------------------------------------------------
31 /* */
32 OpProgress::OpProgress() : Current(0), Total(0), Size(0), SubTotal(1),
33  LastPercent(0), Percent(0)
34 {
35  memset(&LastTime,0,sizeof(LastTime));
36 }
37  /*}}}*/
38 // OpProgress::Progress - Sub progress with no state change /*{{{*/
39 // ---------------------------------------------------------------------
40 /* Current is the Base Overall progress in units of Total. Cur is the sub
41  progress in units of SubTotal. Size is a scaling factor that says what
42  percent of Total SubTotal is. */
43 void OpProgress::Progress(unsigned long long Cur)
44 {
45  if (Total == 0 || Size == 0 || SubTotal == 0)
46  Percent = 0;
47  else
48  Percent = (Current + Cur/((double)SubTotal)*Size)*100.0/Total;
49  Update();
50 }
51  /*}}}*/
52 // OpProgress::OverallProgress - Set the overall progress /*{{{*/
53 // ---------------------------------------------------------------------
54 /* */
55 void OpProgress::OverallProgress(unsigned long long Current, unsigned long long Total,
56  unsigned long long Size,const string &Op)
57 {
58  this->Current = Current;
59  this->Total = Total;
60  this->Size = Size;
61  this->Op = Op;
62  SubOp = string();
63  if (Total == 0)
64  Percent = 0;
65  else
66  Percent = Current*100.0/Total;
67  Update();
68 }
69  /*}}}*/
70 // OpProgress::SubProgress - Set the sub progress state /*{{{*/
71 // ---------------------------------------------------------------------
72 /* */
73 void OpProgress::SubProgress(unsigned long long SubTotal,const string &Op,
74  float const Percent)
75 {
76  this->SubTotal = SubTotal;
77  if (Op.empty() == false)
78  SubOp = Op;
79  if (Total == 0 || Percent == 0)
80  this->Percent = 0;
81  else if (Percent != -1)
82  this->Percent = this->Current += (Size*Percent)/SubTotal;
83  else
84  this->Percent = Current*100.0/Total;
85  Update();
86 }
87  /*}}}*/
88 // OpProgress::CheckChange - See if the display should be updated /*{{{*/
89 // ---------------------------------------------------------------------
90 /* Progress calls are made so frequently that if every one resulted in
91  an update the display would be swamped and the system much slower.
92  This provides an upper bound on the update rate. */
93 bool OpProgress::CheckChange(float Interval)
94 {
95  // For absolute progress, we assume every call is relevant.
96  if (_config->FindB("APT::Internal::OpProgress::Absolute", false))
97  return true;
98  // New major progress indication
99  if (Op != LastOp)
100  {
101  MajorChange = true;
102  LastOp = Op;
103  return true;
104  }
105  MajorChange = false;
106 
107  if (SubOp != LastSubOp)
108  {
109  LastSubOp = SubOp;
110  return true;
111  }
112 
113  if (std::lround(LastPercent) == std::lround(Percent))
114  return false;
115 
117 
118  if (Interval == 0)
119  return false;
120 
121  // Check time delta
122  auto const Now = std::chrono::steady_clock::now().time_since_epoch();
123  auto const Now_sec = std::chrono::duration_cast<std::chrono::seconds>(Now);
124  auto const Now_usec = std::chrono::duration_cast<std::chrono::microseconds>(Now - Now_sec);
125  struct timeval NowTime = { Now_sec.count(), Now_usec.count() };
126 
127  std::chrono::duration<decltype(Interval)> Delta =
128  std::chrono::seconds(NowTime.tv_sec - LastTime.tv_sec) +
129  std::chrono::microseconds(NowTime.tv_usec - LastTime.tv_usec);
130 
131  if (Delta.count() < Interval)
132  return false;
133  LastTime = NowTime;
134  return true;
135 }
136  /*}}}*/
137 // OpTextProgress::OpTextProgress - Constructor /*{{{*/
138 // ---------------------------------------------------------------------
139 /* */
141  NoUpdate(false), NoDisplay(false), LastLen(0)
142 {
143  if (Config.FindI("quiet",0) >= 1 || Config.FindB("quiet::NoUpdate", false) == true)
144  NoUpdate = true;
145  if (Config.FindI("quiet",0) >= 2 || Config.FindB("quiet::NoProgress", false) == true)
146  NoDisplay = true;
147 }
148  /*}}}*/
149 // OpTextProgress::Done - Clean up the display /*{{{*/
150 // ---------------------------------------------------------------------
151 /* */
153 {
154  if (NoUpdate == false && OldOp.empty() == false)
155  {
156  char S[300];
157  if (_error->PendingError() == true)
158  snprintf(S,sizeof(S),_("%c%s... Error!"),'\r',OldOp.c_str());
159  else
160  snprintf(S,sizeof(S),_("%c%s... Done"),'\r',OldOp.c_str());
161  Write(S);
162  cout << endl;
163  OldOp = string();
164  }
165 
166  if (NoUpdate == true && NoDisplay == false && OldOp.empty() == false)
167  {
168  OldOp = string();
169  cout << endl;
170  }
171 }
172  /*}}}*/
173 // OpTextProgress::Update - Simple text spinner /*{{{*/
174 // ---------------------------------------------------------------------
175 /* */
177 {
178  if (CheckChange((NoUpdate == true?0:0.7)) == false)
179  return;
180 
181  // No percent spinner
182  if (NoUpdate == true)
183  {
184  if (MajorChange == false)
185  return;
186  if (NoDisplay == false)
187  {
188  if (OldOp.empty() == false)
189  cout << endl;
190  OldOp = "a";
191  cout << Op << _("...") << flush;
192  }
193 
194  return;
195  }
196 
197  // Erase the old text and 'log' the event
198  char S[300];
199  if (MajorChange == true && OldOp.empty() == false)
200  {
201  snprintf(S,sizeof(S),"\r%s",OldOp.c_str());
202  Write(S);
203  cout << endl;
204  }
205 
206  // Print the spinner. Absolute progress shows us a time progress.
207  if (_config->FindB("APT::Internal::OpProgress::Absolute", false) && Total != -1llu)
208  snprintf(S, sizeof(S), _("%c%s... %llu/%llus"), '\r', Op.c_str(), Current, Total);
209  else if (_config->FindB("APT::Internal::OpProgress::Absolute", false))
210  snprintf(S, sizeof(S), _("%c%s... %llus"), '\r', Op.c_str(), Current);
211  else
212  snprintf(S, sizeof(S), _("%c%s... %u%%"), '\r', Op.c_str(), (unsigned int)Percent);
213  Write(S);
214 
215  OldOp = Op;
216 }
217  /*}}}*/
218 // OpTextProgress::Write - Write the progress string /*{{{*/
219 // ---------------------------------------------------------------------
220 /* This space fills the end to overwrite the previous text */
221 void OpTextProgress::Write(const char *S)
222 {
223  cout << S;
224  for (unsigned int I = strlen(S); I < LastLen; I++)
225  cout << ' ';
226  cout << '\r' << flush;
227  LastLen = strlen(S);
228 }
229  /*}}}*/
static bool std::string const metaIndex const *const pkgAcqMetaClearSig *const pkgAcquire::Item *const I
return false
Provide access methods to various configuration settings.
std::string Op
Definition: progress.h:45
bool CheckChange(float Interval=0.7)
Definition: progress.cc:93
std::string SubOp
Definition: progress.h:46
unsigned long long Size
Definition: progress.h:34
float Percent
Definition: progress.h:47
void OverallProgress(unsigned long long Current, unsigned long long Total, unsigned long long Size, const std::string &Op)
Definition: progress.cc:55
float LastPercent
Definition: progress.h:36
struct timeval LastTime
Definition: progress.h:39
bool MajorChange
Definition: progress.h:49
friend class OpTextProgress
Definition: progress.h:31
std::string LastOp
Definition: progress.h:40
void Progress(unsigned long long Current)
Definition: progress.cc:43
void SubProgress(unsigned long long SubTotal, const std::string &Op="", float const Percent=-1)
Definition: progress.cc:73
unsigned long long SubTotal
Definition: progress.h:35
unsigned long long Total
Definition: progress.h:33
OpProgress()
Definition: progress.cc:32
unsigned long long Current
Definition: progress.h:32
virtual void Update()
Definition: progress.h:52
std::string LastSubOp
Definition: progress.h:41
virtual void Update() APT_OVERRIDE
Definition: progress.cc:176
bool NoUpdate
Definition: progress.h:71
virtual void Done() APT_OVERRIDE
Definition: progress.cc:152
void Write(const char *S)
Definition: progress.cc:221
std::string OldOp
Definition: progress.h:70
bool NoDisplay
Definition: progress.h:72
unsigned long LastLen
Definition: progress.h:73
Configuration * _config