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); }
/** * 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); }
/** * Copy this ObjectId to a byte array. * * @param b * the buffer to copy to. * @param o * the offset within b to write at. */ public void copyRawTo(byte[] b, int o) { NB.encodeInt32(b, o, w1); NB.encodeInt32(b, o + 4, w2); NB.encodeInt32(b, o + 8, w3); NB.encodeInt32(b, o + 12, w4); NB.encodeInt32(b, o + 16, w5); }
void setFileMode(int mode) { NB.encodeInt32(info, infoOffset + P_MODE, mode); }
private static int writePackHeader(byte[] buf, int objectCount) { System.arraycopy(Constants.PACK_SIGNATURE, 0, buf, 0, 4); NB.encodeInt32(buf, 4, 2); // Always use pack version 2. NB.encodeInt32(buf, 8, objectCount); return 12; }
/** {@inheritDoc} */ @Override public void writeInt(int v) throws IOException { NB.encodeInt32(buf, 0, v); fd.write(buf, 0, 4); }
/** * Finish the digest and return the resulting hash. * <p> * Once {@code digest()} is called, this instance should be discarded. * * @return the bytes for the resulting hash. * @throws org.eclipse.jgit.util.sha1.Sha1CollisionException * if a collision was detected and safeHash is false. */ public byte[] digest() throws Sha1CollisionException { finish(); byte[] b = new byte[20]; NB.encodeInt32(b, 0, h.a); NB.encodeInt32(b, 4, h.b); NB.encodeInt32(b, 8, h.c); NB.encodeInt32(b, 12, h.d); NB.encodeInt32(b, 16, h.e); return b; }
private void writeOffset32() throws IOException { int o64 = 0; for (PackedObjectInfo oe : entries) { final long o = oe.getOffset(); if (o <= MAX_OFFSET_32) NB.encodeInt32(tmp, 0, (int) o); else NB.encodeInt32(tmp, 0, IS_OFFSET_64 | o64++); out.write(tmp, 0, 4); } }
final void writeFileHeader(int version, long objectCount) throws IOException { System.arraycopy(PACK_SIGNATURE, 0, headerBuffer, 0, 4); NB.encodeInt32(headerBuffer, 4, version); NB.encodeInt32(headerBuffer, 8, (int) objectCount); write(headerBuffer, 0, 12); ofsDelta = packWriter.isDeltaBaseAsOffset(); }
private void encodeHeader(byte[] hdr) { System.arraycopy(FILE_HEADER_MAGIC, 0, hdr, 0, 4); int bs = alignBlocks ? refBlockSize : 0; NB.encodeInt32(hdr, 4, (VERSION_1 << 24) | bs); NB.encodeInt64(hdr, 8, minUpdateIndex); NB.encodeInt64(hdr, 16, maxUpdateIndex); }
private void writeCRCs() throws IOException { for (PackedObjectInfo oe : entries) { NB.encodeInt32(tmp, 0, oe.getCRC()); out.write(tmp, 0, 4); } }
/** * Output the version 2 (and later) TOC header, with version number. * <p> * Post version 1 all index files start with a TOC header that makes the * file an invalid version 1 file, and then includes the version number. * This header is necessary to recognize a version 1 from a version 2 * formatted index. * * @param version * version number of this index format being written. * @throws java.io.IOException * an error occurred while writing to the output stream. */ protected void writeTOC(int version) throws IOException { out.write(TOC); NB.encodeInt32(tmp, 0, version); out.write(tmp, 0, 4); }
void flushBlock() throws IOException { if (cur > blockSize && blockType != INDEX_BLOCK_TYPE) { throw new IOException(JGitText.get().overflowedReftableBlock); } NB.encodeInt32(blockBuf, blockStart, (blockType << 24) | cur); if (blockType == LOG_BLOCK_TYPE) { // Log blocks are deflated after the block header. out.write(blockBuf, 0, 4); if (deflater != null) { deflater.reset(); } else { deflater = new Deflater(Deflater.BEST_COMPRESSION); compressor = new DeflaterOutputStream(out, deflater); } compressor.write(blockBuf, 4, cur - 4); compressor.finish(); } else { // Other blocks are uncompressed. out.write(blockBuf, 0, cur); } cur = 0; blockType = 0; blockStart = 0; }
origRemaining -= 12; NB.encodeInt32(buf, 8, getObjectCount()); out.seek(0); out.write(buf, 0, 12);
/** * Output the standard 256 entry first-level fan-out table. * <p> * The fan-out table is 4 KB in size, holding 256 32-bit unsigned integer * counts. Each count represents the number of objects within this index * whose {@link org.eclipse.jgit.lib.ObjectId#getFirstByte()} matches the * count's position in the fan-out table. * * @throws java.io.IOException * an error occurred while writing to the output stream. */ protected void writeFanOutTable() throws IOException { final int[] fanout = new int[256]; for (PackedObjectInfo po : entries) fanout[po.getFirstByte() & 0xff]++; for (int i = 1; i < 256; i++) fanout[i] += fanout[i - 1]; for (int n : fanout) { NB.encodeInt32(tmp, 0, n); out.write(tmp, 0, 4); } }
private void finish() { int bufferLen = (int) (length & 63); if (bufferLen > 55) { // Last block is too small; pad, compress, pad another block. buffer[bufferLen++] = (byte) 0x80; Arrays.fill(buffer, bufferLen, 64, (byte) 0); compress(buffer, 0); Arrays.fill(buffer, 0, 56, (byte) 0); } else { // Last block can hold padding and length. buffer[bufferLen++] = (byte) 0x80; Arrays.fill(buffer, bufferLen, 56, (byte) 0); } // SHA-1 appends the length of the message in bits after the // padding block (above). Here length is in bytes. Multiply by // 8 by shifting by 3 as part of storing the 64 bit byte length // into the two words expected in the trailer. NB.encodeInt32(buffer, 56, (int) (length >>> (32 - 3))); NB.encodeInt32(buffer, 60, (int) (length << 3)); compress(buffer, 0); if (foundCollision) { ObjectId id = h.toObjectId(); LOG.warn("possible SHA-1 collision " + id.name()); //$NON-NLS-1$ throw new Sha1CollisionException(id); } }
/** * 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()); }
private void beginPack() throws IOException { objectList = new BlockList<>(); objectMap = new ObjectIdOwnerMap<>(); cache = DfsBlockCache.getInstance(); rollback = true; packDsc = db.newPack(DfsObjDatabase.PackSource.INSERT); DfsOutputStream dfsOut = db.writeFile(packDsc, PACK); packDsc.setBlockSize(PACK, dfsOut.blockSize()); packOut = new PackStream(dfsOut); packKey = packDsc.getStreamKey(PACK); // Write the header as though it were a single object pack. byte[] buf = packOut.hdrBuf; System.arraycopy(Constants.PACK_SIGNATURE, 0, buf, 0, 4); NB.encodeInt32(buf, 4, 2); // Always use pack version 2. NB.encodeInt32(buf, 8, 1); // Always assume 1 object. packOut.write(buf, 0, 12); }
/** {@inheritDoc} */ @Override protected void writeImpl() throws IOException { writeFanOutTable(); for (PackedObjectInfo oe : entries) { if (!canStore(oe)) throw new IOException(JGitText.get().packTooLargeForIndexVersion1); NB.encodeInt32(tmp, 0, (int) oe.getOffset()); oe.copyRawTo(tmp, 4); out.write(tmp); } writeChecksumFooter(); } }
private void writeFileFooter() { int ftrLen = FILE_FOOTER_LEN; byte[] ftr = new byte[ftrLen]; encodeHeader(ftr); NB.encodeInt64(ftr, 24, indexPosition(refs)); NB.encodeInt64(ftr, 32, (firstBlockPosition(objs) << 5) | objIdLen); NB.encodeInt64(ftr, 40, indexPosition(objs)); NB.encodeInt64(ftr, 48, firstBlockPosition(logs)); NB.encodeInt64(ftr, 56, indexPosition(logs)); CRC32 crc = new CRC32(); crc.update(ftr, 0, ftrLen - 4); NB.encodeInt32(ftr, ftrLen - 4, (int) crc.getValue()); out.write(ftr, 0, ftrLen); }