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      public Iterable<IoBuffer> getIoBuffers() {
58          return Collections.singletonList(bb);
59      }
60  
61      /**
62       * @inheritDoc
63       */
64      public IoBuffer getSingleIoBuffer() {
65          return bb;
66      }
67  
68      /**
69       * @inheritDoc
70       * 
71       * Calling <code>free()</code> on the returned slice has no effect.
72       */
73      public ByteArray slice(int index, int length) {
74          int oldLimit = bb.limit();
75          bb.position(index);
76          bb.limit(index + length);
77          IoBuffer slice = bb.slice();
78          bb.limit(oldLimit);
79          return new BufferByteArray(slice) {
80  
81              @Override
82              public void free() {
83                  // Do nothing.
84              }
85          };
86      }
87  
88      /**
89       * @inheritDoc
90       */
91      public abstract void free();
92  
93      /**
94       * @inheritDoc
95       */
96      public Cursor cursor() {
97          return new CursorImpl();
98      }
99  
100     /**
101      * @inheritDoc
102      */
103     public Cursor cursor(int index) {
104         return new CursorImpl(index);
105     }
106 
107     /**
108      * @inheritDoc
109      */
110     public int first() {
111         return 0;
112     }
113 
114     /**
115      * @inheritDoc
116      */
117     public int last() {
118         return bb.limit();
119     }
120 
121     /**
122      * @inheritDoc
123      */
124     public ByteOrder order() {
125         return bb.order();
126     }
127 
128     /**
129      * @inheritDoc
130      */
131     public void order(ByteOrder order) {
132         bb.order(order);
133     }
134 
135     /**
136      * @inheritDoc
137      */
138     public byte get(int index) {
139         return bb.get(index);
140     }
141 
142     /**
143      * @inheritDoc
144      */
145     public void put(int index, byte b) {
146         bb.put(index, b);
147     }
148 
149     /**
150      * @inheritDoc
151      */
152     public void get(int index, IoBuffer other) {
153         bb.position(index);
154         other.put(bb);
155     }
156 
157     /**
158      * @inheritDoc
159      */
160     public void put(int index, IoBuffer other) {
161         bb.position(index);
162         bb.put(other);
163     }
164 
165     /**
166      * @inheritDoc
167      */
168     public short getShort(int index) {
169         return bb.getShort(index);
170     }
171 
172     /**
173      * @inheritDoc
174      */
175     public void putShort(int index, short s) {
176         bb.putShort(index, s);
177     }
178 
179     /**
180      * @inheritDoc
181      */
182     public int getInt(int index) {
183         return bb.getInt(index);
184     }
185 
186     /**
187      * @inheritDoc
188      */
189     public void putInt(int index, int i) {
190         bb.putInt(index, i);
191     }
192 
193     /**
194      * @inheritDoc
195      */
196     public long getLong(int index) {
197         return bb.getLong(index);
198     }
199 
200     /**
201      * @inheritDoc
202      */
203     public void putLong(int index, long l) {
204         bb.putLong(index, l);
205     }
206 
207     /**
208      * @inheritDoc
209      */
210     public float getFloat(int index) {
211         return bb.getFloat(index);
212     }
213 
214     /**
215      * @inheritDoc
216      */
217     public void putFloat(int index, float f) {
218         bb.putFloat(index, f);
219     }
220 
221     /**
222      * @inheritDoc
223      */
224     public double getDouble(int index) {
225         return bb.getDouble(index);
226     }
227 
228     /**
229      * @inheritDoc
230      */
231     public void putDouble(int index, double d) {
232         bb.putDouble(index, d);
233     }
234 
235     /**
236      * @inheritDoc
237      */
238     public char getChar(int index) {
239         return bb.getChar(index);
240     }
241 
242     /**
243      * @inheritDoc
244      */
245     public void putChar(int index, char c) {
246         bb.putChar(index, c);
247     }
248 
249     private class CursorImpl implements Cursor {
250 
251         private int index;
252 
253         public CursorImpl() {
254             // This space intentionally blank.
255         }
256 
257         public CursorImpl(int index) {
258             setIndex(index);
259         }
260 
261         /**
262          * @inheritDoc
263          */
264         public int getRemaining() {
265             return last() - index;
266         }
267 
268         /**
269          * @inheritDoc
270          */
271         public boolean hasRemaining() {
272             return getRemaining() > 0;
273         }
274 
275         /**
276          * @inheritDoc
277          */
278         public int getIndex() {
279             return index;
280         }
281 
282         /**
283          * @inheritDoc
284          */
285         public void setIndex(int index) {
286             if (index < 0 || index > last()) {
287                 throw new IndexOutOfBoundsException();
288             }
289             this.index = index;
290         }
291 
292         public void skip(int length) {
293             setIndex(index + length);
294         }
295 
296         public ByteArray slice(int length) {
297             ByteArray slice = BufferByteArray.this.slice(index, length);
298             index += length;
299             return slice;
300         }
301 
302         /**
303          * @inheritDoc
304          */
305         public ByteOrder order() {
306             return BufferByteArray.this.order();
307         }
308 
309         /**
310          * @inheritDoc
311          */
312         public byte get() {
313             byte b = BufferByteArray.this.get(index);
314             index += 1;
315             return b;
316         }
317 
318         /**
319          * @inheritDoc
320          */
321         public void put(byte b) {
322             BufferByteArray.this.put(index, b);
323             index += 1;
324         }
325 
326         /**
327          * @inheritDoc
328          */
329         public void get(IoBuffer bb) {
330             int size = Math.min(getRemaining(), bb.remaining());
331             BufferByteArray.this.get(index, bb);
332             index += size;
333         }
334 
335         /**
336          * @inheritDoc
337          */
338         public void put(IoBuffer bb) {
339             int size = bb.remaining();
340             BufferByteArray.this.put(index, bb);
341             index += size;
342         }
343 
344         /**
345          * @inheritDoc
346          */
347         public short getShort() {
348             short s = BufferByteArray.this.getShort(index);
349             index += 2;
350             return s;
351         }
352 
353         /**
354          * @inheritDoc
355          */
356         public void putShort(short s) {
357             BufferByteArray.this.putShort(index, s);
358             index += 2;
359         }
360 
361         /**
362          * @inheritDoc
363          */
364         public int getInt() {
365             int i = BufferByteArray.this.getInt(index);
366             index += 4;
367             return i;
368         }
369 
370         /**
371          * @inheritDoc
372          */
373         public void putInt(int i) {
374             BufferByteArray.this.putInt(index, i);
375             index += 4;
376         }
377 
378         /**
379          * @inheritDoc
380          */
381         public long getLong() {
382             long l = BufferByteArray.this.getLong(index);
383             index += 8;
384             return l;
385         }
386 
387         /**
388          * @inheritDoc
389          */
390         public void putLong(long l) {
391             BufferByteArray.this.putLong(index, l);
392             index += 8;
393         }
394 
395         /**
396          * @inheritDoc
397          */
398         public float getFloat() {
399             float f = BufferByteArray.this.getFloat(index);
400             index += 4;
401             return f;
402         }
403 
404         /**
405          * @inheritDoc
406          */
407         public void putFloat(float f) {
408             BufferByteArray.this.putFloat(index, f);
409             index += 4;
410         }
411 
412         /**
413          * @inheritDoc
414          */
415         public double getDouble() {
416             double d = BufferByteArray.this.getDouble(index);
417             index += 8;
418             return d;
419         }
420 
421         /**
422          * @inheritDoc
423          */
424         public void putDouble(double d) {
425             BufferByteArray.this.putDouble(index, d);
426             index += 8;
427         }
428 
429         /**
430          * @inheritDoc
431          */
432         public char getChar() {
433             char c = BufferByteArray.this.getChar(index);
434             index += 2;
435             return c;
436         }
437 
438         /**
439          * @inheritDoc
440          */
441         public void putChar(char c) {
442             BufferByteArray.this.putChar(index, c);
443             index += 2;
444         }
445     }
446 }