/// <exception cref="System.IO.IOException"></exception> internal virtual ObjectLoader Load(WindowCursor curs, long pos) { try { byte[] ib = curs.tempId; PackFile.Delta delta = null; byte[] data = null; int type = Constants.OBJ_BAD; bool cached = false; for (; ;) { ReadFully(pos, ib, 0, 20, curs); int c = ib[0] & unchecked ((int)(0xff)); int typeCode = (c >> 4) & 7; long sz = c & 15; int shift = 4; int p = 1; while ((c & unchecked ((int)(0x80))) != 0) { c = ib[p++] & unchecked ((int)(0xff)); sz += ((long)(c & unchecked ((int)(0x7f)))) << shift; shift += 7; } switch (typeCode) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: { if (sz < curs.GetStreamFileThreshold()) { data = Decompress(pos + p, (int)sz, curs); } if (delta != null) { type = typeCode; goto SEARCH_break; } if (data != null) { return(new ObjectLoader.SmallObject(typeCode, data)); } else { return(new LargePackedWholeObject(typeCode, sz, pos, p, this, curs.db)); } goto case Constants.OBJ_OFS_DELTA; } case Constants.OBJ_OFS_DELTA: { c = ib[p++] & unchecked ((int)(0xff)); long @base = c & 127; while ((c & 128) != 0) { @base += 1; c = ib[p++] & unchecked ((int)(0xff)); @base <<= 7; @base += (c & 127); } @base = pos - @base; delta = new PackFile.Delta(delta, pos, (int)sz, p, @base); if (sz != delta.deltaSize) { goto SEARCH_break; } DeltaBaseCache.Entry e = curs.GetDeltaBaseCache().Get(this, @base); if (e != null) { type = e.type; data = e.data; cached = true; goto SEARCH_break; } pos = @base; goto SEARCH_continue; } case Constants.OBJ_REF_DELTA: { ReadFully(pos + p, ib, 0, 20, curs); long @base = FindDeltaBase(ObjectId.FromRaw(ib)); delta = new PackFile.Delta(delta, pos, (int)sz, p + 20, @base); if (sz != delta.deltaSize) { goto SEARCH_break; } DeltaBaseCache.Entry e = curs.GetDeltaBaseCache().Get(this, @base); if (e != null) { type = e.type; data = e.data; cached = true; goto SEARCH_break; } pos = @base; goto SEARCH_continue; } default: { throw new IOException(MessageFormat.Format(JGitText.Get().unknownObjectType, Sharpen.Extensions.ValueOf (typeCode))); } } SEARCH_continue :; } SEARCH_break :; // At this point there is at least one delta to apply to data. // (Whole objects with no deltas to apply return early above.) if (data == null) { return(delta.Large(this, curs)); } do { // Cache only the base immediately before desired object. if (cached) { cached = false; } else { if (delta.next == null) { curs.GetDeltaBaseCache().Store(this, delta.basePos, data, type); } } pos = delta.deltaPos; byte[] cmds = Decompress(pos + delta.hdrLen, delta.deltaSize, curs); if (cmds == null) { data = null; // Discard base in case of OutOfMemoryError return(delta.Large(this, curs)); } long sz = BinaryDelta.GetResultSize(cmds); if (int.MaxValue <= sz) { return(delta.Large(this, curs)); } byte[] result; try { result = new byte[(int)sz]; } catch (OutOfMemoryException) { data = null; // Discard base in case of OutOfMemoryError return(delta.Large(this, curs)); } BinaryDelta.Apply(data, cmds, result); data = result; delta = delta.next; }while (delta != null); return(new ObjectLoader.SmallObject(type, data)); } catch (SharpZipBaseException dfe) { CorruptObjectException coe = new CorruptObjectException(MessageFormat.Format(JGitText .Get().objectAtHasBadZlibStream, Sharpen.Extensions.ValueOf(pos), GetPackFile()) ); Sharpen.Extensions.InitCause(coe, dfe); throw coe; } }
/// <exception cref="System.IO.IOException"></exception> internal static ObjectLoader Open(InputStream @in, FilePath path, AnyObjectId id, WindowCursor wc) { try { @in = Buffer(@in); @in.Mark(20); byte[] hdr = new byte[64]; IOUtil.ReadFully(@in, hdr, 0, 2); if (IsStandardFormat(hdr)) { @in.Reset(); Inflater inf = wc.Inflater(); InputStream zIn = Inflate(@in, inf); int avail = ReadSome(zIn, hdr, 0, 64); if (avail < 5) { throw new CorruptObjectException(id, JGitText.Get().corruptObjectNoHeader); } MutableInteger p = new MutableInteger(); int type = Constants.DecodeTypeString(id, hdr, unchecked((byte)' '), p); long size = RawParseUtils.ParseLongBase10(hdr, p.value, p); if (size < 0) { throw new CorruptObjectException(id, JGitText.Get().corruptObjectNegativeSize); } if (hdr[p.value++] != 0) { throw new CorruptObjectException(id, JGitText.Get().corruptObjectGarbageAfterSize ); } if (path == null && int.MaxValue < size) { LargeObjectException.ExceedsByteArrayLimit e; e = new LargeObjectException.ExceedsByteArrayLimit(); e.SetObjectId(id); throw e; } if (size < wc.GetStreamFileThreshold() || path == null) { byte[] data = new byte[(int)size]; int n = avail - p.value; if (n > 0) { System.Array.Copy(hdr, p.value, data, 0, n); } IOUtil.ReadFully(zIn, data, n, data.Length - n); CheckValidEndOfStream(@in, inf, id, hdr); return new ObjectLoader.SmallObject(type, data); } return new UnpackedObject.LargeObject(type, size, path, id, wc.db); } else { ReadSome(@in, hdr, 2, 18); int c = hdr[0] & unchecked((int)(0xff)); int type = (c >> 4) & 7; long size = c & 15; int shift = 4; int p = 1; while ((c & unchecked((int)(0x80))) != 0) { c = hdr[p++] & unchecked((int)(0xff)); size += (c & unchecked((int)(0x7f))) << shift; shift += 7; } switch (type) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: { // Acceptable types for a loose object. break; } default: { throw new CorruptObjectException(id, JGitText.Get().corruptObjectInvalidType); } } if (path == null && int.MaxValue < size) { LargeObjectException.ExceedsByteArrayLimit e; e = new LargeObjectException.ExceedsByteArrayLimit(); e.SetObjectId(id); throw e; } if (size < wc.GetStreamFileThreshold() || path == null) { @in.Reset(); IOUtil.SkipFully(@in, p); Inflater inf = wc.Inflater(); InputStream zIn = Inflate(@in, inf); byte[] data = new byte[(int)size]; IOUtil.ReadFully(zIn, data, 0, data.Length); CheckValidEndOfStream(@in, inf, id, hdr); return new ObjectLoader.SmallObject(type, data); } return new UnpackedObject.LargeObject(type, size, path, id, wc.db); } } catch (SharpZipBaseException) { throw new CorruptObjectException(id, JGitText.Get().corruptObjectBadStream); } }
/// <exception cref="System.IO.IOException"></exception> internal static ObjectLoader Open(InputStream @in, FilePath path, AnyObjectId id, WindowCursor wc) { try { @in = Buffer(@in); @in.Mark(20); byte[] hdr = new byte[64]; IOUtil.ReadFully(@in, hdr, 0, 2); if (IsStandardFormat(hdr)) { @in.Reset(); Inflater inf = wc.Inflater(); InputStream zIn = Inflate(@in, inf); int avail = ReadSome(zIn, hdr, 0, 64); if (avail < 5) { throw new CorruptObjectException(id, JGitText.Get().corruptObjectNoHeader); } MutableInteger p = new MutableInteger(); int type = Constants.DecodeTypeString(id, hdr, unchecked ((byte)' '), p); long size = RawParseUtils.ParseLongBase10(hdr, p.value, p); if (size < 0) { throw new CorruptObjectException(id, JGitText.Get().corruptObjectNegativeSize); } if (hdr[p.value++] != 0) { throw new CorruptObjectException(id, JGitText.Get().corruptObjectGarbageAfterSize ); } if (path == null && int.MaxValue < size) { LargeObjectException.ExceedsByteArrayLimit e; e = new LargeObjectException.ExceedsByteArrayLimit(); e.SetObjectId(id); throw e; } if (size < wc.GetStreamFileThreshold() || path == null) { byte[] data = new byte[(int)size]; int n = avail - p.value; if (n > 0) { System.Array.Copy(hdr, p.value, data, 0, n); } IOUtil.ReadFully(zIn, data, n, data.Length - n); CheckValidEndOfStream(@in, inf, id, hdr); return(new ObjectLoader.SmallObject(type, data)); } return(new UnpackedObject.LargeObject(type, size, path, id, wc.db)); } else { ReadSome(@in, hdr, 2, 18); int c = hdr[0] & unchecked ((int)(0xff)); int type = (c >> 4) & 7; long size = c & 15; int shift = 4; int p = 1; while ((c & unchecked ((int)(0x80))) != 0) { c = hdr[p++] & unchecked ((int)(0xff)); size += ((long)(c & unchecked ((int)(0x7f)))) << shift; shift += 7; } switch (type) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: { // Acceptable types for a loose object. break; } default: { throw new CorruptObjectException(id, JGitText.Get().corruptObjectInvalidType); } } if (path == null && int.MaxValue < size) { LargeObjectException.ExceedsByteArrayLimit e; e = new LargeObjectException.ExceedsByteArrayLimit(); e.SetObjectId(id); throw e; } if (size < wc.GetStreamFileThreshold() || path == null) { @in.Reset(); IOUtil.SkipFully(@in, p); Inflater inf = wc.Inflater(); InputStream zIn = Inflate(@in, inf); byte[] data = new byte[(int)size]; IOUtil.ReadFully(zIn, data, 0, data.Length); CheckValidEndOfStream(@in, inf, id, hdr); return(new ObjectLoader.SmallObject(type, data)); } return(new UnpackedObject.LargeObject(type, size, path, id, wc.db)); } } catch (SharpZipBaseException) { throw new CorruptObjectException(id, JGitText.Get().corruptObjectBadStream); } }