]> git.basschouten.com Git - openhab-addons.git/blob
371e54e411d77f0c9662f63afc32e02e51a61939
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2024 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
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
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.insteon.internal.message;
14
15 import java.util.Objects;
16
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;
21
22 /**
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!).
26  *
27  * @author Daniel Pfrommer - Initial contribution
28  * @author Rob Nielsen - Port to openHAB 2 insteon binding
29  */
30 @NonNullByDefault
31 public final class Field {
32     private final String name;
33     private final int offset;
34     private final DataType type;
35
36     public String getName() {
37         return name;
38     }
39
40     public int getOffset() {
41         return offset;
42     }
43
44     public DataType getType() {
45         return type;
46     }
47
48     public Field(String name, DataType type, int off) {
49         this.name = name;
50         this.type = type;
51         this.offset = off;
52     }
53
54     private void check(int arrayLen, DataType t) throws FieldException {
55         checkSpace(arrayLen);
56         checkType(t);
57     }
58
59     private void checkSpace(int arrayLen) throws FieldException {
60         if (offset + type.getSize() > arrayLen) {
61             throw new FieldException("field write beyond end of msg");
62         }
63     }
64
65     private void checkType(DataType t) throws FieldException {
66         if (type != t) {
67             throw new FieldException("field write type mismatch!");
68         }
69     }
70
71     @Override
72     public String toString() {
73         return getName() + " Type: " + getType() + " Offset " + getOffset();
74     }
75
76     public String toString(byte[] array) {
77         String s = name + ":";
78         try {
79             switch (type) {
80                 case BYTE:
81                     s += Utils.getHexByte(getByte(array));
82                     break;
83                 case INT:
84                     s += Integer.toString(getInt(array));
85                     break;
86                 case ADDRESS:
87                     s += getAddress(array).toString();
88                     break;
89                 default:
90                     break;
91             }
92         } catch (FieldException e) {
93             // will just return empty string
94         }
95         return s;
96     }
97
98     public void set(byte[] array, Object o) throws FieldException {
99         switch (getType()) {
100             case BYTE:
101                 setByte(array, (Byte) o);
102                 break;
103             case INT:
104                 setInt(array, (Integer) o);
105                 break;
106             // case FLOAT: setFloat(array, (float) o); break;
107             case ADDRESS:
108                 setAddress(array, (InsteonAddress) o);
109                 break;
110             default:
111                 throw new FieldException("Not implemented data type " + getType() + "!");
112         }
113     }
114
115     /**
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.
118      *
119      * @param array the destination array
120      * @param b the value you want to set the byte to
121      * @throws FieldException
122      */
123     public void setByte(byte[] array, byte b) throws FieldException {
124         check(array.length, DataType.BYTE);
125         array[offset] = b;
126     }
127
128     /**
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.
131      *
132      * @param array the destination array
133      * @param i the integer value to set
134      */
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);
141     }
142
143     /**
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.
146      *
147      * @param array the destination array
148      * @param adr the insteon address value to set
149      */
150
151     public void setAddress(byte[] array, InsteonAddress adr) throws FieldException {
152         check(array.length, DataType.ADDRESS);
153         adr.storeBytes(array, offset);
154     }
155
156     /**
157      * Fetch a byte from the array at the field position
158      *
159      * @param array the array to fetch from
160      * @return the byte value of the field
161      */
162     public byte getByte(byte[] array) throws FieldException {
163         check(array.length, DataType.BYTE);
164         return array[offset];
165     }
166
167     /**
168      * Fetch an int from the array at the field position
169      *
170      * @param array the array to fetch from
171      * @return the int value of the field
172      */
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));
180     }
181
182     /**
183      * Fetch an insteon address from the field position
184      *
185      * @param array the array to fetch from
186      * @return the address
187      */
188
189     public InsteonAddress getAddress(byte[] array) throws FieldException {
190         check(array.length, DataType.ADDRESS);
191         InsteonAddress adr = new InsteonAddress();
192         adr.loadBytes(array, offset);
193         return adr;
194     }
195
196     /**
197      * Equals test
198      */
199     @Override
200     public boolean equals(@Nullable Object o) {
201         if (o instanceof Field f) {
202             return (f.getName().equals(getName())) && (f.getOffset() == getOffset());
203         } else {
204             return false;
205         }
206     }
207
208     @Override
209     public int hashCode() {
210         return Objects.hash(getName(), getOffset());
211     }
212 }