1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.client5.http.impl;
29
30 import java.nio.ByteBuffer;
31
32 import org.apache.hc.core5.annotation.Internal;
33 import org.apache.hc.core5.util.Args;
34 import org.slf4j.Logger;
35
36 @Internal
37 public class Wire {
38
39 private static final int MAX_STRING_BUILDER_SIZE = 2048;
40
41 private static final ThreadLocal<StringBuilder> THREAD_LOCAL = new ThreadLocal<>();
42
43
44
45
46
47
48 private static StringBuilder getStringBuilder() {
49 StringBuilder result = THREAD_LOCAL.get();
50 if (result == null) {
51 result = new StringBuilder(MAX_STRING_BUILDER_SIZE);
52 THREAD_LOCAL.set(result);
53 }
54 trimToMaxSize(result, MAX_STRING_BUILDER_SIZE);
55 result.setLength(0);
56 return result;
57 }
58
59
60
61
62
63
64
65
66 private static void trimToMaxSize(final StringBuilder stringBuilder, final int maxSize) {
67 if (stringBuilder != null && stringBuilder.capacity() > maxSize) {
68 stringBuilder.setLength(maxSize);
69 stringBuilder.trimToSize();
70 }
71 }
72
73 private final Logger log;
74 private final String id;
75
76 public Wire(final Logger log, final String id) {
77 super();
78 this.log = log;
79 this.id = id;
80 }
81
82 private void wire(final String header, final byte[] b, final int pos, final int off) {
83 final StringBuilder buffer = getStringBuilder();
84 for (int i = 0; i < off; i++) {
85 final int ch = b[pos + i];
86 if (ch == 13) {
87 buffer.append("[\\r]");
88 } else if (ch == 10) {
89 buffer.append("[\\n]\"");
90 buffer.insert(0, "\"");
91 buffer.insert(0, header);
92 log.debug("{} {}", this.id, buffer);
93 buffer.setLength(0);
94 } else if ((ch < 32) || (ch >= 127)) {
95 buffer.append("[0x");
96 buffer.append(Integer.toHexString(ch));
97 buffer.append("]");
98 } else {
99 buffer.append((char) ch);
100 }
101 }
102 if (buffer.length() > 0) {
103 buffer.append('\"');
104 buffer.insert(0, '\"');
105 buffer.insert(0, header);
106 log.debug("{} {}", this.id, buffer);
107 }
108 }
109
110
111 public boolean isEnabled() {
112 return log.isDebugEnabled();
113 }
114
115 public void output(final byte[] b, final int pos, final int off) {
116 Args.notNull(b, "Output");
117 wire(">> ", b, pos, off);
118 }
119
120 public void input(final byte[] b, final int pos, final int off) {
121 Args.notNull(b, "Input");
122 wire("<< ", b, pos, off);
123 }
124
125 public void output(final byte[] b) {
126 Args.notNull(b, "Output");
127 output(b, 0, b.length);
128 }
129
130 public void input(final byte[] b) {
131 Args.notNull(b, "Input");
132 input(b, 0, b.length);
133 }
134
135 public void output(final int b) {
136 output(new byte[] {(byte) b});
137 }
138
139 public void input(final int b) {
140 input(new byte[] {(byte) b});
141 }
142
143 public void output(final String s) {
144 Args.notNull(s, "Output");
145 output(s.getBytes());
146 }
147
148 public void input(final String s) {
149 Args.notNull(s, "Input");
150 input(s.getBytes());
151 }
152
153 public void output(final ByteBuffer b) {
154 Args.notNull(b, "Output");
155 if (b.hasArray()) {
156 output(b.array(), b.arrayOffset() + b.position(), b.remaining());
157 } else {
158 final byte[] tmp = new byte[b.remaining()];
159 b.get(tmp);
160 output(tmp);
161 }
162 }
163
164 public void input(final ByteBuffer b) {
165 Args.notNull(b, "Input");
166 if (b.hasArray()) {
167 input(b.array(), b.arrayOffset() + b.position(), b.remaining());
168 } else {
169 final byte[] tmp = new byte[b.remaining()];
170 b.get(tmp);
171 input(tmp);
172 }
173 }
174
175 }