View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the 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  public class ObjectDecoderInputStream extends InputStream implements
29          ObjectInput {
30  
31      private final DataInputStream in;
32      private final int maxObjectSize;
33      private final ClassResolver classResolver;
34  
35      /**
36       * Creates a new {@link ObjectInput}.
37       *
38       * @param in
39       *        the {@link InputStream} where the serialized form will be
40       *        read from
41       */
42      public ObjectDecoderInputStream(InputStream in) {
43          this(in, null);
44      }
45  
46      /**
47       * Creates a new {@link ObjectInput}.
48       *
49       * @param in
50       *        the {@link InputStream} where the serialized form will be
51       *        read from
52       * @param classLoader
53       *        the {@link ClassLoader} which will load the class of the
54       *        serialized object
55       */
56      public ObjectDecoderInputStream(InputStream in, ClassLoader classLoader) {
57          this(in, classLoader, 1048576);
58      }
59  
60      /**
61       * Creates a new {@link ObjectInput}.
62       *
63       * @param in
64       *        the {@link InputStream} where the serialized form will be
65       *        read from
66       * @param maxObjectSize
67       *        the maximum byte length of the serialized object.  if the length
68       *        of the received object is greater than this value,
69       *        a {@link StreamCorruptedException} will be raised.
70       */
71      public ObjectDecoderInputStream(InputStream in, int maxObjectSize) {
72          this(in, null, maxObjectSize);
73      }
74  
75      /**
76       * Creates a new {@link ObjectInput}.
77       *
78       * @param in
79       *        the {@link InputStream} where the serialized form will be
80       *        read from
81       * @param classLoader
82       *        the {@link ClassLoader} which will load the class of the
83       *        serialized object
84       * @param maxObjectSize
85       *        the maximum byte length of the serialized object.  if the length
86       *        of the received object is greater than this value,
87       *        a {@link StreamCorruptedException} will be raised.
88       */
89      public ObjectDecoderInputStream(InputStream in, ClassLoader classLoader, int maxObjectSize) {
90          if (in == null) {
91              throw new NullPointerException("in");
92          }
93          if (maxObjectSize <= 0) {
94              throw new IllegalArgumentException("maxObjectSize: " + maxObjectSize);
95          }
96          if (in instanceof DataInputStream) {
97              this.in = (DataInputStream) in;
98          } else {
99              this.in = new DataInputStream(in);
100         }
101         classResolver = ClassResolvers.weakCachingResolver(classLoader);
102         this.maxObjectSize = maxObjectSize;
103     }
104 
105     public Object readObject() throws ClassNotFoundException, IOException {
106         int dataLen = readInt();
107         if (dataLen <= 0) {
108             throw new StreamCorruptedException("invalid data length: " + dataLen);
109         }
110         if (dataLen > maxObjectSize) {
111             throw new StreamCorruptedException(
112                     "data length too big: " + dataLen + " (max: " + maxObjectSize + ')');
113         }
114 
115         return new CompactObjectInputStream(in, classResolver).readObject();
116     }
117 
118     @Override
119     public int available() throws IOException {
120         return in.available();
121     }
122 
123     @Override
124     public void close() throws IOException {
125         in.close();
126     }
127 
128     @Override
129     public void mark(int readlimit) {
130         in.mark(readlimit);
131     }
132 
133     @Override
134     public boolean markSupported() {
135         return in.markSupported();
136     }
137 
138     @Override
139     public int read() throws IOException {
140         return in.read();
141     }
142 
143     @Override
144     public final int read(byte[] b, int off, int len) throws IOException {
145         return in.read(b, off, len);
146     }
147 
148     @Override
149     public final int read(byte[] b) throws IOException {
150         return in.read(b);
151     }
152 
153     public final boolean readBoolean() throws IOException {
154         return in.readBoolean();
155     }
156 
157     public final byte readByte() throws IOException {
158         return in.readByte();
159     }
160 
161     public final char readChar() throws IOException {
162         return in.readChar();
163     }
164 
165     public final double readDouble() throws IOException {
166         return in.readDouble();
167     }
168 
169     public final float readFloat() throws IOException {
170         return in.readFloat();
171     }
172 
173     public final void readFully(byte[] b, int off, int len) throws IOException {
174         in.readFully(b, off, len);
175     }
176 
177     public final void readFully(byte[] b) throws IOException {
178         in.readFully(b);
179     }
180 
181     public final int readInt() throws IOException {
182         return in.readInt();
183     }
184 
185     @Deprecated
186     public final String readLine() throws IOException {
187         return in.readLine();
188     }
189 
190     public final long readLong() throws IOException {
191         return in.readLong();
192     }
193 
194     public final short readShort() throws IOException {
195         return in.readShort();
196     }
197 
198     public final int readUnsignedByte() throws IOException {
199         return in.readUnsignedByte();
200     }
201 
202     public final int readUnsignedShort() throws IOException {
203         return in.readUnsignedShort();
204     }
205 
206     public final String readUTF() throws IOException {
207         return in.readUTF();
208     }
209 
210     @Override
211     public void reset() throws IOException {
212         in.reset();
213     }
214 
215     @Override
216     public long skip(long n) throws IOException {
217         return in.skip(n);
218     }
219 
220     public final int skipBytes(int n) throws IOException {
221         return in.skipBytes(n);
222     }
223 }