/** * This file is part of git-as-svn. It is subject to the license terms * in the LICENSE file found in the top-level directory of this distribution * and at http://www.gnu.org/licenses/gpl-2.0.html. No part of git-as-svn, * including this file, may be copied, modified, propagated, or distributed * except according to the terms contained in the LICENSE file. */ package svnserver.ext.gitlfs.storage.memory; import org.apache.commons.codec.binary.Hex; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import svnserver.HashHelper; import svnserver.ext.gitlfs.storage.LfsWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.concurrent.ConcurrentHashMap; /** * Local storage writer. * * @author Artem V. Navrotskiy <bozaro@users.noreply.github.com> */ public class LfsMemoryWriter extends LfsWriter { @NotNull private final ConcurrentHashMap<String, byte[]> storage; @NotNull private static final String OID_PREFIX = "sha256:"; @Nullable private ByteArrayOutputStream stream; public LfsMemoryWriter(@NotNull ConcurrentHashMap<String, byte[]> storage) { this.storage = storage; this.stream = new ByteArrayOutputStream(); } @Override public void write(int b) throws IOException { if (stream == null) { throw new IllegalStateException(); } stream.write(b); } @Override public void write(@NotNull byte[] b, int off, int len) throws IOException { if (stream == null) { throw new IllegalStateException(); } stream.write(b, off, len); } @NotNull @Override public String finish(@Nullable String expectedOid) throws IOException { if (stream == null) { throw new IllegalStateException(); } final byte[] content = stream.toByteArray(); String result = Hex.encodeHexString(HashHelper.sha256().digest(content)); final String oid = OID_PREFIX + result; if (expectedOid != null && !expectedOid.equals(oid)) { throw new IOException("Invalid stream checksum: expected " + expectedOid + ", but actual " + oid); } storage.putIfAbsent(oid, content); stream = null; return oid; } @Override public void close() throws IOException { stream = null; } }