]> git.basschouten.com Git - openhab-addons.git/blob
c9c8ae2987726c86e0dfe840765d64824c3e5a15
[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.driver.hub;
14
15 import java.io.IOException;
16 import java.util.Arrays;
17
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.eclipse.jdt.annotation.Nullable;
20
21 /**
22  * ReadByteBuffer buffer class
23  *
24  * @author Daniel Pfrommer - Initial contribution
25  * @author Rob Nielsen - Port to openHAB 2 insteon binding
26  */
27 @NonNullByDefault
28 public class ReadByteBuffer {
29     private byte buf[]; // the actual buffer
30     private int count; // number of valid bytes
31     private int index = 0; // current read index
32     private boolean done = false;
33
34     /**
35      * Constructor for ByteArrayIO with dynamic size
36      *
37      * @param size initial size, but will grow dynamically
38      */
39     public ReadByteBuffer(int size) {
40         this.buf = new byte[size];
41     }
42
43     /**
44      * Done reading bytes
45      */
46     public synchronized void done() {
47         done = true;
48         notifyAll();
49     }
50
51     /**
52      * Number of unread bytes
53      *
54      * @return number of bytes not yet read
55      */
56     public synchronized int remaining() {
57         return count - index;
58     }
59
60     /**
61      * Blocking read of a single byte
62      *
63      * @return byte read
64      * @throws IOException
65      */
66     public synchronized byte get() throws IOException {
67         while (!done && remaining() < 1) {
68             try {
69                 wait();
70             } catch (InterruptedException e) {
71                 throw new IOException("interrupted");
72             }
73         }
74
75         if (done) {
76             throw new IOException("done");
77         }
78
79         return buf[index++];
80     }
81
82     /**
83      * Blocking read of multiple bytes
84      *
85      * @param bytes destination array for bytes read
86      * @param off offset into dest array
87      * @param len max number of bytes to read into dest array
88      * @return number of bytes actually read
89      * @throws IOException
90      */
91     public synchronized int get(byte @Nullable [] bytes, int off, int len) throws IOException {
92         while (!done && remaining() < 1) {
93             try {
94                 wait();
95             } catch (InterruptedException e) {
96                 throw new IOException("interrupted");
97             }
98         }
99
100         if (done) {
101             throw new IOException("done");
102         }
103
104         int b = Math.min(len, remaining());
105         if (bytes != null) {
106             System.arraycopy(buf, index, bytes, off, b);
107         }
108         index += b;
109         return b;
110     }
111
112     /**
113      * Adds bytes to the byte buffer
114      *
115      * @param b byte array with new bytes
116      * @param off starting offset into buffer
117      * @param len number of bytes to add
118      */
119     private synchronized void add(byte b[], int off, int len) {
120         if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0)) {
121             throw new IndexOutOfBoundsException();
122         } else if (len == 0) {
123             return;
124         }
125         int nCount = count + len;
126         if (nCount > buf.length) {
127             // dynamically grow the array
128             buf = Arrays.copyOf(buf, Math.max(buf.length << 1, nCount));
129         }
130         // append new data to end of buffer
131         System.arraycopy(b, off, buf, count, len);
132         count = nCount;
133         notifyAll();
134     }
135
136     /**
137      * Adds bytes to the byte buffer
138      *
139      * @param b the new bytes to be added
140      */
141     public void add(byte[] b) {
142         add(b, 0, b.length);
143     }
144
145     /**
146      * Shrink the buffer to smallest size possible
147      */
148     public synchronized void makeCompact() {
149         if (index == 0) {
150             return;
151         }
152         byte[] newBuf = new byte[remaining()];
153         System.arraycopy(buf, index, newBuf, 0, newBuf.length);
154         index = 0;
155         count = newBuf.length;
156         buf = newBuf;
157     }
158 }