1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package libcore.io; 19 20 import dalvik.annotation.optimization.FastNative; 21 import java.io.FileDescriptor; 22 import java.io.IOException; 23 import java.nio.ByteBuffer; 24 import java.nio.ByteOrder; 25 26 /** 27 * Unsafe access to memory. 28 */ 29 public final class Memory { Memory()30 private Memory() { } 31 32 /** 33 * Used to optimize nio heap buffer bulk get operations. 'dst' must be a primitive array. 34 * 'dstOffset' is measured in units of 'sizeofElements' bytes. 35 */ unsafeBulkGet(Object dst, int dstOffset, int byteCount, byte[] src, int srcOffset, int sizeofElements, boolean swap)36 public static native void unsafeBulkGet(Object dst, int dstOffset, int byteCount, 37 byte[] src, int srcOffset, int sizeofElements, boolean swap); 38 39 /** 40 * Used to optimize nio heap buffer bulk put operations. 'src' must be a primitive array. 41 * 'srcOffset' is measured in units of 'sizeofElements' bytes. 42 */ unsafeBulkPut(byte[] dst, int dstOffset, int byteCount, Object src, int srcOffset, int sizeofElements, boolean swap)43 public static native void unsafeBulkPut(byte[] dst, int dstOffset, int byteCount, 44 Object src, int srcOffset, int sizeofElements, boolean swap); 45 peekInt(byte[] src, int offset, ByteOrder order)46 public static int peekInt(byte[] src, int offset, ByteOrder order) { 47 if (order == ByteOrder.BIG_ENDIAN) { 48 return (((src[offset++] & 0xff) << 24) | 49 ((src[offset++] & 0xff) << 16) | 50 ((src[offset++] & 0xff) << 8) | 51 ((src[offset ] & 0xff) << 0)); 52 } else { 53 return (((src[offset++] & 0xff) << 0) | 54 ((src[offset++] & 0xff) << 8) | 55 ((src[offset++] & 0xff) << 16) | 56 ((src[offset ] & 0xff) << 24)); 57 } 58 } 59 peekLong(byte[] src, int offset, ByteOrder order)60 public static long peekLong(byte[] src, int offset, ByteOrder order) { 61 if (order == ByteOrder.BIG_ENDIAN) { 62 int h = ((src[offset++] & 0xff) << 24) | 63 ((src[offset++] & 0xff) << 16) | 64 ((src[offset++] & 0xff) << 8) | 65 ((src[offset++] & 0xff) << 0); 66 int l = ((src[offset++] & 0xff) << 24) | 67 ((src[offset++] & 0xff) << 16) | 68 ((src[offset++] & 0xff) << 8) | 69 ((src[offset ] & 0xff) << 0); 70 return (((long) h) << 32L) | ((long) l) & 0xffffffffL; 71 } else { 72 int l = ((src[offset++] & 0xff) << 0) | 73 ((src[offset++] & 0xff) << 8) | 74 ((src[offset++] & 0xff) << 16) | 75 ((src[offset++] & 0xff) << 24); 76 int h = ((src[offset++] & 0xff) << 0) | 77 ((src[offset++] & 0xff) << 8) | 78 ((src[offset++] & 0xff) << 16) | 79 ((src[offset ] & 0xff) << 24); 80 return (((long) h) << 32L) | ((long) l) & 0xffffffffL; 81 } 82 } 83 peekShort(byte[] src, int offset, ByteOrder order)84 public static short peekShort(byte[] src, int offset, ByteOrder order) { 85 if (order == ByteOrder.BIG_ENDIAN) { 86 return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff)); 87 } else { 88 return (short) ((src[offset + 1] << 8) | (src[offset] & 0xff)); 89 } 90 } 91 pokeInt(byte[] dst, int offset, int value, ByteOrder order)92 public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) { 93 if (order == ByteOrder.BIG_ENDIAN) { 94 dst[offset++] = (byte) ((value >> 24) & 0xff); 95 dst[offset++] = (byte) ((value >> 16) & 0xff); 96 dst[offset++] = (byte) ((value >> 8) & 0xff); 97 dst[offset ] = (byte) ((value >> 0) & 0xff); 98 } else { 99 dst[offset++] = (byte) ((value >> 0) & 0xff); 100 dst[offset++] = (byte) ((value >> 8) & 0xff); 101 dst[offset++] = (byte) ((value >> 16) & 0xff); 102 dst[offset ] = (byte) ((value >> 24) & 0xff); 103 } 104 } 105 pokeLong(byte[] dst, int offset, long value, ByteOrder order)106 public static void pokeLong(byte[] dst, int offset, long value, ByteOrder order) { 107 if (order == ByteOrder.BIG_ENDIAN) { 108 int i = (int) (value >> 32); 109 dst[offset++] = (byte) ((i >> 24) & 0xff); 110 dst[offset++] = (byte) ((i >> 16) & 0xff); 111 dst[offset++] = (byte) ((i >> 8) & 0xff); 112 dst[offset++] = (byte) ((i >> 0) & 0xff); 113 i = (int) value; 114 dst[offset++] = (byte) ((i >> 24) & 0xff); 115 dst[offset++] = (byte) ((i >> 16) & 0xff); 116 dst[offset++] = (byte) ((i >> 8) & 0xff); 117 dst[offset ] = (byte) ((i >> 0) & 0xff); 118 } else { 119 int i = (int) value; 120 dst[offset++] = (byte) ((i >> 0) & 0xff); 121 dst[offset++] = (byte) ((i >> 8) & 0xff); 122 dst[offset++] = (byte) ((i >> 16) & 0xff); 123 dst[offset++] = (byte) ((i >> 24) & 0xff); 124 i = (int) (value >> 32); 125 dst[offset++] = (byte) ((i >> 0) & 0xff); 126 dst[offset++] = (byte) ((i >> 8) & 0xff); 127 dst[offset++] = (byte) ((i >> 16) & 0xff); 128 dst[offset ] = (byte) ((i >> 24) & 0xff); 129 } 130 } 131 pokeShort(byte[] dst, int offset, short value, ByteOrder order)132 public static void pokeShort(byte[] dst, int offset, short value, ByteOrder order) { 133 if (order == ByteOrder.BIG_ENDIAN) { 134 dst[offset++] = (byte) ((value >> 8) & 0xff); 135 dst[offset ] = (byte) ((value >> 0) & 0xff); 136 } else { 137 dst[offset++] = (byte) ((value >> 0) & 0xff); 138 dst[offset ] = (byte) ((value >> 8) & 0xff); 139 } 140 } 141 142 /** 143 * Copies 'byteCount' bytes from the source to the destination. The objects are either 144 * instances of DirectByteBuffer or byte[]. The offsets in the byte[] case must include 145 * the Buffer.arrayOffset if the array came from a Buffer.array call. We could make this 146 * private and provide the four type-safe variants, but then ByteBuffer.put(ByteBuffer) 147 * would need to work out which to call based on whether the source and destination buffers 148 * are direct or not. 149 * 150 * @hide make type-safe before making public? 151 */ memmove(Object dstObject, int dstOffset, Object srcObject, int srcOffset, long byteCount)152 public static native void memmove(Object dstObject, int dstOffset, Object srcObject, int srcOffset, long byteCount); 153 154 @FastNative peekByte(long address)155 public static native byte peekByte(long address); 156 peekInt(long address, boolean swap)157 public static int peekInt(long address, boolean swap) { 158 int result = peekIntNative(address); 159 if (swap) { 160 result = Integer.reverseBytes(result); 161 } 162 return result; 163 } 164 @FastNative peekIntNative(long address)165 private static native int peekIntNative(long address); 166 peekLong(long address, boolean swap)167 public static long peekLong(long address, boolean swap) { 168 long result = peekLongNative(address); 169 if (swap) { 170 result = Long.reverseBytes(result); 171 } 172 return result; 173 } 174 @FastNative peekLongNative(long address)175 private static native long peekLongNative(long address); 176 peekShort(long address, boolean swap)177 public static short peekShort(long address, boolean swap) { 178 short result = peekShortNative(address); 179 if (swap) { 180 result = Short.reverseBytes(result); 181 } 182 return result; 183 } 184 @FastNative peekShortNative(long address)185 private static native short peekShortNative(long address); 186 peekByteArray(long address, byte[] dst, int dstOffset, int byteCount)187 public static native void peekByteArray(long address, byte[] dst, int dstOffset, int byteCount); peekCharArray(long address, char[] dst, int dstOffset, int charCount, boolean swap)188 public static native void peekCharArray(long address, char[] dst, int dstOffset, int charCount, boolean swap); peekDoubleArray(long address, double[] dst, int dstOffset, int doubleCount, boolean swap)189 public static native void peekDoubleArray(long address, double[] dst, int dstOffset, int doubleCount, boolean swap); peekFloatArray(long address, float[] dst, int dstOffset, int floatCount, boolean swap)190 public static native void peekFloatArray(long address, float[] dst, int dstOffset, int floatCount, boolean swap); peekIntArray(long address, int[] dst, int dstOffset, int intCount, boolean swap)191 public static native void peekIntArray(long address, int[] dst, int dstOffset, int intCount, boolean swap); peekLongArray(long address, long[] dst, int dstOffset, int longCount, boolean swap)192 public static native void peekLongArray(long address, long[] dst, int dstOffset, int longCount, boolean swap); peekShortArray(long address, short[] dst, int dstOffset, int shortCount, boolean swap)193 public static native void peekShortArray(long address, short[] dst, int dstOffset, int shortCount, boolean swap); 194 195 @FastNative pokeByte(long address, byte value)196 public static native void pokeByte(long address, byte value); 197 pokeInt(long address, int value, boolean swap)198 public static void pokeInt(long address, int value, boolean swap) { 199 if (swap) { 200 value = Integer.reverseBytes(value); 201 } 202 pokeIntNative(address, value); 203 } 204 @FastNative pokeIntNative(long address, int value)205 private static native void pokeIntNative(long address, int value); 206 pokeLong(long address, long value, boolean swap)207 public static void pokeLong(long address, long value, boolean swap) { 208 if (swap) { 209 value = Long.reverseBytes(value); 210 } 211 pokeLongNative(address, value); 212 } 213 @FastNative pokeLongNative(long address, long value)214 private static native void pokeLongNative(long address, long value); 215 pokeShort(long address, short value, boolean swap)216 public static void pokeShort(long address, short value, boolean swap) { 217 if (swap) { 218 value = Short.reverseBytes(value); 219 } 220 pokeShortNative(address, value); 221 } 222 @FastNative pokeShortNative(long address, short value)223 private static native void pokeShortNative(long address, short value); 224 pokeByteArray(long address, byte[] src, int offset, int count)225 public static native void pokeByteArray(long address, byte[] src, int offset, int count); pokeCharArray(long address, char[] src, int offset, int count, boolean swap)226 public static native void pokeCharArray(long address, char[] src, int offset, int count, boolean swap); pokeDoubleArray(long address, double[] src, int offset, int count, boolean swap)227 public static native void pokeDoubleArray(long address, double[] src, int offset, int count, boolean swap); pokeFloatArray(long address, float[] src, int offset, int count, boolean swap)228 public static native void pokeFloatArray(long address, float[] src, int offset, int count, boolean swap); pokeIntArray(long address, int[] src, int offset, int count, boolean swap)229 public static native void pokeIntArray(long address, int[] src, int offset, int count, boolean swap); pokeLongArray(long address, long[] src, int offset, int count, boolean swap)230 public static native void pokeLongArray(long address, long[] src, int offset, int count, boolean swap); pokeShortArray(long address, short[] src, int offset, int count, boolean swap)231 public static native void pokeShortArray(long address, short[] src, int offset, int count, boolean swap); 232 } 233