📄 payload.java
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2008, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed 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.//// ----------------------------------------------------------------------------// Description:// Read/Write binary fields// ----------------------------------------------------------------------------// Change History:// 2006/03/26 Martin D. Flynn// -Initial release// 2007/02/25 Martin D. Flynn// -Made 'decodeLong'/'encodeLong' public.// -Moved to 'org.opengts.util'.// 2007/03/11 Martin D. Flynn// -Added check for remaining available read/write bytes// 2008/02/04 Martin D. Flynn// -Added 'encodeDouble'/'decodeDouble' methods for encoding and decoding// 32-bit and 64-bit IEEE 754 floating-point values.// -Added Big/Little-Endian flag// -Added 'writeZeroFill' method// -Fixed 'writeBytes' to proper blank fill written fields// ----------------------------------------------------------------------------package org.opengts.util;import java.lang.*;import java.util.*;public class Payload{ // ------------------------------------------------------------------------ public static final int DEFAULT_MAX_PAYLOAD_LENGTH = 255; public static final byte EMPTY_BYTE_ARRAY[] = new byte[0]; private static final boolean DEFAULT_BIG_ENDIAN = true; // ------------------------------------------------------------------------ private byte payload[] = null; private int size = 0; private int index = 0; private boolean bigEndian = DEFAULT_BIG_ENDIAN; // ------------------------------------------------------------------------ public Payload() { // DESTINATION: configure for creating a new binary payload this(DEFAULT_MAX_PAYLOAD_LENGTH, DEFAULT_BIG_ENDIAN); } public Payload(int maxPayloadLen) { // DESTINATION: configure for creating a new binary payload this(maxPayloadLen, DEFAULT_BIG_ENDIAN); } public Payload(int maxPayloadLen, boolean bigEndian) { // DESTINATION: configure for creating a new binary payload this.payload = new byte[maxPayloadLen]; this.size = 0; // no 'size' yet this.index = 0; // start at index '0' for writing this.setBigEndian(bigEndian); } // ------------------------------------------------------------------------ public Payload(byte b[]) { // SOURCE: configure for reading a binary payload this(b, DEFAULT_BIG_ENDIAN); } public Payload(byte b[], boolean bigEndian) { // SOURCE: configure for reading a binary payload this(b, 0, ((b != null)? b.length : 0), bigEndian); } public Payload(byte b[], int ofs, int len) { this(b, ofs, len, DEFAULT_BIG_ENDIAN); } public Payload(byte b[], int ofs, int len, boolean bigEndian) { // SOURCE: configure for reading a binary payload this(); if ((b == null) || (ofs >= b.length)) { this.payload = new byte[0]; this.size = 0; this.index = 0; } else if ((ofs == 0) && (b.length == len)) { this.payload = b; this.size = b.length; this.index = 0; } else { if (len > (b.length - ofs)) { len = b.length - ofs; } this.payload = new byte[len]; System.arraycopy(b, ofs, this.payload, 0, len); this.size = len; this.index = 0; } this.setBigEndian(bigEndian); } // ------------------------------------------------------------------------ /* set true for big-endian, false for little-endian numeric encoding */ public void setBigEndian(boolean bigEndFirst) { this.bigEndian = bigEndFirst; } /* return true if big-endian, false for little-endian */ public boolean getBigEndian() { return this.bigEndian; } /* return true if big-endian, false if little-endian */ public boolean isBigEndian() { return this.bigEndian; } // ------------------------------------------------------------------------ /* return number of bytes written to payload, or total bytes available to read */ public int getSize() { return this.size; } /* reset payload to empty state */ public void clear() { this.size = 0; this.index = 0; } // ------------------------------------------------------------------------ /* return backing byte array (as-is) */ private byte[] _getBytes() { return this.payload; } /* return a byte array representing the data currently in the payload (may be a copy) */ public byte[] getBytes() { // return the full payload (regardless of the state of 'this.index') byte b[] = this._getBytes(); if (this.size == b.length) { return b; } else { byte n[] = new byte[this.size]; System.arraycopy(b, 0, n, 0, this.size); return n; } } // ------------------------------------------------------------------------ /* return index */ public int getIndex() { return this.index; } /* reset the read/write index to '0' */ public void resetIndex() { // this makes Payload a data source this.resetIndex(0); } /* reset the read/write index to the specified value */ public void resetIndex(int ndx) { this.index = (ndx <= 0)? 0 : ndx; } /* return remaining available read bytes */ public int getAvailableReadLength() { return (this.size - this.index); } /* return remaining available read bytes */ public int getAvailableWriteLength() { byte b[] = this._getBytes(); return (b.length - this.index); } /* return true if there are at least 'length' bytes that can be read from the payload */ public boolean isValidReadLength(int length) { return ((this.index + length) <= this.size); } /* return true if there are at least 'length' available bytes that can be written to the payload */ public boolean isValidWriteLength(int length) { byte b[] = this._getBytes(); return ((this.index + length) <= b.length); } /* return true if there are bytes available for reading */ public boolean hasAvailableRead() { return (this.getAvailableReadLength() > 0); } /* return true if there are bytes available for reading */ public boolean hasAvailableWrite() { return (this.getAvailableWriteLength() > 0); } // ------------------------------------------------------------------------ /* skip bytes */ public void readSkip(int length) { int maxLen = ((this.index + length) <= this.size)? length : (this.size - this.index); if (maxLen <= 0) { // nothing to skip return; } else { this.index += maxLen; return; } } /* skip X bytes in payload */ public void skip(int length) { this.readSkip(length); } // ------------------------------------------------------------------------ /* read length of bytes from payload */ public byte[] readBytes(int length) { // This will read 'length' bytes, or the remaining bytes, whichever is less int maxLen = ((length >= 0) && ((this.index + length) <= this.size))? length : (this.size - this.index); if (maxLen <= 0) { // no room left return new byte[0]; } else { byte n[] = new byte[maxLen]; System.arraycopy(this._getBytes(), this.index, n, 0, maxLen); this.index += maxLen; return n; } } // ------------------------------------------------------------------------ /* decode long value from bytes */ public static long decodeLong(byte data[], int ofs, int len, boolean bigEndian, boolean signed, long dft) { if ((data != null) && (data.length >= (ofs + len))) { if (bigEndian) { // Big-Endian order // { 0x01, 0x02, 0x03 } -> 0x010203 long n = (signed && ((data[ofs] & 0x80) != 0))? -1L : 0L; for (int i = ofs; i < ofs + len; i++) { n = (n << 8) | ((long)data[i] & 0xFF); } return n; } else { // Little-Endian order // { 0x01, 0x02, 0x03 } -> 0x030201 long n = (signed && ((data[ofs + len - 1] & 0x80) != 0))? -1L : 0L; for (int i = ofs + len - 1; i >= ofs; i--) { n = (n << 8) | ((long)data[i] & 0xFF); } return n; } } else { return dft; } } /* read long value from payload (with default) */ public long readLong(int length, long dft) { int maxLen = ((this.index + length) <= this.size)? length : (this.size - this.index); if (maxLen <= 0) { // nothing to read return dft; } else { byte b[] = this._getBytes(); long val = Payload.decodeLong(b, this.index, maxLen, this.bigEndian, true, dft); this.index += maxLen; return val; } } /* read long value from payload */ public long readLong(int length) { return this.readLong(length, 0L); } // ------------------------------------------------------------------------ /* read unsigned long value from payload (with default) */ public long readULong(int length, long dft) { int maxLen = ((this.index + length) <= this.size)? length : (this.size - this.index); if (maxLen <= 0) { // nothing to read return dft; } else { byte b[] = this._getBytes(); long val = Payload.decodeLong(b, this.index, maxLen, this.bigEndian, false, dft); this.index += maxLen; return val; } } /* read unsigned long value from payload */ public long readULong(int length) { return this.readULong(length, 0L); } // ------------------------------------------------------------------------ /* decode double value from bytes */ public static double decodeDouble(byte data[], int ofs, int len, boolean bigEndian, double dft) { // 'len' must be at lest 4 if ((data != null) && (len >= 4) && (data.length >= (ofs + len))) { int flen = (len >= 8)? 8 : 4; long n = 0L; if (bigEndian) { // Big-Endian order // { 0x01, 0x02, 0x03, 0x04 } -> 0x01020304 for (int i = ofs; i < ofs + flen; i++) { n = (n << 8) | ((long)data[i] & 0xFF); } } else { // Little-Endian order // { 0x01, 0x02, 0x03, 0x04 } -> 0x04030201 for (int i = ofs + flen - 1; i >= ofs; i--) { n = (n << 8) | ((long)data[i] & 0xFF); } } if (flen == 8) { //Print.logInfo("Decoding 64-bit float " + n); return Double.longBitsToDouble(n); } else { //Print.logInfo("Decoding 32-bit float " + n); return (double)Float.intBitsToFloat((int)n); } } else { return dft; } } /* read double value from payload (with default) */ public double readDouble(int length, double dft) { // 'length' must be at least 4 int maxLen = ((this.index + length) <= this.size)? length : (this.size - this.index); if (maxLen <= 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -