📄 message.java
字号:
/* tab:4 * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By * downloading, copying, installing or using the software you agree to * this license. If you do not agree to this license, do not download, * install, copy or use the software. * * Intel Open Source License * * Copyright (c) 1996-2000 Intel Corporation * All rights reserved. * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the Intel Corporation nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR ITS * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * Authors: David Gay <dgay@intel-research.net> * Intel Research Berkeley Lab * *//** * Message class (encode/decode tinyos messages).<p> * * The base class for encoding and decoding tinyos messages. Provides * methods to read and write bit fields at an offset for a particular bit * length. Intended for use by the Java code generated by mig. * * @version 1, 15 Jul 2002 * @author David Gay */package net.tinyos.message;public class Message implements Cloneable { /** * The maximum number of characters read from an 8-bit array field * being converted into a Java String. */ public static final int MAX_CONVERTED_STRING_LENGTH = 512; /** * The underlying byte array storing the data for this message. * This is private to enforce access to the data through the accessor * methods in this class, which do bounds checking and manage the * base_offset for embedded messages. */ private byte[] data; /** * The base offset into the data. This allows the message data to * exist at some non-zero offset into the actual data. */ protected int base_offset; /** * The actual length of the message data. Must be less than or * equal to (data.length - base_offset). */ protected int data_length; /** Private to prevent no-arg instantiation. */ private Message() { } /** * Construct a new message of the given size. * @param data_length The size of the message to create. */ protected Message(int data_length) { this(new byte[data_length]); } /** * Construct a new message of the given size and base offset. * Allocates a new byte array of size data_length+base_offset. * @param data_length The size of the message to create. * @param base_offset The base offset into the newly created message. */ protected Message(int data_length, int base_offset) { this(new byte[data_length+base_offset], base_offset); } /** * Construct a message using data as the storage. * The length of data determines the length of this message. * @param data the storage for this message */ protected Message(byte[] data) { this.data = data; this.base_offset = 0; this.data_length = data.length; } /** * Construct a message using data as the storage. * Use the given base_offset as the base offset into the * data array. The data length will be (data.length - base_offset). * @param data the storage for this message * @param base_offset the base offset into the data array */ protected Message(byte[] data, int base_offset) { this.data = data; this.base_offset = base_offset; this.data_length = data.length - base_offset; } /** * Construct a message using data as the storage. * Use the given base_offset as the base offset into the * data array, and the specified data length. * @param data the storage for this message * @param base_offset the base offset into the data array * @param data_length the length of the message data */ protected Message(byte[] data, int base_offset, int data_length) { this.data = data; this.base_offset = base_offset; this.data_length = data_length; if (base_offset + data_length > data.length) throw new ArrayIndexOutOfBoundsException("Cannot create Message with base_offset "+base_offset+", data_length "+data_length+" and data array size "+data.length); } /** * Construct an embedded message within the given 'msg'. * Use the given base_offset as the base offset into the * data array, and the specified data length. * @param msg the message to embed this message into * @param base_offset the base offset into the data array * @param data_length the length of the message data */ protected Message(Message msg, int base_offset, int data_length) { this(msg.dataGet(), msg.base_offset+base_offset, data_length); } private Message cloneself() { Message copy; try { copy = (Message)super.clone(); } catch (CloneNotSupportedException e) { System.err.println("Message: WARNING: CloneNotSupportedException in cloneself(): "+e); System.err.println("Message: This is a bug - please contact dgay@intel-research.net"); copy = null; System.exit(2); } return copy; } /** * Clone this Message, including making a copy of its data */ public Object clone() { Message copy = cloneself(); copy.data = (byte[])data.clone(); copy.base_offset = this.base_offset; copy.data_length = this.data_length; return copy; } /** * Clone this Message, but give it a new unitialised data array of size * size * @param size size of the new data array */ public Message clone(int size) { Message copy = cloneself(); copy.data = new byte[size]; copy.base_offset = this.base_offset; copy.data_length = size; return copy; } /** * Copy new data for this message from 'data'. * Copies min(data.length, this.data_length) bytes. * @param data the array containing the data to be copied * @exception ArrayIndexOutOfBoundsException if any of * data[0..getData().length - 1] are invalid */ public void dataSet(byte[] data) { dataSet(data, 0, this.base_offset, Math.min(this.data_length, data.length)); } /** * Copy new data for this message from offsetFrom in data to * offsetTo in this message. Copies a total of length bytes * @param data the array containing the data to be copied * @param offsetFrom the offset in data to start copying from * @param offsetTo the offset at which to start copying data into * this message. * @param length bytes are copied. * @exception ArrayIndexOutOfBoundsException if any of * the source or target indices are invalid */ public void dataSet(byte[] data, int offsetFrom, int offsetTo, int length) { System.arraycopy(data, offsetFrom, this.data, offsetTo+base_offset, length); } /** * Return the raw byte array representing the data of this message. * Note that only indices in the range * (this.baseOffset(), this.baseOffset()+this.dataLength()) are * valid. */ public byte[] dataGet() { return data; } /** * Return the base offset into the data array for this message. */ public int baseOffset() { return base_offset; } /** * Return the length of the data (in bytes) contained in this message. */ public int dataLength() { return data_length; } /** * Return the active message type of this message (-1 if unknown) */ public int amType() { return -1; } // ASSUMES: little endian bits & bytes // Check that length bits from offset are in bounds private void checkBounds(int offset, int length) { if (offset < 0 || length <= 0 || offset + length > (data_length * 8)) throw new ArrayIndexOutOfBoundsException("Message.checkBounds: bad offset ("+offset+") or length ("+length+"), for data_length "+data_length); } // Check that value is valid for a bitfield of length length private void checkValue(int length, long value) { if (length != 64 && (value < 0 || value >= 1L << length)) throw new IllegalArgumentException("Message.checkValue: bad length ("+length+" or value ("+value+")"); } // Unsigned byte read private int ubyte(int offset) { int val = data[base_offset+offset]; if (val < 0) return val + 256; else return val; } /** * Read the length bit unsigned int at offset * @param offset bit offset where the unsigned int starts * @param length bit length of the unsigned int * @exception ArrayIndexOutOfBoundsException for invalid offset, length */ protected long getUIntElement(int offset, int length) { checkBounds(offset, length); int byteOffset = offset >> 3; int bitOffset = offset & 7; int shift = 0; long val = 0; // all in one byte case if (length + bitOffset <= 8) return (ubyte(byteOffset) >> bitOffset) & ((1 << length) - 1); // get some high order bits if (bitOffset > 0) { val = ubyte(byteOffset) >> bitOffset; byteOffset++; shift += 8 - bitOffset; length -= 8 - bitOffset; } while (length >= 8) { val |= (long)ubyte(byteOffset++) << shift; shift += 8; length -= 8; } // data from last byte if (length > 0) val |= (long)(ubyte(byteOffset) & ((1 << length) - 1)) << shift; return val; } /** * Set the length bit unsigned int at offset to val * @param offset bit offset where the unsigned int starts * @param length bit length of the unsigned int * @param val value to set the bit field to * @exception ArrayIndexOutOfBoundsException for invalid offset, length * @exception IllegalArgumentException if val is an out-of-range value * for this bitfield */ protected void setUIntElement(int offset, int length, long val) { checkBounds(offset, length); //checkValue(length, val); int byteOffset = offset >> 3; int bitOffset = offset & 7; int shift = 0; // all in one byte case if (length + bitOffset <= 8) { data[base_offset+byteOffset] = (byte) ((ubyte(byteOffset) & ~(((1 << length) - 1) << bitOffset)) | val << bitOffset); return; } // set some high order bits if (bitOffset > 0) { data[base_offset+byteOffset] = (byte) ((ubyte(byteOffset) & ((1 << bitOffset) - 1)) | val << bitOffset); byteOffset++; shift += 8 - bitOffset; length -= 8 - bitOffset; } while (length >= 8) { data[base_offset+(byteOffset++)] = (byte)(val >> shift); shift += 8; length -= 8; } // data for last byte if (length > 0) data[base_offset+byteOffset] = (byte) ((ubyte(byteOffset) & ~((1 << length) - 1)) | val >> shift); } /** * Read the length bit signed int at offset * @param offset bit offset where the signed int starts * @param length bit length of the signed int * @exception ArrayIndexOutOfBoundsException for invalid offset, length */ protected long getSIntElement(int offset, int length) throws ArrayIndexOutOfBoundsException { long val = getUIntElement(offset, length); if (length == 64) return val; if ((val & 1L << (length - 1)) != 0) return val - (1L << length); return val; } /** * Set the length bit signed int at offset to val * @param offset bit offset where the signed int starts * @param length bit length of the signed int * @param val value to set the bit field to * @exception ArrayIndexOutOfBoundsException for invalid offset, length * @exception IllegalArgumentException if val is an out-of-range value * for this bitfield */ protected void setSIntElement(int offset, int length, long value) throws ArrayIndexOutOfBoundsException { if (length != 64 && value >= 1L << (length - 1)) throw new IllegalArgumentException(); if (length != 64 && value < 0) value += 1L << length; setUIntElement(offset, length, value); } /** * Read the 32 bit IEEE float at offset * @param offset bit offset where the float starts * @param length is ignored * @exception ArrayIndexOutOfBoundsException for invalid offset */ protected float getFloatElement(int offset, int length) throws ArrayIndexOutOfBoundsException { return Float.intBitsToFloat((int)getUIntElement(offset, 32)); } /** * Set the 32 bit IEEE float at offset to value * @param offset bit offset where the float starts * @param length is ignored * @parem value value to store in bitfield * @exception ArrayIndexOutOfBoundsException for invalid offset */ protected void setFloatElement(int offset, int length, float value) throws ArrayIndexOutOfBoundsException { // using SInt because floatToRawIntBits might return a negative value setSIntElement(offset, 32, Float.floatToRawIntBits(value)); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -