View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.util.byteaccess;
21  
22  import java.nio.ByteOrder;
23  import java.util.Collections;
24  
25  import org.apache.mina.core.buffer.IoBuffer;
26  
27  /**
28   * A <code>ByteArray</code> backed by a <code>IoBuffer</code>. This class
29   * is abstract. Subclasses need to override the <code>free()</code> method. An
30   * implementation backed by a heap <code>IoBuffer</code> can be created with
31   * a <code>SimpleByteArrayFactory</code>.
32   *
33   * @author <a href="http://mina.apache.org">Apache MINA Project</a>
34   */
35  public abstract class BufferByteArray extends AbstractByteArray {
36  
37      /**
38       * The backing <code>IoBuffer</code>.
39       */
40      protected IoBuffer bb;
41  
42      /**
43       * 
44       * Creates a new instance of BufferByteArray and uses the supplied
45       * {@link IoBuffer} to back this class
46       *
47       * @param bb
48       *  The backing buffer
49       */
50      public BufferByteArray(IoBuffer bb) {
51          this.bb = bb;
52      }
53  
54      /**
55       * {@inheritDoc}
56       */
57      @Override
58      public Iterable<IoBuffer> getIoBuffers() {
59          return Collections.singletonList(bb);
60      }
61  
62      /**
63       * {@inheritDoc}
64       */
65      @Override
66      public IoBuffer getSingleIoBuffer() {
67          return bb;
68      }
69  
70      /**
71       * {@inheritDoc}
72       * 
73       * Calling <code>free()</code> on the returned slice has no effect.
74       */
75      @Override
76      public ByteArray slice(int index, int length) {
77          int oldLimit = bb.limit();
78          bb.position(index);
79          bb.limit(index + length);
80          IoBuffer slice = bb.slice();
81          bb.limit(oldLimit);
82          return new BufferByteArray(slice) {
83  
84              @Override
85              public void free() {
86                  // Do nothing.
87              }
88          };
89      }
90  
91      /**
92       * {@inheritDoc}
93       */
94      @Override
95      public Cursor cursor() {
96          return new CursorImpl();
97      }
98  
99      /**
100      * {@inheritDoc}
101      */
102     @Override
103     public Cursor cursor(int index) {
104         return new CursorImpl(index);
105     }
106 
107     /**
108      * {@inheritDoc}
109      */
110     @Override
111     public int first() {
112         return 0;
113     }
114 
115     /**
116      * {@inheritDoc}
117      */
118     @Override
119     public int last() {
120         return bb.limit();
121     }
122 
123     /**
124      * {@inheritDoc}
125      */
126     @Override
127     public ByteOrder order() {
128         return bb.order();
129     }
130 
131     /**
132      * {@inheritDoc}
133      */
134     @Override
135     public void order(ByteOrder order) {
136         bb.order(order);
137     }
138 
139     /**
140      * {@inheritDoc}
141      */
142     @Override
143     public byte get(int index) {
144         return bb.get(index);
145     }
146 
147     /**
148      * {@inheritDoc}
149      */
150     @Override
151     public void put(int index, byte b) {
152         bb.put(index, b);
153     }
154 
155     /**
156      * {@inheritDoc}
157      */
158     @Override
159     public void get(int index, IoBuffer other) {
160         bb.position(index);
161         other.put(bb);
162     }
163 
164     /**
165      * {@inheritDoc}
166      */
167     @Override
168     public void put(int index, IoBuffer other) {
169         bb.position(index);
170         bb.put(other);
171     }
172 
173     /**
174      * {@inheritDoc}
175      */
176     @Override
177     public short getShort(int index) {
178         return bb.getShort(index);
179     }
180 
181     /**
182      * {@inheritDoc}
183      */
184     @Override
185     public void putShort(int index, short s) {
186         bb.putShort(index, s);
187     }
188 
189     /**
190      * {@inheritDoc}
191      */
192     @Override
193     public int getInt(int index) {
194         return bb.getInt(index);
195     }
196 
197     /**
198      * {@inheritDoc}
199      */
200     @Override
201     public void putInt(int index, int i) {
202         bb.putInt(index, i);
203     }
204 
205     /**
206      * {@inheritDoc}
207      */
208     @Override
209     public long getLong(int index) {
210         return bb.getLong(index);
211     }
212 
213     /**
214      * {@inheritDoc}
215      */
216     @Override
217     public void putLong(int index, long l) {
218         bb.putLong(index, l);
219     }
220 
221     /**
222      * {@inheritDoc}
223      */
224     @Override
225     public float getFloat(int index) {
226         return bb.getFloat(index);
227     }
228 
229     /**
230      * {@inheritDoc}
231      */
232     @Override
233     public void putFloat(int index, float f) {
234         bb.putFloat(index, f);
235     }
236 
237     /**
238      * {@inheritDoc}
239      */
240     @Override
241     public double getDouble(int index) {
242         return bb.getDouble(index);
243     }
244 
245     /**
246      * {@inheritDoc}
247      */
248     @Override
249     public void putDouble(int index, double d) {
250         bb.putDouble(index, d);
251     }
252 
253     /**
254      * {@inheritDoc}
255      */
256     @Override
257     public char getChar(int index) {
258         return bb.getChar(index);
259     }
260 
261     /**
262      * {@inheritDoc}
263      */
264     @Override
265     public void putChar(int index, char c) {
266         bb.putChar(index, c);
267     }
268 
269     private class CursorImpl implements Cursor {
270 
271         private int index;
272 
273         public CursorImpl() {
274             // This space intentionally blank.
275         }
276 
277         public CursorImpl(int index) {
278             setIndex(index);
279         }
280 
281         /**
282          * {@inheritDoc}
283          */
284         @Override
285         public int getRemaining() {
286             return last() - index;
287         }
288 
289         /**
290          * {@inheritDoc}
291          */
292         @Override
293         public boolean hasRemaining() {
294             return getRemaining() > 0;
295         }
296 
297         /**
298          * {@inheritDoc}
299          */
300         @Override
301         public int getIndex() {
302             return index;
303         }
304 
305         /**
306          * {@inheritDoc}
307          */
308         @Override
309         public void setIndex(int index) {
310             if (index < 0 || index > last()) {
311                 throw new IndexOutOfBoundsException();
312             }
313             this.index = index;
314         }
315 
316         /**
317          * {@inheritDoc}
318          */
319         @Override
320         public void skip(int length) {
321             setIndex(index + length);
322         }
323 
324         /**
325          * {@inheritDoc}
326          */
327         @Override
328         public ByteArray slice(int length) {
329             ByteArray slice = BufferByteArray.this.slice(index, length);
330             index += length;
331             return slice;
332         }
333 
334         /**
335          * {@inheritDoc}
336          */
337         @Override
338         public ByteOrder order() {
339             return BufferByteArray.this.order();
340         }
341 
342         /**
343          * {@inheritDoc}
344          */
345         @Override
346         public byte get() {
347             byte b = BufferByteArray.this.get(index);
348             index += 1;
349             return b;
350         }
351 
352         /**
353          * {@inheritDoc}
354          */
355         @Override
356         public void put(byte b) {
357             BufferByteArray.this.put(index, b);
358             index += 1;
359         }
360 
361         /**
362          * {@inheritDoc}
363          */
364         @Override
365         public void get(IoBuffer bb) {
366             int size = Math.min(getRemaining(), bb.remaining());
367             BufferByteArray.this.get(index, bb);
368             index += size;
369         }
370 
371         /**
372          * {@inheritDoc}
373          */
374         @Override
375         public void put(IoBuffer bb) {
376             int size = bb.remaining();
377             BufferByteArray.this.put(index, bb);
378             index += size;
379         }
380 
381         /**
382          * {@inheritDoc}
383          */
384         @Override
385         public short getShort() {
386             short s = BufferByteArray.this.getShort(index);
387             index += 2;
388             return s;
389         }
390 
391         /**
392          * {@inheritDoc}
393          */
394         @Override
395         public void putShort(short s) {
396             BufferByteArray.this.putShort(index, s);
397             index += 2;
398         }
399 
400         /**
401          * {@inheritDoc}
402          */
403         @Override
404         public int getInt() {
405             int i = BufferByteArray.this.getInt(index);
406             index += 4;
407             return i;
408         }
409 
410         /**
411          * {@inheritDoc}
412          */
413         @Override
414         public void putInt(int i) {
415             BufferByteArray.this.putInt(index, i);
416             index += 4;
417         }
418 
419         /**
420          * {@inheritDoc}
421          */
422         @Override
423         public long getLong() {
424             long l = BufferByteArray.this.getLong(index);
425             index += 8;
426             return l;
427         }
428 
429         /**
430          * {@inheritDoc}
431          */
432         @Override
433         public void putLong(long l) {
434             BufferByteArray.this.putLong(index, l);
435             index += 8;
436         }
437 
438         /**
439          * {@inheritDoc}
440          */
441         @Override
442         public float getFloat() {
443             float f = BufferByteArray.this.getFloat(index);
444             index += 4;
445             return f;
446         }
447 
448         /**
449          * {@inheritDoc}
450          */
451         @Override
452         public void putFloat(float f) {
453             BufferByteArray.this.putFloat(index, f);
454             index += 4;
455         }
456 
457         /**
458          * {@inheritDoc}
459          */
460         @Override
461         public double getDouble() {
462             double d = BufferByteArray.this.getDouble(index);
463             index += 8;
464             return d;
465         }
466 
467         /**
468          * {@inheritDoc}
469          */
470         @Override
471         public void putDouble(double d) {
472             BufferByteArray.this.putDouble(index, d);
473             index += 8;
474         }
475 
476         /**
477          * {@inheritDoc}
478          */
479         @Override
480         public char getChar() {
481             char c = BufferByteArray.this.getChar(index);
482             index += 2;
483             return c;
484         }
485 
486         /**
487          * {@inheritDoc}
488          */
489         @Override
490         public void putChar(char c) {
491             BufferByteArray.this.putChar(index, c);
492             index += 2;
493         }
494     }
495     
496     
497     /**
498      * {@inheritDoc}
499      */
500     @Override
501     public int hashCode() {
502         int h = 17;
503         
504         if (bb != null) {
505             h = h * 37 + bb.hashCode();
506         }
507         
508         return h;
509     }
510 }