1 /***************************************
2 * *
3 * JBoss: The OpenSource J2EE WebOS *
4 * *
5 * Distributable under LGPL license. *
6 * See terms of license at gnu.org. *
7 * *
8 ***************************************/
9
10 package org.jboss.util.stream;
11
12 import java.io.BufferedInputStream;
13 import java.io.InputStream;
14 import java.io.IOException;
15
16 /**
17 * A buffered input stream that notifies every "chunk"
18 *
19 * @version <tt>$Revision: 1.1.4.1 $</tt>
20 * @author <a href="mailto:Adrian@jboss.org">Adrian Brock</a>
21 */
22 public class NotifyingBufferedInputStream
23 extends BufferedInputStream
24 {
25 /**
26 * The number of bytes between notifications
27 */
28 int chunkSize;
29
30 /**
31 * The number of bytes read in the current chunk
32 */
33 int chunk = 0;
34
35 /**
36 * The listener notified every chunk
37 */
38 StreamListener listener;
39
40 /**
41 * Construct a notifying buffered inputstream.
42 * The listener is notified once every chunk.
43 *
44 * @param is the input stream to be buffered
45 * @param size the buffer size
46 * @param chunkSize the chunk size
47 * @param listener the listener to notify
48 * @exception IllegalArgumentException for a size <= 0 or chunkSize <= size
49 */
50 public NotifyingBufferedInputStream(InputStream is, int size, int chunkSize, StreamListener listener)
51 {
52 super(is, size);
53 if (chunkSize <= size)
54 throw new IllegalArgumentException("chunkSize must be bigger than the buffer");
55 this.chunkSize = chunkSize;
56 this.listener = listener;
57 }
58
59 public void setStreamListener(StreamListener listener)
60 {
61 this.listener = listener;
62 }
63
64 public int read()
65 throws IOException
66 {
67 int result = super.read();
68 if (result == -1)
69 return result;
70 checkNotification(result);
71 return result;
72 }
73
74 public int read(byte[] b, int off, int len)
75 throws IOException
76 {
77 int result = super.read(b, off, len);
78 if (result == -1)
79 return result;
80 checkNotification(result);
81 return result;
82 }
83
84 /**
85 * Checks whether a notification is required and
86 * notifies as appropriate
87 *
88 * @param result the number of bytes read
89 */
90 public void checkNotification(int result)
91 {
92 // Is a notification required?
93 chunk += result;
94 if (chunk >= chunkSize)
95 {
96 if (listener != null)
97 listener.onStreamNotification(this, chunk);
98
99 // Start a new chunk
100 chunk = 0;
101 }
102 }
103 }