OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [javax/] [net/] [ssl/] [provider/] [ExtensionList.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
package gnu.javax.net.ssl.provider;
2
 
3
import java.io.PrintWriter;
4
import java.io.StringWriter;
5
import java.nio.ByteBuffer;
6
import java.nio.ByteOrder;
7
import java.util.ConcurrentModificationException;
8
import java.util.Iterator;
9
import java.util.List;
10
import java.util.ListIterator;
11
import java.util.NoSuchElementException;
12
 
13
/**
14
 * A list of extensions, that may appear in either the {@link ClientHello} or
15
 * {@link ServerHello}. The form of the extensions list is:
16
 *
17
 * <tt>   Extension extensions_list&lt;1..2^16-1&gt;</tt>
18
 *
19
 * @author csm
20
 */
21
public class ExtensionList implements Builder, Iterable<Extension>
22
{
23
  private final ByteBuffer buffer;
24
  private int modCount;
25
 
26
  public ExtensionList (ByteBuffer buffer)
27
  {
28
    this.buffer = buffer.duplicate().order(ByteOrder.BIG_ENDIAN);
29
    modCount = 0;
30
  }
31
 
32
  public ExtensionList(List<Extension> extensions)
33
  {
34
    int length = 2;
35
    for (Extension extension : extensions)
36
      length += extension.length();
37
    buffer = ByteBuffer.allocate(length);
38
    buffer.putShort((short) (length - 2));
39
    for (Extension extension : extensions)
40
      buffer.put(extension.buffer());
41
    buffer.rewind();
42
  }
43
 
44
  public ByteBuffer buffer()
45
  {
46
    return (ByteBuffer) buffer.duplicate().limit(length());
47
  }
48
 
49
  public Extension get (final int index)
50
  {
51
    int length = length ();
52
    int i;
53
    int n = 0;
54
    for (i = 2; i < length && n < index; )
55
      {
56
        int l = buffer.getShort (i+2) & 0xFFFF;
57
        i += l + 4;
58
        n++;
59
      }
60
    if (n < index)
61
      throw new IndexOutOfBoundsException ("no elemenet at " + index);
62
    int el = buffer.getShort (i+2) & 0xFFFF;
63
    ByteBuffer b = (ByteBuffer) buffer.duplicate().position(i).limit(i+el+4);
64
    return new Extension(b.slice());
65
  }
66
 
67
  /**
68
   * Returns the number of extensions this list contains.
69
   *
70
   * @return The number of extensions.
71
   */
72
  public int size ()
73
  {
74
    int length = length ();
75
    if (length == 0)
76
      return 0;
77
    int n = 0;
78
    for (int i = 2; i < length; )
79
      {
80
        int len = buffer.getShort (i+2) & 0xFFFF;
81
        i += len + 4;
82
        n++;
83
      }
84
    return n;
85
  }
86
 
87
  /**
88
   * Returns the length of this extension list, in bytes.
89
   *
90
   * @return The length of this extension list, in bytes.
91
   */
92
  public int length ()
93
  {
94
    return (buffer.getShort (0) & 0xFFFF) + 2;
95
  }
96
 
97
  /**
98
   * Sets the extension at index <i>i</i> to <i>e</i>. Note that setting an
99
   * element at an index <b>may</b> invalidate any other elements that come
100
   * after element at index <i>i</i>. In other words, no attempt is made to
101
   * move existing elements in this list, and since extensions are variable
102
   * length, you can <em>not</em> guarantee that extensions later in the list
103
   * will still be valid.
104
   *
105
   * <p>Thus, elements of this list <b>must</b> be set in order of increasing
106
   * index.
107
   *
108
   * @param index The index to set the extension at.
109
   * @param e The extension.
110
   * @throws java.nio.BufferOverflowException If setting the extension overflows
111
   *  the buffer.
112
   * @throws IllegalArgumentException If it isn't possible to find the given index
113
   *  in the current list (say, if no element index - 1 is set), or if setting
114
   *  the extension will overflow the current list length (given by {@link
115
   *  #length()}).
116
   */
117
  public void set (final int index, Extension e)
118
  {
119
    int length = length();
120
    int n = 0;
121
    int i;
122
    for (i = 2; i < length && n < index; )
123
      {
124
        int len = buffer.getShort(i+2) & 0xFFFF;
125
        i += len + 4;
126
        n++;
127
      }
128
    if (n < index)
129
      throw new IllegalArgumentException("nothing set at index " + (index-1)
130
                                         + " or insufficient space");
131
    if (i + e.length() + 2 > length)
132
      throw new IllegalArgumentException("adding this element will exceed the "
133
                                         + "list length");
134
    buffer.putShort(i, (short) e.type().getValue());
135
    buffer.putShort(i+2, (short) e.length());
136
    ((ByteBuffer) buffer.duplicate().position(i+4)).put (e.valueBuffer());
137
    modCount++;
138
  }
139
 
140
  /**
141
   * Reserve space for an extension at index <i>i</i> in the list. In other
142
   * words, this does the job of {@link #set(int, Extension)}, but does not
143
   * copy the extension value to the underlying buffer.
144
   *
145
   * @param index The index of the extension to reserve space for.
146
   * @param t The type of the extension.
147
   * @param eLength The number of bytes to reserve for this extension. The total
148
   *  number of bytes used by this method is this length, plus four.
149
   */
150
  public void set (final int index, Extension.Type t, final int eLength)
151
  {
152
    int length = length ();
153
    int n = 0;
154
    int i;
155
    for (i = 2; i < length && n < index; )
156
      {
157
        int len = buffer.getShort (i+2) & 0xFFFF;
158
        i += len + 4;
159
        n++;
160
      }
161
    if (n < index)
162
      throw new IllegalArgumentException ("nothing set at index " + (index-1)
163
                                          + " or insufficient space");
164
    if (i + eLength + 2 > length)
165
      throw new IllegalArgumentException ("adding this element will exceed the "
166
                                          + "list length");
167
    buffer.putShort(i, (short) t.getValue());
168
    buffer.putShort(i+2, (short) eLength);
169
    modCount++;
170
  }
171
 
172
  /**
173
   * Set the total length of this list, in bytes.
174
   *
175
   * @param newLength The new list length.
176
   */
177
  public void setLength (final int newLength)
178
  {
179
    if (newLength < 0 || newLength > 65535)
180
      throw new IllegalArgumentException ("invalid length");
181
    buffer.putShort (0, (short) newLength);
182
    modCount++;
183
  }
184
 
185
  public Iterator<Extension> iterator()
186
  {
187
    return new ExtensionsIterator();
188
  }
189
 
190
  public String toString()
191
  {
192
    return toString (null);
193
  }
194
 
195
  public String toString(final String prefix)
196
  {
197
    StringWriter str = new StringWriter();
198
    PrintWriter out = new PrintWriter(str);
199
    if (prefix != null) out.print(prefix);
200
    out.println("ExtensionList {");
201
    if (prefix != null) out.print(prefix);
202
    out.print("  length = ");
203
    out.print(length());
204
    out.println(";");
205
    String subprefix = "  ";
206
    if (prefix != null)
207
      subprefix = prefix + subprefix;
208
    for (Extension e : this)
209
      out.println(e.toString(subprefix));
210
    if (prefix != null) out.print(prefix);
211
    out.print("};");
212
    return str.toString();
213
  }
214
 
215
  /**
216
   * List iterator interface to an extensions list.
217
   *
218
   * @author csm@gnu.org
219
   */
220
  public final class ExtensionsIterator implements ListIterator<Extension>
221
  {
222
    private final int modCount;
223
    private int index;
224
    private final int size;
225
 
226
    public ExtensionsIterator ()
227
    {
228
      this.modCount = ExtensionList.this.modCount;
229
      index = 0;
230
      size = size ();
231
    }
232
 
233
    public boolean hasNext()
234
    {
235
      return index < size;
236
    }
237
 
238
    public boolean hasPrevious()
239
    {
240
      return index > 0;
241
    }
242
 
243
    public Extension next() throws NoSuchElementException
244
    {
245
      if (modCount != ExtensionList.this.modCount)
246
        throw new ConcurrentModificationException ();
247
      if (!hasNext ())
248
        throw new NoSuchElementException ();
249
      return get (index++);
250
    }
251
 
252
    public Extension previous() throws NoSuchElementException
253
    {
254
      if (modCount != ExtensionList.this.modCount)
255
        throw new ConcurrentModificationException ();
256
      if (!hasPrevious ())
257
        throw new NoSuchElementException ();
258
      return get (--index);
259
    }
260
 
261
    public int nextIndex()
262
    {
263
      if (hasNext ())
264
        return index + 1;
265
      return index;
266
    }
267
 
268
    public int previousIndex()
269
    {
270
      if (hasPrevious ())
271
        return index - 1;
272
      return -1;
273
    }
274
 
275
    public void add(Extension e)
276
    {
277
      throw new UnsupportedOperationException ("cannot add items to this iterator");
278
    }
279
 
280
    public void remove()
281
    {
282
      throw new UnsupportedOperationException ("cannot remove items from this iterator");
283
    }
284
 
285
    public void set(Extension e)
286
    {
287
      ExtensionList.this.set (index, e);
288
    }
289
  }
290
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.