1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef INPUT_TABLE_DUMP_H
17 #define INPUT_TABLE_DUMP_H
18 
19 #include <iomanip>
20 #include <iostream>
21 #include <sstream>
22 #include <string>
23 #include <tuple>
24 #include <vector>
25 
26 namespace OHOS {
27 namespace MMI {
28 constexpr size_t EXTRA_CHARACTERS_COUNT { 3 };
29 constexpr int32_t ELEMENT_SPACE_COUNT { 2 };
30 
GetElementLength(const std::string &element)31 inline size_t GetElementLength(const std::string &element)
32 {
33     return element.size();
34 }
35 
CalculateColumnWidths(const std::vector<std::string> &titles, const std::vector<std::vector<std::string>> &rows, size_t &lineWidth)36 inline std::vector<size_t> CalculateColumnWidths(const std::vector<std::string> &titles,
37                                                  const std::vector<std::vector<std::string>> &rows,
38                                                  size_t &lineWidth)
39 {
40     std::vector<size_t> widths(titles.size(), 0);
41     for (size_t i = 0; i < titles.size(); ++i) {
42         widths[i] = std::max(widths[i], GetElementLength(titles[i]));
43     }
44 
45     for (const auto &row : rows) {
46         for (size_t i = 0; i < row.size(); ++i) {
47             widths[i] = std::max(widths[i], GetElementLength(row[i]));
48         }
49     }
50 
51     for (size_t width : widths) {
52         lineWidth += width + EXTRA_CHARACTERS_COUNT;
53     }
54     lineWidth += 1;
55     return widths;
56 }
57 
PrintLine(std::ostream &os, const std::vector<size_t> &widths)58 inline void PrintLine(std::ostream &os, const std::vector<size_t> &widths)
59 {
60     os << "+";
61     for (size_t width : widths) {
62         os << std::setw(static_cast<int32_t>(width) + ELEMENT_SPACE_COUNT) << std::left << std::setfill('-')
63            << "" << "+";
64     }
65     os << std::setfill(' ') << std::endl;
66 }
67 
PrintCentered(std::ostream &os, const std::string &value, size_t width)68 inline void PrintCentered(std::ostream &os, const std::string &value, size_t width)
69 {
70     size_t padding_left = (width - value.size()) / 2;
71     size_t padding_right = width - value.size() - padding_left;
72     os << std::string(padding_left, ' ') << value << std::string(padding_right, ' ');
73 }
74 
PrintHeader(std::ostream &os, const std::vector<size_t> &widths, const std::vector<std::string> &titles)75 inline void PrintHeader(std::ostream &os, const std::vector<size_t> &widths, const std::vector<std::string> &titles)
76 {
77     os << "|";
78     for (size_t i = 0; i < titles.size(); ++i) {
79         os << " ";
80         PrintCentered(os, titles[i], widths[i]);
81         os << " |";
82     }
83     os << std::endl;
84 }
85 
PrintRow(std::ostream &os, const std::vector<size_t> &widths, const std::vector<std::string> &row)86 inline void PrintRow(std::ostream &os, const std::vector<size_t> &widths, const std::vector<std::string> &row)
87 {
88     os << "|";
89     for (size_t i = 0; i < row.size(); ++i) {
90         os << " ";
91         PrintCentered(os, row[i], widths[i]);
92         os << " |";
93     }
94     os << std::endl;
95 }
96 
DumpFullTable(std::ostream &os, const std::string &tableName, const std::vector<std::string> &titles, const std::vector<std::vector<std::string>> &rows)97 inline void DumpFullTable(std::ostream &os, const std::string &tableName,
98                           const std::vector<std::string> &titles,
99                           const std::vector<std::vector<std::string>> &rows)
100 {
101     size_t lineWidth = 0;
102     std::vector<size_t> widths = CalculateColumnWidths(titles, rows, lineWidth);
103 
104     PrintCentered(os, tableName, lineWidth);
105     os << std::endl;
106 
107     PrintLine(os, widths);
108     PrintHeader(os, widths, titles);
109     PrintLine(os, widths);
110 
111     for (const auto &row : rows) {
112         PrintRow(os, widths, row);
113         PrintLine(os, widths);
114     }
115 }
116 } // namespace MMI
117 } // namespace OHOS
118 #endif //INPUT_TABLE_DUMP_H
119