Beispiel #1
0
        /// <summary>
        /// Read() reads from an offset in the file.  A PP_ArrayOutput must be
        /// provided so that output will be stored in its allocated buffer.  This
        /// function might perform a partial read.
        /// </summary>
        /// <param name="buffer">An ArraySegment<byte> to hold the specified number of bytes read.</param>
        /// <param name="offset">The offset into the file.</param>
        /// <param name="bytesToRead">The number of bytes to read from <code>offset</code>.</param>
        /// <returns>Error code.  If the return value is 0, then end-of-file was reached.</returns>
        public PPError Read(ArraySegment <byte> buffer, int offset, int bytesToRead)
        {
            var readToArrayAction = new Action <PPError, byte[]>(
                (result, bytes) =>
            {
                Array.Copy(bytes, buffer.Array, Math.Min(bytes.Length, buffer.Count));
                OnReadData(result);
            }

                );

            var arrayOutput = new CompletionCallbackWithOutput <byte[]>(new CompletionCallbackWithOutputFunc <byte[]>(readToArrayAction));

            return((PPError)PPBFileIO.ReadToArray(this, offset, bytesToRead, ref arrayOutput.ArrayOutput, arrayOutput));
        }
Beispiel #2
0
        private async Task <FileIOResult> ReadAsyncCore(ArraySegment <byte> buffer, int offset, int size, MessageLoop messageLoop = null)
        {
            var tcs = new TaskCompletionSource <FileIOResult>();
            EventHandler <FileIOResult> handler = (s, e) => { tcs.TrySetResult(e); };

            try
            {
                HandleReadData += handler;

                if (MessageLoop == null && messageLoop == null)
                {
                    Read(buffer, offset, size);
                }
                else
                {
                    Action <PPError> action = new Action <PPError>((e) =>
                    {
                        using (var arrayOutput = new ArrayOutputAdapterWithStorage <byte[]>())
                        {
                            PPArrayOutput ao = arrayOutput.PPArrayOutput;
                            var result       = (PPError)PPBFileIO.ReadToArray(this, offset, size, ref ao,
                                                                              new BlockUntilComplete());
                            var bytes = arrayOutput.Output;
                            Array.Copy(bytes, buffer.Array, Math.Min(bytes.Length, buffer.Count));

                            tcs.TrySetResult(new FileIOResult((int)result, (int)result == 0));
                        }
                    }
                                                                   );
                    InvokeHelper(action, messageLoop);
                }
                return(await tcs.Task);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
                tcs.SetException(exc);
                return(new FileIOResult((int)PPError.Aborted, true));
            }
            finally
            {
                HandleReadData -= handler;
            }
        }
Beispiel #3
0
        private async Task <FileIOResult> WriteAsyncCore(byte[] buffer, int offset, int size, MessageLoop messageLoop = null)
        {
            var tcs = new TaskCompletionSource <FileIOResult>();
            EventHandler <FileIOResult> handler = (s, e) => { tcs.TrySetResult(e); };

            try
            {
                HandleWriteData += handler;

                if (MessageLoop == null && messageLoop == null)
                {
                    Write(buffer, offset, size);
                }
                else
                {
                    Action <PPError> action = new Action <PPError>((e) =>
                    {
                        var result = (PPError)PPBFileIO.Write(this, offset,
                                                              buffer,
                                                              size,
                                                              new BlockUntilComplete()
                                                              );
                        tcs.TrySetResult(new FileIOResult((int)result, (int)result == 0));
                    }
                                                                   );
                    InvokeHelper(action, messageLoop);
                }
                return(await tcs.Task);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
                tcs.SetException(exc);
                return(new FileIOResult((int)PPError.Aborted, true));
            }
            finally
            {
                HandleWriteData -= handler;
            }
        }
Beispiel #4
0
        private async Task <FileInfo> QueryAsyncCore(MessageLoop messageLoop = null)
        {
            var tcs = new TaskCompletionSource <FileInfo>();
            EventHandler <FileInfo> handler = (s, e) => { tcs.TrySetResult(e); };

            try
            {
                HandleQuery += handler;

                if (MessageLoop == null && messageLoop == null)
                {
                    Query();
                }
                else
                {
                    Action <PPError> action = new Action <PPError>((e) =>
                    {
                        var fileInfo = new PPFileInfo();
                        var result   = (PPError)PPBFileIO.Query(this, out fileInfo,
                                                                new BlockUntilComplete()
                                                                );
                        tcs.TrySetResult(new FileInfo(result, fileInfo));
                    }
                                                                   );
                    InvokeHelper(action, messageLoop);
                }
                return(await tcs.Task);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
                tcs.SetException(exc);
                return(new FileInfo(PPError.Aborted, new PPFileInfo()));
            }
            finally
            {
                HandleQuery -= handler;
            }
        }
