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.compat.UnsupportedAppUsage; 21 import dalvik.annotation.optimization.FastNative; 22 import java.io.FileDescriptor; 23 import java.io.IOException; 24 import java.nio.ByteBuffer; 25 import java.nio.ByteOrder; 26 27 /** 28 * Unsafe access to memory. 29 * 30 * @hide 31 */ 32 @libcore.api.CorePlatformApi 33 public final class Memory { Memory()34 private Memory() { } 35 36 /** 37 * Used to optimize nio heap buffer bulk get operations. 'dst' must be a primitive array. 38 * 'dstOffset' is measured in units of 'sizeofElements' bytes. 39 */ unsafeBulkGet(Object dst, int dstOffset, int byteCount, byte[] src, int srcOffset, int sizeofElements, boolean swap)40 public static native void unsafeBulkGet(Object dst, int dstOffset, int byteCount, 41 byte[] src, int srcOffset, int sizeofElements, boolean swap); 42 43 /** 44 * Used to optimize nio heap buffer bulk put operations. 'src' must be a primitive array. 45 * 'srcOffset' is measured in units of 'sizeofElements' bytes. 46 */ unsafeBulkPut(byte[] dst, int dstOffset, int byteCount, Object src, int srcOffset, int sizeofElements, boolean swap)47 public static native void unsafeBulkPut(byte[] dst, int dstOffset, int byteCount, 48 Object src, int srcOffset, int sizeofElements, boolean swap); 49 50 @libcore.api.CorePlatformApi peekInt(byte[] src, int offset, ByteOrder order)51 public static int peekInt(byte[] src, int offset, ByteOrder order) { 52 if (order == ByteOrder.BIG_ENDIAN) { 53 return (((src[offset++] & 0xff) << 24) | 54 ((src[offset++] & 0xff) << 16) | 55 ((src[offset++] & 0xff) << 8) | 56 ((src[offset ] & 0xff) << 0)); 57 } else { 58 return (((src[offset++] & 0xff) << 0) | 59 ((src[offset++] & 0xff) << 8) | 60 ((src[offset++] & 0xff) << 16) | 61 ((src[offset ] & 0xff) << 24)); 62 } 63 } 64 peekLong(byte[] src, int offset, ByteOrder order)65 public static long peekLong(byte[] src, int offset, ByteOrder order) { 66 if (order == ByteOrder.BIG_ENDIAN) { 67 int h = ((src[offset++] & 0xff) << 24) | 68 ((src[offset++] & 0xff) << 16) | 69 ((src[offset++] & 0xff) << 8) | 70 ((src[offset++] & 0xff) << 0); 71 int l = ((src[offset++] & 0xff) << 24) | 72 ((src[offset++] & 0xff) << 16) | 73 ((src[offset++] & 0xff) << 8) | 74 ((src[offset ] & 0xff) << 0); 75 return (((long) h) << 32L) | ((long) l) & 0xffffffffL; 76 } else { 77 int l = ((src[offset++] & 0xff) << 0) | 78 ((src[offset++] & 0xff) << 8) | 79 ((src[offset++] & 0xff) << 16) | 80 ((src[offset++] & 0xff) << 24); 81 int h = ((src[offset++] & 0xff) << 0) | 82 ((src[offset++] & 0xff) << 8) | 83 ((src[offset++] & 0xff) << 16) | 84 ((src[offset ] & 0xff) << 24); 85 return (((long) h) << 32L) | ((long) l) & 0xffffffffL; 86 } 87 } 88 89 @libcore.api.CorePlatformApi peekShort(byte[] src, int offset, ByteOrder order)90 public static short peekShort(byte[] src, int offset, ByteOrder order) { 91 if (order == ByteOrder.BIG_ENDIAN) { 92 return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff)); 93 } else { 94 return (short) ((src[offset + 1] << 8) | (src[offset] & 0xff)); 95 } 96 } 97 98 @libcore.api.CorePlatformApi pokeInt(byte[] dst, int offset, int value, ByteOrder order)99 public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) { 100 if (order == ByteOrder.BIG_ENDIAN) { 101 dst[offset++] = (byte) ((value >> 24) & 0xff); 102 dst[offset++] = (byte) ((value >> 16) & 0xff); 103 dst[offset++] = (byte) ((value >> 8) & 0xff); 104 dst[offset ] = (byte) ((value >> 0) & 0xff); 105 } else { 106 dst[offset++] = (byte) ((value >> 0) & 0xff); 107 dst[offset++] = (byte) ((value >> 8) & 0xff); 108 dst[offset++] = (byte) ((value >> 16) & 0xff); 109 dst[offset ] = (byte) ((value >> 24) & 0xff); 110 } 111 } 112 113 @libcore.api.CorePlatformApi pokeLong(byte[] dst, int offset, long value, ByteOrder order)114 public static void pokeLong(byte[] dst, int offset, long value, ByteOrder order) { 115 if (order == ByteOrder.BIG_ENDIAN) { 116 int i = (int) (value >> 32); 117 dst[offset++] = (byte) ((i >> 24) & 0xff); 118 dst[offset++] = (byte) ((i >> 16) & 0xff); 119 dst[offset++] = (byte) ((i >> 8) & 0xff); 120 dst[offset++] = (byte) ((i >> 0) & 0xff); 121 i = (int) value; 122 dst[offset++] = (byte) ((i >> 24) & 0xff); 123 dst[offset++] = (byte) ((i >> 16) & 0xff); 124 dst[offset++] = (byte) ((i >> 8) & 0xff); 125 dst[offset ] = (byte) ((i >> 0) & 0xff); 126 } else { 127 int i = (int) value; 128 dst[offset++] = (byte) ((i >> 0) & 0xff); 129 dst[offset++] = (byte) ((i >> 8) & 0xff); 130 dst[offset++] = (byte) ((i >> 16) & 0xff); 131 dst[offset++] = (byte) ((i >> 24) & 0xff); 132 i = (int) (value >> 32); 133 dst[offset++] = (byte) ((i >> 0) & 0xff); 134 dst[offset++] = (byte) ((i >> 8) & 0xff); 135 dst[offset++] = (byte) ((i >> 16) & 0xff); 136 dst[offset ] = (byte) ((i >> 24) & 0xff); 137 } 138 } 139 140 @libcore.api.CorePlatformApi pokeShort(byte[] dst, int offset, short value, ByteOrder order)141 public static void pokeShort(byte[] dst, int offset, short value, ByteOrder order) { 142 if (order == ByteOrder.BIG_ENDIAN) { 143 dst[offset++] = (byte) ((value >> 8) & 0xff); 144 dst[offset ] = (byte) ((value >> 0) & 0xff); 145 } else { 146 dst[offset++] = (byte) ((value >> 0) & 0xff); 147 dst[offset ] = (byte) ((value >> 8) & 0xff); 148 } 149 } 150 151 /** 152 * Copies 'byteCount' bytes from the source to the destination. The objects are either 153 * instances of DirectByteBuffer or byte[]. The offsets in the byte[] case must include 154 * the Buffer.arrayOffset if the array came from a Buffer.array call. We could make this 155 * private and provide the four type-safe variants, but then ByteBuffer.put(ByteBuffer) 156 * would need to work out which to call based on whether the source and destination buffers 157 * are direct or not. 158 * 159 * @hide make type-safe before making public? 160 */ 161 @libcore.api.CorePlatformApi memmove(Object dstObject, int dstOffset, Object srcObject, int srcOffset, long byteCount)162 public static native void memmove(Object dstObject, int dstOffset, Object srcObject, int srcOffset, long byteCount); 163 164 @UnsupportedAppUsage 165 @FastNative peekByte(long address)166 public static native byte peekByte(long address); 167 168 @UnsupportedAppUsage peekInt(long address, boolean swap)169 public static int peekInt(long address, boolean swap) { 170 int result = peekIntNative(address); 171 if (swap) { 172 result = Integer.reverseBytes(result); 173 } 174 return result; 175 } 176 @FastNative peekIntNative(long address)177 private static native int peekIntNative(long address); 178 179 @UnsupportedAppUsage peekLong(long address, boolean swap)180 public static long peekLong(long address, boolean swap) { 181 long result = peekLongNative(address); 182 if (swap) { 183 result = Long.reverseBytes(result); 184 } 185 return result; 186 } 187 @FastNative peekLongNative(long address)188 private static native long peekLongNative(long address); 189 peekShort(long address, boolean swap)190 public static short peekShort(long address, boolean swap) { 191 short result = peekShortNative(address); 192 if (swap) { 193 result = Short.reverseBytes(result); 194 } 195 return result; 196 } 197 @FastNative peekShortNative(long address)198 private static native short peekShortNative(long address); 199 200 @UnsupportedAppUsage peekByteArray(long address, byte[] dst, int dstOffset, int byteCount)201 public static native void peekByteArray(long address, byte[] dst, int dstOffset, int byteCount); peekCharArray(long address, char[] dst, int dstOffset, int charCount, boolean swap)202 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)203 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)204 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)205 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)206 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)207 public static native void peekShortArray(long address, short[] dst, int dstOffset, int shortCount, boolean swap); 208 209 @UnsupportedAppUsage 210 @FastNative pokeByte(long address, byte value)211 public static native void pokeByte(long address, byte value); 212 213 @UnsupportedAppUsage pokeInt(long address, int value, boolean swap)214 public static void pokeInt(long address, int value, boolean swap) { 215 if (swap) { 216 value = Integer.reverseBytes(value); 217 } 218 pokeIntNative(address, value); 219 } 220 @FastNative pokeIntNative(long address, int value)221 private static native void pokeIntNative(long address, int value); 222 223 @UnsupportedAppUsage pokeLong(long address, long value, boolean swap)224 public static void pokeLong(long address, long value, boolean swap) { 225 if (swap) { 226 value = Long.reverseBytes(value); 227 } 228 pokeLongNative(address, value); 229 } 230 @FastNative pokeLongNative(long address, long value)231 private static native void pokeLongNative(long address, long value); 232 pokeShort(long address, short value, boolean swap)233 public static void pokeShort(long address, short value, boolean swap) { 234 if (swap) { 235 value = Short.reverseBytes(value); 236 } 237 pokeShortNative(address, value); 238 } 239 @FastNative pokeShortNative(long address, short value)240 private static native void pokeShortNative(long address, short value); 241 242 @UnsupportedAppUsage pokeByteArray(long address, byte[] src, int offset, int count)243 public static native void pokeByteArray(long address, byte[] src, int offset, int count); pokeCharArray(long address, char[] src, int offset, int count, boolean swap)244 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)245 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)246 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)247 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)248 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)249 public static native void pokeShortArray(long address, short[] src, int offset, int count, boolean swap); 250 } 251