@@ -137,7 +137,7 @@ private[io] final class PipedStreamBuffer(private[this] val capacity: Int) { sel
137
137
// or just a part of it.
138
138
val toRead = math.min(available, length)
139
139
// Transfer the bytes to the provided byte array.
140
- System .arraycopy (buffer, head % capacity, b, offset, toRead)
140
+ circularRead (buffer, head, capacity, b, offset, toRead)
141
141
// The bytes are marked as read by advancing the head of the
142
142
// circular buffer.
143
143
head += toRead
@@ -192,6 +192,35 @@ private[io] final class PipedStreamBuffer(private[this] val capacity: Int) { sel
192
192
override def available (): Int = self.synchronized {
193
193
if (closed) 0 else tail - head
194
194
}
195
+
196
+ /** Reads bytes from a circular buffer by copying them into a regular
197
+ * buffer.
198
+ *
199
+ * @param src the source circular buffer
200
+ * @param srcPos the offset into the source circular buffer
201
+ * @param srcCap the capacity of the source circular buffer
202
+ * @param dst the destination buffer
203
+ * @param dstPos the offset into the destination buffer
204
+ * @param length the number of bytes to be transferred
205
+ */
206
+ private [this ] def circularRead (
207
+ src : Array [Byte ],
208
+ srcPos : Int ,
209
+ srcCap : Int ,
210
+ dst : Array [Byte ],
211
+ dstPos : Int ,
212
+ length : Int
213
+ ): Unit = {
214
+ val srcOffset = srcPos % srcCap
215
+ if (srcOffset + length >= srcCap) {
216
+ val batch1 = srcCap - srcOffset
217
+ val batch2 = length - batch1
218
+ System .arraycopy(src, srcOffset, dst, dstPos, batch1)
219
+ System .arraycopy(src, 0 , dst, dstPos + batch1, batch2)
220
+ } else {
221
+ System .arraycopy(src, srcOffset, dst, dstPos, length)
222
+ }
223
+ }
195
224
}
196
225
197
226
val outputStream : OutputStream = new OutputStream {
@@ -270,7 +299,7 @@ private[io] final class PipedStreamBuffer(private[this] val capacity: Int) { sel
270
299
// or just a part of it.
271
300
val toWrite = math.min(available, length)
272
301
// Transfer the bytes to the provided byte array.
273
- System .arraycopy (b, offset, buffer, tail % capacity, toWrite)
302
+ circularWrite (b, offset, buffer, tail, capacity, toWrite)
274
303
// The bytes are marked as written by advancing the tail of the
275
304
// circular buffer.
276
305
tail += toWrite
@@ -316,5 +345,34 @@ private[io] final class PipedStreamBuffer(private[this] val capacity: Int) { sel
316
345
readerPermit.release()
317
346
}
318
347
}
348
+
349
+ /** Writes bytes into a circular buffer by copying them from a regular
350
+ * buffer.
351
+ *
352
+ * @param src the source buffer
353
+ * @param srcPos the offset into the source buffer
354
+ * @param dst the destination circular buffer
355
+ * @param dstPos the offset into the destination circular buffer
356
+ * @param dstCap the capacity of the destination circular buffer
357
+ * @param length the number of bytes to be transferred
358
+ */
359
+ private [this ] def circularWrite (
360
+ src : Array [Byte ],
361
+ srcPos : Int ,
362
+ dst : Array [Byte ],
363
+ dstPos : Int ,
364
+ dstCap : Int ,
365
+ length : Int
366
+ ): Unit = {
367
+ val dstOffset = dstPos % dstCap
368
+ if (dstOffset + length >= dstCap) {
369
+ val batch1 = dstCap - dstOffset
370
+ val batch2 = length - batch1
371
+ System .arraycopy(src, srcPos, dst, dstOffset, batch1)
372
+ System .arraycopy(src, srcPos + batch1, dst, 0 , batch2)
373
+ } else {
374
+ System .arraycopy(src, srcPos, dst, dstOffset, length)
375
+ }
376
+ }
319
377
}
320
378
}
0 commit comments