/// <exception cref="System.IO.IOException"></exception> internal override void Write(PackOutputStream @out, long pos, int cnt, MessageDigest digest) { int ptr = (int)(pos - start); @out.Write(array, ptr, cnt); if (digest != null) { digest.Update(array, ptr, cnt); } }
/// <exception cref="System.IO.IOException"></exception> internal override void Write(PackOutputStream @out, long pos, int cnt, MessageDigest digest) { ByteBuffer s = buffer.Slice(); s.Position((int)(pos - start)); while (0 < cnt) { byte[] buf = @out.GetCopyBuffer(); int n = Math.Min(cnt, buf.Length); s.Get(buf, 0, n); @out.Write(buf, 0, n); if (digest != null) { digest.Update(buf, 0, n); } cnt -= n; } }
/// <exception cref="System.IO.IOException"></exception> /// <exception cref="NGit.Errors.StoredObjectRepresentationNotAvailableException"></exception> private void CopyAsIs2(PackOutputStream @out, LocalObjectToPack src, bool validate , WindowCursor curs) { CRC32 crc1 = validate ? new CRC32() : null; CRC32 crc2 = validate ? new CRC32() : null; byte[] buf = @out.GetCopyBuffer(); // Rip apart the header so we can discover the size. // ReadFully(src.offset, buf, 0, 20, curs); int c = buf[0] & unchecked ((int)(0xff)); int typeCode = (c >> 4) & 7; long inflatedLength = c & 15; int shift = 4; int headerCnt = 1; while ((c & unchecked ((int)(0x80))) != 0) { c = buf[headerCnt++] & unchecked ((int)(0xff)); inflatedLength += ((long)(c & unchecked ((int)(0x7f)))) << shift; shift += 7; } if (typeCode == Constants.OBJ_OFS_DELTA) { do { c = buf[headerCnt++] & unchecked ((int)(0xff)); }while ((c & 128) != 0); if (validate) { crc1.Update(buf, 0, headerCnt); crc2.Update(buf, 0, headerCnt); } } else { if (typeCode == Constants.OBJ_REF_DELTA) { if (validate) { crc1.Update(buf, 0, headerCnt); crc2.Update(buf, 0, headerCnt); } ReadFully(src.offset + headerCnt, buf, 0, 20, curs); if (validate) { crc1.Update(buf, 0, 20); crc2.Update(buf, 0, 20); } headerCnt += 20; } else { if (validate) { crc1.Update(buf, 0, headerCnt); crc2.Update(buf, 0, headerCnt); } } } long dataOffset = src.offset + headerCnt; long dataLength = src.length; long expectedCRC; ByteArrayWindow quickCopy; // Verify the object isn't corrupt before sending. If it is, // we report it missing instead. // try { quickCopy = curs.QuickCopy(this, dataOffset, dataLength); if (validate && Idx().HasCRC32Support()) { // Index has the CRC32 code cached, validate the object. // expectedCRC = Idx().FindCRC32(src); if (quickCopy != null) { quickCopy.Crc32(crc1, dataOffset, (int)dataLength); } else { long pos = dataOffset; long cnt = dataLength; while (cnt > 0) { int n = (int)Math.Min(cnt, buf.Length); ReadFully(pos, buf, 0, n, curs); crc1.Update(buf, 0, n); pos += n; cnt -= n; } } if (crc1.GetValue() != expectedCRC) { SetCorrupt(src.offset); throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().objectAtHasBadZlibStream , Sharpen.Extensions.ValueOf(src.offset), GetPackFile())); } } else { if (validate) { // We don't have a CRC32 code in the index, so compute it // now while inflating the raw data to get zlib to tell us // whether or not the data is safe. // Inflater inf = curs.Inflater(); byte[] tmp = new byte[1024]; if (quickCopy != null) { quickCopy.Check(inf, tmp, dataOffset, (int)dataLength); } else { long pos = dataOffset; long cnt = dataLength; while (cnt > 0) { int n = (int)Math.Min(cnt, buf.Length); ReadFully(pos, buf, 0, n, curs); crc1.Update(buf, 0, n); inf.SetInput(buf, 0, n); while (inf.Inflate(tmp, 0, tmp.Length) > 0) { continue; } pos += n; cnt -= n; } } if (!inf.IsFinished || inf.TotalIn != dataLength) { SetCorrupt(src.offset); throw new EOFException(MessageFormat.Format(JGitText.Get().shortCompressedStreamAt , Sharpen.Extensions.ValueOf(src.offset))); } expectedCRC = crc1.GetValue(); } else { expectedCRC = -1; } } } catch (SharpZipBaseException dataFormat) { SetCorrupt(src.offset); CorruptObjectException corruptObject = new CorruptObjectException(MessageFormat.Format (JGitText.Get().objectAtHasBadZlibStream, Sharpen.Extensions.ValueOf(src.offset) , GetPackFile())); Sharpen.Extensions.InitCause(corruptObject, dataFormat); StoredObjectRepresentationNotAvailableException gone; gone = new StoredObjectRepresentationNotAvailableException(src); Sharpen.Extensions.InitCause(gone, corruptObject); throw gone; } catch (IOException ioError) { StoredObjectRepresentationNotAvailableException gone; gone = new StoredObjectRepresentationNotAvailableException(src); Sharpen.Extensions.InitCause(gone, ioError); throw gone; } if (quickCopy != null) { // The entire object fits into a single byte array window slice, // and we have it pinned. Write this out without copying. // @out.WriteHeader(src, inflatedLength); quickCopy.Write(@out, dataOffset, (int)dataLength, null); } else { if (dataLength <= buf.Length) { // Tiny optimization: Lots of objects are very small deltas or // deflated commits that are likely to fit in the copy buffer. // if (!validate) { long pos = dataOffset; long cnt = dataLength; while (cnt > 0) { int n = (int)Math.Min(cnt, buf.Length); ReadFully(pos, buf, 0, n, curs); pos += n; cnt -= n; } } @out.WriteHeader(src, inflatedLength); @out.Write(buf, 0, (int)dataLength); } else { // Now we are committed to sending the object. As we spool it out, // check its CRC32 code to make sure there wasn't corruption between // the verification we did above, and us actually outputting it. // @out.WriteHeader(src, inflatedLength); long pos = dataOffset; long cnt = dataLength; while (cnt > 0) { int n = (int)Math.Min(cnt, buf.Length); ReadFully(pos, buf, 0, n, curs); if (validate) { crc2.Update(buf, 0, n); } @out.Write(buf, 0, n); pos += n; cnt -= n; } if (validate && crc2.GetValue() != expectedCRC) { throw new CorruptObjectException(MessageFormat.Format(JGitText.Get().objectAtHasBadZlibStream , Sharpen.Extensions.ValueOf(src.offset), GetPackFile())); } } } }