/// <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);
}
}