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

   1: /* CipherSuiteList.java -- A list of cipher suites.
   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: import java.util.ConcurrentModificationException;
  46: import java.util.ListIterator;
  47: import java.util.NoSuchElementException;
  48: 
  49: public final class CipherSuiteList implements Iterable<CipherSuite>
  50: {
  51:   private final ByteBuffer buffer;
  52:   private final ProtocolVersion version;
  53:   private int modCount;
  54: 
  55:   public CipherSuiteList (final ByteBuffer buffer)
  56:   {
  57:     this (buffer, ProtocolVersion.SSL_3);
  58:   }
  59: 
  60:   public CipherSuiteList (final ByteBuffer buffer, final ProtocolVersion version)
  61:   {
  62:     this.version = version;
  63:     this.buffer = buffer;
  64:     modCount = 0;
  65:   }
  66: 
  67:   /**
  68:    * Return the number of elements in this list.
  69:    *
  70:    * @return The size of this list.
  71:    */
  72:   public int size ()
  73:   {
  74:     return (buffer.getShort (0) & 0xFFFF) >>> 1;
  75:   }
  76: 
  77:   /**
  78:    * Get the cipher suite at the specified index.
  79:    *
  80:    * @param index The index of the suite to get.
  81:    * @return The cipher suite at that index.
  82:    * @throws IndexOutOfBoundsException If the index is negative or is
  83:    * not less than {@link size()}.
  84:    */
  85:   public CipherSuite get (final int index)
  86:   {
  87:     int size = size ();
  88:     if (index < 0 || index >= size)
  89:       throw new IndexOutOfBoundsException ("limit: " + size
  90:                                            + "; requested: " + index);
  91:     return CipherSuite.forValue(buffer.getShort(2 + (index << 1))).resolve();
  92:   }
  93: 
  94:   /**
  95:    * Set the CipherSuite at the specified index. The list must have
  96:    * sufficient size to hold the element (that is, <code>index &lt;=
  97:    * size ()</code>).
  98:    *
  99:    * @param index The index to put the suite.
 100:    * @param suite The CipherSuite object.
 101:    * @throws IndexOutOfBoundsException If <code>index</code> is not
 102:    * less than @{link #size()}, or if it is negative.
 103:    * @throws NullPointerException If <code>suite</code> is
 104:    * <code>null</code>.
 105:    * @throws java.nio.ReadOnlyBufferException If the underlying buffer
 106:    * is not writable.
 107:    */
 108:   public void put (final int index, final CipherSuite suite)
 109:   {
 110:     int size = size ();
 111:     if (index < 0 || index >= size)
 112:       throw new IndexOutOfBoundsException ("limit: " + size
 113:                                            + "; requested: " + index);
 114:     buffer.position (2 + (index << 1));
 115:     buffer.put (suite.id ());
 116:     modCount++;
 117:   }
 118: 
 119:   /**
 120:    * Sets the size of this list. You must call this if you are adding
 121:    * elements to the list; calling {@link
 122:    * #put(int,gnu.jessie.provider.CipherSuite)} does not expand the
 123:    * list size (the same goes for removing elements, as there is no
 124:    * <code>remove</code> method).
 125:    *
 126:    * @param newSize The new size of this list.
 127:    * @throws IllegalArgumentException If the new size is negative or
 128:    * greater than 32767, or if there is insufficient space for that
 129:    * many elements in the underlying buffer.
 130:    * @throws java.nio.ReadOnlyBufferException If the underlying buffer
 131:    * is not writable.
 132:    */
 133:   public void setSize (final int newSize)
 134:   {
 135:     if (newSize < 0 || newSize > 32767)
 136:       throw new IllegalArgumentException ("size must be between 0 and 32767");
 137:     if ((newSize << 1) + 2 > buffer.capacity ())
 138:       throw new IllegalArgumentException ("limit: " + buffer.capacity ()
 139:                                           + "; requested: " + newSize);
 140:     buffer.putShort (0, (short) (newSize << 1));
 141:     modCount++;
 142:   }
 143: 
 144:   public String toString ()
 145:   {
 146:     return toString (null);
 147:   }
 148: 
 149:   public String toString (final String prefix)
 150:   {
 151:     StringWriter str = new StringWriter ();
 152:     PrintWriter out = new PrintWriter (str);
 153:     if (prefix != null)
 154:       out.print (prefix);
 155:     out.print ("[");
 156:     out.print (size ());
 157:     out.println ("] {");
 158:     for (Iterator it = new Iterator (); it.hasNext (); )
 159:       {
 160:         CipherSuite suite = (CipherSuite) it.next ();
 161:         if (prefix != null)
 162:           out.print (prefix);
 163:         out.print ("  ");
 164:         out.print (suite);
 165:         if (it.hasNext ())
 166:           out.print (",");
 167:         out.println ();
 168:       }
 169:     if (prefix != null)
 170:       out.print (prefix);
 171:     out.print ("};");
 172:     return str.toString ();
 173:   }
 174: 
 175:   public boolean equals (Object o)
 176:   {
 177:     if (!(o instanceof CipherSuiteList))
 178:       return false;
 179:     CipherSuiteList that = (CipherSuiteList) o;
 180: 
 181:     if (size () != that.size ())
 182:       return false;
 183: 
 184:     for (Iterator it1 = new Iterator (), it2 = that.new Iterator ();
 185:          it1.hasNext () && it2.hasNext (); )
 186:       {
 187:         if (!it1.next ().equals (it2.next ()))
 188:           return false;
 189:       }
 190:     return true;
 191:   }
 192: 
 193:   public java.util.Iterator<CipherSuite> iterator ()
 194:   {
 195:     return new Iterator ();
 196:   }
 197: 
 198:   /**
 199:    * An iterator for the elements in this list. The iterator supports
 200:    * only the <code>set</code> method out of the optional methods,
 201:    * because elements in a CipherSuiteList may not be removed or
 202:    * added; only the size of the list can be changed, and elements at
 203:    * a specific index changed.
 204:    */
 205:   public class Iterator implements ListIterator<CipherSuite>
 206:   {
 207:     private final int modCount;
 208:     private int index;
 209: 
 210:     Iterator ()
 211:     {
 212:       this.modCount = CipherSuiteList.this.modCount;
 213:       index = 0;
 214:     }
 215: 
 216:     public void add (CipherSuite cs)
 217:     {
 218:       throw new UnsupportedOperationException ();
 219:     }
 220: 
 221:     public boolean hasNext ()
 222:     {
 223:       return (index < size ());
 224:     }
 225: 
 226:     public boolean hasPrevious ()
 227:     {
 228:       return (index > 0);
 229:     }
 230: 
 231:     public CipherSuite next () throws NoSuchElementException
 232:     {
 233:       if (modCount != CipherSuiteList.this.modCount)
 234:         throw new ConcurrentModificationException ();
 235:       try
 236:         {
 237:           return get (index++);
 238:         }
 239:       catch (IndexOutOfBoundsException ioobe)
 240:         {
 241:           throw new NoSuchElementException ();
 242:         }
 243:     }
 244: 
 245:     public int nextIndex ()
 246:     {
 247:       if (hasNext ())
 248:         return (index + 1);
 249:       return -1;
 250:     }
 251: 
 252:     public CipherSuite previous () throws NoSuchElementException
 253:     {
 254:       if (index == 0)
 255:         throw new NoSuchElementException ();
 256:       if (modCount != CipherSuiteList.this.modCount)
 257:         throw new ConcurrentModificationException ();
 258:       try
 259:         {
 260:           return get (--index);
 261:         }
 262:       catch (IndexOutOfBoundsException ioobe) // on empty list
 263:         {
 264:           throw new NoSuchElementException ();
 265:         }
 266:     }
 267: 
 268:     public int previousIndex ()
 269:     {
 270:       return (index - 1);
 271:     }
 272: 
 273:     public void remove ()
 274:     {
 275:       throw new UnsupportedOperationException ();
 276:     }
 277: 
 278:     public void set (final CipherSuite cs)
 279:     {
 280:       put (index, cs);
 281:     }
 282:   }
 283: }