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.core5.http2.impl.io;
29
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.util.ArrayDeque;
33 import java.util.Queue;
34
35 class MultiByteArrayInputStream extends InputStream {
36
37 private final Queue<byte[]> bufs;
38 private byte[] current;
39 private int pos;
40
41 public MultiByteArrayInputStream(final byte[]... bufs) {
42 super();
43 this.bufs = new ArrayDeque<>();
44 for (final byte[] buf: bufs) {
45 if (buf.length > 0) {
46 this.bufs.add(buf);
47 }
48 }
49 }
50
51 private void advance() {
52 if (this.current != null) {
53 if (this.pos >= this.current.length) {
54 this.current = null;
55 }
56 }
57 if (this.current == null) {
58 this.current = this.bufs.poll();
59 this.pos = 0;
60 }
61 }
62
63 @Override
64 public int read() throws IOException {
65 advance();
66 if (this.current == null) {
67 return -1;
68 }
69 return this.current[this.pos++];
70 }
71
72 @Override
73 public int read(final byte b[], final int off, final int len) throws IOException {
74 if (b == null) {
75 throw new NullPointerException();
76 } else if ((off < 0) || (off > b.length) || (len < 0) ||
77 ((off + len) > b.length) || ((off + len) < 0)) {
78 throw new IndexOutOfBoundsException();
79 }
80 advance();
81 if (this.current == null) {
82 return -1;
83 }
84 final int chunk = Math.min(this.current.length - this.pos, len);
85 if (chunk <= 0) {
86 return 0;
87 }
88 System.arraycopy(this.current, this.pos, b, off, chunk);
89 this.pos += chunk;
90 return chunk;
91 }
92
93 @Override
94 public long skip(final long n) {
95 advance();
96 final int chunk = Math.min(this.current.length - this.pos, (int) n);
97 if (chunk <= 0) {
98 return 0;
99 }
100 this.pos += chunk;
101 return chunk;
102 }
103
104 @Override
105 public int available() {
106 advance();
107 return this.current != null ? this.current.length - this.pos : 0;
108 }
109
110 @Override
111 public boolean markSupported() {
112 return false;
113 }
114
115 }