ping: use a member function rather than `operator<<` for stats

Change-Id: I8e2d469d80d9b5d5e82d14e9f3039a464a7eeae5
diff --git a/COPYING.md b/COPYING.md
index 2fb2e74..496acdb 100644
--- a/COPYING.md
+++ b/COPYING.md
@@ -1,4 +1,4 @@
-### GNU GENERAL PUBLIC LICENSE
+# GNU GENERAL PUBLIC LICENSE
 
 Version 3, 29 June 2007
 
@@ -8,7 +8,7 @@
 Everyone is permitted to copy and distribute verbatim copies of this
 license document, but changing it is not allowed.
 
-### Preamble
+## Preamble
 
 The GNU General Public License is a free, copyleft license for
 software and other kinds of works.
@@ -73,9 +73,9 @@
 The precise terms and conditions for copying, distribution and
 modification follow.
 
-### TERMS AND CONDITIONS
+## TERMS AND CONDITIONS
 
-#### 0. Definitions.
+### 0. Definitions.
 
 "This License" refers to version 3 of the GNU General Public License.
 
@@ -115,7 +115,7 @@
 the interface presents a list of user commands or options, such as a
 menu, a prominent item in the list meets this criterion.
 
-#### 1. Source Code.
+### 1. Source Code.
 
 The "source code" for a work means the preferred form of the work for
 making modifications to it. "Object code" means any non-source form of
@@ -156,7 +156,7 @@
 The Corresponding Source for a work in source code form is that same
 work.
 
-#### 2. Basic Permissions.
+### 2. Basic Permissions.
 
 All rights granted under this License are granted for the term of
 copyright on the Program, and are irrevocable provided the stated
@@ -181,7 +181,7 @@
 conditions stated below. Sublicensing is not allowed; section 10 makes
 it unnecessary.
 
-#### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+### 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
 
 No covered work shall be deemed part of an effective technological
 measure under any applicable law fulfilling obligations under article
@@ -197,7 +197,7 @@
 the work's users, your or third parties' legal rights to forbid
 circumvention of technological measures.
 
-#### 4. Conveying Verbatim Copies.
+### 4. Conveying Verbatim Copies.
 
 You may convey verbatim copies of the Program's source code as you
 receive it, in any medium, provided that you conspicuously and
@@ -210,7 +210,7 @@
 You may charge any price or no price for each copy that you convey,
 and you may offer support or warranty protection for a fee.
 
-#### 5. Conveying Modified Source Versions.
+### 5. Conveying Modified Source Versions.
 
 You may convey a work based on the Program, or the modifications to
 produce it from the Program, in the form of source code under the
@@ -245,7 +245,7 @@
 in an aggregate does not cause this License to apply to the other
 parts of the aggregate.
 
-#### 6. Conveying Non-Source Forms.
+### 6. Conveying Non-Source Forms.
 
 You may convey a covered work in object code form under the terms of
 sections 4 and 5, provided that you also convey the machine-readable
@@ -341,7 +341,7 @@
 source code form), and must require no special password or key for
 unpacking, reading or copying.
 
-#### 7. Additional Terms.
+### 7. Additional Terms.
 
 "Additional permissions" are terms that supplement the terms of this
 License by making exceptions from one or more of its conditions.
@@ -400,7 +400,7 @@
 form of a separately written license, or stated as exceptions; the
 above requirements apply either way.
 
-#### 8. Termination.
+### 8. Termination.
 
 You may not propagate or modify a covered work except as expressly
 provided under this License. Any attempt otherwise to propagate or
@@ -428,7 +428,7 @@
 reinstated, you do not qualify to receive new licenses for the same
 material under section 10.
 
-#### 9. Acceptance Not Required for Having Copies.
+### 9. Acceptance Not Required for Having Copies.
 
 You are not required to accept this License in order to receive or run
 a copy of the Program. Ancillary propagation of a covered work
@@ -439,7 +439,7 @@
 not accept this License. Therefore, by modifying or propagating a
 covered work, you indicate your acceptance of this License to do so.
 
-#### 10. Automatic Licensing of Downstream Recipients.
+### 10. Automatic Licensing of Downstream Recipients.
 
 Each time you convey a covered work, the recipient automatically
 receives a license from the original licensors, to run, modify and
@@ -464,7 +464,7 @@
 any patent claim is infringed by making, using, selling, offering for
 sale, or importing the Program or any portion of it.
 
-#### 11. Patents.
+### 11. Patents.
 
 A "contributor" is a copyright holder who authorizes use under this
 License of the Program or a work on which the Program is based. The
@@ -533,7 +533,7 @@
 any implied license or other defenses to infringement that may
 otherwise be available to you under applicable patent law.
 
-#### 12. No Surrender of Others' Freedom.
+### 12. No Surrender of Others' Freedom.
 
 If conditions are imposed on you (whether by court order, agreement or
 otherwise) that contradict the conditions of this License, they do not
@@ -546,7 +546,7 @@
 satisfy both those terms and this License would be to refrain entirely
 from conveying the Program.
 
-#### 13. Use with the GNU Affero General Public License.
+### 13. Use with the GNU Affero General Public License.
 
 Notwithstanding any other provision of this License, you have
 permission to link or combine any covered work with a work licensed
@@ -557,7 +557,7 @@
 section 13, concerning interaction through a network will apply to the
 combination as such.
 
-#### 14. Revised Versions of this License.
+### 14. Revised Versions of this License.
 
 The Free Software Foundation may publish revised and/or new versions
 of the GNU General Public License from time to time. Such new versions
@@ -583,7 +583,7 @@
 author or copyright holder as a result of your choosing to follow a
 later version.
 
