/// <summary>Copy this object to the output stream.</summary> /// <remarks> /// Copy this object to the output stream. /// <p> /// For some object store implementations, this method may be more efficient /// than reading from /// <see cref="OpenStream()">OpenStream()</see> /// into a temporary byte array, then /// writing to the destination stream. /// <p> /// The default implementation of this method is to copy with a temporary /// byte array for large objects, or to pass through the cached byte array /// for small objects. /// </remarks> /// <param name="out"> /// stream to receive the complete copy of this object's data. /// Caller is responsible for flushing or closing this stream /// after this method returns. /// </param> /// <exception cref="NGit.Errors.MissingObjectException">the object no longer exists. /// </exception> /// <exception cref="System.IO.IOException"> /// the object store cannot be accessed, or the stream cannot be /// written to. /// </exception> public virtual void CopyTo(OutputStream @out) { if (IsLarge()) { ObjectStream @in = OpenStream(); try { long sz = @in.GetSize(); byte[] tmp = new byte[8192]; long copied = 0; while (copied < sz) { int n = @in.Read(tmp); if (n < 0) { throw new EOFException(); } @out.Write(tmp, 0, n); copied += n; } if (0 <= @in.Read()) { throw new EOFException(); } } finally { @in.Close(); } } else { @out.Write(GetCachedBytes()); } }
/// <summary>Obtain a reference to the (possibly cached) bytes of this object.</summary> /// <remarks> /// Obtain a reference to the (possibly cached) bytes of this object. /// If the object size is less than or equal to /// <code>sizeLimit</code> /// this method /// will provide it as a byte array, even if /// <see cref="IsLarge()">IsLarge()</see> /// is true. This /// utility is useful for application code that absolutely must have the /// object as a single contiguous byte array in memory. /// This method offers direct access to the internal caches, potentially /// saving on data copies between the internal cache and higher level code. /// Callers who receive this reference <b>must not</b> modify its contents. /// Changes (if made) will affect the cache but not the repository itself. /// </remarks> /// <param name="sizeLimit"> /// maximum number of bytes to return. If the object size is /// larger than this limit and /// <see cref="IsLarge()">IsLarge()</see> /// is true, /// <see cref="NGit.Errors.LargeObjectException">NGit.Errors.LargeObjectException</see> /// will be thrown. /// </param> /// <returns>the cached bytes of this object. Do not modify it.</returns> /// <exception cref="NGit.Errors.LargeObjectException"> /// if the object is bigger than /// <code>sizeLimit</code> /// , or if /// <see cref="System.OutOfMemoryException">System.OutOfMemoryException</see> /// occurs during allocation of the /// result array. Callers should use /// <see cref="OpenStream()">OpenStream()</see> /// instead to access the contents. /// </exception> /// <exception cref="NGit.Errors.MissingObjectException">the object is large, and it no longer exists. /// </exception> /// <exception cref="System.IO.IOException">the object store cannot be accessed.</exception> public virtual byte[] GetCachedBytes(int sizeLimit) { if (!IsLarge()) { return(GetCachedBytes()); } ObjectStream @in = OpenStream(); try { long sz = @in.GetSize(); if (sizeLimit < sz) { throw new LargeObjectException.ExceedsLimit(sizeLimit, sz); } if (int.MaxValue < sz) { throw new LargeObjectException.ExceedsByteArrayLimit(); } byte[] buf; try { buf = new byte[(int)sz]; } catch (OutOfMemoryException notEnoughHeap) { throw new LargeObjectException.OutOfMemory(notEnoughHeap); } IOUtil.ReadFully(@in, buf, 0, buf.Length); return(buf); } finally { @in.Close(); } }