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.transport.message;
15 import java.util.Arrays;
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.HexUtils;
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
29 * @author Jeremy Setton - Rewrite insteon binding
32 public final class Field {
33 private final String name;
34 private final int offset;
35 private final DataType type;
37 public String getName() {
41 public int getOffset() {
45 public DataType getType() {
49 public Field(String name, DataType type, int offset) {
55 private void check(int len, DataType t) throws FieldException {
56 if (offset + type.getSize() > len) {
57 throw new FieldException("field write beyond end of msg");
60 throw new FieldException("field write type mismatch!");
64 public void set(byte[] data, Object o) throws FieldException {
67 setByte(data, (Byte) o);
70 setAddress(data, (InsteonAddress) o);
73 throw new FieldException("field data type unknown");
78 * Sets a byte value to a byte array, at the proper offset.
79 * Use this function to set the value of a field within a message.
81 * @param data the byte array to update
82 * @param b the byte value to set
83 * @throws FieldException
85 public void setByte(byte[] data, byte b) throws FieldException {
86 check(data.length, DataType.BYTE);
91 * Sets the value of an InsteonAddress to a message array.
92 * Use this function to set the value of a field within a message.
94 * @param data the byte array to update
95 * @param address the insteon address value to set
96 * @throws FieldException
98 public void setAddress(byte[] data, InsteonAddress address) throws FieldException {
99 check(data.length, DataType.ADDRESS);
100 System.arraycopy(address.getBytes(), 0, data, offset, type.getSize());
104 * Returns a byte from a byte array at the field position
106 * @param data the byte array to use
108 * @throws FieldException
110 public byte getByte(byte[] data) throws FieldException {
111 check(data.length, DataType.BYTE);
116 * Returns an insteon address from the field position
118 * @param data the byte array to use
119 * @return the insteon address
120 * @throws FieldException
122 public InsteonAddress getAddress(byte[] data) throws FieldException {
123 check(data.length, DataType.ADDRESS);
124 byte[] address = Arrays.copyOfRange(data, offset, offset + type.getSize());
125 return new InsteonAddress(address);
129 * Returns a string representation for a given byte array
131 * @param data the byte array to use
132 * @return the string representation
134 public String toString(byte[] data) {
135 String s = name + ":";
139 s += HexUtils.getHexString(getByte(data));
142 s += getAddress(data).toString();
145 throw new FieldException("field data type unknown");
147 } catch (FieldException e) {
154 public String toString() {
155 return name + " Type: " + type + " Offset: " + offset;
159 public boolean equals(@Nullable Object obj) {
166 if (getClass() != obj.getClass()) {
169 Field other = (Field) obj;
170 return name.equals(other.name) && offset == other.offset;
174 public int hashCode() {
175 final int prime = 31;
177 result = prime * result + name.hashCode();
178 result = prime * result + offset;