Пример #1
0
        int StreamCreateCallback(out IntPtr git_writestream_out, GitFilter self, IntPtr payload, IntPtr filterSourcePtr, IntPtr git_writestream_next)
        {
            int result = 0;

            try
            {
                Ensure.ArgumentNotZeroIntPtr(filterSourcePtr, "filterSourcePtr");
                Ensure.ArgumentNotZeroIntPtr(git_writestream_next, "git_writestream_next");

                thisStream       = new GitWriteStream();
                thisStream.close = StreamCloseCallback;
                thisStream.write = StreamWriteCallback;
                thisStream.free  = StreamFreeCallback;
                thisPtr          = Marshal.AllocHGlobal(Marshal.SizeOf(thisStream));
                Marshal.StructureToPtr(thisStream, thisPtr, false);
                nextPtr    = git_writestream_next;
                nextStream = new GitWriteStream();
                Marshal.PtrToStructure(nextPtr, nextStream);
                filterSource = FilterSource.FromNativePtr(filterSourcePtr);
                output       = new WriteStream(nextStream, nextPtr);

                Create(filterSource.Path, filterSource.Root, filterSource.SourceMode);
            }
            catch (Exception exception)
            {
                // unexpected failures means memory clean up required
                if (thisPtr != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(thisPtr);
                    thisPtr = IntPtr.Zero;
                }

                Log.Write(LogLevel.Error, "Filter.StreamCreateCallback exception");
                Log.Write(LogLevel.Error, exception.ToString());
                Proxy.giterr_set_str(GitErrorCategory.Filter, exception);
                result = (int)GitErrorCode.Error;
            }

            git_writestream_out = thisPtr;

            return(result);
        }
Пример #2
0
        private unsafe Blob CreateBlob(Stream stream, string hintpath, long?numberOfBytesToConsume)
        {
            Ensure.ArgumentNotNull(stream, "stream");

            // there's no need to buffer the file for filtering, so simply use a stream
            if (hintpath == null && numberOfBytesToConsume.HasValue)
            {
                return(CreateBlob(stream, numberOfBytesToConsume.Value));
            }

            if (!stream.CanRead)
            {
                throw new ArgumentException("The stream cannot be read from.", "stream");
            }

            IntPtr         writestream_ptr = Proxy.git_blob_create_fromstream(repo.Handle, hintpath);
            GitWriteStream writestream     = (GitWriteStream)Marshal.PtrToStructure(writestream_ptr, typeof(GitWriteStream));

            try
            {
                var  buffer    = new byte[4 * 1024];
                long totalRead = 0;
                int  read      = 0;

                while (true)
                {
                    int toRead = numberOfBytesToConsume.HasValue ?
                                 (int)Math.Min(numberOfBytesToConsume.Value - totalRead, (long)buffer.Length) :
                                 buffer.Length;

                    if (toRead > 0)
                    {
                        read = (toRead > 0) ? stream.Read(buffer, 0, toRead) : 0;
                    }

                    if (read == 0)
                    {
                        break;
                    }

                    fixed(byte *buffer_ptr = buffer)
                    {
                        writestream.write(writestream_ptr, (IntPtr)buffer_ptr, (UIntPtr)read);
                    }

                    totalRead += read;
                }

                if (numberOfBytesToConsume.HasValue && totalRead < numberOfBytesToConsume.Value)
                {
                    throw new EndOfStreamException("The stream ended unexpectedly");
                }
            }
            catch (Exception e)
            {
                writestream.free(writestream_ptr);
                throw e;
            }

            ObjectId id = Proxy.git_blob_create_fromstream_commit(writestream_ptr);

            return(repo.Lookup <Blob>(id));
        }