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 package org.apache.http.nio.client.methods;
28
29 import java.io.IOException;
30 import java.nio.ByteBuffer;
31 import java.nio.CharBuffer;
32 import java.nio.charset.Charset;
33 import java.nio.charset.CharsetDecoder;
34 import java.nio.charset.CoderResult;
35
36 import org.apache.http.HttpEntity;
37 import org.apache.http.entity.ContentType;
38 import org.apache.http.nio.ContentDecoder;
39 import org.apache.http.nio.IOControl;
40 import org.apache.http.nio.protocol.AbstractAsyncResponseConsumer;
41 import org.apache.http.protocol.HTTP;
42 import org.apache.http.util.Asserts;
43
44
45
46
47
48
49
50
51 public abstract class AsyncCharConsumer<T> extends AbstractAsyncResponseConsumer<T> {
52
53 private final ByteBuffer bbuf;
54 private final CharBuffer cbuf;
55
56 private CharsetDecoder chardecoder;
57
58 public AsyncCharConsumer(final int bufSize) {
59 super();
60 this.bbuf = ByteBuffer.allocate(bufSize);
61 this.cbuf = CharBuffer.allocate(bufSize);
62 }
63
64 public AsyncCharConsumer() {
65 this(8 * 1024);
66 }
67
68
69
70
71
72
73
74
75
76
77 protected abstract void onCharReceived(
78 CharBuffer buf, IOControl ioctrl) throws IOException;
79
80
81
82
83
84
85
86
87
88
89
90 protected CharsetDecoder createDecoder(final ContentType contentType) {
91 Charset charset = contentType != null ? contentType.getCharset() : null;
92 if (charset == null) {
93 charset = HTTP.DEF_CONTENT_CHARSET;
94 }
95 return charset.newDecoder();
96 }
97
98 @Override
99 protected final void onEntityEnclosed(
100 final HttpEntity entity, final ContentType contentType) throws IOException {
101 this.chardecoder = createDecoder(contentType != null ? contentType : ContentType.DEFAULT_TEXT);
102 }
103
104 @Override
105 protected final void onContentReceived(
106 final ContentDecoder decoder, final IOControl ioctrl) throws IOException {
107 Asserts.notNull(this.bbuf, "Byte buffer");
108
109 final int bytesRead = decoder.read(this.bbuf);
110 if (bytesRead <= 0) {
111 return;
112 }
113 this.bbuf.flip();
114 final boolean completed = decoder.isCompleted();
115 CoderResult result = this.chardecoder.decode(this.bbuf, this.cbuf, completed);
116 handleDecodingResult(result, ioctrl);
117 this.bbuf.compact();
118 if (completed) {
119 result = this.chardecoder.flush(this.cbuf);
120 handleDecodingResult(result, ioctrl);
121 }
122 }
123
124 private void handleDecodingResult(
125 final CoderResult result, final IOControl ioctrl) throws IOException {
126 if (result.isError()) {
127 result.throwException();
128 }
129 this.cbuf.flip();
130 if (this.cbuf.hasRemaining()) {
131 onCharReceived(this.cbuf, ioctrl);
132 }
133 this.cbuf.clear();
134 }
135
136 @Override
137 protected void releaseResources() {
138 }
139
140 }