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