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 }