Beispiel #5
0
        private async Task <PPError> OpenAsyncCore(FileRef fileRef, FileOpenFlags openFlags, MessageLoop openLoop = null)
        {
            var tcs = new TaskCompletionSource <PPError>();
            EventHandler <PPError> handler = (s, e) => { tcs.TrySetResult(e); };

            try
            {
                HandleOpen += handler;

                if (MessageLoop == null && openLoop == null)
                {
                    Open(fileRef, openFlags);
                }
                else
                {
                    Action <PPError> action = new Action <PPError>((e) =>
                    {
                        var result = (PPError)PPBFileIO.Open(this, fileRef, (int)openFlags,
                                                             new BlockUntilComplete()
                                                             );
                        tcs.TrySetResult(result);
                    }
                                                                   );
                    InvokeHelper(action, openLoop);
                }
                return(await tcs.Task);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
                tcs.SetException(exc);
                return(PPError.Aborted);
            }
            finally
            {
                HandleOpen -= handler;
            }
        }
Beispiel #6
0
        private async Task <PPError> FlushAsyncCore(MessageLoop messageLoop = null)
        {
            var tcs = new TaskCompletionSource <PPError>();
            EventHandler <PPError> handler = (s, e) => { tcs.TrySetResult(e); };

            try
            {
                HandleFlush += handler;

                if (MessageLoop == null && messageLoop == null)
                {
                    Flush();
                }
                else
                {
                    Action <PPError> action = new Action <PPError>((e) =>
                    {
                        var result = (PPError)PPBFileIO.Flush(this,
                                                              new BlockUntilComplete()
                                                              );
                        tcs.TrySetResult(result);
                    }
                                                                   );
                    InvokeHelper(action, messageLoop);
                }
                return(await tcs.Task);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
                tcs.SetException(exc);
                return(PPError.Aborted);
            }
            finally
            {
                HandleFlush -= handler;
            }
        }
Beispiel #7
0
        private async Task <PPError> CloseAsyncCore(MessageLoop messageLoop = null)
        {
            var tcs = new TaskCompletionSource <PPError>();
            EventHandler <PPError> handler = (s, e) => { tcs.TrySetResult(e); };

            try
            {
                HandleClose += handler;

                if (MessageLoop == null && messageLoop == null)
                {
                    Close();
                }
                else
                {
                    Action <PPError> action = new Action <PPError>((e) =>
                    {
                        PPBFileIO.Close(this);
                        tcs.TrySetResult(PPError.Ok);
                    }
                                                                   );
                    InvokeHelper(action, messageLoop);
                }
                return(await tcs.Task);
            }
            catch (Exception exc)
            {
                Console.WriteLine(exc.Message);
                tcs.SetException(exc);
                return(PPError.Aborted);
            }
            finally
            {
                HandleClose -= handler;
            }
        }
Beispiel #8
0
 /// <summary>
 /// Close() cancels any IO that may be pending, and closes the FileIO object.
 /// Any pending callbacks will still run, reporting
 /// <code>Aborted</code> if pending IO was interrupted.  It is not
 /// valid to call Open() again after a call to this method.
 ///
 /// <strong>Note:</strong> If the FileIO object is destroyed, and it is still
 /// open, then it will be implicitly closed, so you are not required to call
 /// Close().
 /// </summary>
 public void Close()
 {
     PPBFileIO.Close(this);
     OnClose(PPError.Ok);
 }
Beispiel #9
0
 /// <summary>
 /// Open() opens the specified regular file for I/O according to the given
 /// open flags, which is a bit-mask of the FileOpenFlags values.  Upon
 /// success, the corresponding file is classified as "in use" by this FileIO
 /// object until such time as the FileIO object is closed or destroyed.
 /// </summary>
 /// <param name="fileRef">A FileRef instance</param>
 /// <param name="openFlags">A bit-mask of <code>FileOpenFlags</code> values.</param>
 /// <returns>Error code</returns>
 public PPError Open(FileRef fileRef, FileOpenFlags openFlags)
 => (PPError)PPBFileIO.Open(this, fileRef, (int)openFlags, new CompletionCallback(OnOpen));
