| // Copyright 2025 The Bazel Authors. All rights reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| package com.google.devtools.build.lib.vfs; |
| |
| import static java.nio.charset.StandardCharsets.UTF_8; |
| |
| import java.io.ByteArrayOutputStream; |
| import java.security.MessageDigest; |
| import java.security.NoSuchAlgorithmException; |
| |
| /** A {@link MessageDigest} for GitSha1. */ |
| public final class GitSha1MessageDigest extends MessageDigest { |
| private static final byte[] header = {'b', 'l', 'o', 'b', ' '}; |
| private final MessageDigest sha1; |
| private final ByteArrayOutputStream stream; |
| |
| public GitSha1MessageDigest() throws NoSuchAlgorithmException { |
| super("GITSHA1"); |
| sha1 = MessageDigest.getInstance("SHA-1"); |
| stream = new ByteArrayOutputStream(); |
| } |
| |
| @Override |
| public void engineUpdate(byte[] data, int offset, int length) { |
| stream.write(data, offset, length); |
| } |
| |
| @Override |
| public void engineUpdate(byte b) { |
| stream.write(b); |
| } |
| |
| @Override |
| protected void engineReset() { |
| internalReset(); |
| } |
| |
| @Override |
| protected byte[] engineDigest() { |
| int size = stream.size(); |
| sha1.update(header); |
| sha1.update(Integer.toString(size).getBytes(UTF_8)); |
| sha1.update((byte) 0); |
| sha1.update(stream.toByteArray()); |
| byte[] digest = sha1.digest(); |
| internalReset(); |
| return digest; |
| } |
| |
| private void internalReset() { |
| sha1.reset(); |
| stream.reset(); |
| } |
| } |