+ /**
+ * Consolidate the push-back buffers so the last one is at least the given
+ * size, if possible.
+ * <p>
+ * If there is not enough data in the push-back buffers, they will all be
+ * consolidated.
+ *
+ * @param size
+ * the minimum size of the consolidated buffer, or -1 to force
+ * the consolidation of all push-back buffers
+ *
+ * @return the size of the last, consolidated buffer; can be less than the
+ * requested size if not enough data
+ */
+ protected int consolidatePushBack(int size) {
+ int bbIndex = -1;
+ int bbUpToSize = 0;
+ for (Entry<byte[], Integer> entry : backBuffers) {
+ bbIndex++;
+ bbUpToSize += entry.getKey().length - entry.getValue();
+
+ if (size >= 0 && bbUpToSize >= size) {
+ break;
+ }
+ }
+
+ // Index 0 means "the last buffer is already big enough"
+ if (bbIndex > 0) {
+ byte[] consolidatedBuffer = new byte[bbUpToSize];
+ int consolidatedPos = 0;
+ for (int i = 0; i <= bbIndex; i++) {
+ Entry<byte[], Integer> bb = backBuffers
+ .remove(backBuffers.size() - 1);
+ byte[] bbBuffer = bb.getKey();
+ int bbOffset = bb.getValue();
+ int bbSize = bbBuffer.length - bbOffset;
+ System.arraycopy(bbBuffer, bbOffset, consolidatedBuffer,
+ consolidatedPos, bbSize);
+ }
+
+ pushback(consolidatedBuffer, 0);
+ }
+
+ return bbUpToSize;
+ }
+