/*
 * Copyright (C) 2008-2009, Google Inc.
 * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
 * Copyright (C) 2010, Matthias Sohn <matthias.sohn@sap.com>
 * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> 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.dircache;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.text.MessageFormat;
import java.time.Instant;
import java.util.Arrays;

import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.util.IO;
import org.eclipse.jgit.util.MutableInteger;
import org.eclipse.jgit.util.NB;
import org.eclipse.jgit.util.SystemReader;

/**
 * A single file (or stage of a file) in a
 * {@link org.eclipse.jgit.dircache.DirCache}.
 * <p>
 * An entry represents exactly one stage of a file. If a file path is unmerged
 * then multiple DirCacheEntry instances may appear for the same path name.
 */
public class DirCacheEntry {
	private static final byte[] nullpad = new byte[8];

	/** The standard (fully merged) stage for an entry. */
	public static final int STAGE_0 = 0;

	/** The base tree revision for an entry. */
	public static final int STAGE_1 = 1;

	/** The first tree revision (usually called "ours"). */
	public static final int STAGE_2 = 2;

	/** The second tree revision (usually called "theirs"). */
	public static final int STAGE_3 = 3;

	private static final int P_CTIME = 0;

	// private static final int P_CTIME_NSEC = 4;

	private static final int P_MTIME = 8;

	// private static final int P_MTIME_NSEC = 12;

	// private static final int P_DEV = 16;

	// private static final int P_INO = 20;

	private static final int P_MODE = 24;

	// private static final int P_UID = 28;

	// private static final int P_GID = 32;

	private static final int P_SIZE = 36;

	private static final int P_OBJECTID = 40;

	private static final int P_FLAGS = 60;
	private static final int P_FLAGS2 = 62;

	/** Mask applied to data in {@link #P_FLAGS} to get the name length. */
	private static final int NAME_MASK = 0xfff;

	private static final int INTENT_TO_ADD = 0x20000000;
	private static final int SKIP_WORKTREE = 0x40000000;
	private static final int EXTENDED_FLAGS = (INTENT_TO_ADD | SKIP_WORKTREE);

	private static final int INFO_LEN = 62;
	private static final int INFO_LEN_EXTENDED = 64;

	private static final int EXTENDED = 0x40;
	private static final int ASSUME_VALID = 0x80;

	/** In-core flag signaling that the entry should be considered as modified. */
	private static final int UPDATE_NEEDED = 0x1;

	/** (Possibly shared) header information storage. */
	private final byte[] info;

	/** First location within {@link #info} where our header starts. */
	private final int infoOffset;

	/** Our encoded path name, from the root of the repository. */
	final byte[] path;

	/** Flags which are never stored to disk. */
	private byte inCoreFlags;

	DirCacheEntry(final byte[] sharedInfo, final MutableInteger infoAt,
			final InputStream in, final MessageDigest md, final Instant smudge)
			throws IOException {
		info = sharedInfo;
		infoOffset = infoAt.value;

		IO.readFully(in, info, infoOffset, INFO_LEN);

		final int len;
		if (isExtended()) {
			len = INFO_LEN_EXTENDED;
			IO.readFully(in, info, infoOffset + INFO_LEN, INFO_LEN_EXTENDED - INFO_LEN);

			if ((getExtendedFlags() & ~EXTENDED_FLAGS) != 0)
				throw new IOException(MessageFormat.format(JGitText.get()
						.DIRCUnrecognizedExtendedFlags, String.valueOf(getExtendedFlags())));
		} else
			len = INFO_LEN;

		infoAt.value += len;
		md.update(info, infoOffset, len);

		int pathLen = NB.decodeUInt16(info, infoOffset + P_FLAGS) & NAME_MASK;
		int skipped = 0;
		if (pathLen < NAME_MASK) {
			path = new byte[pathLen];
			IO.readFully(in, path, 0, pathLen);
			md.update(path, 0, pathLen);
		} else {
			final ByteArrayOutputStream tmp = new ByteArrayOutputStream();
			{
				final byte[] buf = new byte[NAME_MASK];
				IO.readFully(in, buf, 0, NAME_MASK);
				tmp.write(buf);
			}
			for (;;) {
				final int c = in.read();
				if (c < 0)
					throw new EOFException(JGitText.get().shortReadOfBlock);
				if (c == 0)
					break;
				tmp.write(c);
			}
			path = tmp.toByteArray();
			pathLen = path.length;
			skipped = 1; // we already skipped 1 '\0' above to break the loop.
			md.update(path, 0, pathLen);
			md.update((byte) 0);
		}

		try {
			checkPath(path);
		} catch (InvalidPathException e) {
			CorruptObjectException p =
				new CorruptObjectException(e.getMessage());
			if (e.getCause() != null)
				p.initCause(e.getCause());
			throw p;
		}

		// Index records are padded out to the next 8 byte alignment
		// for historical reasons related to how C Git read the files.
		//
		final int actLen = len + pathLen;
		final int expLen = (actLen + 8) & ~7;
		final int padLen = expLen - actLen - skipped;
		if (padLen > 0) {
			IO.skipFully(in, padLen);
			md.update(nullpad, 0, padLen);
		}

		if (mightBeRacilyClean(smudge)) {
			smudgeRacilyClean();
		}
	}

