예제 #1
0
 /// <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());
     }
 }
        public virtual void TestLargeObjectLoader()
        {
            byte[]       act = GetRng().NextBytes(512);
            ObjectLoader ldr = new _ObjectLoader_122(act);

            NUnit.Framework.Assert.AreEqual(Constants.OBJ_BLOB, ldr.GetType());
            NUnit.Framework.Assert.AreEqual(act.Length, ldr.GetSize());
            NUnit.Framework.Assert.IsTrue(ldr.IsLarge(), "is large");
            try
            {
                ldr.GetCachedBytes();
                NUnit.Framework.Assert.Fail("did not throw on getCachedBytes()");
            }
            catch (LargeObjectException)
            {
            }
            // expected
            try
            {
                ldr.GetBytes();
                NUnit.Framework.Assert.Fail("did not throw on getBytes()");
            }
            catch (LargeObjectException)
            {
            }
            // expected
            try
            {
                ldr.GetCachedBytes(64);
                NUnit.Framework.Assert.Fail("did not throw on getCachedBytes(64)");
            }
            catch (LargeObjectException)
            {
            }
            // expected
            byte[] copy = ldr.GetCachedBytes(1024);
            NUnit.Framework.Assert.AreNotSame(act, copy);
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(act, copy), "same content");
            ObjectStream @in = ldr.OpenStream();

            NUnit.Framework.Assert.IsNotNull(@in, "has stream");
            NUnit.Framework.Assert.AreEqual(Constants.OBJ_BLOB, @in.GetType());
            NUnit.Framework.Assert.AreEqual(act.Length, @in.GetSize());
            NUnit.Framework.Assert.AreEqual(act.Length, @in.Available());
            NUnit.Framework.Assert.IsTrue(@in.MarkSupported(), "mark supported");
            copy = new byte[act.Length];
            NUnit.Framework.Assert.AreEqual(act.Length, @in.Read(copy));
            NUnit.Framework.Assert.AreEqual(0, @in.Available());
            NUnit.Framework.Assert.AreEqual(-1, @in.Read());
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(act, copy), "same content");
            ByteArrayOutputStream tmp = new ByteArrayOutputStream();

            ldr.CopyTo(tmp);
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(act, tmp.ToByteArray()), "same content"
                                          );
        }
        public virtual void TestSmallObjectLoader()
        {
            byte[]       act = GetRng().NextBytes(512);
            ObjectLoader ldr = new ObjectLoader.SmallObject(Constants.OBJ_BLOB, act);

            NUnit.Framework.Assert.AreEqual(Constants.OBJ_BLOB, ldr.GetType());
            NUnit.Framework.Assert.AreEqual(act.Length, ldr.GetSize());
            NUnit.Framework.Assert.IsFalse(ldr.IsLarge(), "not is large");
            NUnit.Framework.Assert.AreSame(act, ldr.GetCachedBytes());
            NUnit.Framework.Assert.AreSame(act, ldr.GetCachedBytes(1));
            NUnit.Framework.Assert.AreSame(act, ldr.GetCachedBytes(int.MaxValue));
            byte[] copy = ldr.GetBytes();
            NUnit.Framework.Assert.AreNotSame(act, copy);
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(act, copy), "same content");
            copy = ldr.GetBytes(1);
            NUnit.Framework.Assert.AreNotSame(act, copy);
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(act, copy), "same content");
            copy = ldr.GetBytes(int.MaxValue);
            NUnit.Framework.Assert.AreNotSame(act, copy);
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(act, copy), "same content");
            ObjectStream @in = ldr.OpenStream();

            NUnit.Framework.Assert.IsNotNull(@in, "has stream");
            NUnit.Framework.Assert.IsTrue(@in is ObjectStream.SmallStream, "is small stream");
            NUnit.Framework.Assert.AreEqual(Constants.OBJ_BLOB, @in.GetType());
            NUnit.Framework.Assert.AreEqual(act.Length, @in.GetSize());
            NUnit.Framework.Assert.AreEqual(act.Length, @in.Available());
            NUnit.Framework.Assert.IsTrue(@in.MarkSupported(), "mark supported");
            copy = new byte[act.Length];
            NUnit.Framework.Assert.AreEqual(act.Length, @in.Read(copy));
            NUnit.Framework.Assert.AreEqual(0, @in.Available());
            NUnit.Framework.Assert.AreEqual(-1, @in.Read());
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(act, copy), "same content");
            ByteArrayOutputStream tmp = new ByteArrayOutputStream();

            ldr.CopyTo(tmp);
            NUnit.Framework.Assert.IsTrue(Arrays.Equals(act, tmp.ToByteArray()), "same content"
                                          );
        }
예제 #4
0
        /// <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();
            }
        }