示例#1
0
  public void testSkip() throws IOException {
    init(32, 15);
    copy(2, 2);
    insert("ab");
    insert("cd");
    copy(4, 4);
    copy(0, 2);
    insert("efg");
    assertValidState();

    for (int p = 0; p < data.length; p++) {
      byte[] act = new byte[data.length];
      System.arraycopy(data, 0, act, 0, p);
      DeltaStream in = open();
      IO.skipFully(in, p);
      assertEquals(data.length - p, in.read(act, p, data.length - p));
      assertEquals(-1, in.read());
      assertTrue("skipping " + p, Arrays.equals(data, act));
    }

    // Skip all the way to the end should still recognize EOF.
    DeltaStream in = open();
    IO.skipFully(in, data.length);
    assertEquals(-1, in.read());
    assertEquals(0, in.skip(1));

    // Skip should not open the base as we move past it, but it
    // will open when we need to start copying data from it.
    final boolean[] opened = new boolean[1];
    in =
        new DeltaStream(new ByteArrayInputStream(delta)) {
          @Override
          protected long getBaseSize() throws IOException {
            return base.length;
          }

          @Override
          protected InputStream openBase() throws IOException {
            opened[0] = true;
            return new ByteArrayInputStream(base);
          }
        };
    IO.skipFully(in, 7);
    assertFalse("not yet open", opened[0]);
    assertEquals(data[7], in.read());
    assertTrue("now open", opened[0]);
  }
示例#2
0
  private void readFrom(final InputStream inStream) throws IOException, CorruptObjectException {
    final BufferedInputStream in = new BufferedInputStream(inStream);
    final MessageDigest md = Constants.newMessageDigest();

    // Read the index header and verify we understand it.
    //
    final byte[] hdr = new byte[20];
    IO.readFully(in, hdr, 0, 12);
    md.update(hdr, 0, 12);
    if (!is_DIRC(hdr)) throw new CorruptObjectException(JGitText.get().notADIRCFile);
    final int ver = NB.decodeInt32(hdr, 4);
    boolean extended = false;
    if (ver == 3) extended = true;
    else if (ver != 2)
      throw new CorruptObjectException(
          MessageFormat.format(JGitText.get().unknownDIRCVersion, Integer.valueOf(ver)));
    entryCnt = NB.decodeInt32(hdr, 8);
    if (entryCnt < 0) throw new CorruptObjectException(JGitText.get().DIRCHasTooManyEntries);

    snapshot = FileSnapshot.save(liveFile);
    int smudge_s = (int) (snapshot.lastModified() / 1000);
    int smudge_ns = ((int) (snapshot.lastModified() % 1000)) * 1000000;

    // Load the individual file entries.
    //
    final int infoLength = DirCacheEntry.getMaximumInfoLength(extended);
    final byte[] infos = new byte[infoLength * entryCnt];
    sortedEntries = new DirCacheEntry[entryCnt];

    final MutableInteger infoAt = new MutableInteger();
    for (int i = 0; i < entryCnt; i++)
      sortedEntries[i] = new DirCacheEntry(infos, infoAt, in, md, smudge_s, smudge_ns);

    // After the file entries are index extensions, and then a footer.
    //
    for (; ; ) {
      in.mark(21);
      IO.readFully(in, hdr, 0, 20);
      if (in.read() < 0) {
        // No extensions present; the file ended where we expected.
        //
        break;
      }

      in.reset();
      md.update(hdr, 0, 8);
      IO.skipFully(in, 8);

      long sz = NB.decodeUInt32(hdr, 4);
      switch (NB.decodeInt32(hdr, 0)) {
        case EXT_TREE:
          {
            if (Integer.MAX_VALUE < sz) {
              throw new CorruptObjectException(
                  MessageFormat.format(
                      JGitText.get().DIRCExtensionIsTooLargeAt,
                      formatExtensionName(hdr),
                      Long.valueOf(sz)));
            }
            final byte[] raw = new byte[(int) sz];
            IO.readFully(in, raw, 0, raw.length);
            md.update(raw, 0, raw.length);
            tree = new DirCacheTree(raw, new MutableInteger(), null);
            break;
          }
        default:
          if (hdr[0] >= 'A' && hdr[0] <= 'Z') {
            // The extension is optional and is here only as
            // a performance optimization. Since we do not
            // understand it, we can safely skip past it, after
            // we include its data in our checksum.
            //
            skipOptionalExtension(in, md, hdr, sz);
          } else {
            // The extension is not an optimization and is
            // _required_ to understand this index format.
            // Since we did not trap it above we must abort.
            //
            throw new CorruptObjectException(
                MessageFormat.format(
                    JGitText.get().DIRCExtensionNotSupportedByThisVersion,
                    formatExtensionName(hdr)));
          }
      }
    }

    readIndexChecksum = md.digest();
    if (!Arrays.equals(readIndexChecksum, hdr)) {
      throw new CorruptObjectException(JGitText.get().DIRCChecksumMismatch);
    }
  }