0001: /*
0002: * Licensed to the Apache Software Foundation (ASF) under one or more
0003: * contributor license agreements. See the NOTICE file distributed with
0004: * this work for additional information regarding copyright ownership.
0005: * The ASF licenses this file to You under the Apache License, Version 2.0
0006: * (the "License"); you may not use this file except in compliance with
0007: * the License. You may obtain a copy of the License at
0008: *
0009: * http://www.apache.org/licenses/LICENSE-2.0
0010: *
0011: * Unless required by applicable law or agreed to in writing, software
0012: * distributed under the License is distributed on an "AS IS" BASIS,
0013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014: * See the License for the specific language governing permissions and
0015: * limitations under the License.
0016: */
0017: /**
0018: * @author Rustem Rafikov
0019: * @version $Revision$
0020: */package org.apache.harmony.awt.nativebridge;
0021:
0022: import java.util.Arrays;
0023:
0024: import org.apache.harmony.awt.internal.nls.Messages;
0025: import org.apache.harmony.misc.accessors.AccessorFactory;
0026: import org.apache.harmony.misc.accessors.ArrayAccessor;
0027: import org.apache.harmony.misc.accessors.LockedArray;
0028: import org.apache.harmony.misc.accessors.MemoryAccessor;
0029: import org.apache.harmony.misc.accessors.StringAccessor;
0030:
0031: public class ByteBase {
0032: static MemoryAccessor macc = AccessorFactory.getMemoryAccessor();
0033: static ArrayAccessor arac = AccessorFactory.getArrayAccessor();
0034: static StringAccessor stac = AccessorFactory.getStringAccessor();
0035: static NativeBridge nb = NativeBridge.getInstance();
0036:
0037: static final int NATIVE_BYTE_ORDER = macc.getNativeByteOrder();
0038: static final int JAVA_BYTE_ORDER = MemoryAccessor.BIG_ENDIAN;
0039:
0040: /**
0041: * size of C pointer type, in bytes.
0042: */
0043: public static final int POINTER_SIZE = macc.getPointerSize();
0044:
0045: /**
0046: * size of C long type, in bytes.
0047: */
0048: public static final int CLONG_SIZE = macc.getPointerSize();
0049:
0050: private long addr = 0L; // (void*) pointer to native memory
0051: private LockedArray lock = null;
0052: private byte[] array = null; // wrapped byte array
0053: private int offset = 0;
0054: private int size = -1; // -1 - unknown size
0055:
0056: ByteBase(int size, boolean direct) {
0057: if (direct) {
0058: this .addr = macc.malloc(size);
0059: } else {
0060: this .array = new byte[size];//(byte[]) arac.createArray(byte.class, size);
0061: }
0062: this .size = size;
0063: }
0064:
0065: ByteBase(byte[] arr, int offset, int size) {
0066: this .array = arr;
0067: this .offset = offset;
0068: this .size = size;
0069: }
0070:
0071: ByteBase(long addr) {
0072: this .addr = addr;
0073: size = -1;
0074: }
0075:
0076: /**
0077: * @see VoidPointer#free()
0078: */
0079: public void free() {
0080: if (addr != 0L) {
0081: macc.free(addr);
0082: addr = 0L;
0083: } else {
0084: unlockNoCopy();
0085: }
0086: }
0087:
0088: /**
0089: * @see VoidPointer#longLockPointer()
0090: */
0091: public long longLockPointer() {
0092: if (addr == 0L) {
0093: if (lock == null) {
0094: lock = arac.lockArrayLong(array);
0095: }
0096: return lock.getAddress() + offset;
0097: }
0098: return addr;
0099: }
0100:
0101: /**
0102: * @see VoidPointer#shortLockPointer()
0103: */
0104: long shortLockPointer() {
0105: if (addr == 0L) {
0106: if (lock == null) {
0107: lock = arac.lockArrayShort(array);
0108: }
0109: return lock.getAddress() + offset;
0110: }
0111: return addr;
0112: }
0113:
0114: void unlock() {
0115: if (addr == 0L && lock != null) {
0116: lock.release();
0117: lock = null;
0118: }
0119: }
0120:
0121: void unlockNoCopy() {
0122: if (addr == 0L && lock != null) {
0123: lock.releaseNoCopy();
0124: lock = null;
0125: }
0126: }
0127:
0128: /**
0129: * @see VoidPointer#isDirect()
0130: */
0131: public boolean isDirect() {
0132: return addr != 0L;
0133: }
0134:
0135: /**
0136: * returns the number of elements in memeory referenced by this pointer.
0137: * Returns -1 if size is unknown.
0138: */
0139: public int size() {
0140: return size;
0141: }
0142:
0143: /**
0144: * Returns the element at the specified position.
0145: * @throws IndexOutOfBoundsException if index is out of range
0146: */
0147: public byte get(int index) {
0148: if (addr == 0) { // throws ArrayIndexOutofBounds
0149: return array[offset + index];
0150: }
0151: checkIndex(index, 1);
0152: return macc.getByte(addr + index);
0153: }
0154:
0155: /**
0156: * This method transfers bytes into the given destination array.
0157: *
0158: * @param dst - The array into which bytes are to be written
0159: * @param from - Initial offset in the destination array.
0160: * Must be non-negative and no larger than dst.length
0161: * @param length - The maximum number of bytes to be written to the given array;
0162: * must be non-negative and no larger than dst.length - from
0163: *
0164: * @throws IndexOutOfBoundsException if from < 0 || from > dst.length
0165: * @throws IndexOutOfBoundsException if length < 0 || length > dst.length - from
0166: * @throws IndexOutOfBoundsException if length > this.size()
0167: */
0168: public void get(byte[] dst, int from, int length) {
0169: checkArraysBounds(from, dst.length, length, 1);
0170: if (addr == 0) {
0171: System.arraycopy(array, this .offset, dst, from, length);
0172: } else {
0173: macc.getByte(addr, dst, from, length);
0174: }
0175: }
0176:
0177: /**
0178: * This method transfers bytes from the given destination array.
0179: *
0180: * @param src - The array from which bytes are to be read
0181: * @param offset - The offset within the array of the first byte to be read;
0182: * must be non-negative and no larger than dst.length
0183: * @param length - The maximum number of bytes to be read from the given array;
0184: * must be non-negative and no larger than array.length - offset
0185: *
0186: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0187: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0188: * @throws IndexOutOfBoundsException if length > this.size()
0189: */
0190: public void set(byte[] src, int offset, int length) {
0191: checkArraysBounds(offset, src.length, length, 1);
0192: if (addr == 0) {
0193: System.arraycopy(src, offset, array, this .offset, length);
0194: } else {
0195: macc.setByte(addr, src, offset, length);
0196: }
0197: }
0198:
0199: /**
0200: * Copies <code>length</code> bytes from src byteBase to this byteBase.
0201: * Offset in destination base is dstOffset. Starting offset in src base
0202: * is always 0;
0203: *
0204: * @param src source byte base
0205: * @param dstOffset destination
0206: * @param length
0207: */
0208: void copy(ByteBase src, int dstOffset, int length) {
0209: if (src.size != -1 && src.size < length) {
0210: // awt.30=wrong number of elements to copy: {0}, size: {1}
0211: throw new IndexOutOfBoundsException(Messages.getString(
0212: "awt.30", length, src.size)); //$NON-NLS-1$
0213: }
0214: if (size != -1 && size - dstOffset < length) {
0215: // awt.31=no room to copy: {0}, size: {1}
0216: throw new IndexOutOfBoundsException(Messages.getString(
0217: "awt.31", length, src.size)); //$NON-NLS-1$
0218: }
0219:
0220: byte[] tmp = new byte[length];
0221: src.get(tmp, 0, length);
0222: if (addr == 0) {
0223: System.arraycopy(tmp, 0, array, this .offset + dstOffset,
0224: length);
0225: } else {
0226: macc.setByte(addr + dstOffset, tmp, 0, length);
0227: }
0228: }
0229:
0230: /**
0231: * Sets the element at the specified position.
0232: *
0233: * @throws IndexOutOfBoundsException if index is out of range
0234: */
0235: public void set(int index, byte value) {
0236: if (addr == 0) {
0237: array[offset + index] = value;
0238: } else {
0239: checkIndex(index, 1);
0240: macc.setByte(addr + index, value);
0241: }
0242: }
0243:
0244: /**
0245: * Reads two bytes at the given index, composing them into a char value
0246: * according.
0247: *
0248: * @param index - The index from which the bytes will be read
0249: * @return The char value at the given index
0250: *
0251: * @throws IndexOutOfBoundsException if index is out of range
0252: */
0253: public char getChar(int index) {
0254: if (addr == 0) {
0255: return getCharFromArray(index);
0256: }
0257: checkIndex(index, 2);
0258: return macc.getChar(addr + index);
0259: }
0260:
0261: /**
0262: * Writes two bytes to the given index, decomposing them from a char value
0263: * according
0264: * @param index - The index from which the bytes will be read
0265: * @param value - char value
0266: *
0267: * @throws IndexOutOfBoundsException if index is out of range
0268: */
0269: public void setChar(int index, char value) {
0270: if (addr == 0) {
0271: setCharInArray(index, value);
0272: } else {
0273: checkIndex(index, 2);
0274: macc.setChar(addr + index, value);
0275: }
0276: }
0277:
0278: /**
0279: * This method transfers chars into the given destination array.
0280: *
0281: * @param dst - The array into which chars are to be written
0282: * @param offset - The offset within the array of the first element to be written;
0283: * must be non-negative and no larger than dst.length
0284: * @param length - The maximum number of elements to be written to the given array;
0285: * must be non-negative and no larger than dst.length - offset
0286: *
0287: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0288: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0289: * @throws IndexOutOfBoundsException if length > this.size()
0290: */
0291: public void getChar(char[] dst, int offset, int length) {
0292: checkArraysBounds(offset, dst.length, length, 2);
0293: if (addr == 0) {
0294: for (int i = 0, j = offset; i < length; i++, j++) {
0295: dst[j] = getCharFromArray(i * 2);
0296: }
0297: } else {
0298: macc.getChar(addr, dst, offset, length);
0299: }
0300: }
0301:
0302: /**
0303: * This method transfers chars from the given destination array.
0304: *
0305: * @param src - The array from which chars are to be read
0306: * @param offset - The offset within the array of the first element to be read;
0307: * must be non-negative and no larger than dst.length
0308: * @param length - The maximum number of elements to be read from the given array;
0309: * must be non-negative and no larger than dst.length - offset
0310: *
0311: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0312: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0313: * @throws IndexOutOfBoundsException if length > this.size()
0314: */
0315: public void setChar(char[] src, int offset, int length) {
0316: checkArraysBounds(offset, src.length, length, 2);
0317: if (addr == 0) {
0318: for (int i = 0, j = offset; i < length; i++, j++) {
0319: setCharInArray(i * 2, src[j]);
0320: }
0321: } else {
0322: macc.setChar(addr, src, offset, length);
0323: }
0324: }
0325:
0326: /**
0327: * Reads two bytes at the given index, composing them into a short value
0328: * according
0329: * @param index - The index to which the bytes will be write
0330: * @return The short value at the given index
0331: *
0332: * @throws IndexOutOfBoundsException if index is out of range
0333: */
0334: public short getInt16(int index) {
0335: if (addr == 0) {
0336: return getInt16FromArray(index);
0337: }
0338: checkIndex(index, 2);
0339: return macc.getShort(addr + index);
0340: }
0341:
0342: /**
0343: * Writes two bytes to the given index, decomposing them from a short value
0344: * according
0345: * @param index - The index from which the bytes will be write
0346: * @param value - short value
0347: *
0348: * @throws IndexOutOfBoundsException if index is out of range
0349: */
0350: public void setInt16(int index, short value) {
0351: if (addr == 0) {
0352: setInt16InArray(index, value);
0353: } else {
0354: checkIndex(index, 2);
0355: macc.setShort(addr + index, value);
0356: }
0357: }
0358:
0359: /**
0360: * This method transfers short values into the given destination array.
0361: *
0362: * @param dst - The array into which values are to be written
0363: * @param offset - The offset within the array of the first element to be written;
0364: * must be non-negative and no larger than dst.length
0365: * @param length - The maximum number of elements to be written to the given array;
0366: * must be non-negative and no larger than dst.length - offset
0367: *
0368: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0369: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0370: * @throws IndexOutOfBoundsException if length > this.size()
0371: */
0372: public void getInt16(short[] dst, int offset, int length) {
0373: checkArraysBounds(offset, dst.length, length, 2);
0374: if (addr == 0) {
0375: for (int i = 0, j = offset; i < length; i++, j++) {
0376: dst[j] = getInt16FromArray(i * 2);
0377: }
0378: } else {
0379: macc.getShort(addr, dst, offset, length);
0380: }
0381: }
0382:
0383: /**
0384: * This method transfers short values from the given destination array.
0385: *
0386: * @param src - The array from which values are to be read
0387: * @param offset - The offset within the array of the first element to be read;
0388: * must be non-negative and no larger than dst.length
0389: * @param length - The maximum number of elements to be read from the given array;
0390: * must be non-negative and no larger than dst.length - offset
0391: *
0392: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0393: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0394: * @throws IndexOutOfBoundsException if length > this.size()
0395: */
0396: public void setInt16(short[] src, int offset, int length) {
0397: checkArraysBounds(offset, src.length, length, 2);
0398: if (addr == 0) {
0399: for (int i = 0, j = offset; i < length; i++, j++) {
0400: setInt16InArray(i * 2, src[j]);
0401: }
0402: } else {
0403: macc.setShort(addr, src, offset, length);
0404: }
0405: }
0406:
0407: /**
0408: * Reads four bytes at the given index, composing them into a float value
0409: * according
0410: * @param index - The index from which the bytes will be read
0411: * @return The float value at the given index
0412: *
0413: * @throws IndexOutOfBoundsException if index is out of range
0414: */
0415: public float getFloat(int index) {
0416: if (addr == 0) {
0417: return Float.intBitsToFloat(getInt32FromArray(index));
0418: }
0419: checkIndex(index, 4);
0420: return macc.getFloat(addr + index);
0421: }
0422:
0423: /**
0424: * Writes four bytes to the given index, decomposing them from a float value
0425: * according
0426: * @param index - The index from which the bytes will be write
0427: * @param value - float value
0428: *
0429: * @throws IndexOutOfBoundsException if index is out of range
0430: */
0431: public void setFloat(int index, float value) {
0432: if (addr == 0) {
0433: setInt32(index, Float.floatToIntBits(value));
0434: } else {
0435: checkIndex(index, 4);
0436: macc.setFloat(addr + index, value);
0437: }
0438: }
0439:
0440: /**
0441: * Reads four bytes at the given index, composing them into a double value
0442: * according
0443: * @param index - The index from which the bytes will be read
0444: * @return The double value at the given index
0445: *
0446: * @throws IndexOutOfBoundsException if index is out of range
0447: */
0448: public double getDouble(int index) {
0449: if (addr == 0) {
0450: return Double.longBitsToDouble(getInt64FromArray(index));
0451: }
0452: checkIndex(index, 8);
0453: return macc.getDouble(addr + index);
0454: }
0455:
0456: /**
0457: * Writes four bytes to the given index, decomposing them from a double value
0458: * according
0459: * @param index - The index from which the bytes will be write
0460: * @param value - double value
0461: *
0462: * @throws IndexOutOfBoundsException if index is out of range
0463: */
0464: public void setDouble(int index, double value) {
0465: if (addr == 0) {
0466: setInt64InArray(index, Double.doubleToLongBits(value));
0467: } else {
0468: checkIndex(index, 8);
0469: macc.setDouble(addr + index, value);
0470: }
0471: }
0472:
0473: /**
0474: * This method transfers float values into the given destination array.
0475: *
0476: * @param dst - The array into which values are to be written
0477: * @param offset - The offset within the array of the first element to be written;
0478: * must be non-negative and no larger than dst.length
0479: * @param length - The maximum number of elements to be written to the given array;
0480: * must be non-negative and no larger than dst.length - offset
0481: *
0482: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0483: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0484: * @throws IndexOutOfBoundsException if length > this.size()
0485: */
0486: public void getFloat(float[] dst, int offset, int length) {
0487: checkArraysBounds(offset, dst.length, length, 4);
0488: if (addr == 0) {
0489: for (int i = 0, j = offset; i < length; i++, j++) {
0490: dst[j] = Float.intBitsToFloat(getInt32FromArray(i * 4));
0491: }
0492: } else {
0493: macc.getFloat(addr, dst, offset, length);
0494: }
0495: }
0496:
0497: /**
0498: * This method transfers float values from the given destination array.
0499: *
0500: * @param src - The array from which values are to be read
0501: * @param offset - The offset within the array of the first element to be read;
0502: * must be non-negative and no larger than dst.length
0503: * @param length - The maximum number of elements to be read from the given array;
0504: * must be non-negative and no larger than dst.length - offset
0505: *
0506: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0507: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0508: * @throws IndexOutOfBoundsException if length > this.size()
0509: */
0510: public void setFloat(float[] src, int offset, int length) {
0511: checkArraysBounds(offset, src.length, length, 4);
0512: if (addr == 0) {
0513: for (int i = 0, j = offset; i < length; i++, j++) {
0514: setInt32InArray(i * 4, Float.floatToIntBits(src[j]));
0515: }
0516: } else {
0517: macc.setFloat(addr, src, offset, length);
0518: }
0519: }
0520:
0521: /**
0522: * This method transfers double values into the given destination array.
0523: *
0524: * @param dst - The array into which values are to be written
0525: * @param offset - The offset within the array of the first element to be written;
0526: * must be non-negative and no larger than dst.length
0527: * @param length - The maximum number of elements to be written to the given array;
0528: * must be non-negative and no larger than dst.length - offset
0529: *
0530: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0531: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0532: * @throws IndexOutOfBoundsException if length > this.size()
0533: */
0534: public void getDouble(double[] dst, int offset, int length) {
0535: checkArraysBounds(offset, dst.length, length, 8);
0536: if (addr == 0) {
0537: for (int i = 0, j = offset; i < length; i++, j++) {
0538: dst[j] = Double
0539: .longBitsToDouble(getInt64FromArray(i * 8));
0540: }
0541: } else {
0542: macc.getDouble(addr, dst, offset, length);
0543: }
0544: }
0545:
0546: /**
0547: * This method transfers double values from the given destination array.
0548: *
0549: * @param src - The array from which values are to be read
0550: * @param offset - The offset within the array of the first element to be read;
0551: * must be non-negative and no larger than dst.length
0552: * @param length - The maximum number of elements to be read from the given array;
0553: * must be non-negative and no larger than dst.length - offset
0554: *
0555: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0556: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0557: * @throws IndexOutOfBoundsException if length > this.size()
0558: */
0559: public void setDouble(double[] src, int offset, int length) {
0560: checkArraysBounds(offset, src.length, length, 8);
0561: if (addr == 0) {
0562: for (int i = 0, j = offset; i < length; i++, j++) {
0563: setInt64InArray(i * 8, Double.doubleToLongBits(src[j]));
0564: }
0565: } else {
0566: macc.setDouble(addr, src, offset, length);
0567: }
0568: }
0569:
0570: /**
0571: * Reads four bytes at the given index, composing them into a int value
0572: * according
0573: * @param index - The index from which the bytes will be read
0574: * @return The int value at the given index
0575: *
0576: * @throws IndexOutOfBoundsException if index is out of range
0577: */
0578: public int getInt32(int index) {
0579: if (addr == 0) {
0580: return getInt32FromArray(index);
0581: }
0582: checkIndex(index, 4);
0583: return macc.getInt(addr + index);
0584: }
0585:
0586: /**
0587: * Writes four bytes to the given index, decomposing them from a int value
0588: * according
0589: * @param index - The index from which the bytes will be write
0590: * @param value - int value
0591: *
0592: * @throws IndexOutOfBoundsException if index is out of range
0593: */
0594: public void setInt32(int index, int value) {
0595: if (addr == 0) {
0596: setInt32InArray(index, value);
0597: } else {
0598: checkIndex(index, 4);
0599: macc.setInt(addr + index, value);
0600: }
0601: }
0602:
0603: /**
0604: * This method transfers int values into the given destination array.
0605: *
0606: * @param dst - The array into which values are to be written
0607: * @param offset - The offset within the array of the first element to be written;
0608: * must be non-negative and no larger than dst.length
0609: * @param length - The maximum number of elements to be written to the given array;
0610: * must be non-negative and no larger than dst.length - offset
0611: *
0612: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0613: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0614: * @throws IndexOutOfBoundsException if length > this.size()
0615: */
0616: public void getInt32(int[] dst, int offset, int length) {
0617: checkArraysBounds(offset, dst.length, length, 4);
0618: if (addr == 0) {
0619: for (int i = 0, j = offset; i < length; i++, j++) {
0620: dst[j] = getInt32FromArray(i * 4);
0621: }
0622: } else {
0623: macc.getInt(addr, dst, offset, length);
0624: }
0625: }
0626:
0627: /**
0628: * This method transfers int values from the given destination array.
0629: *
0630: * @param src - The array from which values are to be read
0631: * @param offset - The offset within the array of the first element to be read;
0632: * must be non-negative and no larger than dst.length
0633: * @param length - The maximum number of elements to be read from the given array;
0634: * must be non-negative and no larger than dst.length - offset
0635: *
0636: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0637: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0638: * @throws IndexOutOfBoundsException if length > this.size()
0639: */
0640: public void setInt32(int[] src, int offset, int length) {
0641: checkArraysBounds(offset, src.length, length, 4);
0642: if (addr == 0) {
0643: for (int i = 0, j = offset; i < length; i++, j++) {
0644: setInt32InArray(i * 4, src[j]);
0645: }
0646: } else {
0647: macc.setInt(addr, src, offset, length);
0648: }
0649: }
0650:
0651: /**
0652: * Reads 8 bytes at the given index, composing them into a long value
0653: * according
0654: * @param index - The index from which the bytes will be read
0655: * @return The long value at the given index
0656: *
0657: * @throws IndexOutOfBoundsException if index is out of range
0658: */
0659: public long getInt64(int index) {
0660: if (addr == 0) {
0661: return getInt64FromArray(index);
0662: }
0663: checkIndex(index, 8);
0664: return macc.getLong(addr + index);
0665: }
0666:
0667: /**
0668: * Writes 8 bytes to the given index, decomposing them from a long value
0669: * according
0670: * @param index - The index from which the bytes will be write
0671: * @param value - long value
0672: *
0673: * @throws IndexOutOfBoundsException if index is out of range
0674: */
0675: public void setInt64(int index, long value) {
0676: if (addr == 0) {
0677: setInt64InArray(index, value);
0678: } else {
0679: checkIndex(index, 8);
0680: macc.setLong(addr + index, value);
0681: }
0682: }
0683:
0684: /**
0685: * This method transfers long values into the given destination array.
0686: *
0687: * @param dst - The array into which values are to be written
0688: * @param offset - The offset within the array of the first element to be written;
0689: * must be non-negative and no larger than dst.length
0690: * @param length - The maximum number of elements to be written to the given array;
0691: * must be non-negative and no larger than dst.length - offset
0692: *
0693: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0694: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0695: * @throws IndexOutOfBoundsException if length > this.size()
0696: */
0697: public void getInt64(long[] dst, int offset, int length) {
0698: checkArraysBounds(offset, dst.length, length, 8);
0699: if (addr == 0) {
0700: for (int i = 0, j = offset; i < length; i++, j++) {
0701: dst[j] = getInt64FromArray(i * 8);
0702: }
0703: } else {
0704: macc.getLong(addr, dst, offset, length);
0705: }
0706: }
0707:
0708: /**
0709: * This method transfers long values from the given destination array.
0710: *
0711: * @param src - The array from which values are to be read
0712: * @param offset - The offset within the array of the first element to be read;
0713: * must be non-negative and no larger than dst.length
0714: * @param length - The maximum number of elements to be read from the given array;
0715: * must be non-negative and no larger than dst.length - offset
0716: *
0717: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0718: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0719: * @throws IndexOutOfBoundsException if length > this.size()
0720: */
0721: public void setInt64(long[] src, int offset, int length) {
0722: checkArraysBounds(offset, src.length, length, 8);
0723: if (addr == 0) {
0724: for (int i = 0, j = offset; i < length; i++, j++) {
0725: setInt64InArray(i * 8, src[j]);
0726: }
0727: } else {
0728: macc.setLong(addr, src, offset, length);
0729: }
0730: }
0731:
0732: /**
0733: * Reads 4/8 bytes (depending of C long type size on current platform) at
0734: * the given index, composing them into a long value according
0735: * @param index - The index from which the bytes will be read
0736: * @return The long value at the given index
0737: *
0738: * @throws IndexOutOfBoundsException if index is out of range
0739: */
0740: public long getCLong(int index) {
0741: if (addr == 0) {
0742: return CLONG_SIZE == 8 ? getInt64FromArray(index)
0743: : getInt32FromArray(index) & 0x00000000ffffffffL;
0744: }
0745: // native
0746: checkIndex(index, CLONG_SIZE == 8 ? 8 : 4);
0747: return CLONG_SIZE == 8 ? macc.getLong(addr + index) : macc
0748: .getInt(addr + index) & 0x00000000ffffffffL;
0749: }
0750:
0751: /**
0752: * Writes 4/8 bytes (depending of C long type size on current platform) to
0753: * the given index, decomposing them from a long value according
0754: * @param index - The index from which the bytes will be write
0755: * @param value - long value
0756: *
0757: * @throws IndexOutOfBoundsException if index is out of range
0758: */
0759: public void setCLong(int index, long value) {
0760: if (addr == 0) {
0761: if (CLONG_SIZE == 8) {
0762: setInt64InArray(index, value);
0763: } else {
0764: setInt32InArray(index, (int) value);
0765: }
0766: } else {
0767: checkIndex(index, CLONG_SIZE == 8 ? 8 : 4);
0768: if (CLONG_SIZE == 8) { // 64-bit
0769: macc.setLong(addr + index, value);
0770: } else {
0771: macc.setInt(addr + index, (int) value);
0772: }
0773: }
0774: }
0775:
0776: /**
0777: * This method transfers C long values into the given destination array.
0778: *
0779: * @param dst - The array into which values are to be written
0780: * @param offset - The offset within the array of the first element to be written;
0781: * must be non-negative and no larger than dst.length
0782: * @param length - The maximum number of elements to be written to the given array;
0783: * must be non-negative and no larger than dst.length - offset
0784: *
0785: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0786: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0787: * @throws IndexOutOfBoundsException if length > this.size()
0788: */
0789: public void getCLong(long[] dst, int offset, int length) {
0790: checkArraysBounds(offset, dst.length, length,
0791: CLONG_SIZE == 8 ? 8 : 4);
0792: for (int i = 0, j = offset; i < length; i++, j++) {
0793: dst[j] = getCLong(i * CLONG_SIZE);
0794: }
0795: }
0796:
0797: /**
0798: * This method transfers C long values from the given destination array.
0799: *
0800: * @param src - The array from which values are to be read
0801: * @param offset - The offset within the array of the first element to be read;
0802: * must be non-negative and no larger than dst.length
0803: * @param length - The maximum number of elements to be read from the given array;
0804: * must be non-negative and no larger than dst.length - offset
0805: *
0806: * @throws IndexOutOfBoundsException if from < 0 || from > src.length
0807: * @throws IndexOutOfBoundsException if length < 0 || length > src.length - from
0808: * @throws IndexOutOfBoundsException if length > this.size()
0809: */
0810: public void setCLong(long[] src, int offset, int length) {
0811: checkArraysBounds(offset, src.length, length,
0812: CLONG_SIZE == 8 ? 8 : 4);
0813: for (int i = 0, j = offset; i < length; i++, j++) {
0814: setCLong(i * CLONG_SIZE, src[j]);
0815: }
0816: }
0817:
0818: /**
0819: * Returns native pointer value from the specified index.
0820: *
0821: * @throws IndexOutOfBoundsException if index is out of range
0822: */
0823: public long getAddress(int index) {
0824: if (addr != 0) {
0825: checkIndex(index, POINTER_SIZE == 8 ? 8 : 4);
0826: return macc.getPointer(addr + index);
0827: }
0828: return POINTER_SIZE == 8 ? getInt64FromArray(index)
0829: : getInt32FromArray(index);
0830: }
0831:
0832: /**
0833: * Sets the native address to the specified index.
0834: *
0835: * @throws IndexOutOfBoundsException if index is out of range
0836: */
0837: public void setAddress(int index, long value) {
0838: if (addr != 0) {
0839: checkIndex(index, POINTER_SIZE == 8 ? 8 : 4);
0840: macc.setPointer(addr + index, value);
0841: } else {
0842: if (POINTER_SIZE == 8) {
0843: setInt64InArray(index, value);
0844: } else {
0845: setInt32InArray(index, (int) value);
0846: }
0847: }
0848: }
0849:
0850: // Int8Pointer getPointer(int index) {
0851: // return NativeBridge.createInt8Pointer(getAddress(index));
0852: // }
0853:
0854: /**
0855: * @param index
0856: * @param p - pointer to set; should be unlocked in a caller method after usage;
0857: */
0858: public void setPointer(int index, VoidPointer p) {
0859: setAddress(index, p.lock());
0860: }
0861:
0862: /**
0863: * Convert String to 0 terminated UTF16 (Unicode) string.
0864: * And set it to the internal buffer.
0865: *
0866: * TODO: 1. if size is unknown
0867: * TODO: 2. add convinient method getChars(addr, size, str) to StringAccessor to avoid substringing in it
0868: */
0869: public void setString(String str) {
0870: if (str.length() * 2 > size - 2) { // 2 times lager than str.length and 2 bytes for termination zeroes
0871: // awt.32=String: '{0}' does not fit
0872: throw new IndexOutOfBoundsException(Messages.getString(
0873: "awt.32", str)); //$NON-NLS-1$
0874: }
0875: if (addr == 0) {
0876: setStringInArray(str);
0877: } else {
0878: stac.getChars(addr, size, str, 0, str.length());
0879: }
0880: }
0881:
0882: /**
0883: * Creates String from 0 terminated UTF16 (Unicode) string.
0884: * convert UTF16 bytes to String
0885: */
0886: public String getString() {
0887: return addr == 0 ? getStringFromArray((size) >> 1) : stac
0888: .createString(addr);
0889: }
0890:
0891: /**
0892: * Creates String from 0 terminated UTF16 (Unicode) string of max
0893: * strlen length in bytes.
0894: */
0895: public String getString(long strlen) {
0896: if (addr == 0) {
0897: int max = (size) >> 1;
0898: if (max > strlen) {
0899: max = (int) strlen;
0900: }
0901: return getStringFromArray(max);
0902: }
0903: return stac.createString(addr, strlen);
0904: }
0905:
0906: /**
0907: * Creates String from 0 terminated modified UTF8 string.
0908: */
0909: public String getStringUTF() {
0910: long locked = shortLockPointer();
0911: String str = stac.createStringUTF(locked);
0912: unlock();
0913: return str;
0914: }
0915:
0916: /**
0917: * Creates String from 0 terminated modified UTF8 native string of max
0918: * strlen length in bytes.
0919: *
0920: * TODO bounds check for Modified UTF-8 strings?
0921: */
0922: public String getStringUTF(long strlen) {
0923: long locked = shortLockPointer();
0924: String str = stac.createStringUTF(locked, strlen);
0925: unlock();
0926: return str;
0927: }
0928:
0929: /**
0930: * Convert String to 0 terminated UTF8 (Unicode) string.
0931: * And set it to buffer
0932: *
0933: * TODO add convinient method getUTFChars(addr, size, str) to StringAccessor
0934: */
0935: public void setStringUTF(String str) {
0936: long locked = shortLockPointer();
0937: stac.getUTFChars(locked, size, str, 0, str.length());
0938: unlock();
0939: }
0940:
0941: public void fill(byte value, int size) {
0942: if (addr == 0) {
0943: Arrays.fill(array, offset, size + offset, value);
0944: } else {
0945: macc.memset(addr, value, size);
0946: }
0947: }
0948:
0949: //-------------------------------------------------------------------------------------
0950: //-------------------------------------------------------------------------------------
0951: //-------------------------------------------------------------------------------------
0952: /**
0953: * Gets char from the internal array reordering bytes according platform byte order.
0954: * It is convinient method to be used in subclasses
0955: */
0956: char getCharFromArray(int index) {
0957: index += offset;
0958: return NATIVE_BYTE_ORDER == JAVA_BYTE_ORDER ? (char) (((array[index++] & 0xff) << 8) + (array[index] & 0xff))
0959: : (char) ((array[index++] & 0xff) + ((array[index] & 0xff) << 8));
0960: }
0961:
0962: /**
0963: * Sets char in the internal array reordering bytes according platform byte order.
0964: * It is convinient method to be used in subclasses
0965: */
0966: void setCharInArray(int index, char value) {
0967: index += offset;
0968: if (NATIVE_BYTE_ORDER == JAVA_BYTE_ORDER) {
0969: array[index++] = (byte) (value >> 8);
0970: array[index] = (byte) value;
0971: } else {
0972: array[index++] = (byte) value;
0973: array[index] = (byte) (value >> 8);
0974: }
0975: }
0976:
0977: short getInt16FromArray(int index) {
0978: index += offset;
0979: return NATIVE_BYTE_ORDER == JAVA_BYTE_ORDER ? (short) (((array[index++] & 0xff) << 8) + (array[index] & 0xff))
0980: : (short) ((array[index++] & 0xff) + ((array[index] & 0xff) << 8));
0981: }
0982:
0983: void setInt16InArray(int index, short value) {
0984: index += offset;
0985: if (NATIVE_BYTE_ORDER == JAVA_BYTE_ORDER) {
0986: array[index++] = (byte) (value >> 8);
0987: array[index] = (byte) value;
0988: } else {
0989: array[index++] = (byte) value;
0990: array[index] = (byte) (value >> 8);
0991: }
0992: }
0993:
0994: int getInt32FromArray(int index) {
0995: index += offset;
0996: if (NATIVE_BYTE_ORDER == JAVA_BYTE_ORDER) {
0997: return (array[index++] & 0xff) << 24
0998: + ((array[index++] & 0xff) << 16)
0999: + ((array[index++] & 0xff) << 8) + array[index];
1000: }
1001: return (array[index++] & 0xff) + ((array[index++] & 0xff) << 8)
1002: + ((array[index++] & 0xff) << 16)
1003: + (array[index] << 24);
1004: }
1005:
1006: void setInt32InArray(int index, int value) {
1007: index += offset;
1008:
1009: if (NATIVE_BYTE_ORDER == JAVA_BYTE_ORDER) {
1010: array[index++] = (byte) (value >> 24);
1011: array[index++] = (byte) (value >> 16);
1012: array[index++] = (byte) (value >> 8);
1013: array[index] = (byte) value;
1014: } else {
1015: array[index++] = (byte) value;
1016: array[index++] = (byte) (value >> 8);
1017: array[index++] = (byte) (value >> 16);
1018: array[index] = (byte) (value >> 24);
1019: }
1020: }
1021:
1022: long getInt64FromArray(int index) {
1023: index += offset;
1024: if (NATIVE_BYTE_ORDER == JAVA_BYTE_ORDER) {
1025: return (array[index++] & 0xffl) << 56 + (array[index++] & 0xffl) << 48 + (array[index++] & 0xffl) << 40 + (array[index++] & 0xffl) << 32 + (array[index++] & 0xffl) << 24
1026: + ((array[index++] & 0xffl) << 16)
1027: + ((array[index++] & 0xffl) << 8) + array[index];
1028: }
1029: return (array[index++] & 0xffl)
1030: + ((array[index++] & 0xffl) << 8)
1031: + ((array[index++] & 0xffl) << 16)
1032: + ((array[index++] & 0xffl) << 24)
1033: + ((array[index++] & 0xffl) << 32)
1034: + ((array[index++] & 0xffl) << 40)
1035: + ((array[index++] & 0xffl) << 48)
1036: + ((array[index] & 0xffl) << 56);
1037: }
1038:
1039: void setInt64InArray(int index, long value) {
1040: index += offset;
1041:
1042: if (NATIVE_BYTE_ORDER == JAVA_BYTE_ORDER) {
1043: array[index++] = (byte) (value >> 56);
1044: array[index++] = (byte) (value >> 48);
1045: array[index++] = (byte) (value >> 40);
1046: array[index++] = (byte) (value >> 32);
1047: array[index++] = (byte) (value >> 24);
1048: array[index++] = (byte) (value >> 16);
1049: array[index++] = (byte) (value >> 8);
1050: array[index] = (byte) value;
1051: } else {
1052: array[index++] = (byte) value;
1053: array[index++] = (byte) (value >> 8);
1054: array[index++] = (byte) (value >> 16);
1055: array[index++] = (byte) (value >> 24);
1056: array[index++] = (byte) (value >> 32);
1057: array[index++] = (byte) (value >> 40);
1058: array[index++] = (byte) (value >> 48);
1059: array[index] = (byte) (value >> 56);
1060: }
1061: }
1062:
1063: String getStringFromArray(int length) {
1064: char[] carr = new char[length];
1065: int i = 0;
1066: int index = offset;
1067: while (i < length) {
1068: char ch = (char) ((array[index++] & 0xff) + ((array[index++] & 0xff) << 8));
1069: if (ch == 0) {
1070: break;
1071: }
1072: carr[i++] = ch;
1073: }
1074: return new String(carr, 0, i);
1075: }
1076:
1077: void setStringInArray(String str) {
1078: char[] chars = str.toCharArray();
1079: int index = offset;
1080: for (char element : chars) {
1081: array[index++] = (byte) element;
1082: array[index++] = (byte) (element >> 8);
1083: }
1084: //-- 2 null value are terminated the string
1085: array[index++] = 0;
1086: array[index] = 0;
1087: }
1088:
1089: final void checkIndex(int index, int numBytes)
1090: throws IndexOutOfBoundsException {
1091: if (size == -1) { // was created using "long addr"
1092: return;
1093: }
1094: if (index < 0 || index + numBytes - 1 > size) {
1095: // awt.33=index is out of range
1096: throw new IndexOutOfBoundsException(Messages
1097: .getString("awt.33")); //$NON-NLS-1$
1098: }
1099: }
1100:
1101: final void checkArraysBounds(int toIdx, int srcDstLength,
1102: int copyLength, int bytesInData) {
1103: if (size == -1) {
1104: return;
1105: }
1106: if (toIdx < 0 || toIdx > srcDstLength) {
1107: // awt.34=Initial offset in the destination array is wrong: {0}
1108: throw new IndexOutOfBoundsException(Messages.getString(
1109: "awt.34", toIdx)); //$NON-NLS-1$
1110: }
1111: if (copyLength < 0 || copyLength > srcDstLength - toIdx
1112: || copyLength * bytesInData > size) {
1113: // awt.35=Wrong number of elements to copy: {0}
1114: throw new IndexOutOfBoundsException(Messages.getString(
1115: "awt.35", copyLength)); //$NON-NLS-1$
1116: }
1117: }
1118:
1119: ByteBase getBytesBaseElementPointer(int index, int numBytes) {
1120: checkIndex(index, numBytes);
1121: ByteBase sub;
1122: if (addr == 0) {
1123: sub = new ByteBase(array, index + offset, this .size - index);
1124: } else {
1125: sub = new ByteBase(this .addr + index);
1126: if (this .size > 0) {
1127: sub.size = this .size - index;
1128: }
1129: }
1130: return sub;
1131: }
1132:
1133: public Int8Pointer getElementPointer(int index) {
1134: return new Int8Pointer(getBytesBaseElementPointer(index, 1));
1135: }
1136: }
|