001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.filter.codec.serialization; 021 022import java.io.DataInput; 023import java.io.DataInputStream; 024import java.io.IOException; 025import java.io.InputStream; 026import java.io.ObjectInput; 027import java.io.StreamCorruptedException; 028 029import org.apache.mina.core.buffer.BufferDataException; 030import org.apache.mina.core.buffer.IoBuffer; 031 032/** 033 * An {@link ObjectInput} and {@link InputStream} that can read the objects encoded 034 * by {@link ObjectSerializationEncoder}. 035 * 036 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 037 */ 038public class ObjectSerializationInputStream extends InputStream implements ObjectInput { 039 040 private final DataInputStream in; 041 042 private final ClassLoader classLoader; 043 044 private int maxObjectSize = 1048576; 045 046 /** 047 * Create a new instance of an ObjectSerializationInputStream 048 * @param in The {@link InputStream} to use 049 */ 050 public ObjectSerializationInputStream(InputStream in) { 051 this(in, null); 052 } 053 054 /** 055 * Create a new instance of an ObjectSerializationInputStream 056 * @param in The {@link InputStream} to use 057 * @param classLoader The class loader to use 058 */ 059 public ObjectSerializationInputStream(InputStream in, ClassLoader classLoader) { 060 if (in == null) { 061 throw new IllegalArgumentException("in"); 062 } 063 064 if (classLoader == null) { 065 classLoader = Thread.currentThread().getContextClassLoader(); 066 } 067 068 if (in instanceof DataInputStream) { 069 this.in = (DataInputStream) in; 070 } else { 071 this.in = new DataInputStream(in); 072 } 073 074 this.classLoader = classLoader; 075 } 076 077 /** 078 * @return the allowed maximum size of the object to be decoded. 079 * If the size of the object to be decoded exceeds this value, this 080 * decoder will throw a {@link BufferDataException}. The default 081 * value is <tt>1048576</tt> (1MB). 082 */ 083 public int getMaxObjectSize() { 084 return maxObjectSize; 085 } 086 087 /** 088 * Sets the allowed maximum size of the object to be decoded. 089 * If the size of the object to be decoded exceeds this value, this 090 * decoder will throw a {@link BufferDataException}. The default 091 * value is <tt>1048576</tt> (1MB). 092 * 093 * @param maxObjectSize The maximum decoded object size 094 */ 095 public void setMaxObjectSize(int maxObjectSize) { 096 if (maxObjectSize <= 0) { 097 throw new IllegalArgumentException("maxObjectSize: " + maxObjectSize); 098 } 099 100 this.maxObjectSize = maxObjectSize; 101 } 102 103 /** 104 * {@inheritDoc} 105 */ 106 @Override 107 public int read() throws IOException { 108 return in.read(); 109 } 110 111 /** 112 * {@inheritDoc} 113 */ 114 public Object readObject() throws ClassNotFoundException, IOException { 115 int objectSize = in.readInt(); 116 if (objectSize <= 0) { 117 throw new StreamCorruptedException("Invalid objectSize: " + objectSize); 118 } 119 if (objectSize > maxObjectSize) { 120 throw new StreamCorruptedException("ObjectSize too big: " + objectSize + " (expected: <= " + maxObjectSize 121 + ')'); 122 } 123 124 IoBuffer buf = IoBuffer.allocate(objectSize + 4, false); 125 buf.putInt(objectSize); 126 in.readFully(buf.array(), 4, objectSize); 127 buf.position(0); 128 buf.limit(objectSize + 4); 129 130 return buf.getObject(classLoader); 131 } 132 133 /** 134 * {@inheritDoc} 135 */ 136 public boolean readBoolean() throws IOException { 137 return in.readBoolean(); 138 } 139 140 /** 141 * {@inheritDoc} 142 */ 143 public byte readByte() throws IOException { 144 return in.readByte(); 145 } 146 147 /** 148 * {@inheritDoc} 149 */ 150 public char readChar() throws IOException { 151 return in.readChar(); 152 } 153 154 /** 155 * {@inheritDoc} 156 */ 157 public double readDouble() throws IOException { 158 return in.readDouble(); 159 } 160 161 /** 162 * {@inheritDoc} 163 */ 164 public float readFloat() throws IOException { 165 return in.readFloat(); 166 } 167 168 /** 169 * {@inheritDoc} 170 */ 171 public void readFully(byte[] b) throws IOException { 172 in.readFully(b); 173 } 174 175 /** 176 * {@inheritDoc} 177 */ 178 public void readFully(byte[] b, int off, int len) throws IOException { 179 in.readFully(b, off, len); 180 } 181 182 /** 183 * {@inheritDoc} 184 */ 185 public int readInt() throws IOException { 186 return in.readInt(); 187 } 188 189 /** 190 * @see DataInput#readLine() 191 * @deprecated 192 */ 193 @Deprecated 194 public String readLine() throws IOException { 195 return in.readLine(); 196 } 197 198 /** 199 * {@inheritDoc} 200 */ 201 public long readLong() throws IOException { 202 return in.readLong(); 203 } 204 205 /** 206 * {@inheritDoc} 207 */ 208 public short readShort() throws IOException { 209 return in.readShort(); 210 } 211 212 /** 213 * {@inheritDoc} 214 */ 215 public String readUTF() throws IOException { 216 return in.readUTF(); 217 } 218 219 /** 220 * {@inheritDoc} 221 */ 222 public int readUnsignedByte() throws IOException { 223 return in.readUnsignedByte(); 224 } 225 226 /** 227 * {@inheritDoc} 228 */ 229 public int readUnsignedShort() throws IOException { 230 return in.readUnsignedShort(); 231 } 232 233 /** 234 * {@inheritDoc} 235 */ 236 public int skipBytes(int n) throws IOException { 237 return in.skipBytes(n); 238 } 239}