	/**
	 * Create an empty entry at stage 0.
	 *
	 * @param newPath
	 *            name of the cache entry.
	 * @throws java.lang.IllegalArgumentException
	 *             If the path starts or ends with "/", or contains "//" either
	 *             "\0". These sequences are not permitted in a git tree object
	 *             or DirCache file.
	 */
	public DirCacheEntry(String newPath) {
		this(Constants.encode(newPath), STAGE_0);
	}

	/**
	 * Create an empty entry at the specified stage.
	 *
	 * @param newPath
	 *            name of the cache entry.
	 * @param stage
	 *            the stage index of the new entry.
	 * @throws java.lang.IllegalArgumentException
	 *             If the path starts or ends with "/", or contains "//" either
	 *             "\0". These sequences are not permitted in a git tree object
	 *             or DirCache file.  Or if {@code stage} is outside of the
	 *             range 0..3, inclusive.
	 */
	public DirCacheEntry(String newPath, int stage) {
		this(Constants.encode(newPath), stage);
	}

	/**
	 * Create an empty entry at stage 0.
	 *
	 * @param newPath
	 *            name of the cache entry, in the standard encoding.
	 * @throws java.lang.IllegalArgumentException
	 *             If the path starts or ends with "/", or contains "//" either
	 *             "\0". These sequences are not permitted in a git tree object
	 *             or DirCache file.
	 */
	public DirCacheEntry(byte[] newPath) {
		this(newPath, STAGE_0);
	}

	/**
	 * Create an empty entry at the specified stage.
	 *
	 * @param path
	 *            name of the cache entry, in the standard encoding.
	 * @param stage
	 *            the stage index of the new entry.
	 * @throws java.lang.IllegalArgumentException
	 *             If the path starts or ends with "/", or contains "//" either
	 *             "\0". These sequences are not permitted in a git tree object
	 *             or DirCache file.  Or if {@code stage} is outside of the
	 *             range 0..3, inclusive.
	 */
	@SuppressWarnings("boxing")
	public DirCacheEntry(byte[] path, int stage) {
		checkPath(path);
		if (stage < 0 || 3 < stage)
			throw new IllegalArgumentException(MessageFormat.format(
					JGitText.get().invalidStageForPath,
					stage, toString(path)));

		info = new byte[INFO_LEN];
		infoOffset = 0;
		this.path = path;

		int flags = ((stage & 0x3) << 12);
		if (path.length < NAME_MASK)
			flags |= path.length;
		else
			flags |= NAME_MASK;
		NB.encodeInt16(info, infoOffset + P_FLAGS, flags);
	}

	/**
	 * Duplicate DirCacheEntry with same path and copied info.
	 * <p>
	 * The same path buffer is reused (avoiding copying), however a new info
	 * buffer is created and its contents are copied.
	 *
	 * @param src
	 *            entry to clone.
	 * @since 4.2
	 */
	public DirCacheEntry(DirCacheEntry src) {
		path = src.path;
		info = new byte[INFO_LEN];
		infoOffset = 0;
		System.arraycopy(src.info, src.infoOffset, info, 0, INFO_LEN);
	}

