BinaryHunkOutputStream.java
- /*
- * Copyright (C) 2021 Thomas Wolf <thomas.wolf@paranor.ch> and others
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Distribution License v. 1.0 which is available at
- * https://www.eclipse.org/org/documents/edl-v10.php.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- package org.eclipse.jgit.util.io;
- import java.io.IOException;
- import java.io.OutputStream;
- import org.eclipse.jgit.util.Base85;
- /**
- * An {@link OutputStream} that encodes data for a git binary patch.
- *
- * @since 5.12
- */
- public class BinaryHunkOutputStream extends OutputStream {
- private static final int MAX_BYTES = 52;
- private final OutputStream out;
- private final byte[] buffer = new byte[MAX_BYTES];
- private int pos;
- /**
- * Creates a new {@link BinaryHunkOutputStream}.
- *
- * @param out
- * {@link OutputStream} to write the encoded data to
- */
- public BinaryHunkOutputStream(OutputStream out) {
- this.out = out;
- }
- /**
- * Flushes and closes this stream, and closes the underlying
- * {@link OutputStream}.
- */
- @Override
- public void close() throws IOException {
- flush();
- out.close();
- }
- /**
- * Writes any buffered output as a binary patch line to the underlying
- * {@link OutputStream} and flushes that stream, too.
- */
- @Override
- public void flush() throws IOException {
- if (pos > 0) {
- encode(buffer, 0, pos);
- pos = 0;
- }
- out.flush();
- }
- @Override
- public void write(int b) throws IOException {
- buffer[pos++] = (byte) b;
- if (pos == buffer.length) {
- encode(buffer, 0, pos);
- pos = 0;
- }
- }
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- if (len == 0) {
- return;
- }
- int toCopy = len;
- int in = off;
- if (pos > 0) {
- // Fill the buffer
- int chunk = Math.min(toCopy, buffer.length - pos);
- System.arraycopy(b, in, buffer, pos, chunk);
- in += chunk;
- pos += chunk;
- toCopy -= chunk;
- if (pos == buffer.length) {
- encode(buffer, 0, pos);
- pos = 0;
- }
- if (toCopy == 0) {
- return;
- }
- }
- while (toCopy >= MAX_BYTES) {
- encode(b, in, MAX_BYTES);
- toCopy -= MAX_BYTES;
- in += MAX_BYTES;
- }
- if (toCopy > 0) {
- System.arraycopy(b, in, buffer, 0, toCopy);
- pos = toCopy;
- }
- }
- private void encode(byte[] data, int off, int length) throws IOException {
- if (length <= 26) {
- out.write('A' + length - 1);
- } else {
- out.write('a' + length - 27);
- }
- out.write(Base85.encode(data, off, length));
- out.write('\n');
- }
- }