View Javadoc
1   /*
2    * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  
11  package org.eclipse.jgit.internal.storage.file;
12  
13  import java.io.IOException;
14  import java.io.OutputStream;
15  
16  import org.eclipse.jgit.transport.PackedObjectInfo;
17  import org.eclipse.jgit.util.NB;
18  
19  /**
20   * Creates the version 2 pack table of contents files.
21   *
22   * @see PackIndexWriter
23   * @see PackIndexV2
24   */
25  class PackIndexWriterV2 extends PackIndexWriter {
26  	private static final int MAX_OFFSET_32 = 0x7fffffff;
27  	private static final int IS_OFFSET_64 = 0x80000000;
28  
29  	PackIndexWriterV2(final OutputStream dst) {
30  		super(dst);
31  	}
32  
33  	/** {@inheritDoc} */
34  	@Override
35  	protected void writeImpl() throws IOException {
36  		writeTOC(2);
37  		writeFanOutTable();
38  		writeObjectNames();
39  		writeCRCs();
40  		writeOffset32();
41  		writeOffset64();
42  		writeChecksumFooter();
43  	}
44  
45  	private void writeObjectNames() throws IOException {
46  		for (PackedObjectInfo oe : entries)
47  			oe.copyRawTo(out);
48  	}
49  
50  	private void writeCRCs() throws IOException {
51  		for (PackedObjectInfo oe : entries) {
52  			NB.encodeInt32(tmp, 0, oe.getCRC());
53  			out.write(tmp, 0, 4);
54  		}
55  	}
56  
57  	private void writeOffset32() throws IOException {
58  		int o64 = 0;
59  		for (PackedObjectInfo oe : entries) {
60  			final long o = oe.getOffset();
61  			if (o <= MAX_OFFSET_32)
62  				NB.encodeInt32(tmp, 0, (int) o);
63  			else
64  				NB.encodeInt32(tmp, 0, IS_OFFSET_64 | o64++);
65  			out.write(tmp, 0, 4);
66  		}
67  	}
68  
69  	private void writeOffset64() throws IOException {
70  		for (PackedObjectInfo oe : entries) {
71  			final long o = oe.getOffset();
72  			if (MAX_OFFSET_32 < o) {
73  				NB.encodeInt64(tmp, 0, o);
74  				out.write(tmp, 0, 8);
75  			}
76  		}
77  	}
78  }