	void write(OutputStream os) throws IOException {
		final int len = isExtended() ? INFO_LEN_EXTENDED : INFO_LEN;
		final int pathLen = path.length;
		os.write(info, infoOffset, len);
		os.write(path, 0, pathLen);

		// Index records are padded out to the next 8 byte alignment
		// for historical reasons related to how C Git read the files.
		//
		final int actLen = len + pathLen;
		final int expLen = (actLen + 8) & ~7;
		if (actLen != expLen)
			os.write(nullpad, 0, expLen - actLen);
	}

	/**
	 * Is it possible for this entry to be accidentally assumed clean?
	 * <p>
	 * The "racy git" problem happens when a work file can be updated faster
	 * than the filesystem records file modification timestamps. It is possible
	 * for an application to edit a work file, update the index, then edit it
	 * again before the filesystem will give the work file a new modification
	 * timestamp. This method tests to see if file was written out at the same
	 * time as the index.
	 *
	 * @param smudge_s
	 *            seconds component of the index's last modified time.
	 * @param smudge_ns
	 *            nanoseconds component of the index's last modified time.
	 * @return true if extra careful checks should be used.
	 * @deprecated use {@link #mightBeRacilyClean(Instant)} instead
	 */
	@Deprecated
	public final boolean mightBeRacilyClean(int smudge_s, int smudge_ns) {
		return mightBeRacilyClean(Instant.ofEpochSecond(smudge_s, smudge_ns));
	}

	/**
	 * Is it possible for this entry to be accidentally assumed clean?
	 * <p>
	 * The "racy git" problem happens when a work file can be updated faster
	 * than the filesystem records file modification timestamps. It is possible
	 * for an application to edit a work file, update the index, then edit it
	 * again before the filesystem will give the work file a new modification
	 * timestamp. This method tests to see if file was written out at the same
	 * time as the index.
	 *
	 * @param smudge
	 *            index's last modified time.
	 * @return true if extra careful checks should be used.
	 * @since 5.1.9
	 */
	public final boolean mightBeRacilyClean(Instant smudge) {
		// If the index has a modification time then it came from disk
		// and was not generated from scratch in memory. In such cases
		// the entry is 'racily clean' if the entry's cached modification
		// time is equal to or later than the index modification time. In
		// such cases the work file is too close to the index to tell if
		// it is clean or not based on the modification time alone.
		//
		final int base = infoOffset + P_MTIME;
		final int mtime = NB.decodeInt32(info, base);
		if ((int) smudge.getEpochSecond() == mtime) {
			return smudge.getNano() <= NB.decodeInt32(info, base + 4);
		}
		return false;
	}

	/**
	 * Force this entry to no longer match its working tree file.
	 * <p>
	 * This avoids the "racy git" problem by making this index entry no longer
	 * match the file in the working directory. Later git will be forced to
	 * compare the file content to ensure the file matches the working tree.
	 */
	public final void smudgeRacilyClean() {
		// To mark an entry racily clean we set its length to 0 (like native git
		// does). Entries which are not racily clean and have zero length can be
		// distinguished from racily clean entries by checking P_OBJECTID
		// against the SHA1 of empty content. When length is 0 and P_OBJECTID is
		// different from SHA1 of empty content we know the entry is marked
		// racily clean
		final int base = infoOffset + P_SIZE;
		Arrays.fill(info, base, base + 4, (byte) 0);
	}

	/**
	 * Check whether this entry has been smudged or not
	 * <p>
	 * If a blob has length 0 we know its id, see
	 * {@link org.eclipse.jgit.lib.Constants#EMPTY_BLOB_ID}. If an entry has
	 * length 0 and an ID different from the one for empty blob we know this
	 * entry was smudged.
	 *
	 * @return <code>true</code> if the entry is smudged, <code>false</code>
	 *         otherwise
	 */
	public final boolean isSmudged() {
		final int base = infoOffset + P_OBJECTID;
		return (getLength() == 0) && (Constants.EMPTY_BLOB_ID.compareTo(info, base) != 0);
	}

	final byte[] idBuffer() {
		return info;
	}

	final int idOffset() {
		return infoOffset + P_OBJECTID;
	}

	/**
	 * Is this entry always thought to be unmodified?
	 * <p>
	 * Most entries in the index do not have this flag set. Users may however
	 * set them on if the file system stat() costs are too high on this working
	 * directory, such as on NFS or SMB volumes.
	 *
	 * @return true if we must assume the entry is unmodified.
	 */
	public boolean isAssumeValid() {
		return (info[infoOffset + P_FLAGS] & ASSUME_VALID) != 0;
	}

