1
1
/*******************************************************************************
2
- * HPCC SYSTEMS software Copyright (C) 2024 HPCC Systems®.
2
+ * HPCC SYSTEMS software Copyright (C) 2025 HPCC Systems®.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
5
5
* the License. You may obtain a copy of the License at
13
13
14
14
package org .hpccsystems .dfs .client ;
15
15
16
- import java .io .IOException ;
17
-
18
16
public class CircularByteBuffer
19
17
{
20
18
private final byte [] buffer ;
21
19
private int readPos = 0 ;
22
20
private int writePos = 0 ;
23
- private int markPos = 0 ;
21
+ private int markPos = - 1 ;
24
22
private int bytesReadAfterMark = 0 ;
25
23
private int currentNumberOfBytes = 0 ;
26
24
27
- public CircularByteBuffer (int bufferSize )
25
+ /**
26
+ * Instantiates a new circular byte buffer.
27
+ *
28
+ * @param bufferSize the buffer size
29
+ * @throws IllegalArgumentException if buffer size is less than or equal to 0
30
+ */
31
+ public CircularByteBuffer (int bufferSize ) throws IllegalArgumentException
28
32
{
33
+ if (bufferSize <= 0 )
34
+ {
35
+ throw new IllegalArgumentException ("Buffer size must be greater than 0" );
36
+ }
37
+
29
38
buffer = new byte [bufferSize ];
30
39
}
31
40
32
- public int getCurrentNumberOfBytes ()
41
+ /**
42
+ * Gets the number of bytes available in the buffer.
43
+ *
44
+ * @return aviailable bytes
45
+ */
46
+ public int getBytesAvailable ()
33
47
{
34
48
// We only adjust for the mark internally and when providing information about available space
35
49
return currentNumberOfBytes ;
36
50
}
37
51
52
+ /**
53
+ * Checks if the buffer has space.
54
+ *
55
+ * @return true, if successful
56
+ */
38
57
public boolean hasSpace ()
39
58
{
40
- return getSpace () > 0 ;
59
+ return getFreeSpace () > 0 ;
41
60
}
42
61
43
- public int getSpace ()
62
+ /**
63
+ * Gets the free space in the buffer.
64
+ *
65
+ * @return the free space
66
+ */
67
+ public int getFreeSpace ()
44
68
{
45
69
int adjustedByteCount = currentNumberOfBytes ;
46
70
if (markPos >= 0 )
@@ -51,7 +75,12 @@ public int getSpace()
51
75
return buffer .length - adjustedByteCount ;
52
76
}
53
77
54
- public int getContiguousSpace ()
78
+ /**
79
+ * Gets the contiguous free space in the buffer.
80
+ *
81
+ * @return the contiguous free space
82
+ */
83
+ public int getContiguousFreeSpace ()
55
84
{
56
85
if (!hasSpace ())
57
86
{
@@ -75,11 +104,22 @@ public int getContiguousSpace()
75
104
}
76
105
}
77
106
107
+ /**
108
+ * Gets the location of the next write.
109
+ *
110
+ * @return the write offset
111
+ */
78
112
public int getWriteOffset ()
79
113
{
80
114
return writePos ;
81
115
}
82
116
117
+ /**
118
+ * Increments write offset.
119
+ *
120
+ * @param increment number of bytes to increment
121
+ * @return the number of bytes incremented
122
+ */
83
123
public int incrementWriteOffset (int increment )
84
124
{
85
125
int maxIncrement = buffer .length - writePos ;
@@ -95,29 +135,43 @@ public int incrementWriteOffset(int increment)
95
135
return increment ;
96
136
}
97
137
98
- public void add (final byte [] targetBuffer , final int offset , final int length ) throws IOException
138
+ /**
139
+ * Adds the bytes to the buffer.
140
+ *
141
+ * @param srcBuffer the source buffer
142
+ * @param offset the offset within the source buffer
143
+ * @param length the length of bytes to add
144
+ * @return the number of bytes added
145
+ */
146
+ public int add (final byte [] srcBuffer , int offset , int length )
99
147
{
100
148
if (currentNumberOfBytes + length > buffer .length )
101
149
{
102
- throw new IOException ( "Not enough space available" ) ;
150
+ length = buffer . length - currentNumberOfBytes ;
103
151
}
104
152
105
153
for (int i = 0 ; i < length ; i ++)
106
154
{
107
- buffer [writePos ] = targetBuffer [offset + i ];
155
+ buffer [writePos ] = srcBuffer [offset + i ];
108
156
if (++writePos == buffer .length )
109
157
{
110
158
writePos = 0 ;
111
159
}
112
160
}
113
161
currentNumberOfBytes += length ;
162
+ return length ;
114
163
}
115
164
116
- public byte read () throws IOException
165
+ /**
166
+ * Reads a byte from the buffer.
167
+ *
168
+ * @return the byte read as an int [0-255] or -1 if no bytes are available
169
+ */
170
+ public int read ()
117
171
{
118
172
if (currentNumberOfBytes <= 0 )
119
173
{
120
- throw new IOException ( "No bytes available to read" ) ;
174
+ return - 1 ;
121
175
}
122
176
123
177
byte b = buffer [readPos ];
@@ -128,20 +182,28 @@ public byte read() throws IOException
128
182
bytesReadAfterMark ++;
129
183
}
130
184
131
- readPos ++;
132
- if (readPos >= buffer .length )
185
+ if (++readPos >= buffer .length )
133
186
{
134
187
readPos = 0 ;
135
188
}
136
189
137
- return b ;
190
+ int ret = b ;
191
+ return ret + 128 ;
138
192
}
139
193
140
- public void read (final byte [] targetBuffer , final int targetOffset , final int length ) throws IOException
194
+ /**
195
+ * Reads bytes from the buffer.
196
+ *
197
+ * @param targetBuffer the target buffer to write to
198
+ * @param targetOffset the target offset within the target buffer
199
+ * @param length the number of bytes to read
200
+ * @return the number of bytes read
201
+ */
202
+ public int read (final byte [] targetBuffer , int targetOffset , int length )
141
203
{
142
204
if (length > currentNumberOfBytes )
143
205
{
144
- throw new IOException ( "Not enough bytes available to read" ) ;
206
+ length = currentNumberOfBytes ;
145
207
}
146
208
147
209
if (readPos + length <= buffer .length )
@@ -166,13 +228,26 @@ public void read(final byte[] targetBuffer, final int targetOffset, final int le
166
228
{
167
229
bytesReadAfterMark += length ;
168
230
}
231
+
232
+ return length ;
169
233
}
170
234
235
+ /**
236
+ * Gets the internal buffer.
237
+ *
238
+ * @return the internal buffer
239
+ */
171
240
public byte [] getInternalBuffer ()
172
241
{
173
242
return buffer ;
174
243
}
175
244
245
+ /**
246
+ * Marks the current read position, allowing a reset to return to this position.
247
+ *
248
+ * @param readLim the read limit before a reset is no longer allowed
249
+ * @throws IllegalArgumentException if read limit exceeds available bytes
250
+ */
176
251
public void mark (int readLim ) throws IllegalArgumentException
177
252
{
178
253
if (readLim > buffer .length )
@@ -184,6 +259,9 @@ public void mark(int readLim) throws IllegalArgumentException
184
259
bytesReadAfterMark = 0 ;
185
260
}
186
261
262
+ /**
263
+ * Resets the read position to the last marked position.
264
+ */
187
265
public void reset ()
188
266
{
189
267
if (markPos < 0 )
@@ -198,11 +276,17 @@ public void reset()
198
276
bytesReadAfterMark = 0 ;
199
277
}
200
278
201
- public long skip (long n ) throws IOException
279
+ /**
280
+ * Skips the specified number of bytes.
281
+ *
282
+ * @param n the number of bytes to skip
283
+ * @return the number of bytes skipped
284
+ */
285
+ public int skip (int n )
202
286
{
203
287
if (n > currentNumberOfBytes )
204
288
{
205
- throw new IOException ( "Not enough bytes available to skip" ) ;
289
+ n = currentNumberOfBytes ;
206
290
}
207
291
208
292
readPos += n ;
@@ -212,6 +296,10 @@ public long skip(long n) throws IOException
212
296
}
213
297
214
298
currentNumberOfBytes -= n ;
299
+ if (markPos >= 0 )
300
+ {
301
+ bytesReadAfterMark += n ;
302
+ }
215
303
return n ;
216
304
}
217
305
};
0 commit comments