-#### 15. Disclaimer of Warranty.
+### 15. Disclaimer of Warranty.
 
 THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
 APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
@@ -595,7 +595,7 @@
 DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR
 CORRECTION.
 
-#### 16. Limitation of Liability.
+### 16. Limitation of Liability.
 
 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR
@@ -607,7 +607,7 @@
 TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER
 PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 
-#### 17. Interpretation of Sections 15 and 16.
+### 17. Interpretation of Sections 15 and 16.
 
 If the disclaimer of warranty and limitation of liability provided
 above cannot be given local legal effect according to their terms,
@@ -618,7 +618,7 @@
 
 END OF TERMS AND CONDITIONS
 
-### How to Apply These Terms to Your New Programs
+## How to Apply These Terms to Your New Programs
 
 If you develop a new program, and you want it to be of the greatest
 possible use to the public, the best way to achieve this is to make it
diff --git a/tools/ping/client/main.cpp b/tools/ping/client/main.cpp
index d29549b..2e5e337 100644
--- a/tools/ping/client/main.cpp
+++ b/tools/ping/client/main.cpp
@@ -64,8 +64,8 @@
       return 2;
     }
 
-    Statistics statistics = m_statisticsCollector.computeStatistics();
-    std::cout << statistics << "\n";
+    auto statistics = m_statisticsCollector.computeStatistics();
+    statistics.printFull(std::cout);
 
     if (statistics.nReceived == statistics.nSent) {
       return 0;
@@ -102,6 +102,7 @@
     }
 
     m_statisticsCollector.computeStatistics().printSummary(std::cout);
+
     m_signalSetQuit.async_wait([this] (const auto& err, int) { onQuitSignal(err); });
   }
 
diff --git a/tools/ping/client/statistics-collector.cpp b/tools/ping/client/statistics-collector.cpp
index cc8842c..dcb8ae9 100644
--- a/tools/ping/client/statistics-collector.cpp
+++ b/tools/ping/client/statistics-collector.cpp
@@ -100,7 +100,7 @@
   return statistics;
 }
 
-std::ostream&
+void
 Statistics::printSummary(std::ostream& os) const
 {
   os << nReceived << "/" << nSent << " packets";
@@ -110,39 +110,33 @@
   }
 
   if (nReceived > 0) {
-    os << ", min/avg/max/mdev = " << minRtt << "/" << avgRtt << "/" << maxRtt << "/" << stdDevRtt
-       << " ms";
+    os << ", min/avg/max/mdev = " << minRtt << "/" << avgRtt << "/" << maxRtt
+       << "/" << stdDevRtt << " ms";
   }
 
-  return os << "\n";
+  os << "\n";
 }
 
-std::ostream&
-operator<<(std::ostream& os, const Statistics& statistics)
+void
+Statistics::printFull(std::ostream& os) const
 {
+  os << "\n--- " << prefix << " ping statistics ---\n"
+     << nSent << " packets transmitted"
+     << ", " << nReceived << " received"
+     << ", " << nNacked << " nacked";
+
+  if (nSent > 0) {
+    os << ", " << packetLossRate * 100.0 << "% lost, " << packetNackedRate * 100.0 << "% nacked";
+  }
+
+  os << ", time " << sumRtt << " ms";
+
+  if (nReceived > 0) {
+    os << "\nrtt min/avg/max/mdev = " << minRtt << "/" << avgRtt << "/" << maxRtt
+       << "/" << stdDevRtt << " ms";
+  }
+
   os << "\n";
-  os << "--- " << statistics.prefix << " ping statistics ---\n";
-  os << statistics.nSent << " packets transmitted";
-  os << ", " << statistics.nReceived << " received";
-  os << ", " << statistics.nNacked << " nacked";
-
-  if (statistics.nSent > 0) {
-    os << ", " << statistics.packetLossRate * 100.0 << "% lost";
-    os << ", " << statistics.packetNackedRate * 100.0 << "% nacked";
-  }
-
-  os << ", time " << statistics.sumRtt << " ms";
-
-  if (statistics.nReceived > 0) {
-    os << "\n";
-    os << "rtt min/avg/max/mdev = ";
-    os << statistics.minRtt << "/";
-    os << statistics.avgRtt << "/";
-    os << statistics.maxRtt << "/";
-    os << statistics.stdDevRtt << " ms";
-  }
-
-  return os;
 }
 
 } // namespace ndn::ping::client
diff --git a/tools/ping/client/statistics-collector.hpp b/tools/ping/client/statistics-collector.hpp
index e335aae..10e1d58 100644
--- a/tools/ping/client/statistics-collector.hpp
+++ b/tools/ping/client/statistics-collector.hpp
@@ -31,11 +31,16 @@
 
 namespace ndn::ping::client {
 
-/**
- * @brief statistics data
- */
-struct Statistics
+class Statistics
 {
+public:
+  void
+  printSummary(std::ostream& os) const;
+
+  void
+  printFull(std::ostream& os) const;
+
+public:
   Name prefix;                                  //!< prefix pinged
   int nSent;                                    //!< number of pings sent
   int nReceived;                                //!< number of pings received
@@ -48,16 +53,10 @@
   double sumRtt;                                //!< sum of round trip times
   double avgRtt;                                //!< average round trip time
   double stdDevRtt;                             //!< std dev of round trip time
-
-  std::ostream&
-  printSummary(std::ostream& os) const;
-
-  friend std::ostream&
-  operator<<(std::ostream& os, const Statistics& statistics);
 };
 
 /**
- * @brief Statistics collector from ping client
+ * @brief Statistics collector from ping client.
  */
 class StatisticsCollector : noncopyable
 {