| /******************************************************************************* |
| * Copyright (c) 2004, 2007 Boeing. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Boeing - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.osee.ote.message.data; |
| |
| import java.nio.ByteBuffer; |
| import java.util.logging.Level; |
| import org.eclipse.osee.ote.message.MessageSystemException; |
| |
| /** |
| * @author Andrew M. Finkbeiner |
| */ |
| public class MemoryResourceByteBuffer { |
| private byte _data[]; |
| private final int _offset; |
| public boolean _dataHasChanged; |
| |
| private final ByteBuffer buffer; |
| |
| public MemoryResourceByteBuffer(byte data[], int offset, int length) { |
| _data = data; |
| _offset = offset; |
| _dataHasChanged = false; |
| buffer = ByteBuffer.wrap(_data); |
| } |
| |
| public void setData(byte data[]) { |
| _data = data; |
| _dataHasChanged = true; |
| } |
| |
| public byte[] getData() { |
| return _data; |
| } |
| |
| public long getRawDataLong(int offset, int msb, int lsb) { |
| |
| if (lsb < 8) { |
| return getByte(offset, msb, lsb); |
| } else if (lsb < 16) { |
| return getShort(offset, msb, lsb); |
| } else if (lsb < 32) { |
| offset += _offset; |
| if (msb == 0 && lsb == 31) { |
| return getIntFromOffset(offset); |
| } else { |
| int i = getIntFromOffset(offset); |
| int mask = (1 << 32 - msb) - 1; |
| mask = mask & 0x80000000 >>> lsb; |
| return (i & mask) >> 31 - lsb; |
| } |
| } else if (lsb == 63) { |
| return getLong(offset, msb, lsb); |
| } else { |
| throw new IllegalArgumentException("lsb greater than 63"); |
| } |
| } |
| |
| public int getRawDataInt(int offset, int msb, int lsb) { |
| |
| if (lsb < 8) { |
| return getByte(offset, msb, lsb); |
| } else if (lsb < 16) { |
| return getShort(offset, msb, lsb); |
| } else if (lsb < 32) { |
| offset += _offset; |
| if (msb == 0 && lsb == 31) { |
| return getIntFromOffset(offset); |
| } else { |
| int i = getIntFromOffset(offset); |
| int mask = (1 << 32 - msb) - 1; |
| mask = mask & 0x80000000 >>> lsb; |
| return (i & mask) >> 31 - lsb; |
| } |
| } else { |
| throw new IllegalArgumentException("lsb greater than 31"); |
| } |
| } |
| |
| public void setRawData(long v, int offset, int msb, int lsb) { |
| if (lsb < 8) { |
| setByte((int) v, offset, msb, lsb); |
| } else if (lsb < 16) { |
| setShort((int) v, offset, msb, lsb); |
| } else if (lsb < 32) { |
| setInt((int) v, offset, msb, lsb); |
| } else { |
| setLong(v, offset, msb, lsb); |
| } |
| } |
| |
| public byte getByte(int offset, int msb, int lsb) { |
| offset += _offset; |
| if (msb == 0 && lsb == 7) { |
| return getByteFromOffset(offset); |
| } else { |
| int b = getByteFromOffset(offset); |
| int mask = (1 << 8 - msb) - 1; |
| mask = mask & 0xFFFFFF80 >>> lsb; |
| return (byte) ((b & mask) >> 7 - lsb); |
| } |
| } |
| |
| private byte getByteFromOffset(int offset) { |
| return _data[offset]; |
| } |
| |
| public short getShort(int offset, int msb, int lsb) { |
| offset += _offset; |
| if (msb == 0 && lsb == 15) { |
| return getShortFromOffset(offset); |
| } else { |
| int s = getShortFromOffset(offset); |
| int mask = (1 << 16 - msb) - 1; |
| mask = mask & 0xFFFF8000 >>> lsb; |
| return (short) ((s & mask) >> 15 - lsb); |
| } |
| } |
| |
| private short getShortFromOffset(int offset) { |
| int ch1 = _data[offset] & 0xFF; |
| int ch2 = _data[offset + 1] & 0xFF; |
| return (short) ((ch1 << 8) + (ch2 << 0)); |
| } |
| |
| public char getASCIIChar(int offset, int msb, int lsb) { |
| offset += _offset; |
| if (msb == 0 && lsb == 7) { |
| return getASCIICharFromOffset(offset); |
| } else if (msb == 8 && lsb == 15) { |
| return getASCIICharFromOffset(offset + 1); |
| } else if (msb == 16 && lsb == 23) { |
| return getASCIICharFromOffset(offset + 2); |
| } else if (msb == 24 && lsb == 31) { |
| return getASCIICharFromOffset(offset + 3); |
| } else { |
| throw new IllegalArgumentException("not supported"); |
| } |
| } |
| |
| private final char getASCIICharFromOffset(int offset) { |
| return (char) _data[offset]; |
| } |
| |
| public int getInt(int offset, int msb, int lsb) { |
| |
| int nextFourBytes = getIntFromOffset(offset + _offset); |
| |
| int bitsToShift = 32 - msb; |
| int maskLeft = msb == 0 ? -1 : (1 << bitsToShift) - 1;//(int)Math.pow(2, 32 - msb ) -1; |
| |
| int retVal = (nextFourBytes & maskLeft) >>> 31 - lsb; |
| return retVal; |
| |
| // if (lsb < 8) { |
| // return getByte(offset, msb, lsb); |
| // } |
| // else if (lsb < 16) { |
| // return getShort(offset, msb, lsb); |
| // } |
| // else if (lsb < 32) { |
| // offset += _offset; |
| // if (msb == 0 && lsb == 31) { |
| // return getIntFromOffset(offset); |
| // } |
| // else { |
| // int i = getIntFromOffset(offset); |
| // int mask = (1 << (32 - msb)) - 1; |
| // mask = mask & (0x80000000 >>> lsb); |
| // return (i & mask) >> (31 - lsb); |
| // } |
| // } |
| // else { |
| // throw new IllegalArgumentException("lsb greater than 31"); |
| // } |
| } |
| |
| private int getIntFromOffset(int offset) { |
| int ch1 = 0, ch2 = 0, ch3 = 0, ch4 = 0; |
| |
| if (_data.length > offset) { |
| ch1 = _data[offset] & 0xFF; |
| } |
| if (_data.length > offset + 1) { |
| ch2 = _data[offset + 1] & 0xFF; |
| } |
| if (_data.length > offset + 2) { |
| ch3 = _data[offset + 2] & 0xFF; |
| } |
| if (_data.length > offset + 3) { |
| ch4 = _data[offset + 3] & 0xFF; |
| } |
| return (ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0); |
| } |
| |
| public final long getLong(int offset, int msb, int lsb) { |
| offset += _offset; |
| if (msb == 0 && lsb == 63) { |
| return getLongFromOffset(offset); |
| } else { |
| throw new IllegalArgumentException("gettting long with bits not supported"); |
| } |
| } |
| |
| private final long getLongFromOffset(int offset) { |
| long byte1 = 0, byte2 = 0, byte3 = 0, byte4 = 0, byte5 = 0, byte6 = 0, byte7 = 0, byte8 = 0; |
| |
| if (_data.length > offset) { |
| byte1 = _data[offset]; |
| } |
| if (_data.length > offset + 1) { |
| byte2 = _data[offset + 1]; |
| } |
| if (_data.length > offset + 2) { |
| byte3 = _data[offset + 2]; |
| } |
| if (_data.length > offset + 3) { |
| byte4 = _data[offset + 3]; |
| } |
| if (_data.length > offset + 4) { |
| byte5 = _data[offset + 4]; |
| } |
| if (_data.length > offset + 5) { |
| byte6 = _data[offset + 5]; |
| } |
| if (_data.length > offset + 6) { |
| byte7 = _data[offset + 6]; |
| } |
| if (_data.length > offset + 7) { |
| byte8 = _data[offset + 7]; |
| } |
| |
| long retVal = |
| (byte1 << 56) + ((byte2 & 0xFF) << 48) + ((byte3 & 0xFF) << 40) + ((byte4 & 0xFF) << 32) + ((byte5 & 0xFF) << 24) + ((byte6 & 0xFF) << 16) + ((byte7 & 0xFF) << 8) + (byte8 & 0xFF); |
| |
| return retVal; |
| // return (((long) _data[offset] << 56) + ((long) (_data[offset + 1] & 255) << 48) |
| // + ((long) (_data[offset + 2] & 255) << 40) + ((long) (_data[offset + 3] & 255) << 32) |
| // + ((long) (_data[offset + 4] & 255) << 24) + ((_data[offset + 5] & 255) << 16) |
| // + ((_data[offset + 6] & 255) << 8) + ((_data[offset + 7] & 255) << 0)); |
| } |
| |
| public final String getASCIIString(int offset, int length) { |
| offset += _offset; |
| // int size = ((lsb - msb) + 1) / 8; |
| |
| StringBuffer str = new StringBuffer(length); |
| for (int i = 0; i < length; i++) { |
| char ch = getASCIICharFromOffset(offset + i); |
| if (ch != 0) {// NOTE this was done to be compatible with java |
| // Strings that don't null char termination |
| str.append(getASCIICharFromOffset(offset + i)); |
| } |
| } |
| return str.toString(); |
| } |
| |
| public final String getASCIIString(int offset, int msb, int lsb) { |
| offset += _offset; |
| int size = (lsb - msb + 1) / 8; |
| |
| StringBuffer str = new StringBuffer(size); |
| for (int i = 0; i < size; i++) { |
| char ch = getASCIICharFromOffset(offset + i); |
| if (ch != 0) {// NOTE this was done to be compatible with java |
| // Strings that don't null char termination |
| str.append(getASCIICharFromOffset(offset + i)); |
| } |
| } |
| return str.toString(); |
| } |
| |
| public void setBoolean(boolean v, int offset, int msb, int lsb) { |
| int i = v ? 1 : 0; |
| if (lsb < 8) { |
| setByte(i, offset, msb, lsb); |
| } else if (lsb < 16) { |
| setShort(i, offset, msb, lsb); |
| } else if (lsb < 32) { |
| setInt(i, offset, msb, lsb); |
| } else { |
| throw new RuntimeException("Not supported lsb = " + lsb); |
| } |
| } |
| |
| public final void setByte(int v, int offset, int msb, int lsb) { |
| offset += _offset; |
| if (msb == 0 && lsb == 7) { |
| setByteFromOffset(v, offset); |
| } else { |
| if ((v & 1 >>> 7 - (lsb - msb)) != 0) { |
| throw new IllegalArgumentException("Tried to set signal to value that is too large"); |
| } |
| int mask = createMask(msb, lsb, 7); |
| v = v << 7 - lsb; |
| setByteFromOffset(v | getByteFromOffset(offset) & mask, offset); |
| } |
| } |
| |
| public final void setBytesInHeader(int v, int offset, int msb, int lsb) { |
| if (offset > _offset) { |
| throw new IllegalArgumentException("Data beyond header attempting to be set!!!"); |
| } |
| if (msb == 0 && lsb == 7) { |
| setByteFromOffset(v, offset); |
| } else { |
| if ((v & 1 >>> 7 - (lsb - msb)) != 0) { |
| throw new IllegalArgumentException("Tried to set signal to value that is too large"); |
| } |
| int mask = (1 << 7 - lsb) - 1; |
| mask = mask | 0xFFFFFF00 >>> msb; |
| v = v << 7 - lsb; |
| setByteFromOffset(v | getByteFromOffset(offset) & mask, offset); |
| } |
| } |
| |
| private final void setByteFromOffset(int v, int offset) { |
| _data[offset] = (byte) v; |
| _dataHasChanged = true; |
| } |
| |
| private final void setShort(int v, int offset, int msb, int lsb) { |
| offset += _offset; |
| if (msb == 0 && lsb == 15) { |
| setShortFromOffset(v, offset); |
| } else { |
| if ((v & 1 >>> 15 - (lsb - msb)) != 0) { |
| throw new IllegalArgumentException("Tried to set signal to value that is too large"); |
| } |
| int mask = createMask(msb, lsb, 15); |
| |
| // shift the value into the correct position within the whole int |
| v = v << 15 - lsb; |
| // zero out the element we are setting before oring in the new value |
| setShortFromOffset(v | getShortFromOffset(offset) & mask, offset); |
| } |
| } |
| |
| private final void setShortFromOffset(int v, int offset) { |
| _data[offset] = (byte) (v >>> 8 & 0xFF); |
| _data[offset + 1] = (byte) (v >>> 0 & 0xFF); |
| _dataHasChanged = true; |
| } |
| |
| public final void setASCIIChar(char v, int offset, int msb, int lsb) { |
| offset += _offset; |
| if (msb == 0 && lsb == 7) { |
| setASCIICharFromOffset(v, offset); |
| } else if (msb == 8 && lsb == 15) { |
| setASCIICharFromOffset(v, offset + 1); |
| } else if (msb == 16 && lsb == 23) { |
| setASCIICharFromOffset(v, offset + 2); |
| } else if (msb == 24 && lsb == 31) { |
| setASCIICharFromOffset(v, offset + 3); |
| } else { |
| throw new IllegalArgumentException("only 8 bit char supported"); |
| } |
| } |
| |
| private final void setASCIICharFromOffset(char v, int offset) { |
| _data[offset] = (byte) (v & 0xFF); |
| _dataHasChanged = true; |
| } |
| |
| public final void setInt(int v, int offset, int msb, int lsb) { |
| if (lsb < 8) { |
| setByte(v, offset, msb, lsb); |
| } else if (lsb < 16) { |
| setShort(v, offset, msb, lsb); |
| } else { |
| offset += _offset; |
| if (msb == 0 && lsb == 31) { |
| setIntFromOffset(v, offset); |
| } else { |
| if ((v & 1 >>> 31 - (lsb - msb)) != 0) { |
| throw new IllegalArgumentException("Tried to set signal to value that is too large"); |
| } |
| int mask = createMask(msb, lsb, 31); |
| // shift the value into the correct position within the whole int |
| v = v << 31 - lsb; |
| // zero out the element we are setting before oring in the new value |
| setIntFromOffset(v | getIntFromOffset(offset) & mask, offset); |
| } |
| } |
| } |
| |
| private int createMask(int msb, int lsb, int maxBitPosition) { |
| int maximumElementValue = (int) Math.pow(2, lsb - msb + 1) - 1; |
| int maxValueInPosition = maximumElementValue << maxBitPosition - lsb; |
| //the mask is all ones except at the bit positions we are setting |
| int mask = ~maxValueInPosition; |
| return mask; |
| } |
| |
| private final void setIntFromOffset(int v, int offset) { |
| if (_data.length > offset) { |
| _data[offset] = (byte) (v >>> 24 & 0xFF); |
| } |
| if (_data.length > offset + 1) { |
| _data[offset + 1] = (byte) (v >>> 16 & 0xFF); |
| } |
| if (_data.length > offset + 2) { |
| _data[offset + 2] = (byte) (v >>> 8 & 0xFF); |
| } |
| if (_data.length > offset + 3) { |
| _data[offset + 3] = (byte) (v >>> 0 & 0xFF); |
| } |
| _dataHasChanged = true; |
| } |
| |
| public final void setLong(long v, int offset, int msb, int lsb) { |
| offset += _offset; |
| if (msb == 0 && lsb == 63) { |
| setLongFromOffset(v, offset); |
| } else { |
| throw new IllegalArgumentException("not supported"); |
| } |
| } |
| |
| private final void setLongFromOffset(long v, int offset) { |
| if (_data.length > offset) { |
| _data[offset] = (byte) (v >>> 56); |
| } |
| if (_data.length > offset + 1) { |
| _data[offset + 1] = (byte) (v >>> 48); |
| } |
| if (_data.length > offset + 2) { |
| _data[offset + 2] = (byte) (v >>> 40); |
| } |
| if (_data.length > offset + 3) { |
| _data[offset + 3] = (byte) (v >>> 32); |
| } |
| if (_data.length > offset + 4) { |
| _data[offset + 4] = (byte) (v >>> 24); |
| } |
| if (_data.length > offset + 5) { |
| _data[offset + 5] = (byte) (v >>> 16); |
| } |
| if (_data.length > offset + 6) { |
| _data[offset + 6] = (byte) (v >>> 8); |
| } |
| if (_data.length > offset + 7) { |
| _data[offset + 7] = (byte) (v >>> 0); |
| } |
| _dataHasChanged = true; |
| } |
| |
| public final void setASCIIString(String s, int offset, int msb, int lsb) { |
| offset += _offset; |
| int size = (lsb - msb + 1) / 8; |
| |
| int len = s.length(); |
| for (int i = 0; i < len && i < size; i++) { |
| setASCIICharFromOffset(s.charAt(i), offset + i); |
| } |
| } |
| |
| public final void setASCIIString(String s, int offset) { |
| offset += _offset; |
| int len = s.length(); |
| for (int i = 0; i < len; i++) { |
| setASCIICharFromOffset(s.charAt(i), offset + i); |
| } |
| } |
| |
| public boolean getBoolean(int offset, int msb, int lsb) { |
| int i; |
| if (lsb < 8) { |
| i = getByte(offset, msb, lsb); |
| } else if (lsb < 16) { |
| i = getShort(offset, msb, lsb); |
| } else { |
| i = getInt(offset, msb, lsb); |
| } |
| return i != 0; |
| } |
| |
| public void copyData(int offset, byte[] src, int srcOffset, int length) { |
| // assert(_data.length >= length ); |
| if (_data.length < src.length) { |
| throw new MessageSystemException("backing byte[] is too small for copy operation", Level.SEVERE); |
| } |
| System.arraycopy(src, srcOffset, _data, offset, length); |
| _dataHasChanged = true; |
| } |
| |
| public void copyData(ByteBuffer src) { |
| src.get(_data); |
| _dataHasChanged = true; |
| } |
| |
| public void copyData(int offset, ByteBuffer src, int length) { |
| src.get(_data, offset, length); |
| _dataHasChanged = true; |
| } |
| |
| public ByteBuffer getAsBuffer() { |
| return ByteBuffer.wrap(_data); |
| } |
| |
| public void set(ByteBuffer other) { |
| buffer.put(other); |
| } |
| |
| public ByteBuffer getAsBuffer(int offset, int length) { |
| return ByteBuffer.wrap(_data, offset, length); |
| } |
| } |