1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.hbtop.terminal.impl;
19
20 import static org.apache.hadoop.hbase.hbtop.terminal.impl.EscapeSequences.clearRemainingLine;
21 import static org.apache.hadoop.hbase.hbtop.terminal.impl.EscapeSequences.color;
22 import static org.apache.hadoop.hbase.hbtop.terminal.impl.EscapeSequences.cursor;
23 import static org.apache.hadoop.hbase.hbtop.terminal.impl.EscapeSequences.moveCursor;
24 import static org.apache.hadoop.hbase.hbtop.terminal.impl.EscapeSequences.normal;
25
26 import java.io.PrintWriter;
27
28 import org.apache.hadoop.hbase.classification.InterfaceAudience;
29 import org.apache.hadoop.hbase.hbtop.terminal.Attributes;
30 import org.apache.hadoop.hbase.hbtop.terminal.CursorPosition;
31
32
33
34
35 @InterfaceAudience.Private
36 public class ScreenBuffer {
37 private int columns;
38 private int rows;
39
40 private Cell[][] buffer;
41 private Cell[][] physical;
42
43 private boolean cursorVisible;
44 private int cursorColumn;
45 private int cursorRow;
46
47 public void reallocate(int columns, int rows) {
48 buffer = new Cell[columns][rows];
49 physical = new Cell[columns][rows];
50
51 for (int row = 0; row < rows; row++) {
52 for (int column = 0; column < columns; column++) {
53 buffer[column][row] = new Cell();
54
55 physical[column][row] = new Cell();
56 physical[column][row].unset();
57 }
58 }
59
60 this.columns = columns;
61 this.rows = rows;
62 }
63
64 public void clear() {
65 for (int row = 0; row < rows; row++) {
66 for (int col = 0; col < columns; col++) {
67 buffer[col][row].reset();
68 }
69 }
70 }
71
72 public void flush(PrintWriter output) {
73 StringBuilder sb = new StringBuilder();
74
75 sb.append(normal());
76 Attributes attributes = new Attributes();
77 for (int row = 0; row < rows; row++) {
78 flushRow(row, sb, attributes);
79 }
80
81 if (cursorVisible && cursorRow >= 0 && cursorColumn >= 0 && cursorRow < rows &&
82 cursorColumn < columns) {
83 sb.append(cursor(true));
84 sb.append(moveCursor(cursorColumn, cursorRow));
85 } else {
86 sb.append(cursor(false));
87 }
88
89 output.write(sb.toString());
90 output.flush();
91 }
92
93 private void flushRow(int row, StringBuilder sb, Attributes lastAttributes) {
94 int lastColumn = -1;
95 for (int column = 0; column < columns; column++) {
96 Cell cell = buffer[column][row];
97 Cell pCell = physical[column][row];
98
99 if (!cell.equals(pCell)) {
100 if (lastColumn != column - 1 || lastColumn == -1) {
101 sb.append(moveCursor(column, row));
102 }
103
104 if (cell.isEndOfLine()) {
105 for (int i = column; i < columns; i++) {
106 physical[i][row].set(buffer[i][row]);
107 }
108
109 sb.append(clearRemainingLine());
110 lastAttributes.reset();
111 return;
112 }
113
114 if (!cell.getAttributes().equals(lastAttributes)) {
115 sb.append(color(cell.getForegroundColor(), cell.getBackgroundColor(), cell.isBold(),
116 cell.isReverse(), cell.isBlink(), cell.isUnderline()));
117 }
118
119 sb.append(cell.getChar());
120
121 lastColumn = column;
122 lastAttributes.set(cell.getAttributes());
123
124 physical[column][row].set(cell);
125 }
126 }
127 }
128
129 public CursorPosition getCursorPosition() {
130 return new CursorPosition(cursorColumn, cursorRow);
131 }
132
133 public void setCursorPosition(int column, int row) {
134 cursorVisible = true;
135 cursorColumn = column;
136 cursorRow = row;
137 }
138
139 public void hideCursor() {
140 cursorVisible = false;
141 }
142
143 public void putString(int column, int row, String string, Attributes attributes) {
144 int i = column;
145 for (int j = 0; j < string.length(); j++) {
146 char ch = string.charAt(j);
147 putChar(i, row, ch, attributes);
148 i += 1;
149 if (i == columns) {
150 break;
151 }
152 }
153 }
154
155 public void putChar(int column, int row, char ch, Attributes attributes) {
156 if (column >= 0 && column < columns && row >= 0 && row < rows) {
157 buffer[column][row].setAttributes(attributes);
158 buffer[column][row].setChar(ch);
159 }
160 }
161
162 public void endOfLine(int column, int row) {
163 if (column >= 0 && column < columns && row >= 0 && row < rows) {
164 buffer[column][row].endOfLine();
165 for (int i = column + 1; i < columns; i++) {
166 buffer[i][row].reset();
167 }
168 }
169 }
170 }