• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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