blob: 9bf1acb6d851e1cd342cb0ce1b5ccff6db5c582d [file] [log] [blame]
The Android Open Source Projectb5de22c2012-04-01 00:00:00 -07001/*
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}