Beispiel #10
0
 /// <summary>
 /// Flush() flushes changes to disk.  This call can be very expensive!
 /// </summary>
 /// <returns>Error code.</returns>
 public PPError Flush()
 => (PPError)PPBFileIO.Flush(this, new CompletionCallback(OnFlush));
Beispiel #11
0
 /// <summary>
 /// SetLength() sets the length of the file.  If the file size is extended,
 /// then the extended area of the file is zero-filled.  The FileIO object must
 /// have been opened with write access.
 /// </summary>
 /// <param name="length">The length of the file to be set.</param>
 /// <returns></returns>
 public PPError SetLength(long length)
 => (PPError)PPBFileIO.SetLength(this, length, new CompletionCallback(OnSetLength));
Beispiel #12
0
 /// <summary>
 /// Write() writes to an offset in the file.  This function might perform a
 /// partial write. The FileIO object must have been opened with write access.
 /// </summary>
 /// <param name="buffer">The buffer to hold the specified number of bytes read.</param>
 /// <param name="offset">The offset into the file.</param>
 /// <param name="bytesToWrite">The number of bytes to write to
 /// <code>offset</code>.</param>
 /// <returns>Error code</returns>
 public PPError Write(byte[] buffer, int offset, int bytesToWrite)
 => (PPError)PPBFileIO.Write(this, offset, buffer, bytesToWrite, new CompletionCallback(OnWriteData));
Beispiel #13
0
 public FileIO(Instance instance)
 {
     handle = PPBFileIO.Create(instance);
 }
Beispiel #14
0
 /// <summary>
 /// Reads from an offset in the file.
 ///
 /// The size of the buffer must be large enough to hold the specified number
 /// of bytes to read.  This function might perform a partial read, meaning
 /// that all the requested bytes might not be returned, even if the end of the
 /// file has not been reached.
 ///
 /// This function reads into a buffer that the caller supplies. This buffer
 /// must remain valid as long as the FileIO resource is alive. If you use
 /// a completion callback factory and it goes out of scope, it will not issue
 /// the callback on your class, BUT the callback factory can NOT cancel
 /// the request from the browser's perspective. This means that the browser
 /// will still try to write to your buffer even if the callback factory is
 /// destroyed!
 ///
 /// So you must ensure that your buffer outlives the FileIO resource. If you
 /// have one class and use the FileIO resource exclusively from that class
 /// and never make any copies, this will be fine: the resource will be
 /// destroyed when your class is. But keep in mind that copying a pp::FileIO
 /// object just creates a second reference to the original resource. For
 /// example, if you have a function like this:
 ///   FileIO MyClass.GetFileIO();
 /// where a copy of your FileIO resource could outlive your class, the
 /// callback will still be pending when your class goes out of scope, creating
 /// the possibility of writing into invalid memory. So it's recommended to
 /// keep your FileIO resource and any output buffers tightly controlled in
 /// the same scope.
 ///
 /// <strong>Caveat:</strong> This Read() is potentially unsafe if you're using
 /// an EventHandler to scope callbacks to the lifetime of your
 /// class.  When your class goes out of scope, the native callback factory will not
 /// actually cancel the callback, but will rather just skip issuing the
 /// callback on your class.  This means that if the FileIO object outlives
 /// your class (if you made a copy saved somewhere else, for example), then
 /// the browser will still try to write into your buffer when the
 /// asynchronous read completes, potentially causing a crash.
 ///
 /// See the other version of Read() which avoids this problem by writing into
 /// ArraySegment, where the output buffer is automatically managed by the native callback.
 ///
 /// </summary>
 /// <param name="buffer">The buffer to hold the specified number of bytes read.</param>
 /// <param name="offset">The offset into the file.</param>
 /// <param name="bytesToRead">The number of bytes to read from <code>offset</code>.</param>
 /// <returns>Error code.  If the return value is 0, then end-of-file was
 /// reached.</returns>
 public PPError Read(byte[] buffer, int offset, int bytesToRead)
 => (PPError)PPBFileIO.Read(this, offset, buffer, bytesToRead, new CompletionCallback(OnReadData));
Beispiel #15
0
        /// <summary>
        /// Query() queries info about the file opened by this FileIO object. This
        /// function will fail if the FileIO object has not been opened.
        /// </summary>
        /// <returns>Error code</returns>
        public PPError Query()
        {
            var ficb = new CompletionCallbackWithOutput <PPFileInfo>(OnQuery);

            return((PPError)PPBFileIO.Query(this, out ficb.OutputAdapter.output, ficb));
        }