1
2
3
4
5 package org.neo.swarm.util.io;
6
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.util.List;
10
11 /***
12 * Unwraps the contents of a socketchannel using a bytebuffer presents a streaming API.
13 * network packet (chunked). </nl>
14 * <b>Note:</b> Alternative implementations of the these streams could be written to handle
15 * different wire protocols such as SOAP or HTTP.
16 * @author navery
17 */
18 public class PacketInputStream extends InputStream {
19
20 List dataSet;
21 ByteBufferInputStream parent;
22 int size;
23
24 /***
25 * This is a package header, 7 bytes
26 */
27 public static final byte[] START_DATA = { 70, 76, 84, 50, 48, 48, 50};
28
29 /***
30 * This is the package footer, 7 bytes
31 */
32 public static final byte[] END_DATA = { 84, 76, 70, 50, 48, 48, 51};
33
34 /***
35 * START_DATA - 7 bytes
36 * SIZE - 4 bytes - size of the data package
37 * DATA - should be as many bytes as the prev SIZE
38 * END_DATA - 7 bytes
39 */
40
41 public PacketInputStream(ByteBufferInputStream parent) {
42 this.parent = parent;
43 }
44
45
46
47
48
49
50 public int read() throws IOException {
51
52 throw new IOException("use int available() and then read(byte[]) instead");
53 }
54
55 /***
56 * Uses the parent state to determine the correct operation
57 * to calldown onto, once completely read then the available
58 * bytes are returned.
59 */
60 public int available() throws IOException {
61
62 int avail = parent.available();
63
64 if (avail > 0 ) {
65 validateHeader(parent.getHeaderBuffer());
66 validateFooter(parent.getFooterBuffer());
67 }
68 return avail;
69 }
70
71
72
73
74
75
76 public int read(byte[] userData) throws IOException {
77
78 byte[] body = parent.getContent();
79 if (userData.length != body.length) throw new IOException("Invalid user buffer size given, expected:" + body.length + " given:" + userData.length);
80
81 System.arraycopy(body, 0, userData, 0, body.length);
82 return userData.length;
83 }
84
85 public void close() throws IOException {
86 parent.close();
87 }
88
89 /***
90 * @throws IOException
91 */
92 private void validateHeader(byte[] header) throws IOException {
93
94 for (int i = 0; i < START_DATA.length; i++) {
95 if (header[i] != START_DATA[i]) {
96 throw new IOException("Invalid header data received");
97 }
98 }
99 }
100
101 /***
102 * @throws IOException
103 */
104 private void validateFooter(byte[] footer) throws IOException {
105 for (int i = 0; i < END_DATA.length; i++) {
106 if (footer[i] != END_DATA[i]) {
107 throw new IOException("Invalid footer data received");
108 }
109 }
110 }
111
112 }