	/**
	 * Set the assume valid flag for this entry,
	 *
	 * @param assume
	 *            true to ignore apparent modifications; false to look at last
	 *            modified to detect file modifications.
	 */
	public void setAssumeValid(boolean assume) {
		if (assume)
			info[infoOffset + P_FLAGS] |= (byte) ASSUME_VALID;
		else
			info[infoOffset + P_FLAGS] &= (byte) ~ASSUME_VALID;
	}

	/**
	 * Whether this entry should be checked for changes
	 *
	 * @return {@code true} if this entry should be checked for changes
	 */
	public boolean isUpdateNeeded() {
		return (inCoreFlags & UPDATE_NEEDED) != 0;
	}

	/**
	 * Set whether this entry must be checked for changes
	 *
	 * @param updateNeeded
	 *            whether this entry must be checked for changes
	 */
	public void setUpdateNeeded(boolean updateNeeded) {
		if (updateNeeded)
			inCoreFlags |= (byte) UPDATE_NEEDED;
		else
			inCoreFlags &= (byte) ~UPDATE_NEEDED;
	}

	/**
	 * Get the stage of this entry.
	 * <p>
	 * Entries have one of 4 possible stages: 0-3.
	 *
	 * @return the stage of this entry.
	 */
	public int getStage() {
		return (info[infoOffset + P_FLAGS] >>> 4) & 0x3;
	}

	/**
	 * Returns whether this entry should be skipped from the working tree.
	 *
	 * @return true if this entry should be skipepd.
	 */
	public boolean isSkipWorkTree() {
		return (getExtendedFlags() & SKIP_WORKTREE) != 0;
	}

	/**
	 * Returns whether this entry is intent to be added to the Index.
	 *
	 * @return true if this entry is intent to add.
	 */
	public boolean isIntentToAdd() {
		return (getExtendedFlags() & INTENT_TO_ADD) != 0;
	}

	/**
	 * Returns whether this entry is in the fully-merged stage (0).
	 *
	 * @return true if this entry is merged
	 * @since 2.2
	 */
	public boolean isMerged() {
		return getStage() == STAGE_0;
	}

	/**
	 * Obtain the raw {@link org.eclipse.jgit.lib.FileMode} bits for this entry.
	 *
	 * @return mode bits for the entry.
	 * @see FileMode#fromBits(int)
	 */
	public int getRawMode() {
		return NB.decodeInt32(info, infoOffset + P_MODE);
	}

	/**
	 * Obtain the {@link org.eclipse.jgit.lib.FileMode} for this entry.
	 *
	 * @return the file mode singleton for this entry.
	 */
	public FileMode getFileMode() {
		return FileMode.fromBits(getRawMode());
	}

	/**
	 * Set the file mode for this entry.
	 *
	 * @param mode
	 *            the new mode constant.
	 * @throws java.lang.IllegalArgumentException
	 *             If {@code mode} is
	 *             {@link org.eclipse.jgit.lib.FileMode#MISSING},
	 *             {@link org.eclipse.jgit.lib.FileMode#TREE}, or any other type
	 *             code not permitted in a tree object.
	 */
	public void setFileMode(FileMode mode) {
		switch (mode.getBits() & FileMode.TYPE_MASK) {
		case FileMode.TYPE_MISSING:
		case FileMode.TYPE_TREE:
			throw new IllegalArgumentException(MessageFormat.format(
					JGitText.get().invalidModeForPath, mode, getPathString()));
		}
		NB.encodeInt32(info, infoOffset + P_MODE, mode.getBits());
	}

	void setFileMode(int mode) {
		NB.encodeInt32(info, infoOffset + P_MODE, mode);
	}

	/**
	 * Get the cached creation time of this file, in milliseconds.
	 *
	 * @return cached creation time of this file, in milliseconds since the
	 *         Java epoch (midnight Jan 1, 1970 UTC).
	 */
	public long getCreationTime() {
		return decodeTS(P_CTIME);
	}

	/**
	 * Set the cached creation time of this file, using milliseconds.
	 *
	 * @param when
	 *            new cached creation time of the file, in milliseconds.
	 */
	public void setCreationTime(long when) {
		encodeTS(P_CTIME, when);
	}

