Source for gnu.javax.net.ssl.provider.CompressionMethodList

   1: /* CompressionMethodList.java -- A list of compression methods.
   2:    Copyright (C) 2006  Free Software Foundation, Inc.
   3: 
   4: This file is a part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2 of the License, or (at
   9: your option) any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; if not, write to the Free Software
  18: Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
  19: USA
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version.  */
  37: 
  38: 
  39: package gnu.javax.net.ssl.provider;
  40: 
  41: import java.io.PrintWriter;
  42: import java.io.StringWriter;
  43: 
  44: import java.nio.ByteBuffer;
  45: 
  46: import java.util.ConcurrentModificationException;
  47: import java.util.ListIterator;
  48: import java.util.NoSuchElementException;
  49: 
  50: /**
  51:  * A basic list interface to a list of compression methods in an SSL
  52:  * packet.
  53:  */
  54: public final class CompressionMethodList implements Iterable<CompressionMethod>
  55: {
  56:   private final ByteBuffer buffer;
  57:   private int modCount;
  58: 
  59:   public CompressionMethodList (final ByteBuffer buffer)
  60:   {
  61:     this.buffer = buffer;
  62:     modCount = 0;
  63:   }
  64: 
  65:   /**
  66:    * Return the number of elements in this list.
  67:    *
  68:    * @return The size of this list.
  69:    */
  70:   public int size ()
  71:   {
  72:     return (buffer.get (0) & 0xFF);
  73:   }
  74: 
  75:   /**
  76:    * Get the cipher suite at the specified index.
  77:    *
  78:    * @param index The index of the suite to get.
  79:    * @return The cipher suite at that index.
  80:    * @throws IndexOutOfBoundsException If the index is negative or is
  81:    * not less than {@link #size()}.
  82:    */
  83:   public CompressionMethod get (final int index)
  84:   {
  85:     int size = size ();
  86:     if (index < 0 || index >= size)
  87:       throw new IndexOutOfBoundsException ("limit: " + size
  88:                                            + "; requested: " + index);
  89:     return CompressionMethod.getInstance (buffer.get (1 + index));
  90:   }
  91: 
  92:   /**
  93:    * Set the CompressionMethod at the specified index. The list must
  94:    * have sufficient size to hold the element (that is, <code>index
  95:    * &lt;= size ()</code>).
  96:    *
  97:    * @param index The index to put the suite.
  98:    * @param method The CompressionMethod object.
  99:    * @throws IndexOutOfBoundsException If <code>index</code> is not
 100:    * less than @{link #size()}, or if it is negative.
 101:    * @throws NullPointerException If <code>suite</code> is
 102:    * <code>null</code>.
 103:    * @throws java.nio.ReadOnlyBufferException If the underlying buffer
 104:    * is not writable.
 105:    */
 106:   public void put (final int index, final CompressionMethod method)
 107:   {
 108:     int size = size ();
 109:     if (index < 0 || index >= size)
 110:       throw new IndexOutOfBoundsException ("limit: " + size
 111:                                            + "; requested: " + index);
 112:     buffer.position (1 + index);
 113:     buffer.put ((byte) method.getValue ());
 114:     modCount++;
 115:   }
 116: 
 117:   /**
 118:    * Sets the size of this list. You must call this if you are adding
 119:    * elements to the list; calling {@link
 120:    * #put(int,gnu.jessie.provider.CipherSuite)} does not expand the
 121:    * list size (the same goes for removing elements, as there is no
 122:    * <code>remove</code> method).
 123:    *
 124:    * @param newSize The new size of this list.
 125:    * @throws IllegalArgumentException If the new size is negative or
 126:    * greater than 32767, or if there is insufficient space for that
 127:    * many elements in the underlying buffer.
 128:    * @throws java.nio.ReadOnlyBufferException If the underlying buffer
 129:    * is not writable.
 130:    */
 131:   public void setSize (final int newSize)
 132:   {
 133:     if (newSize < 0 || newSize > 255)
 134:       throw new IllegalArgumentException ("size must be between 0 and 255");
 135:     if (newSize + 1 > buffer.capacity ())
 136:       throw new IllegalArgumentException ("limit: " + buffer.capacity ()
 137:                                           + "; requested: " + newSize);
 138:     buffer.put (0, (byte) newSize);
 139:     modCount++;
 140:   }
 141: 
 142:   public String toString ()
 143:   {
 144:     return toString (null);
 145:   }
 146: 
 147:   public String toString (final String prefix)
 148:   {
 149:     StringWriter str = new StringWriter ();
 150:     PrintWriter out = new PrintWriter (str);
 151:     if (prefix != null)
 152:       out.print (prefix);
 153:     out.print ("[");
 154:     out.print (size ());
 155:     out.println ("] {");
 156:     for (Iterator it = new Iterator (); it.hasNext (); )
 157:       {
 158:         CompressionMethod method = (CompressionMethod) it.next ();
 159:         if (prefix != null)
 160:           out.print (prefix);
 161:         out.print ("  ");
 162:         out.print (method);
 163:         if (it.hasNext ())
 164:           out.print (",");
 165:         out.println ();
 166:       }
 167:     if (prefix != null)
 168:       out.print (prefix);
 169:     out.print ("};");
 170:     return str.toString ();
 171:   }
 172: 
 173:   public boolean equals (Object o)
 174:   {
 175:     if (!(o instanceof CompressionMethodList))
 176:       return false;
 177:     CompressionMethodList that = (CompressionMethodList) o;
 178: 
 179:     if (size () != that.size ())
 180:       return false;
 181: 
 182:     for (Iterator it1 = new Iterator (), it2 = that.new Iterator ();
 183:          it1.hasNext () && it2.hasNext (); )
 184:       {
 185:         if (!it1.next ().equals (it2.next ()))
 186:           return false;
 187:       }
 188:     return true;
 189:   }
 190: 
 191:   public java.util.Iterator<CompressionMethod> iterator ()
 192:   {
 193:     return new Iterator ();
 194:   }
 195: 
 196:   /**
 197:    * An iterator for the elements in this list. The iterator supports
 198:    * only the <code>set</code> method out of the optional methods,
 199:    * because elements in a CipherSuiteList may not be removed or
 200:    * added; only the size of the list can be changed, and elements at
 201:    * a specific index changed.
 202:    */
 203:   public class Iterator implements ListIterator<CompressionMethod>
 204:   {
 205:     private int index;
 206:     private final int modCount;
 207: 
 208:     Iterator ()
 209:     {
 210:       index = 0;
 211:       modCount = CompressionMethodList.this.modCount;
 212:     }
 213: 
 214:     public void add (CompressionMethod cm)
 215:     {
 216:       throw new UnsupportedOperationException ();
 217:     }
 218: 
 219:     public boolean hasNext ()
 220:     {
 221:       return (index < size ());
 222:     }
 223: 
 224:     public boolean hasPrevious ()
 225:     {
 226:       return (index > 0);
 227:     }
 228: 
 229:     public CompressionMethod next () throws NoSuchElementException
 230:     {
 231:       if (modCount != CompressionMethodList.this.modCount)
 232:         throw new ConcurrentModificationException ();
 233:       try
 234:         {
 235:           return get (index++);
 236:         }
 237:       catch (IndexOutOfBoundsException ioobe)
 238:         {
 239:           throw new NoSuchElementException ();
 240:         }
 241:     }
 242: 
 243:     public int nextIndex ()
 244:     {
 245:       if (hasNext ())
 246:         return (index + 1);
 247:       return -1;
 248:     }
 249: 
 250:     public CompressionMethod previous () throws NoSuchElementException
 251:     {
 252:       if (index == 0)
 253:         throw new NoSuchElementException ();
 254:       if (modCount != CompressionMethodList.this.modCount)
 255:         throw new ConcurrentModificationException ();
 256:       try
 257:         {
 258:           return get (--index);
 259:         }
 260:       catch (IndexOutOfBoundsException ioobe) // on empty list
 261:         {
 262:           throw new NoSuchElementException ();
 263:         }
 264:     }
 265: 
 266:     public int previousIndex ()
 267:     {
 268:       return (index - 1);
 269:     }
 270: 
 271:     public void remove ()
 272:     {
 273:       throw new UnsupportedOperationException ();
 274:     }
 275: 
 276:     public void set (final CompressionMethod cm)
 277:     {
 278:       put (index, cm);
 279:     }
 280:   }
 281: }