Esempio n. 1
0
		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);
			}
		}
Esempio n. 2
0
		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");
			}
		}