View Javadoc

1   /***
2    * Jetrix TetriNET Server
3    * Copyright (C) 2005  Emmanuel Bourg
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18   */
19  
20  package net.jetrix.protocols;
21  
22  import java.io.ByteArrayOutputStream;
23  import java.io.IOException;
24  import java.io.InputStream;
25  
26  import net.jetrix.Protocol;
27  
28  /***
29   * Abstract protocol implementing the readLine(Reader) method.
30   *
31   * @since 0.3
32   *
33   * @author Emmanuel Bourg
34   * @version $Revision: 848 $, $Date: 2010-05-03 22:51:32 +0200 (lun., 03 mai 2010) $
35   */
36  public abstract class AbstractProtocol implements Protocol
37  {
38      /*** Maximum size allowed for a message frame. */
39      private static final int MAX_SIZE = 8192;
40  
41      /*** Maximum delay allowed for parsing a message frame (in milliseconds). */
42      private static final int MAX_DELAY = 10000;
43      
44      /***
45       * Reads the next message frame from the specified input stream.
46       * No charset decoding is performed at this stage.
47       */
48      public byte[] readFrame(InputStream in) throws IOException
49      {
50          ByteArrayOutputStream input = new ByteArrayOutputStream(256);
51          
52          long time = 0;
53          
54          int b;
55          while ((b = in.read()) != -1 && b != getEOL() && b != 0x0A && b != 0x0D && input.size() < MAX_SIZE)
56          {
57              input.write(b);
58              
59              if (input.size() == 1)
60              {
61                  // let's start monitoring the input speed
62                  time = System.currentTimeMillis();
63              }
64              else if (System.currentTimeMillis() - time > MAX_DELAY)
65              {
66                  throw new IOException("Slow input detected (" + input.size() + " bytes over " + (System.currentTimeMillis() - time) + "ms)");
67              }
68          }
69          
70          if (b == -1)
71          {
72              throw new IOException("End of stream");
73          }
74          
75          if (input.size() >= MAX_SIZE)
76          {
77              throw new IOException("Message frame exceeded the " + MAX_SIZE + " limit");
78          }
79          
80          return input.toByteArray();
81      }
82  
83      public String readLine(InputStream in, String encoding) throws IOException
84      {
85          return new String(readFrame(in), encoding);
86      }
87  
88      public boolean equals(Object o)
89      {
90          if (this == o)
91          {
92              return true;
93          }
94          if (o == null || getClass() != o.getClass())
95          {
96              return false;
97          }
98  
99          Protocol that = (Protocol) o;
100 
101         if (!getName().equals(that.getName()))
102         {
103             return false;
104         }
105 
106         return true;
107     }
108 
109     public int hashCode()
110     {
111         return getName().hashCode();
112     }
113 
114     public String toString()
115     {
116         return "[Protocol name=" + getName() + "]";
117     }
118 }