View Javadoc

1   /*
2    * Created on Apr 19, 2004
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       * (non-Javadoc)
47       * 
48       * @see java.io.InputStream#read()
49       */
50      public int read() throws IOException {
51          // shouldnt be used
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       * (non-Javadoc)
73       * 
74       * @see java.io.InputStream#read(byte[])
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          // validate the header
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 }