	/**
	 * Get the cached last modification date of this file, in milliseconds.
	 * <p>
	 * One of the indicators that the file has been modified by an application
	 * changing the working tree is if the last modification time for the file
	 * differs from the time stored in this entry.
	 *
	 * @return last modification time of this file, in milliseconds since the
	 *         Java epoch (midnight Jan 1, 1970 UTC).
	 * @deprecated use {@link #getLastModifiedInstant()} instead
	 */
	@Deprecated
	public long getLastModified() {
		return decodeTS(P_MTIME);
	}

	/**
	 * Get the cached last modification date of this file.
	 * <p>
	 * One of the indicators that the file has been modified by an application
	 * changing the working tree is if the last modification time for the file
	 * differs from the time stored in this entry.
	 *
	 * @return last modification time of this file.
	 * @since 5.1.9
	 */
	public Instant getLastModifiedInstant() {
		return decodeTSInstant(P_MTIME);
	}

	/**
	 * Set the cached last modification date of this file, using milliseconds.
	 *
	 * @param when
	 *            new cached modification date of the file, in milliseconds.
	 * @deprecated use {@link #setLastModified(Instant)} instead
	 */
	@Deprecated
	public void setLastModified(long when) {
		encodeTS(P_MTIME, when);
	}

	/**
	 * Set the cached last modification date of this file.
	 *
	 * @param when
	 *            new cached modification date of the file.
	 * @since 5.1.9
	 */
	public void setLastModified(Instant when) {
		encodeTS(P_MTIME, when);
	}

	/**
	 * Get the cached size (mod 4 GB) (in bytes) of this file.
	 * <p>
	 * One of the indicators that the file has been modified by an application
	 * changing the working tree is if the size of the file (in bytes) differs
	 * from the size stored in this entry.
	 * <p>
	 * Note that this is the length of the file in the working directory, which
	 * may differ from the size of the decompressed blob if work tree filters
	 * are being used, such as LF&lt;-&gt;CRLF conversion.
	 * <p>
	 * Note also that for very large files, this is the size of the on-disk file
	 * truncated to 32 bits, i.e. modulo 4294967296. If that value is larger
	 * than 2GB, it will appear negative.
	 *
	 * @return cached size of the working directory file, in bytes.
	 */
	public int getLength() {
		return NB.decodeInt32(info, infoOffset + P_SIZE);
	}

	/**
	 * Set the cached size (in bytes) of this file.
	 *
	 * @param sz
	 *            new cached size of the file, as bytes. If the file is larger
	 *            than 2G, cast it to (int) before calling this method.
	 */
	public void setLength(int sz) {
		NB.encodeInt32(info, infoOffset + P_SIZE, sz);
	}

	/**
	 * Set the cached size (in bytes) of this file.
	 *
	 * @param sz
	 *            new cached size of the file, as bytes.
	 */
	public void setLength(long sz) {
		setLength((int) sz);
	}

	/**
	 * Obtain the ObjectId for the entry.
	 * <p>
	 * Using this method to compare ObjectId values between entries is
	 * inefficient as it causes memory allocation.
	 *
	 * @return object identifier for the entry.
	 */
	public ObjectId getObjectId() {
		return ObjectId.fromRaw(idBuffer(), idOffset());
	}

	/**
	 * Set the ObjectId for the entry.
	 *
	 * @param id
	 *            new object identifier for the entry. May be
	 *            {@link org.eclipse.jgit.lib.ObjectId#zeroId()} to remove the
	 *            current identifier.
	 */
	public void setObjectId(AnyObjectId id) {
		id.copyRawTo(idBuffer(), idOffset());
	}

	/**
	 * Set the ObjectId for the entry from the raw binary representation.
	 *
	 * @param bs
	 *            the raw byte buffer to read from. At least 20 bytes after p
	 *            must be available within this byte array.
	 * @param p
	 *            position to read the first byte of data from.
	 */
	public void setObjectIdFromRaw(byte[] bs, int p) {
		final int n = Constants.OBJECT_ID_LENGTH;
		System.arraycopy(bs, p, idBuffer(), idOffset(), n);
	}

