ObjectIdSerializer.java

  1. /*
  2.  * Copyright (C) 2009, The Android Open Source Project
  3.  * Copyright (C) 2009, Shawn O. Pearce <spearce@spearce.org>
  4.  * Copyright (C) 2018, David Pursehouse <david.pursehouse@gmail.com> and others
  5.  *
  6.  * This program and the accompanying materials are made available under the
  7.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  8.  * https://www.eclipse.org/org/documents/edl-v10.php.
  9.  *
  10.  * SPDX-License-Identifier: BSD-3-Clause
  11.  */

  12. package org.eclipse.jgit.lib;

  13. import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;

  14. import java.io.IOException;
  15. import java.io.InputStream;
  16. import java.io.OutputStream;

  17. import org.eclipse.jgit.annotations.NonNull;
  18. import org.eclipse.jgit.annotations.Nullable;
  19. import org.eclipse.jgit.util.IO;

  20. /**
  21.  * Helper to serialize {@link ObjectId} instances. {@link ObjectId} is already
  22.  * serializable, but this class provides methods to handle null and non-null
  23.  * instances.
  24.  *
  25.  * @since 4.11
  26.  */
  27. public class ObjectIdSerializer {
  28.     /*
  29.      * Marker to indicate a null ObjectId instance.
  30.      */
  31.     private static final byte NULL_MARKER = 0;

  32.     /*
  33.      * Marker to indicate a non-null ObjectId instance.
  34.      */
  35.     private static final byte NON_NULL_MARKER = 1;

  36.     /**
  37.      * Write a possibly null {@link ObjectId} to the stream, using markers to
  38.      * differentiate null and non-null instances.
  39.      *
  40.      * <p>
  41.      * If the id is non-null, writes a {@link #NON_NULL_MARKER} followed by the
  42.      * id's words. If it is null, writes a {@link #NULL_MARKER} and nothing
  43.      * else.
  44.      *
  45.      * @param out
  46.      *            the output stream
  47.      * @param id
  48.      *            the object id to serialize; may be null
  49.      * @throws IOException
  50.      *             the stream writing failed
  51.      */
  52.     public static void write(OutputStream out, @Nullable AnyObjectId id)
  53.             throws IOException {
  54.         if (id != null) {
  55.             out.write(NON_NULL_MARKER);
  56.             writeWithoutMarker(out, id);
  57.         } else {
  58.             out.write(NULL_MARKER);
  59.         }
  60.     }

  61.     /**
  62.      * Write a non-null {@link ObjectId} to the stream.
  63.      *
  64.      * @param out
  65.      *            the output stream
  66.      * @param id
  67.      *            the object id to serialize; never null
  68.      * @throws IOException
  69.      *             the stream writing failed
  70.      * @since 4.11
  71.      */
  72.     public static void writeWithoutMarker(OutputStream out, @NonNull AnyObjectId id)
  73.             throws IOException {
  74.         id.copyRawTo(out);
  75.     }

  76.     /**
  77.      * Read a possibly null {@link ObjectId} from the stream.
  78.      *
  79.      * Reads the first byte of the stream, which is expected to be either
  80.      * {@link #NON_NULL_MARKER} or {@link #NULL_MARKER}.
  81.      *
  82.      * @param in
  83.      *            the input stream
  84.      * @return the object id, or null
  85.      * @throws IOException
  86.      *             there was an error reading the stream
  87.      */
  88.     @Nullable
  89.     public static ObjectId read(InputStream in) throws IOException {
  90.         byte marker = (byte) in.read();
  91.         switch (marker) {
  92.         case NULL_MARKER:
  93.             return null;
  94.         case NON_NULL_MARKER:
  95.             return readWithoutMarker(in);
  96.         default:
  97.             throw new IOException("Invalid flag before ObjectId: " + marker); //$NON-NLS-1$
  98.         }
  99.     }

  100.     /**
  101.      * Read a non-null {@link ObjectId} from the stream.
  102.      *
  103.      * @param in
  104.      *            the input stream
  105.      * @return the object id; never null
  106.      * @throws IOException
  107.      *             there was an error reading the stream
  108.      * @since 4.11
  109.      */
  110.     @NonNull
  111.     public static ObjectId readWithoutMarker(InputStream in) throws IOException {
  112.         final byte[] b = new byte[OBJECT_ID_LENGTH];
  113.         IO.readFully(in, b, 0, OBJECT_ID_LENGTH);
  114.         return ObjectId.fromRaw(b);
  115.     }

  116.     private ObjectIdSerializer() {
  117.     }
  118. }