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 18package libcore.io; 19 20import java.io.FileDescriptor; 21import java.io.IOException; 22import java.nio.ByteBuffer; 23import java.nio.ByteOrder; 24 25/** 26 * Unsafe access to memory. 27 */ 28public final class Memory { 29 private Memory() { } 30 31 /** 32 * Used to optimize nio heap buffer bulk get operations. 'dst' must be a primitive array. 33 * 'dstOffset' is measured in units of 'sizeofElements' bytes. 34 */ 35 public static native void unsafeBulkGet(Object dst, int dstOffset, int byteCount, 36 byte[] src, int srcOffset, int sizeofElements, boolean swap); 37 38 /** 39 * Used to optimize nio heap buffer bulk put operations. 'src' must be a primitive array. 40 * 'srcOffset' is measured in units of 'sizeofElements' bytes. 41 */ 42 public static native void unsafeBulkPut(byte[] dst, int dstOffset, int byteCount, 43 Object src, int srcOffset, int sizeofElements, boolean swap); 44 45 public static int peekInt(byte[] src, int offset, ByteOrder order) { 46 if (order == ByteOrder.BIG_ENDIAN) { 47 return (((src[offset++] & 0xff) << 24) | 48 ((src[offset++] & 0xff) << 16) | 49 ((src[offset++] & 0xff) << 8) | 50 ((src[offset ] & 0xff) << 0)); 51 } else { 52 return (((src[offset++] & 0xff) << 0) | 53 ((src[offset++] & 0xff) << 8) | 54 ((src[offset++] & 0xff) << 16) | 55 ((src[offset ] & 0xff) << 24)); 56 } 57 } 58 59 public static long peekLong(byte[] src, int offset, ByteOrder order) { 60 if (order == ByteOrder.BIG_ENDIAN) { 61 int h = ((src[offset++] & 0xff) << 24) | 62 ((src[offset++] & 0xff) << 16) | 63 ((src[offset++] & 0xff) << 8) | 64 ((src[offset++] & 0xff) << 0); 65 int l = ((src[offset++] & 0xff) << 24) | 66 ((src[offset++] & 0xff) << 16) | 67 ((src[offset++] & 0xff) << 8) | 68 ((src[offset ] & 0xff) << 0); 69 return (((long) h) << 32L) | ((long) l) & 0xffffffffL; 70 } else { 71 int l = ((src[offset++] & 0xff) << 0) | 72 ((src[offset++] & 0xff) << 8) | 73 ((src[offset++] & 0xff) << 16) | 74 ((src[offset++] & 0xff) << 24); 75 int h = ((src[offset++] & 0xff) << 0) | 76 ((src[offset++] & 0xff) << 8) | 77 ((src[offset++] & 0xff) << 16) | 78 ((src[offset ] & 0xff) << 24); 79 return (((long) h) << 32L) | ((long) l) & 0xffffffffL; 80 } 81 } 82 83 public static short peekShort(byte[] src, int offset, ByteOrder order) { 84 if (order == ByteOrder.BIG_ENDIAN) { 85 return (short) ((src[offset] << 8) | (src[offset + 1] & 0xff)); 86 } else { 87 return (short) ((src[offset + 1] << 8) | (src[offset] & 0xff)); 88 } 89 } 90 91 public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) { 92 if (order == ByteOrder.BIG_ENDIAN) { 93 dst[offset++] = (byte) ((value >> 24) & 0xff); 94 dst[offset++] = (byte) ((value >> 16) & 0xff); 95 dst[offset++] = (byte) ((value >> 8) & 0xff); 96 dst[offset ] = (byte) ((value >> 0) & 0xff); 97 } else { 98 dst[offset++] = (byte) ((value >> 0) & 0xff); 99 dst[offset++] = (byte) ((value >> 8) & 0xff); 100 dst[offset++] = (byte) ((value >> 16) & 0xff); 101 dst[offset ] = (byte) ((value >> 24) & 0xff); 102 } 103 } 104 105 public static void pokeLong(byte[] dst, int offset, long value, ByteOrder order) { 106 if (order == ByteOrder.BIG_ENDIAN) { 107 int i = (int) (value >> 32); 108 dst[offset++] = (byte) ((i >> 24) & 0xff); 109 dst[offset++] = (byte) ((i >> 16) & 0xff); 110 dst[offset++] = (byte) ((i >> 8) & 0xff); 111 dst[offset++] = (byte) ((i >> 0) & 0xff); 112 i = (int) value; 113 dst[offset++] = (byte) ((i >> 24) & 0xff); 114 dst[offset++] = (byte) ((i >> 16) & 0xff); 115 dst[offset++] = (byte) ((i >> 8) & 0xff); 116 dst[offset ] = (byte) ((i >> 0) & 0xff); 117 } else { 118 int i = (int) value; 119 dst[offset++] = (byte) ((i >> 0) & 0xff); 120 dst[offset++] = (byte) ((i >> 8) & 0xff); 121 dst[offset++] = (byte) ((i >> 16) & 0xff); 122 dst[offset++] = (byte) ((i >> 24) & 0xff); 123 i = (int) (value >> 32); 124 dst[offset++] = (byte) ((i >> 0) & 0xff); 125 dst[offset++] = (byte) ((i >> 8) & 0xff); 126 dst[offset++] = (byte) ((i >> 16) & 0xff); 127 dst[offset ] = (byte) ((i >> 24) & 0xff); 128 } 129 } 130 131 public static void pokeShort(byte[] dst, int offset, short value, ByteOrder order) { 132 if (order == ByteOrder.BIG_ENDIAN) { 133 dst[offset++] = (byte) ((value >> 8) & 0xff); 134 dst[offset ] = (byte) ((value >> 0) & 0xff); 135 } else { 136 dst[offset++] = (byte) ((value >> 0) & 0xff); 137 dst[offset ] = (byte) ((value >> 8) & 0xff); 138 } 139 } 140 141 /** 142 * Copies 'byteCount' bytes from the source to the destination. The objects are either 143 * instances of DirectByteBuffer or byte[]. The offsets in the byte[] case must include 144 * the Buffer.arrayOffset if the array came from a Buffer.array call. We could make this 145 * private and provide the four type-safe variants, but then ByteBuffer.put(ByteBuffer) 146 * would need to work out which to call based on whether the source and destination buffers 147 * are direct or not. 148 * 149 * @hide make type-safe before making public? 150 */ 151 public static native void memmove(Object dstObject, int dstOffset, Object srcObject, int srcOffset, long byteCount); 152 153 public static native byte peekByte(int address); 154 public static native int peekInt(int address, boolean swap); 155 public static native long peekLong(int address, boolean swap); 156 public static native short peekShort(int address, boolean swap); 157 158 public static native void peekByteArray(int address, byte[] dst, int dstOffset, int byteCount); 159 public static native void peekCharArray(int address, char[] dst, int dstOffset, int charCount, boolean swap); 160 public static native void peekDoubleArray(int address, double[] dst, int dstOffset, int doubleCount, boolean swap); 161 public static native void peekFloatArray(int address, float[] dst, int dstOffset, int floatCount, boolean swap); 162 public static native void peekIntArray(int address, int[] dst, int dstOffset, int intCount, boolean swap); 163 public static native void peekLongArray(int address, long[] dst, int dstOffset, int longCount, boolean swap); 164 public static native void peekShortArray(int address, short[] dst, int dstOffset, int shortCount, boolean swap); 165 166 public static native void pokeByte(int address, byte value); 167 public static native void pokeInt(int address, int value, boolean swap); 168 public static native void pokeLong(int address, long value, boolean swap); 169 public static native void pokeShort(int address, short value, boolean swap); 170 171 public static native void pokeByteArray(int address, byte[] src, int offset, int count); 172 public static native void pokeCharArray(int address, char[] src, int offset, int count, boolean swap); 173 public static native void pokeDoubleArray(int address, double[] src, int offset, int count, boolean swap); 174 public static native void pokeFloatArray(int address, float[] src, int offset, int count, boolean swap); 175 public static native void pokeIntArray(int address, int[] src, int offset, int count, boolean swap); 176 public static native void pokeLongArray(int address, long[] src, int offset, int count, boolean swap); 177 public static native void pokeShortArray(int address, short[] src, int offset, int count, boolean swap); 178} 179