	/**
	 * Get the entry's complete path.
	 * <p>
	 * This method is not very efficient and is primarily meant for debugging
	 * and final output generation. Applications should try to avoid calling it,
	 * and if invoked do so only once per interesting entry, where the name is
	 * absolutely required for correct function.
	 *
	 * @return complete path of the entry, from the root of the repository. If
	 *         the entry is in a subtree there will be at least one '/' in the
	 *         returned string.
	 */
	public String getPathString() {
		return toString(path);
	}

	/**
	 * Get a copy of the entry's raw path bytes.
	 *
	 * @return raw path bytes.
	 * @since 3.4
	 */
	public byte[] getRawPath() {
		return path.clone();
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Use for debugging only !
	 */
	@SuppressWarnings("nls")
	@Override
	public String toString() {
		return getFileMode() + " " + getLength() + " "
				+ getLastModifiedInstant()
				+ " " + getObjectId() + " " + getStage() + " "
				+ getPathString() + "\n";
	}

	/**
	 * Copy the ObjectId and other meta fields from an existing entry.
	 * <p>
	 * This method copies everything except the path from one entry to another,
	 * supporting renaming.
	 *
	 * @param src
	 *            the entry to copy ObjectId and meta fields from.
	 */
	public void copyMetaData(DirCacheEntry src) {
		copyMetaData(src, false);
	}

	/**
	 * Copy the ObjectId and other meta fields from an existing entry.
	 * <p>
	 * This method copies everything except the path and possibly stage from one
	 * entry to another, supporting renaming.
	 *
	 * @param src
	 *            the entry to copy ObjectId and meta fields from.
	 * @param keepStage
	 *            if true, the stage attribute will not be copied
	 */
	void copyMetaData(DirCacheEntry src, boolean keepStage) {
		int origflags = NB.decodeUInt16(info, infoOffset + P_FLAGS);
		int newflags = NB.decodeUInt16(src.info, src.infoOffset + P_FLAGS);
		System.arraycopy(src.info, src.infoOffset, info, infoOffset, INFO_LEN);
		final int pLen = origflags & NAME_MASK;
		final int SHIFTED_STAGE_MASK = 0x3 << 12;
		final int pStageShifted;
		if (keepStage)
			pStageShifted = origflags & SHIFTED_STAGE_MASK;
		else
			pStageShifted = newflags & SHIFTED_STAGE_MASK;
		NB.encodeInt16(info, infoOffset + P_FLAGS, pStageShifted | pLen
				| (newflags & ~NAME_MASK & ~SHIFTED_STAGE_MASK));
	}

	/**
	 * @return true if the entry contains extended flags.
	 */
	boolean isExtended() {
		return (info[infoOffset + P_FLAGS] & EXTENDED) != 0;
	}

	private long decodeTS(int pIdx) {
		final int base = infoOffset + pIdx;
		final int sec = NB.decodeInt32(info, base);
		final int ms = NB.decodeInt32(info, base + 4) / 1000000;
		return 1000L * sec + ms;
	}

	private Instant decodeTSInstant(int pIdx) {
		final int base = infoOffset + pIdx;
		final int sec = NB.decodeInt32(info, base);
		final int nano = NB.decodeInt32(info, base + 4);
		return Instant.ofEpochSecond(sec, nano);
	}

	private void encodeTS(int pIdx, long when) {
		final int base = infoOffset + pIdx;
		NB.encodeInt32(info, base, (int) (when / 1000));
		NB.encodeInt32(info, base + 4, ((int) (when % 1000)) * 1000000);
	}

	private void encodeTS(int pIdx, Instant when) {
		final int base = infoOffset + pIdx;
		NB.encodeInt32(info, base, (int) when.getEpochSecond());
		NB.encodeInt32(info, base + 4, when.getNano());
	}

	private int getExtendedFlags() {
		if (isExtended()) {
			return NB.decodeUInt16(info, infoOffset + P_FLAGS2) << 16;
		}
		return 0;
	}

	private static void checkPath(byte[] path) {
		try {
			SystemReader.getInstance().checkPath(path);
		} catch (CorruptObjectException e) {
			InvalidPathException p = new InvalidPathException(toString(path));
			p.initCause(e);
			throw p;
		}
	}

	static String toString(byte[] path) {
		return UTF_8.decode(ByteBuffer.wrap(path)).toString();
	}

	static int getMaximumInfoLength(boolean extended) {
		return extended ? INFO_LEN_EXTENDED : INFO_LEN;
	}
}
