Exemplo n.º 1
0
        /// <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;
            }
        }
Exemplo n.º 2
0
		/// <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);
			}
		}
Exemplo n.º 3
0
        /// <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);
            }
        }