View Javadoc

1   /*
2    * Copyright 2009 Red Hat, Inc.
3    *
4    * Red Hat licenses this file to you under the Apache License, version 2.0
5    * (the "License"); you may not use this file except in compliance with the
6    * License.  You may obtain a copy of the License at:
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package org.jboss.netty.handler.codec.serialization;
17  
18  import java.io.DataInputStream;
19  import java.io.IOException;
20  import java.io.InputStream;
21  import java.io.ObjectInput;
22  import java.io.StreamCorruptedException;
23  
24  /**
25   * An {@link ObjectInput} which is interoperable with {@link ObjectEncoder}
26   * and {@link ObjectEncoderOutputStream}.
27   *
28   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
29   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
30   *
31   * @version $Rev: 2080 $, $Date: 2010-01-26 18:04:19 +0900 (Tue, 26 Jan 2010) $
32   *
33   */
34  public class ObjectDecoderInputStream extends InputStream implements
35          ObjectInput {
36  
37      private final DataInputStream in;
38      private final ClassLoader classLoader;
39      private final int maxObjectSize;
40  
41      /**
42       * Creates a new {@link ObjectInput}.
43       *
44       * @param in
45       *        the {@link InputStream} where the serialized form will be
46       *        read from
47       */
48      public ObjectDecoderInputStream(InputStream in) {
49          this(in, null);
50      }
51  
52      /**
53       * Creates a new {@link ObjectInput}.
54       *
55       * @param in
56       *        the {@link InputStream} where the serialized form will be
57       *        read from
58       * @param classLoader
59       *        the {@link ClassLoader} which will load the class of the
60       *        serialized object
61       */
62      public ObjectDecoderInputStream(InputStream in, ClassLoader classLoader) {
63          this(in, classLoader, 1048576);
64      }
65  
66      /**
67       * Creates a new {@link ObjectInput}.
68       *
69       * @param in
70       *        the {@link InputStream} where the serialized form will be
71       *        read from
72       * @param maxObjectSize
73       *        the maximum byte length of the serialized object.  if the length
74       *        of the received object is greater than this value,
75       *        a {@link StreamCorruptedException} will be raised.
76       */
77      public ObjectDecoderInputStream(InputStream in, int maxObjectSize) {
78          this(in, null, maxObjectSize);
79      }
80  
81      /**
82       * Creates a new {@link ObjectInput}.
83       *
84       * @param in
85       *        the {@link InputStream} where the serialized form will be
86       *        read from
87       * @param classLoader
88       *        the {@link ClassLoader} which will load the class of the
89       *        serialized object
90       * @param maxObjectSize
91       *        the maximum byte length of the serialized object.  if the length
92       *        of the received object is greater than this value,
93       *        a {@link StreamCorruptedException} will be raised.
94       */
95      public ObjectDecoderInputStream(InputStream in, ClassLoader classLoader, int maxObjectSize) {
96          if (in == null) {
97              throw new NullPointerException("in");
98          }
99          if (maxObjectSize <= 0) {
100             throw new IllegalArgumentException("maxObjectSize: " + maxObjectSize);
101         }
102         if (in instanceof DataInputStream) {
103             this.in = (DataInputStream) in;
104         } else {
105             this.in = new DataInputStream(in);
106         }
107         this.classLoader = classLoader;
108         this.maxObjectSize = maxObjectSize;
109     }
110 
111     public Object readObject() throws ClassNotFoundException, IOException {
112         int dataLen = readInt();
113         if (dataLen <= 0) {
114             throw new StreamCorruptedException("invalid data length: " + dataLen);
115         }
116         if (dataLen > maxObjectSize) {
117             throw new StreamCorruptedException(
118                     "data length too big: " + dataLen + " (max: " + maxObjectSize + ')');
119         }
120 
121         return new CompactObjectInputStream(in, classLoader).readObject();
122     }
123 
124     @Override
125     public int available() throws IOException {
126         return in.available();
127     }
128 
129     @Override
130     public void close() throws IOException {
131         in.close();
132     }
133 
134     @Override
135     public void mark(int readlimit) {
136         in.mark(readlimit);
137     }
138 
139     @Override
140     public boolean markSupported() {
141         return in.markSupported();
142     }
143 
144     @Override
145     public int read() throws IOException {
146         return in.read();
147     }
148 
149     @Override
150     public final int read(byte[] b, int off, int len) throws IOException {
151         return in.read(b, off, len);
152     }
153 
154     @Override
155     public final int read(byte[] b) throws IOException {
156         return in.read(b);
157     }
158 
159     public final boolean readBoolean() throws IOException {
160         return in.readBoolean();
161     }
162 
163     public final byte readByte() throws IOException {
164         return in.readByte();
165     }
166 
167     public final char readChar() throws IOException {
168         return in.readChar();
169     }
170 
171     public final double readDouble() throws IOException {
172         return in.readDouble();
173     }
174 
175     public final float readFloat() throws IOException {
176         return in.readFloat();
177     }
178 
179     public final void readFully(byte[] b, int off, int len) throws IOException {
180         in.readFully(b, off, len);
181     }
182 
183     public final void readFully(byte[] b) throws IOException {
184         in.readFully(b);
185     }
186 
187     public final int readInt() throws IOException {
188         return in.readInt();
189     }
190 
191     @Deprecated
192     public final String readLine() throws IOException {
193         return in.readLine();
194     }
195 
196     public final long readLong() throws IOException {
197         return in.readLong();
198     }
199 
200     public final short readShort() throws IOException {
201         return in.readShort();
202     }
203 
204     public final int readUnsignedByte() throws IOException {
205         return in.readUnsignedByte();
206     }
207 
208     public final int readUnsignedShort() throws IOException {
209         return in.readUnsignedShort();
210     }
211 
212     public final String readUTF() throws IOException {
213         return in.readUTF();
214     }
215 
216     @Override
217     public void reset() throws IOException {
218         in.reset();
219     }
220 
221     @Override
222     public long skip(long n) throws IOException {
223         return in.skip(n);
224     }
225 
226     public final int skipBytes(int n) throws IOException {
227         return in.skipBytes(n);
228     }
229 }