Memory.java revision 0568a63ba1086a78ffb4cff68dd2eac4f9908e13
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughespackage libcore.io; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 207e25eff38a191d9c19e45093f4fde5102fb09d78Elliott Hughesimport java.io.FileDescriptor; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 220568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughesimport java.nio.ByteBuffer; 238510524dab13e0acc1babf22cbc55002fb122777Elliott Hughesimport java.nio.ByteOrder; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 26f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes * Unsafe access to memory. 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 28f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughespublic final class Memory { 29f934c3d2c8dd9e6bc5299cef41adace2a671637dElliott Hughes private Memory() { } 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 328fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes * Used to optimize nio heap buffer bulk get operations. 'dst' must be a primitive array. 336944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes * 'dstOffset' is measured in units of 'sizeofElements' bytes. 346944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes */ 358fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes public static native void unsafeBulkGet(Object dst, int dstOffset, int byteCount, 366944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes byte[] src, int srcOffset, int sizeofElements, boolean swap); 376944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes 386944bea4a129dc2d4be687c72f2a9f228ec532bcElliott Hughes /** 398fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes * Used to optimize nio heap buffer bulk put operations. 'src' must be a primitive array. 408fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes * 'srcOffset' is measured in units of 'sizeofElements' bytes. 418fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes */ 428fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes public static native void unsafeBulkPut(byte[] dst, int dstOffset, int byteCount, 438fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes Object src, int srcOffset, int sizeofElements, boolean swap); 448fbc397fc09158bee0bc0cb231c609c4c6e9fc15Elliott Hughes 45af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes public static int peekInt(byte[] src, int offset, ByteOrder order) { 46af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes if (order == ByteOrder.BIG_ENDIAN) { 47af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes return (((src[offset++] & 0xff) << 24) | 48af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 16) | 49af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 8) | 50af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset ] & 0xff) << 0)); 51af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } else { 52af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes return (((src[offset++] & 0xff) << 0) | 53af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 8) | 54af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 16) | 55af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset ] & 0xff) << 24)); 56af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 57af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 58af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes 59af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes public static long peekLong(byte[] src, int offset, ByteOrder order) { 60af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes if (order == ByteOrder.BIG_ENDIAN) { 61af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes int h = ((src[offset++] & 0xff) << 24) | 62af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 16) | 63af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 8) | 64af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 0); 65af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes int l = ((src[offset++] & 0xff) << 24) | 66af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 16) | 67af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 8) | 68af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset ] & 0xff) << 0); 69af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes return (((long) h) << 32L) | ((long) l) & 0xffffffffL; 70af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } else { 71af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes int l = ((src[offset++] & 0xff) << 0) | 72af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 8) | 73af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 16) | 74af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 24); 75af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes int h = ((src[offset++] & 0xff) << 0) | 76af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 8) | 77af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset++] & 0xff) << 16) | 78af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes ((src[offset ] & 0xff) << 24); 79af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes return (((long) h) << 32L) | ((long) l) & 0xffffffffL; 80af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 81af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 82af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes 83af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes public static short peekShort(byte[] src, int offset, ByteOrder order) { 84af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes if (order == ByteOrder.BIG_ENDIAN) { 85af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff)); 86af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } else { 87af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes return (short) ((src[offset + 1] << 8) | (src[offset] & 0xff)); 88af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 89af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 90af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes 91af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) { 92af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes if (order == ByteOrder.BIG_ENDIAN) { 93af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((value >> 24) & 0xff); 94af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((value >> 16) & 0xff); 95af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((value >> 8) & 0xff); 96af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset ] = (byte) ((value >> 0) & 0xff); 97af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } else { 98af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((value >> 0) & 0xff); 99af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((value >> 8) & 0xff); 100af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((value >> 16) & 0xff); 101af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset ] = (byte) ((value >> 24) & 0xff); 102af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 103af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 104af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes 105af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes public static void pokeLong(byte[] dst, int offset, long value, ByteOrder order) { 106af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes if (order == ByteOrder.BIG_ENDIAN) { 107af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes int i = (int) (value >> 32); 108af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 24) & 0xff); 109af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 16) & 0xff); 110af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 8) & 0xff); 111af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 0) & 0xff); 112af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes i = (int) value; 113af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 24) & 0xff); 114af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 16) & 0xff); 115af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 8) & 0xff); 116af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset ] = (byte) ((i >> 0) & 0xff); 117af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } else { 118af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes int i = (int) value; 119af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 0) & 0xff); 120af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 8) & 0xff); 121af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 16) & 0xff); 122af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 24) & 0xff); 123af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes i = (int) (value >> 32); 124af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 0) & 0xff); 125af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 8) & 0xff); 126af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((i >> 16) & 0xff); 127af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset ] = (byte) ((i >> 24) & 0xff); 128af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 129af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 130af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes 131af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes public static void pokeShort(byte[] dst, int offset, short value, ByteOrder order) { 132af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes if (order == ByteOrder.BIG_ENDIAN) { 133af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((value >> 8) & 0xff); 134af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset ] = (byte) ((value >> 0) & 0xff); 135af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } else { 136af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset++] = (byte) ((value >> 0) & 0xff); 137af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes dst[offset ] = (byte) ((value >> 8) & 0xff); 138af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 139af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes } 140af301fb0e674665dae3e9cb94344558923ec8e0aElliott Hughes 1410568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes /** 1420568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes * Copies 'byteCount' bytes from the source to the destination. The objects are either 1430568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes * instances of DirectByteBuffer or byte[]. The offsets in the byte[] case must include 1440568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes * the Buffer.arrayOffset if the array came from a Buffer.array call. We could make this 1450568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes * private and provide the four type-safe variants, but then ByteBuffer.put(ByteBuffer) 1460568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes * would need to work out which to call based on whether the source and destination buffers 1470568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes * are direct or not. 1480568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes * 1490568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes * @hide make type-safe before making public? 1500568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes */ 1510568a63ba1086a78ffb4cff68dd2eac4f9908e13Elliott Hughes public static native void memmove(Object dstObject, int dstOffset, Object srcObject, int srcOffset, long byteCount); 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1531b9018762e87e3dda69020248817011efd5a40dcElliott Hughes public static native byte peekByte(int address); 1541b9018762e87e3dda69020248817011efd5a40dcElliott Hughes public static native int peekInt(int address, boolean swap); 1551b9018762e87e3dda69020248817011efd5a40dcElliott Hughes public static native long peekLong(int address, boolean swap); 1561b9018762e87e3dda69020248817011efd5a40dcElliott Hughes public static native short peekShort(int address, boolean swap); 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 158692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes public static native void peekByteArray(int address, byte[] dst, int dstOffset, int byteCount); 159961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes public static native void peekCharArray(int address, char[] dst, int dstOffset, int charCount, boolean swap); 160961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes public static native void peekDoubleArray(int address, double[] dst, int dstOffset, int doubleCount, boolean swap); 161961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes public static native void peekFloatArray(int address, float[] dst, int dstOffset, int floatCount, boolean swap); 162692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes public static native void peekIntArray(int address, int[] dst, int dstOffset, int intCount, boolean swap); 163961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes public static native void peekLongArray(int address, long[] dst, int dstOffset, int longCount, boolean swap); 164961da1e7487bdb8ad8ac226d4f2789d003aa87b9Elliott Hughes public static native void peekShortArray(int address, short[] dst, int dstOffset, int shortCount, boolean swap); 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1661b9018762e87e3dda69020248817011efd5a40dcElliott Hughes public static native void pokeByte(int address, byte value); 1671b9018762e87e3dda69020248817011efd5a40dcElliott Hughes public static native void pokeInt(int address, int value, boolean swap); 1681b9018762e87e3dda69020248817011efd5a40dcElliott Hughes public static native void pokeLong(int address, long value, boolean swap); 1691b9018762e87e3dda69020248817011efd5a40dcElliott Hughes public static native void pokeShort(int address, short value, boolean swap); 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 171692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes public static native void pokeByteArray(int address, byte[] src, int offset, int count); 172692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes public static native void pokeCharArray(int address, char[] src, int offset, int count, boolean swap); 173692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes public static native void pokeDoubleArray(int address, double[] src, int offset, int count, boolean swap); 174692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes public static native void pokeFloatArray(int address, float[] src, int offset, int count, boolean swap); 175692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes public static native void pokeIntArray(int address, int[] src, int offset, int count, boolean swap); 176692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes public static native void pokeLongArray(int address, long[] src, int offset, int count, boolean swap); 177692222b08ff88eb92b523bf4780d7ea17a23aa80Elliott Hughes public static native void pokeShortArray(int address, short[] src, int offset, int count, boolean swap); 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 179