2 * Copyright (c) 2010-2024 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.insteon.internal.message;
15 import java.util.Objects;
17 import org.eclipse.jdt.annotation.NonNullByDefault;
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.openhab.binding.insteon.internal.device.InsteonAddress;
20 import org.openhab.binding.insteon.internal.utils.Utils;
23 * An Insteon message has several fields with known type and offset
24 * within the message. This class represents a single field, and
25 * holds name, type, and offset (but not value!).
27 * @author Daniel Pfrommer - Initial contribution
28 * @author Rob Nielsen - Port to openHAB 2 insteon binding
31 public final class Field {
32 private final String name;
33 private final int offset;
34 private final DataType type;
36 public String getName() {
40 public int getOffset() {
44 public DataType getType() {
48 public Field(String name, DataType type, int off) {
54 private void check(int arrayLen, DataType t) throws FieldException {
59 private void checkSpace(int arrayLen) throws FieldException {
60 if (offset + type.getSize() > arrayLen) {
61 throw new FieldException("field write beyond end of msg");
65 private void checkType(DataType t) throws FieldException {
67 throw new FieldException("field write type mismatch!");
72 public String toString() {
73 return getName() + " Type: " + getType() + " Offset " + getOffset();
76 public String toString(byte[] array) {
77 String s = name + ":";
81 s += Utils.getHexByte(getByte(array));
84 s += Integer.toString(getInt(array));
87 s += getAddress(array).toString();
92 } catch (FieldException e) {
93 // will just return empty string
98 public void set(byte[] array, Object o) throws FieldException {
101 setByte(array, (Byte) o);
104 setInt(array, (Integer) o);
106 // case FLOAT: setFloat(array, (float) o); break;
108 setAddress(array, (InsteonAddress) o);
111 throw new FieldException("Not implemented data type " + getType() + "!");
116 * Writes a byte value to a byte array, at the proper offset.
117 * Use this function to set the value of a field within a message.
119 * @param array the destination array
120 * @param b the value you want to set the byte to
121 * @throws FieldException
123 public void setByte(byte[] array, byte b) throws FieldException {
124 check(array.length, DataType.BYTE);
129 * Writes the value of an integer field to a byte array
130 * Use this function to set the value of a field within a message.
132 * @param array the destination array
133 * @param i the integer value to set
135 public void setInt(byte[] array, int i) throws FieldException {
136 check(array.length, DataType.INT);
137 array[offset] = (byte) ((i >>> 24) & 0xFF);
138 array[offset + 1] = (byte) ((i >>> 16) & 0xFF);
139 array[offset + 2] = (byte) ((i >>> 8) & 0xFF);
140 array[offset + 3] = (byte) ((i >>> 0) & 0xFF);
144 * Writes the value of an InsteonAddress to a message array.
145 * Use this function to set the value of a field within a message.
147 * @param array the destination array
148 * @param adr the insteon address value to set
151 public void setAddress(byte[] array, InsteonAddress adr) throws FieldException {
152 check(array.length, DataType.ADDRESS);
153 adr.storeBytes(array, offset);
157 * Fetch a byte from the array at the field position
159 * @param array the array to fetch from
160 * @return the byte value of the field
162 public byte getByte(byte[] array) throws FieldException {
163 check(array.length, DataType.BYTE);
164 return array[offset];
168 * Fetch an int from the array at the field position
170 * @param array the array to fetch from
171 * @return the int value of the field
173 public int getInt(byte[] array) throws FieldException {
174 check(array.length, DataType.INT);
175 byte b1 = array[offset];
176 byte b2 = array[offset + 1];
177 byte b3 = array[offset + 2];
178 byte b4 = array[offset + 3];
179 return ((b1 << 24) + (b2 << 16) + (b3 << 8) + (b4 << 0));
183 * Fetch an insteon address from the field position
185 * @param array the array to fetch from
186 * @return the address
189 public InsteonAddress getAddress(byte[] array) throws FieldException {
190 check(array.length, DataType.ADDRESS);
191 InsteonAddress adr = new InsteonAddress();
192 adr.loadBytes(array, offset);
200 public boolean equals(@Nullable Object o) {
201 if (o instanceof Field f) {
202 return (f.getName().equals(getName())) && (f.getOffset() == getOffset());
209 public int hashCode() {
210 return Objects.hash(getName(), getOffset());