xref: /aosp_15_r20/libcore/ojluni/src/main/java/java/nio/Heap-X-Buffer.java.template (revision 89a6322812dc8573315e60046e7959c50dad91d4)
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.  Oracle designates this
9 * particular file as subject to the "Classpath" exception as provided
10 * by Oracle in the LICENSE file that accompanied this code.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 */
26
27#warn This file is preprocessed before being compiled
28// Android-note: This file is generated by ojluni/src/tools/gensrc_android.sh.
29
30package java.nio;
31
32import java.util.Objects;
33import libcore.io.Memory;
34
35/**
36#if[rw]
37 * A read/write Heap$Type$Buffer.
38#else[rw]
39 * A read-only Heap$Type$Buffer.  This class extends the corresponding
40 * read/write class, overriding the mutation methods to throw a {@link
41 * ReadOnlyBufferException} and overriding the view-buffer methods to return an
42 * instance of this class rather than of the superclass.
43#end[rw]
44 */
45// Android-changed: Make it final as no subclasses exist.
46final class Heap$Type$Buffer$RW$
47    extends {#if[ro]?Heap}$Type$Buffer
48{
49    // Android-removed: Removed unused constants.
50    /*
51    // Cached array base offset
52    private static final long ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset($type$[].class);
53
54    // Cached array index scale
55    private static final long ARRAY_INDEX_SCALE = UNSAFE.arrayIndexScale($type$[].class);
56    */
57
58    // For speed these fields are actually declared in X-Buffer;
59    // these declarations are here as documentation
60    /*
61#if[rw]
62    protected final $type$[] hb;
63    protected final int offset;
64#end[rw]
65    */
66    // Android-removed: Removed MemorySegmentProxy to be supported yet.
67    Heap$Type$Buffer$RW$(int cap, int lim) {            // package-private
68#if[rw]
69        // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
70        // super(-1, 0, lim, cap, new $type$[cap], 0);
71        this(cap, lim, false);
72        /*
73        hb = new $type$[cap];
74        offset = 0;
75        */
76        // Android-removed: buffer.address is only used by Direct*Buffer.
77        // this.address = ARRAY_BASE_OFFSET;
78#else[rw]
79        super(cap, lim);
80        this.isReadOnly = true;
81#end[rw]
82    }
83
84#if[rw]
85   // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
86    private Heap$Type$Buffer$RW$(int cap, int lim, boolean isReadOnly) {
87        super(-1, 0, lim, cap, new $type$[cap], 0);
88        this.isReadOnly = isReadOnly;
89    }
90#end[rw]
91
92    // Android-removed: Removed MemorySegmentProxy to be supported yet.
93    Heap$Type$Buffer$RW$($type$[] buf, int off, int len) { // package-private
94#if[rw]
95        // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
96        // super(-1, off, off + len, buf.length, buf, 0);
97        this(buf, off, len, false);
98        /*
99        hb = buf;
100        offset = 0;
101        */
102        // Android-removed: buffer.address is only used by Direct*Buffer.
103        // this.address = ARRAY_BASE_OFFSET;
104#else[rw]
105        super(buf, off, len);
106        this.isReadOnly = true;
107#end[rw]
108    }
109
110#if[rw]
111   // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
112    private Heap$Type$Buffer$RW$($type$[] buf, int off, int len, boolean isReadOnly) {
113        super(-1, off, off + len, buf.length, buf, 0);
114        this.isReadOnly = isReadOnly;
115    }
116#end[rw]
117
118    // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
119    // Android-changed: Make the method private.
120    // Android-removed: Removed MemorySegmentProxy to be supported yet.
121    private Heap$Type$Buffer$RW$($type$[] buf,
122                                   int mark, int pos, int lim, int cap,
123                                   int off, boolean isReadOnly)
124    {
125#if[rw]
126        super(mark, pos, lim, cap, buf, off);
127        // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
128        this.isReadOnly = isReadOnly;
129        /*
130        hb = buf;
131        offset = off;
132        */
133        // Android-removed: buffer.address is only used by Direct*Buffer.
134        // this.address = ARRAY_BASE_OFFSET + off * ARRAY_INDEX_SCALE;
135#else[rw]
136        super(buf, mark, pos, lim, cap, off);
137        this.isReadOnly = true;
138#end[rw]
139    }
140
141    public $Type$Buffer slice() {
142        int pos = this.position();
143        int lim = this.limit();
144        int rem = (pos <= lim ? lim - pos : 0);
145        return new Heap$Type$Buffer$RW$(hb,
146                -1,
147                0,
148                rem,
149                rem,
150        // Android-removed: Removed MemorySegmentProxy not supported yet.
151                pos + offset,
152        // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
153                isReadOnly);
154    }
155
156    @Override
157    public $Type$Buffer slice(int index, int length) {
158        Objects.checkFromIndexSize(index, length, limit());
159        return new Heap$Type$Buffer$RW$(hb,
160                -1,
161                0,
162                length,
163                length,
164        // Android-removed: Removed MemorySegmentProxy not supported yet.
165                index + offset,
166        // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
167                isReadOnly);
168    }
169
170    public $Type$Buffer duplicate() {
171        return new Heap$Type$Buffer$RW$(hb,
172                this.markValue(),
173                this.position(),
174                this.limit(),
175                this.capacity(),
176        // Android-removed: Removed MemorySegmentProxy not supported yet.
177                offset,
178        // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
179                isReadOnly);
180    }
181
182    public $Type$Buffer asReadOnlyBuffer() {
183#if[rw]
184        // Android-removed: Removed MemorySegmentProxy not supported yet.
185        // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
186        /*
187        return new Heap$Type$BufferR(hb,
188                                     this.markValue(),
189                                     this.position(),
190                                     this.limit(),
191                                     this.capacity(),
192                                     offset, segment);
193        */
194        return new Heap$Type$Buffer(hb,
195                this.markValue(),
196                this.position(),
197                this.limit(),
198                this.capacity(),
199                offset,
200                true /* isReadOnly */);
201#else[rw]
202        return duplicate();
203#end[rw]
204    }
205
206#if[rw]
207
208    // Android-changed:  Make it private as no subclasses exist.
209    private int ix(int i) {
210        return i + offset;
211    }
212
213#if[byte]
214    private long byteOffset(long i) {
215        return address + i;
216    }
217#end[byte]
218
219    @Override
220    public $type$ get() {
221        return hb[ix(nextGetIndex())];
222    }
223
224    @Override
225    public $type$ get(int i) {
226        return hb[ix(checkIndex(i))];
227    }
228
229#if[streamableType]
230    @Override
231    $type$ getUnchecked(int i) {
232    return hb[ix(i)];
233    }
234#end[streamableType]
235
236    @Override
237    public $Type$Buffer get($type$[] dst, int offset, int length) {
238        checkScope();
239        Objects.checkFromIndexSize(offset, length, dst.length);
240        int pos = position();
241        if (length > limit() - pos)
242            throw new BufferUnderflowException();
243        System.arraycopy(hb, ix(pos), dst, offset, length);
244        position(pos + length);
245        return this;
246    }
247
248    @Override
249    public $Type$Buffer get(int index, $type$[] dst, int offset, int length) {
250        checkScope();
251        Objects.checkFromIndexSize(index, length, limit());
252        Objects.checkFromIndexSize(offset, length, dst.length);
253        System.arraycopy(hb, ix(index), dst, offset, length);
254        return this;
255    }
256
257    public boolean isDirect() {
258        return false;
259    }
260
261#end[rw]
262
263    @Override
264    public boolean isReadOnly() {
265        // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
266        return {#if[rw]?isReadOnly:true};
267    }
268
269    @Override
270    public $Type$Buffer put($type$ x) {
271#if[rw]
272        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
273        throwIfReadOnly();
274        hb[ix(nextPutIndex())] = x;
275        return this;
276#else[rw]
277        throw new ReadOnlyBufferException();
278#end[rw]
279    }
280
281    @Override
282    public $Type$Buffer put(int i, $type$ x) {
283#if[rw]
284        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
285        throwIfReadOnly();
286        hb[ix(checkIndex(i))] = x;
287        return this;
288#else[rw]
289        throw new ReadOnlyBufferException();
290#end[rw]
291    }
292
293    @Override
294    public $Type$Buffer put($type$[] src, int offset, int length) {
295#if[rw]
296        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
297        throwIfReadOnly();
298        checkScope();
299        Objects.checkFromIndexSize(offset, length, src.length);
300        int pos = position();
301        if (length > limit() - pos)
302            throw new BufferOverflowException();
303        System.arraycopy(src, offset, hb, ix(pos), length);
304        position(pos + length);
305        return this;
306#else[rw]
307        throw new ReadOnlyBufferException();
308#end[rw]
309    }
310
311    @Override
312    public $Type$Buffer put($Type$Buffer src) {
313#if[rw]
314        checkScope();
315#if[byte]
316        // Android-note: The super class speed-up this operation with Memory.memmove, and arraycopy.
317        super.put(src);
318#else[byte]
319        // Android-changed: Speed-up this operation if the src is a heap or direct buffer.
320        // super.put(src);
321        if (src == this) {
322            throw createSameBufferException();
323        }
324        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
325        throwIfReadOnly();
326        if (src instanceof Heap$Type$Buffer sb) {
327            int n = sb.remaining();
328            if (n > remaining())
329                throw new BufferOverflowException();
330            System.arraycopy(sb.hb, sb.ix(sb.position()),
331                    hb, ix(position()), n);
332            sb.position(sb.position() + n);
333            position(position() + n);
334        } else if (src.isDirect()) {
335            int n = src.remaining();
336            if (n > remaining())
337                throw new BufferOverflowException();
338            src.get(hb, ix(position()), n);
339            position(position() + n);
340        } else {
341            super.put(src);
342        }
343#end[byte]
344        return this;
345#else[rw]
346        throw new ReadOnlyBufferException();
347#end[rw]
348    }
349
350    @Override
351    public $Type$Buffer put(int index, $Type$Buffer src, int offset, int length) {
352#if[rw]
353        checkScope();
354        super.put(index, src, offset, length);
355        return this;
356#else[rw]
357        throw new ReadOnlyBufferException();
358#end[rw]
359    }
360
361    @Override
362    public $Type$Buffer put(int index, $type$[] src, int offset, int length) {
363#if[rw]
364        checkScope();
365        Objects.checkFromIndexSize(index, length, limit());
366        Objects.checkFromIndexSize(offset, length, src.length);
367        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
368        throwIfReadOnly();
369        System.arraycopy(src, offset, hb, ix(index), length);
370        return this;
371#else[rw]
372        throw new ReadOnlyBufferException();
373#end[rw]
374    }
375
376#if[char]
377
378    @Override
379    public $Type$Buffer put(String src, int start, int end) {
380#if[rw]
381        checkScope();
382        int length = end - start;
383        Objects.checkFromIndexSize(start, length, src.length());
384        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
385        throwIfReadOnly();
386        int pos = position();
387        int lim = limit();
388        int rem = (pos <= lim) ? lim - pos : 0;
389        if (length > rem)
390            throw new BufferOverflowException();
391        src.getChars(start, end, hb, ix(pos));
392        position(pos + length);
393        return this;
394#else[rw]
395        throw new ReadOnlyBufferException();
396#end[rw]
397    }
398
399#end[char]
400
401    @Override
402    public $Type$Buffer compact() {
403#if[rw]
404        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
405        throwIfReadOnly();
406        int pos = position();
407        int lim = limit();
408        assert (pos <= lim);
409        int rem = (pos <= lim ? lim - pos : 0);
410        System.arraycopy(hb, ix(pos), hb, ix(0), rem);
411        position(rem);
412        limit(capacity());
413        discardMark();
414        return this;
415#else[rw]
416        throw new ReadOnlyBufferException();
417#end[rw]
418    }
419
420
421
422#if[byte]
423
424    @Override
425    byte _get(int i) {                          // package-private
426        return hb[i];
427    }
428
429    @Override
430    void _put(int i, byte b) {                  // package-private
431#if[rw]
432        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
433        throwIfReadOnly();
434        hb[i] = b;
435#else[rw]
436        throw new ReadOnlyBufferException();
437#end[rw]
438    }
439
440    // char
441
442#if[rw]
443
444    @Override
445    public char getChar() {
446        // Android-changed: Avoid unsupported ScopedMemoryAccess.
447        // return SCOPED_MEMORY_ACCESS.getCharUnaligned(scope(), hb, byteOffset(nextGetIndex(2)), bigEndian);
448        return getCharUnchecked(nextGetIndex(2));
449    }
450
451    @Override
452    public char getChar(int i) {
453        // Android-changed: Avoid unsupported ScopedMemoryAccess.
454        // return SCOPED_MEMORY_ACCESS.getCharUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), bigEndian);
455        return getCharUnchecked(checkIndex(i, 2));
456    }
457
458#end[rw]
459
460    @Override
461    public $Type$Buffer putChar(char x) {
462#if[rw]
463        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
464        throwIfReadOnly();
465        // Android-changed: Avoid unsupported ScopedMemoryAccess.
466        // SCOPED_MEMORY_ACCESS.putCharUnaligned(scope(), hb, byteOffset(nextPutIndex(2)), x, bigEndian);
467        putCharUnchecked(nextPutIndex(2), x);
468        return this;
469#else[rw]
470        throw new ReadOnlyBufferException();
471#end[rw]
472    }
473
474    // BEGIN Android-added: {get,put}*Unchecked() accessors.
475    @Override
476    char getCharUnchecked(int i) {
477        int ix = ix(i);
478        byte[] src = hb;
479        if (bigEndian) {
480            return (char) ((src[ix] << 8) | (src[ix + 1] & 0xff));
481        } else {
482            return (char) ((src[ix + 1] << 8) | (src[ix] & 0xff));
483        }
484    }
485
486    @Override
487    void getUnchecked(int pos, char[] dst, int dstOffset, int length) {
488        Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
489    }
490    // END Android-added: {get,put}*Unchecked() accessors.
491
492    @Override
493    public $Type$Buffer putChar(int i, char x) {
494#if[rw]
495        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
496        throwIfReadOnly();
497        // Android-changed: Avoid unsupported ScopedMemoryAccess.
498        // SSCOPED_MEMORY_ACCESS.putCharUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
499        putCharUnchecked(checkIndex(i, 2), x);
500        return this;
501#else[rw]
502        throw new ReadOnlyBufferException();
503#end[rw]
504    }
505
506    // BEGIN Android-added: {get,put}*Unchecked() accessors.
507    @Override
508    void putCharUnchecked(int i, char x) {
509        int ix = ix(i);
510        byte[] dst = hb;
511
512        if (bigEndian) {
513            dst[ix++] = (byte) ((x >> 8) & 0xff);
514            dst[ix  ] = (byte) ((x >> 0) & 0xff);
515        } else {
516            dst[ix++] = (byte) ((x >> 0) & 0xff);
517            dst[ix  ] = (byte) ((x >> 8) & 0xff);
518        }
519    }
520
521    @Override
522    void putUnchecked(int pos, char[] src, int srcOffset, int length) {
523        Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
524    }
525    // END Android-added: {get,put}*Unchecked() accessors.
526
527    @Override
528    public CharBuffer asCharBuffer() {
529        int pos = position();
530        int size = (limit() - pos) >> 1;
531        // Android-removed: buffer.address is only used by Direct*Buffer.
532        // long addr = address + pos;
533        // Android-changed: Merge the big and little endian buffer class.
534        /*
535        return (bigEndian
536                ? (CharBuffer)(new ByteBufferAsCharBuffer$RW$B(this,
537                                                               -1,
538                                                               0,
539                                                               size,
540                                                               size,
541                                                               addr, segment))
542                : (CharBuffer)(new ByteBufferAsCharBuffer$RW$L(this,
543                                                               -1,
544                                                               0,
545                                                               size,
546                                                               size,
547                                                               addr, segment)));
548        */
549        return new ByteBufferAsCharBuffer(this,
550                -1,
551                0,
552                size,
553                size,
554                pos,
555                order());
556    }
557
558
559    // short
560
561#if[rw]
562
563    @Override
564    public short getShort() {
565        // Android-changed: Avoid unsupported ScopedMemoryAccess.
566        // return SCOPED_MEMORY_ACCESS.getShortUnaligned(scope(), hb, byteOffset(nextGetIndex(2)), bigEndian);
567        return getShortUnchecked(nextGetIndex(2));
568    }
569
570    @Override
571    public short getShort(int i) {
572        // Android-changed: Avoid unsupported ScopedMemoryAccess.
573        // return SCOPED_MEMORY_ACCESS.getShortUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), bigEndian);
574        return getShortUnchecked(checkIndex(i, 2));
575    }
576
577#end[rw]
578
579    // BEGIN Android-added: {get,put}*Unchecked() accessors.
580    @Override
581    short getShortUnchecked(int i) {
582        byte[] src = hb;
583        int ix = ix(i);
584        if (bigEndian) {
585            return (short) ((src[ix] << 8) | (src[ix + 1] & 0xff));
586        } else {
587            return (short) ((src[ix + 1] << 8) | (src[ix] & 0xff));
588        }
589    }
590
591    @Override
592    void getUnchecked(int pos, short[] dst, int dstOffset, int length) {
593        Memory.unsafeBulkGet(dst, dstOffset, length * 2, hb, ix(pos), 2, !nativeByteOrder);
594    }
595    // END Android-added: {get,put}*Unchecked() accessors.
596
597    @Override
598    public $Type$Buffer putShort(short x) {
599#if[rw]
600        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
601        throwIfReadOnly();
602        // Android-changed: Avoid unsupported ScopedMemoryAccess.
603        // SCOPED_MEMORY_ACCESS.putShortUnaligned(scope(), hb, byteOffset(nextPutIndex(2)), x, bigEndian);
604        putShortUnchecked(nextPutIndex(2), x);
605        return this;
606#else[rw]
607        throw new ReadOnlyBufferException();
608#end[rw]
609    }
610
611    @Override
612    public $Type$Buffer putShort(int i, short x) {
613#if[rw]
614        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
615        throwIfReadOnly();
616        // Android-changed: Avoid unsupported ScopedMemoryAccess.
617        // SCOPED_MEMORY_ACCESS.putShortUnaligned(scope(), hb, byteOffset(checkIndex(i, 2)), x, bigEndian);
618        putShortUnchecked(checkIndex(i, 2), x);
619        return this;
620#else[rw]
621        throw new ReadOnlyBufferException();
622#end[rw]
623    }
624
625    // BEGIN Android-added: {get,put}*Unchecked() accessors.
626    @Override
627    void putShortUnchecked(int i, short x) {
628        byte[] dst = hb;
629        int ix = ix(i);
630        if (bigEndian) {
631            dst[ix++] = (byte) ((x >> 8) & 0xff);
632            dst[ix  ] = (byte) ((x >> 0) & 0xff);
633        } else {
634            dst[ix++] = (byte) ((x >> 0) & 0xff);
635            dst[ix  ] = (byte) ((x >> 8) & 0xff);
636        }
637    }
638
639    @Override
640    void putUnchecked(int pos, short[] src, int srcOffset, int length) {
641        Memory.unsafeBulkPut(hb, ix(pos), length * 2, src, srcOffset, 2, !nativeByteOrder);
642    }
643    // END Android-added: {get,put}*Unchecked() accessors.
644
645    @Override
646    public ShortBuffer asShortBuffer() {
647        int pos = position();
648        int size = (limit() - pos) >> 1;
649        // Android-removed: buffer.address is only used by Direct*Buffer.
650        // long addr = address + pos;
651        // Android-changed: Merge the big and little endian buffer class.
652        /*
653        return (bigEndian
654                ? (ShortBuffer)(new ByteBufferAsShortBuffer$RW$B(this,
655                                                                 -1,
656                                                                 0,
657                                                                 size,
658                                                                 size,
659                                                                 addr, segment))
660                : (ShortBuffer)(new ByteBufferAsShortBuffer$RW$L(this,
661                                                                 -1,
662                                                                 0,
663                                                                 size,
664                                                                 size,
665                                                                 addr, segment)));
666        */
667        return new ByteBufferAsShortBuffer(this,
668                -1,
669                0,
670                size,
671                size,
672                pos,
673                order());
674    }
675
676
677    // int
678
679#if[rw]
680
681    @Override
682    public int getInt() {
683        // Android-changed: Avoid unsupported ScopedMemoryAccess.
684        // return SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(nextGetIndex(4)), bigEndian);
685        return getIntUnchecked(nextGetIndex(4));
686    }
687
688    @Override
689    public int getInt(int i) {
690        // Android-changed: Avoid unsupported ScopedMemoryAccess.
691        // return SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), bigEndian);
692        return getIntUnchecked(checkIndex(i, 4));
693    }
694
695#end[rw]
696
697    // BEGIN Android-added: {get,put}*Unchecked() accessors.
698    @Override
699    int getIntUnchecked(int i) {
700        int ix = ix(i);
701        byte[] src = hb;
702        if (bigEndian) {
703            return (((src[ix++] & 0xff) << 24) |
704                    ((src[ix++] & 0xff) << 16) |
705                    ((src[ix++] & 0xff) <<  8) |
706                    ((src[ix  ] & 0xff)      ));
707        } else {
708            return (((src[ix++] & 0xff)      ) |
709                    ((src[ix++] & 0xff) <<  8) |
710                    ((src[ix++] & 0xff) << 16) |
711                    ((src[ix  ] & 0xff) << 24));
712        }
713    }
714
715    @Override
716    void getUnchecked(int pos, int[] dst, int dstOffset, int length) {
717        Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
718    }
719    // END Android-added: {get,put}*Unchecked() accessors.
720
721    @Override
722    public $Type$Buffer putInt(int x) {
723#if[rw]
724        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
725        throwIfReadOnly();
726        // Android-changed: Avoid unsupported ScopedMemoryAccess.
727        // SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(nextPutIndex(4)), x, bigEndian);
728        putIntUnchecked(nextPutIndex(4), x);
729        return this;
730#else[rw]
731        throw new ReadOnlyBufferException();
732#end[rw]
733    }
734
735    @Override
736    public $Type$Buffer putInt(int i, int x) {
737#if[rw]
738        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
739        throwIfReadOnly();
740        // Android-changed: Avoid unsupported ScopedMemoryAccess.
741        // SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), x, bigEndian);
742        putIntUnchecked(checkIndex(i, 4), x);
743        return this;
744#else[rw]
745        throw new ReadOnlyBufferException();
746#end[rw]
747    }
748
749    // BEGIN Android-added: {get,put}*Unchecked() accessors.
750    @Override
751    void putIntUnchecked(int i, int x) {
752        int ix = ix(i);
753        byte[] dst = hb;
754
755        if (bigEndian) {
756            dst[ix++] = (byte) ((x >> 24) & 0xff);
757            dst[ix++] = (byte) ((x >> 16) & 0xff);
758            dst[ix++] = (byte) ((x >>  8) & 0xff);
759            dst[ix  ] = (byte) ((x      ) & 0xff);
760        } else {
761            dst[ix++] = (byte) ((x      ) & 0xff);
762            dst[ix++] = (byte) ((x >>  8) & 0xff);
763            dst[ix++] = (byte) ((x >> 16) & 0xff);
764            dst[ix  ] = (byte) ((x >> 24) & 0xff);
765        }
766    }
767
768    @Override
769    void putUnchecked(int pos, int[] src, int srcOffset, int length) {
770        Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
771    }
772    // END Android-added: {get,put}*Unchecked() accessors.
773
774    @Override
775    public IntBuffer asIntBuffer() {
776        int pos = position();
777        int size = (limit() - pos) >> 2;
778        // Android-removed: buffer.address is only used by Direct*Buffer.
779        // long addr = address + pos;
780        // Android-changed: Merge the big and little endian buffer class.
781        /*
782        return (bigEndian
783                ? (IntBuffer)(new ByteBufferAsIntBuffer$RW$B(this,
784                                                             -1,
785                                                             0,
786                                                             size,
787                                                             size,
788                                                             addr, segment))
789                : (IntBuffer)(new ByteBufferAsIntBuffer$RW$L(this,
790                                                             -1,
791                                                             0,
792                                                             size,
793                                                             addr, segment)));
794        */
795        return new ByteBufferAsIntBuffer(this,
796                -1,
797                0,
798                size,
799                size,
800                pos,
801                order());
802    }
803
804
805    // long
806
807#if[rw]
808
809    @Override
810    public long getLong() {
811        // Android-changed: Avoid unsupported ScopedMemoryAccess.
812        // return SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(nextGetIndex(8)), bigEndian);
813        return getLongUnchecked(nextGetIndex(8));
814    }
815
816    @Override
817    public long getLong(int i) {
818        // Android-changed: Avoid unsupported ScopedMemoryAccess.
819        // return SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), bigEndian);
820        return getLongUnchecked(checkIndex(i, 8));
821    }
822
823#end[rw]
824
825    // BEGIN Android-added: {get,put}*Unchecked() accessors.
826    @Override
827    long getLongUnchecked(int i) {
828        int ix = ix(i);
829        byte[] src = hb;
830
831        if (bigEndian) {
832            int h = ((src[ix++] & 0xff) << 24) |
833                    ((src[ix++] & 0xff) << 16) |
834                    ((src[ix++] & 0xff) <<  8) |
835                    ((src[ix++] & 0xff) <<  0);
836            int l = ((src[ix++] & 0xff) << 24) |
837                    ((src[ix++] & 0xff) << 16) |
838                    ((src[ix++] & 0xff) <<  8) |
839                    ((src[ix  ] & 0xff) <<  0);
840            return (((long) h) << 32L) | (((long) l) & 0xffffffffL);
841        } else {
842            int l = ((src[ix++] & 0xff) <<  0) |
843                    ((src[ix++] & 0xff) <<  8) |
844                    ((src[ix++] & 0xff) << 16) |
845                    ((src[ix++] & 0xff) << 24);
846            int h = ((src[ix++] & 0xff) <<  0) |
847                    ((src[ix++] & 0xff) <<  8) |
848                    ((src[ix++] & 0xff) << 16) |
849                    ((src[ix  ] & 0xff) << 24);
850            return (((long) h) << 32L) | (((long) l) & 0xffffffffL);
851        }
852    }
853
854    @Override
855    void getUnchecked(int pos, long[] dst, int dstOffset, int length) {
856        Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
857    }
858    // END Android-added: {get,put}*Unchecked() accessors.
859
860    @Override
861    public $Type$Buffer putLong(long x) {
862#if[rw]
863        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
864        throwIfReadOnly();
865        // Android-changed: Avoid unsupported ScopedMemoryAccess.
866        // SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(nextPutIndex(8)), x, bigEndian);
867        putLongUnchecked(nextPutIndex(8), x);
868        return this;
869#else[rw]
870        throw new ReadOnlyBufferException();
871#end[rw]
872    }
873
874    @Override
875    public $Type$Buffer putLong(int i, long x) {
876#if[rw]
877        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
878        throwIfReadOnly();
879        // Android-changed: Avoid unsupported ScopedMemoryAccess.
880        // SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), x, bigEndian);
881        putLongUnchecked(checkIndex(i, 8), x);
882        return this;
883#else[rw]
884        throw new ReadOnlyBufferException();
885#end[rw]
886    }
887
888    // BEGIN Android-added: {get,put}*Unchecked() accessors.
889    @Override
890    void putLongUnchecked(int i, long x) {
891        int ix = ix(i);
892        byte[] dst = hb;
893        if (bigEndian) {
894            int t = (int) (x >> 32);
895            dst[ix++] = (byte) ((t >> 24) & 0xff);
896            dst[ix++] = (byte) ((t >> 16) & 0xff);
897            dst[ix++] = (byte) ((t >>  8) & 0xff);
898            dst[ix++] = (byte) ((t >>  0) & 0xff);
899            t = (int) x;
900            dst[ix++] = (byte) ((t >> 24) & 0xff);
901            dst[ix++] = (byte) ((t >> 16) & 0xff);
902            dst[ix++] = (byte) ((t >>  8) & 0xff);
903            dst[ix  ] = (byte) ((t >>  0) & 0xff);
904        } else {
905            int t = (int) x;
906            dst[ix++] = (byte) ((t >>  0) & 0xff);
907            dst[ix++] = (byte) ((t >>  8) & 0xff);
908            dst[ix++] = (byte) ((t >> 16) & 0xff);
909            dst[ix++] = (byte) ((t >> 24) & 0xff);
910            t = (int) (x >> 32);
911            dst[ix++] = (byte) ((t >>  0) & 0xff);
912            dst[ix++] = (byte) ((t >>  8) & 0xff);
913            dst[ix++] = (byte) ((t >> 16) & 0xff);
914            dst[ix  ] = (byte) ((t >> 24) & 0xff);
915        }
916    }
917
918    @Override
919    void putUnchecked(int pos, long[] src, int srcOffset, int length) {
920        Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
921    }
922    // END Android-added: {get,put}*Unchecked() accessors.
923
924    @Override
925    public LongBuffer asLongBuffer() {
926        int pos = position();
927        int size = (limit() - pos) >> 3;
928        // Android-removed: buffer.address is only used by Direct*Buffer.
929        // long addr = address + pos;
930        // Android-changed: Merge the big and little endian buffer class.
931        /*
932        return (bigEndian
933                ? (LongBuffer)(new ByteBufferAsLongBuffer$RW$B(this,
934                                                               -1,
935                                                               0,
936                                                               size,
937                                                               size,
938                                                               addr, segment))
939                : (LongBuffer)(new ByteBufferAsLongBuffer$RW$L(this,
940                                                               -1,
941                                                               0,
942                                                               size,
943                                                               size,
944                                                               addr, segment)));
945        */
946        return new ByteBufferAsLongBuffer(this,
947                -1,
948                0,
949                size,
950                size,
951                pos,
952                order());
953    }
954
955
956    // float
957
958#if[rw]
959
960    @Override
961    public float getFloat() {
962        // Android-changed: Avoid unsupported ScopedMemoryAccess.
963        // int x = SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(nextGetIndex(4)), bigEndian);
964        // return Float.intBitsToFloat(x);
965        return getFloatUnchecked(nextGetIndex(4));
966    }
967
968    @Override
969    public float getFloat(int i) {
970        // Android-changed: Avoid unsupported ScopedMemoryAccess.
971        // int x = SCOPED_MEMORY_ACCESS.getIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), bigEndian);
972        // return Float.intBitsToFloat(x);
973        return getFloatUnchecked(checkIndex(i, 4));
974    }
975
976#end[rw]
977
978    // BEGIN Android-added: {get,put}*Unchecked() accessors.
979    @Override
980    float getFloatUnchecked(int i) {
981        return Float.intBitsToFloat(getIntUnchecked(i));
982    }
983
984    @Override
985    void getUnchecked(int pos, float[] dst, int dstOffset, int length) {
986        Memory.unsafeBulkGet(dst, dstOffset, length * 4, hb, ix(pos), 4, !nativeByteOrder);
987    }
988    // END Android-added: {get,put}*Unchecked() accessors.
989
990    @Override
991    public $Type$Buffer putFloat(float x) {
992#if[rw]
993        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
994        throwIfReadOnly();
995        // Android-changed: Avoid unsupported ScopedMemoryAccess.
996        // int y = Float.floatToRawIntBits(x);
997        // SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(nextPutIndex(4)), y, bigEndian);
998        putFloatUnchecked(nextPutIndex(4), x);
999        return this;
1000#else[rw]
1001        throw new ReadOnlyBufferException();
1002#end[rw]
1003    }
1004
1005    @Override
1006    public $Type$Buffer putFloat(int i, float x) {
1007#if[rw]
1008        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
1009        throwIfReadOnly();
1010        // Android-changed: Avoid unsupported ScopedMemoryAccess.
1011        // int y = Float.floatToRawIntBits(x);
1012        // SCOPED_MEMORY_ACCESS.putIntUnaligned(scope(), hb, byteOffset(checkIndex(i, 4)), y, bigEndian);
1013        putFloatUnchecked(checkIndex(i, 4), x);
1014        return this;
1015#else[rw]
1016        throw new ReadOnlyBufferException();
1017#end[rw]
1018    }
1019
1020    // BEGIN Android-added: {get,put}*Unchecked() accessors.
1021    @Override
1022    void putFloatUnchecked(int i, float x) {
1023        putIntUnchecked(i, Float.floatToRawIntBits(x));
1024    }
1025
1026    @Override
1027    void putUnchecked(int pos, float[] src, int srcOffset, int length) {
1028        Memory.unsafeBulkPut(hb, ix(pos), length * 4, src, srcOffset, 4, !nativeByteOrder);
1029    }
1030    // END Android-added: {get,put}*Unchecked() accessors.
1031
1032    @Override
1033    public FloatBuffer asFloatBuffer() {
1034        int pos = position();
1035        int size = (limit() - pos) >> 2;
1036        // Android-removed: buffer.address is only used by Direct*Buffer.
1037        // long addr = address + pos;
1038        // Android-changed: Merge the big and little endian buffer class.
1039        /*
1040        return (bigEndian
1041                ? (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$B(this,
1042                                                                 -1,
1043                                                                 0,
1044                                                                 size,
1045                                                                 size,
1046                                                                 addr, segment))
1047                : (FloatBuffer)(new ByteBufferAsFloatBuffer$RW$L(this,
1048                                                                 -1,
1049                                                                 0,
1050                                                                 size,
1051                                                                 size,
1052                                                                 addr, segment)));
1053        */
1054        return new ByteBufferAsFloatBuffer(this,
1055                -1,
1056                0,
1057                size,
1058                size,
1059                pos,
1060                order());
1061    }
1062
1063
1064    // double
1065
1066#if[rw]
1067
1068    @Override
1069    public double getDouble() {
1070        // Android-changed: Avoid unsupported ScopedMemoryAccess.
1071        // long x = SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(nextGetIndex(8)), bigEndian);
1072        // return Double.longBitsToDouble(x);
1073        return getDoubleUnchecked(nextGetIndex(8));
1074    }
1075
1076    @Override
1077    public double getDouble(int i) {
1078        // Android-changed: Avoid unsupported ScopedMemoryAccess.
1079        // long x = SCOPED_MEMORY_ACCESS.getLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), bigEndian);
1080        // return Double.longBitsToDouble(x);
1081        return getDoubleUnchecked(checkIndex(i, 8));
1082    }
1083
1084#end[rw]
1085
1086    // BEGIN Android-added: {get,put}*Unchecked() accessors.
1087    @Override
1088    double getDoubleUnchecked(int i) {
1089        return Double.longBitsToDouble(getLongUnchecked(i));
1090    }
1091
1092    @Override
1093    void getUnchecked(int pos, double[] dst, int dstOffset, int length) {
1094        Memory.unsafeBulkGet(dst, dstOffset, length * 8, hb, ix(pos), 8, !nativeByteOrder);
1095    }
1096    // END Android-added: {get,put}*Unchecked() accessors.
1097
1098    @Override
1099    public $Type$Buffer putDouble(double x) {
1100#if[rw]
1101        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
1102        throwIfReadOnly();
1103        // Android-changed: Avoid unsupported ScopedMemoryAccess.
1104        // long y = Double.doubleToRawLongBits(x);
1105        // SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(nextPutIndex(8)), y, bigEndian);
1106        putDoubleUnchecked(nextPutIndex(8), x);
1107        return this;
1108#else[rw]
1109        throw new ReadOnlyBufferException();
1110#end[rw]
1111    }
1112
1113    @Override
1114    public $Type$Buffer putDouble(int i, double x) {
1115#if[rw]
1116        // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
1117        throwIfReadOnly();
1118        // Android-changed: Avoid unsupported ScopedMemoryAccess.
1119        // long y = Double.doubleToRawLongBits(x);
1120        // SCOPED_MEMORY_ACCESS.putLongUnaligned(scope(), hb, byteOffset(checkIndex(i, 8)), y, bigEndian);
1121        putDoubleUnchecked(checkIndex(i, 8), x);
1122        return this;
1123#else[rw]
1124        throw new ReadOnlyBufferException();
1125#end[rw]
1126    }
1127
1128    // BEGIN Android-added: {get,put}*Unchecked() accessors.
1129    @Override
1130    void putDoubleUnchecked(int i, double x) {
1131        putLongUnchecked(i, Double.doubleToRawLongBits(x));
1132    }
1133
1134    @Override
1135    void putUnchecked(int pos, double[] src, int srcOffset, int length) {
1136        Memory.unsafeBulkPut(hb, ix(pos), length * 8, src, srcOffset, 8, !nativeByteOrder);
1137    }
1138    // END Android-added: {get,put}*Unchecked() accessors.
1139
1140    @Override
1141    public DoubleBuffer asDoubleBuffer() {
1142        int pos = position();
1143        int size = (limit() - pos) >> 3;
1144        // Android-removed: buffer.address is only used by Direct*Buffer.
1145        // long addr = address + pos;
1146        // Android-changed: Merge the big and little endian buffer class.
1147        /*
1148        return (bigEndian
1149                ? (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$B(this,
1150                                                                   -1,
1151                                                                   0,
1152                                                                   size,
1153                                                                   size,
1154                                                                   addr, segment))
1155                : (DoubleBuffer)(new ByteBufferAsDoubleBuffer$RW$L(this,
1156                                                                   -1,
1157                                                                   0,
1158                                                                   size,
1159                                                                   size,
1160                                                                   addr, segment)));
1161        */
1162        return new ByteBufferAsDoubleBuffer(this,
1163                -1,
1164                0,
1165                size,
1166                size,
1167                pos,
1168                order());
1169    }
1170
1171
1172#end[byte]
1173
1174
1175#if[char]
1176
1177    String toString(int start, int end) {               // package-private
1178        try {
1179            return new String(hb, start + offset, end - start);
1180        } catch (StringIndexOutOfBoundsException x) {
1181            throw new IndexOutOfBoundsException();
1182        }
1183    }
1184
1185
1186    // --- Methods to support CharSequence ---
1187
1188    public CharBuffer subSequence(int start, int end) {
1189        int pos = position();
1190        Objects.checkFromToIndex(start, end, limit() - pos);
1191        return new HeapCharBuffer$RW$(hb,
1192                -1,
1193                pos + start,
1194                pos + end,
1195                capacity(),
1196        // Android-removed: Removed MemorySegmentProxy not supported yet.
1197                offset,
1198        // Android-changed: Merge the Read-only buffer class with this Read-Write buffer class.
1199                isReadOnly);
1200    }
1201
1202#end[char]
1203
1204
1205#if[!byte]
1206
1207    public ByteOrder order() {
1208        return ByteOrder.nativeOrder();
1209    }
1210#end[!byte]
1211#if[char]
1212
1213    ByteOrder charRegionOrder() {
1214        return order();
1215    }
1216#end[char]
1217
1218    // Android-added: Merge the Read-only buffer class with this Read-Write buffer class.
1219    private void throwIfReadOnly() {
1220        if (isReadOnly) {
1221            throw new ReadOnlyBufferException();
1222        }
1223    }
1224}
1225