public override void materialize(WindowCursor curs) { if (cachedBytes != null) { return; } if (objectType != OBJ_COMMIT) { UnpackedObjectCache.Entry cache = pack.readCache(dataOffset); if (cache != null) { curs.release(); objectType = cache.type; objectSize = cache.data.Length; cachedBytes = cache.data; return; } } try { PackedObjectLoader baseLoader = getBaseLoader(curs); baseLoader.materialize(curs); cachedBytes = BinaryDelta.Apply(baseLoader.getCachedBytes(), pack.decompress(dataOffset, deltaSize, curs)); curs.release(); objectType = baseLoader.getType(); objectSize = cachedBytes.Length; if (objectType != OBJ_COMMIT) pack.saveCache(dataOffset, cachedBytes, objectType); } catch (IOException dfe) { CorruptObjectException coe; coe = new CorruptObjectException("object at " + dataOffset + " in " + pack.File.FullName + " has bad zlib stream", dfe); throw coe; } }
private UnpackedObjectLoader(byte[] compressed, AnyObjectId id) { // Try to determine if this is a legacy format loose object or // a new style loose object. The legacy format was completely // compressed with zlib so the first byte must be 0x78 (15-bit // window size, deflated) and the first 16 bit word must be // evenly divisible by 31. Otherwise its a new style loose // object. // Inflater inflater = InflaterCache.Instance.get(); try { int fb = compressed[0] & 0xff; if (fb == 0x78 && (((fb << 8) | compressed[1] & 0xff) % 31) == 0) { inflater.SetInput(compressed); var hdr = new byte[64]; int avail = 0; while (!inflater.IsFinished && avail < hdr.Length) { try { avail += inflater.Inflate(hdr, avail, hdr.Length - avail); } catch (IOException dfe) { var coe = new CorruptObjectException(id, "bad stream", dfe); //inflater.end(); throw coe; } } if (avail < 5) { throw new CorruptObjectException(id, "no header"); } var p = new MutableInteger(); _objectType = Constants.decodeTypeString(id, hdr, (byte)' ', p); _objectSize = RawParseUtils.parseBase10(hdr, p.value, p); if (_objectSize < 0) { throw new CorruptObjectException(id, "negative size"); } if (hdr[p.value++] != 0) { throw new CorruptObjectException(id, "garbage after size"); } _bytes = new byte[_objectSize]; if (p.value < avail) { Array.Copy(hdr, p.value, _bytes, 0, avail - p.value); } Decompress(id, inflater, avail - p.value); } else { int p = 0; int c = compressed[p++] & 0xff; int typeCode = (c >> 4) & 7; int size = c & 15; int shift = 4; while ((c & 0x80) != 0) { c = compressed[p++] & 0xff; size += (c & 0x7f) << shift; shift += 7; } switch (typeCode) { case Constants.OBJ_COMMIT: case Constants.OBJ_TREE: case Constants.OBJ_BLOB: case Constants.OBJ_TAG: _objectType = typeCode; break; default: throw new CorruptObjectException(id, "invalid type"); } _objectSize = size; _bytes = new byte[_objectSize]; inflater.SetInput(compressed, p, compressed.Length - p); Decompress(id, inflater, 0); } } finally { InflaterCache.Instance.release(inflater); } }
public override void materialize(WindowCursor curs) { if (cachedBytes != null) { return; } if (objectType != OBJ_COMMIT) { UnpackedObjectCache.Entry cache = pack.readCache(dataOffset); if (cache != null) { curs.release(); cachedBytes = cache.data; return; } } try { cachedBytes = pack.decompress(dataOffset, objectSize, curs); curs.release(); if (objectType != OBJ_COMMIT) pack.saveCache(dataOffset, cachedBytes, objectType); } catch (IOException dfe) { CorruptObjectException coe; coe = new CorruptObjectException("object at " + dataOffset + " in " + pack.File.FullName + " has bad zlib stream", dfe); throw coe; } }
private void Decompress(AnyObjectId id, Inflater inf, int p) { try { while (!inf.IsFinished) { p += inf.Inflate(_bytes, p, _objectSize - p); } } catch (IOException dfe) { var coe = new CorruptObjectException(id, "bad stream", dfe); throw coe; } if (p != _objectSize) { throw new CorruptObjectException(id, "incorrect Length"); } }