HeapByteBuffer.java revision 490d8356c6d541aa296c5bf19b872473cd78deb8
1/*
2 * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26
27package java.nio;
28
29
30/**
31 * A read/write HeapByteBuffer.
32 */
33
34class HeapByteBuffer extends ByteBuffer {
35
36    // For speed these fields are actually declared in X-Buffer;
37    // these declarations are here as documentation
38    /*
39
40      protected final byte[] hb;
41      protected final int offset;
42
43    */
44
45    private final boolean isReadOnly;
46
47    HeapByteBuffer(int cap, int lim) {            // packag-private
48        this(cap, lim, false);
49    }
50
51
52    HeapByteBuffer(int cap, int lim, boolean isReadOnly) {            // package-private
53        super(-1, 0, lim, cap, new byte[cap], 0);
54        this.isReadOnly = isReadOnly;
55    }
56
57    HeapByteBuffer(byte[] buf, int off, int len) { // package-private
58        this(buf, off, len, false);
59    }
60
61    HeapByteBuffer(byte[] buf, int off, int len, boolean isReadOnly) { // package-private
62        super(-1, off, off + len, buf.length, buf, 0);
63        this.isReadOnly = isReadOnly;
64    }
65
66    protected HeapByteBuffer(byte[] buf,
67                             int mark, int pos, int lim, int cap,
68                             int off) {
69        this(buf, mark, pos, lim, cap, off, false);
70    }
71
72    protected HeapByteBuffer(byte[] buf,
73                             int mark, int pos, int lim, int cap,
74                             int off, boolean isReadOnly) {
75        super(mark, pos, lim, cap, buf, off);
76        this.isReadOnly = isReadOnly;
77    }
78
79    public ByteBuffer slice() {
80        return new HeapByteBuffer(hb,
81                                  -1,
82                                  0,
83                                  this.remaining(),
84                                  this.remaining(),
85                                  this.position() + offset);
86    }
87
88    public ByteBuffer duplicate() {
89        return new HeapByteBuffer(hb,
90                                  this.markValue(),
91                                  this.position(),
92                                  this.limit(),
93                                  this.capacity(),
94                                  offset);
95    }
96
97    public ByteBuffer asReadOnlyBuffer() {
98
99        return new HeapByteBuffer(hb,
100                                  this.markValue(),
101                                  this.position(),
102                                  this.limit(),
103                                  this.capacity(),
104                                  offset, true);
105
106
107
108    }
109
110    protected int ix(int i) {
111        return i + offset;
112    }
113
114    public byte get() {
115        return hb[ix(nextGetIndex())];
116    }
117
118    public byte get(int i) {
119        return hb[ix(checkIndex(i))];
120    }
121
122    public ByteBuffer get(byte[] dst, int offset, int length) {
123        checkBounds(offset, length, dst.length);
124        if (length > remaining())
125            throw new BufferUnderflowException();
126        System.arraycopy(hb, ix(position()), dst, offset, length);
127        position(position() + length);
128        return this;
129    }
130
131    public boolean isDirect() {
132        return false;
133    }
134
135    public boolean isReadOnly() {
136        return isReadOnly;
137    }
138
139    public ByteBuffer put(byte x) {
140        if (isReadOnly) {
141            throw new ReadOnlyBufferException();
142        }
143        hb[ix(nextPutIndex())] = x;
144        return this;
145    }
146
147    public ByteBuffer put(int i, byte x) {
148        if (isReadOnly) {
149            throw new ReadOnlyBufferException();
150        }
151        hb[ix(checkIndex(i))] = x;
152        return this;
153    }
154
155    public ByteBuffer put(byte[] src, int offset, int length) {
156        if (isReadOnly) {
157            throw new ReadOnlyBufferException();
158        }
159        checkBounds(offset, length, src.length);
160        if (length > remaining())
161            throw new BufferOverflowException();
162        System.arraycopy(src, offset, hb, ix(position()), length);
163        position(position() + length);
164        return this;
165    }
166
167    public ByteBuffer put(ByteBuffer src) {
168        if (isReadOnly) {
169            throw new ReadOnlyBufferException();
170        }
171        if (src instanceof HeapByteBuffer) {
172            if (src == this)
173                throw new IllegalArgumentException();
174            HeapByteBuffer sb = (HeapByteBuffer)src;
175            int n = sb.remaining();
176            if (n > remaining())
177                throw new BufferOverflowException();
178            System.arraycopy(sb.hb, sb.ix(sb.position()),
179                             hb, ix(position()), n);
180            sb.position(sb.position() + n);
181            position(position() + n);
182        } else if (src.isDirect()) {
183            int n = src.remaining();
184            if (n > remaining())
185                throw new BufferOverflowException();
186            src.get(hb, ix(position()), n);
187            position(position() + n);
188        } else {
189            super.put(src);
190        }
191        return this;
192    }
193
194    public ByteBuffer compact() {
195        if (isReadOnly) {
196            throw new ReadOnlyBufferException();
197        }
198        System.arraycopy(hb, ix(position()), hb, ix(0), remaining());
199        position(remaining());
200        limit(capacity());
201        discardMark();
202        return this;
203    }
204
205    byte _get(int i) {                          // package-private
206        return hb[i];
207    }
208
209    void _put(int i, byte b) {                  // package-private
210        if (isReadOnly) {
211            throw new ReadOnlyBufferException();
212        }
213        hb[i] = b;
214    }
215
216    public char getChar() {
217        return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian);
218    }
219
220    public char getChar(int i) {
221        return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian);
222    }
223
224    public ByteBuffer putChar(char x) {
225        if (isReadOnly) {
226            throw new ReadOnlyBufferException();
227        }
228        Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian);
229        return this;
230    }
231
232    public ByteBuffer putChar(int i, char x) {
233        if (isReadOnly) {
234            throw new ReadOnlyBufferException();
235        }
236        Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian);
237        return this;
238    }
239
240    public CharBuffer asCharBuffer() {
241        int size = this.remaining() >> 1;
242        int off = offset + position();
243        if (isReadOnly) {
244            return (bigEndian
245                    ? (CharBuffer)(new ByteBufferAsCharBufferRB(this,
246                                                                -1,
247                                                                0,
248                                                                size,
249                                                                size,
250                                                                off))
251                    : (CharBuffer)(new ByteBufferAsCharBufferRL(this,
252                                                                -1,
253                                                                0,
254                                                                size,
255                                                                size,
256                                                                off)));
257        } else {
258            return (bigEndian
259                    ? (CharBuffer)(new ByteBufferAsCharBufferB(this,
260                                                               -1,
261                                                               0,
262                                                               size,
263                                                               size,
264                                                               off))
265                    : (CharBuffer)(new ByteBufferAsCharBufferL(this,
266                                                               -1,
267                                                               0,
268                                                               size,
269                                                               size,
270                                                               off)));
271        }
272    }
273
274    public short getShort() {
275        return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian);
276    }
277
278    public short getShort(int i) {
279        return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian);
280    }
281
282    public ByteBuffer putShort(short x) {
283        if (isReadOnly) {
284            throw new ReadOnlyBufferException();
285        }
286        Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian);
287        return this;
288    }
289
290    public ByteBuffer putShort(int i, short x) {
291        if (isReadOnly) {
292            throw new ReadOnlyBufferException();
293        }
294        Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian);
295        return this;
296    }
297
298    public ShortBuffer asShortBuffer() {
299        int size = this.remaining() >> 1;
300        int off = offset + position();
301        return new ByteBufferAsShortBuffer(this,
302                                           -1,
303                                           0,
304                                           size,
305                                           size,
306                                           off,
307                                           order(),
308                                           isReadOnly);
309    }
310
311    public int getInt() {
312        return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian);
313    }
314
315    public int getInt(int i) {
316        return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian);
317    }
318
319    public ByteBuffer putInt(int x) {
320        if (isReadOnly) {
321            throw new ReadOnlyBufferException();
322        }
323        Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian);
324        return this;
325    }
326
327    public ByteBuffer putInt(int i, int x) {
328        if (isReadOnly) {
329            throw new ReadOnlyBufferException();
330        }
331        Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian);
332        return this;
333    }
334
335    public IntBuffer asIntBuffer() {
336        int size = this.remaining() >> 2;
337        int off = offset + position();
338
339        return (IntBuffer)(new ByteBufferAsIntBuffer(this,
340                                                     -1,
341                                                     0,
342                                                     size,
343                                                     size,
344                                                     off,
345                                                     order(),
346                                                     isReadOnly));
347    }
348
349    public long getLong() {
350        return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian);
351    }
352
353    public long getLong(int i) {
354        return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian);
355    }
356
357    public ByteBuffer putLong(long x) {
358        if (isReadOnly) {
359            throw new ReadOnlyBufferException();
360        }
361        Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian);
362        return this;
363    }
364
365    public ByteBuffer putLong(int i, long x) {
366        if (isReadOnly) {
367            throw new ReadOnlyBufferException();
368        }
369        Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian);
370        return this;
371    }
372
373    public LongBuffer asLongBuffer() {
374        int size = this.remaining() >> 3;
375        int off = offset + position();
376        if (isReadOnly) {
377            return (bigEndian
378                    ? (LongBuffer)(new ByteBufferAsLongBufferRB(this,
379                                                                -1,
380                                                                0,
381                                                                size,
382                                                                size,
383                                                                off))
384                    : (LongBuffer)(new ByteBufferAsLongBufferRL(this,
385                                                                -1,
386                                                                0,
387                                                                size,
388                                                                size,
389                                                                off)));
390        } else {
391            return (bigEndian
392                    ? (LongBuffer)(new ByteBufferAsLongBufferB(this,
393                                                               -1,
394                                                               0,
395                                                               size,
396                                                               size,
397                                                               off))
398                    : (LongBuffer)(new ByteBufferAsLongBufferL(this,
399                                                               -1,
400                                                               0,
401                                                               size,
402                                                               size,
403                                                               off)));
404        }
405    }
406
407    public float getFloat() {
408        return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian);
409    }
410
411    public float getFloat(int i) {
412        return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian);
413    }
414
415
416
417    public ByteBuffer putFloat(float x) {
418        if (isReadOnly) {
419            throw new ReadOnlyBufferException();
420        }
421        Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian);
422        return this;
423    }
424
425    public ByteBuffer putFloat(int i, float x) {
426        if (isReadOnly) {
427            throw new ReadOnlyBufferException();
428        }
429        Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian);
430        return this;
431    }
432
433    public FloatBuffer asFloatBuffer() {
434        int size = this.remaining() >> 2;
435        int off = offset + position();
436        if (isReadOnly) {
437            return (bigEndian
438                    ? (FloatBuffer)(new ByteBufferAsFloatBufferRB(this,
439                                                                  -1,
440                                                                  0,
441                                                                  size,
442                                                                  size,
443                                                                  off))
444                    : (FloatBuffer)(new ByteBufferAsFloatBufferRL(this,
445                                                                  -1,
446                                                                  0,
447                                                                  size,
448                                                                  size,
449                                                                  off)));
450        } else {
451            return (bigEndian
452                    ? (FloatBuffer)(new ByteBufferAsFloatBufferB(this,
453                                                                 -1,
454                                                                 0,
455                                                                 size,
456                                                                 size,
457                                                                 off))
458                    : (FloatBuffer)(new ByteBufferAsFloatBufferL(this,
459                                                                 -1,
460                                                                 0,
461                                                                 size,
462                                                                 size,
463                                                                 off)));
464        }
465    }
466
467    public double getDouble() {
468        return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian);
469    }
470
471    public double getDouble(int i) {
472        return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian);
473    }
474
475
476
477    public ByteBuffer putDouble(double x) {
478        if (isReadOnly) {
479            throw new ReadOnlyBufferException();
480        }
481        Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian);
482        return this;
483    }
484
485    public ByteBuffer putDouble(int i, double x) {
486        if (isReadOnly) {
487            throw new ReadOnlyBufferException();
488        }
489        Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian);
490        return this;
491    }
492
493    public DoubleBuffer asDoubleBuffer() {
494        int size = this.remaining() >> 3;
495        int off = offset + position();
496        return (bigEndian
497                ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer(this,
498                                                              -1,
499                                                              0,
500                                                              size,
501                                                              size,
502                                                              off,
503                                                              ByteOrder.BIG_ENDIAN,
504                                                              isReadOnly))
505                : (DoubleBuffer)(new ByteBufferAsDoubleBuffer(this,
506                                                              -1,
507                                                              0,
508                                                              size,
509                                                              size,
510                                                              off,
511                                                              ByteOrder.LITTLE_ENDIAN,
512                                                              isReadOnly)));
513
514    }
515}
516