public static decodeTypeString ( AnyObjectId id, byte typeString, byte endMark, MutableInteger offset ) : int | ||
id | AnyObjectId |
/// |
typeString | byte | string version of the type code. |
endMark | byte | /// Character immediately following the type string. Usually ' ' /// (space) or '\n' (line feed). /// |
offset | MutableInteger |
/// Position within |
return | int |
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); } }