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.marshalling;
17  
18  import java.io.IOException;
19  
20  import org.jboss.marshalling.ByteInput;
21  
22  /**
23   * {@link ByteInput} implementation which wraps another {@link ByteInput} and throws a {@link TooBigObjectException}
24   * if the read limit was reached.
25   *
26   *
27   */
28  class LimitingByteInput implements ByteInput {
29  
30      // Use a static instance here to remove the overhead of fillStacktrace
31      private static final TooBigObjectException EXCEPTION = new TooBigObjectException();
32  
33      private final ByteInput input;
34      private final long limit;
35      private long read;
36  
37      public LimitingByteInput(ByteInput input, long limit) {
38          if (limit <= 0) {
39              throw new IllegalArgumentException("The limit MUST be > 0");
40          }
41          this.input = input;
42          this.limit = limit;
43      }
44  
45      public void close() throws IOException {
46          // Nothing todo
47      }
48  
49      public int available() throws IOException {
50          int available = input.available();
51          int readable = readable(available);
52          return readable;
53      }
54  
55      public int read() throws IOException {
56          int readable = readable(1);
57          if (readable > 0) {
58              int b = input.read();
59              read++;
60              return b;
61          } else {
62              throw EXCEPTION;
63          }
64      }
65  
66      public int read(byte[] array) throws IOException {
67          return read(array, 0, array.length);
68      }
69  
70      public int read(byte[] array, int offset, int length) throws IOException {
71          int readable = readable(length);
72          if (readable > 0) {
73              int i = input.read(array, offset, readable);
74              read += i;
75              return i;
76          } else {
77              throw EXCEPTION;
78          }
79      }
80  
81      public long skip(long bytes) throws IOException {
82          int readable = readable((int) bytes);
83          if (readable > 0) {
84              long i = input.skip(readable);
85              read += i;
86              return i;
87          } else {
88              throw EXCEPTION;
89          }
90      }
91  
92      private int readable(int length) {
93          return (int) Math.min(length, limit - read);
94      }
95  
96      /**
97       * Exception that will get thrown if the {@link Object} is to big to unmarshall
98       *
99       */
100     static final class TooBigObjectException extends IOException {
101         private static final long serialVersionUID = 1L;
102     }
103 }