Skip to content

Commit

Permalink
fix-write-stream (#40)
Browse files Browse the repository at this point in the history
* fix-write-stream

* edit doc for encode() method
  • Loading branch information
Billy Messenger authored Sep 13, 2023
1 parent dd10074 commit e1c7aff
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 8 deletions.
3 changes: 3 additions & 0 deletions core/src/write/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ pub trait Encoder: Sized + 'static {

/// Write a block of data to the file.
///
/// The block may contain less written frames than the length of the channel
/// `Vec`s, so be sure to only read up to `block.written_frames()`.
///
/// If the write was successful, return `WriteStatus::Ok`.
///
/// If the codec has a maximum file size (i.e. 4GB for WAV), then keep track of
Expand Down
59 changes: 51 additions & 8 deletions core/src/write/write_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,17 +292,47 @@ impl<E: Encoder> WriteDiskStream<E> {
Ok(())
}

/// Finish the file and close the stream. The stream cannot be used after calling this.
/// Finish the file and close the stream. `WriteDiskStream::write()` cannot be used
/// after calling this.
///
/// This is realtime-safe.
///
/// `WriteDiskStream.finish_complete()` will return true once the file has been
/// successfully finished and closed.
/// Because this method is realtime safe and doesn't block, the file may still be in
/// the process of finishing when this method returns. If you wish to make sure that
/// the file has successfully finished, periodically call `WriteDiskStream::poll()`
/// and then `WriteDiskStream::finish_complete()` for a response. (If
/// `WriteDiskStream::poll()` returns an error, then it may mean that the file
/// failed to save correctly.)
pub fn finish_and_close(&mut self) -> Result<(), WriteError<E::FatalError>> {
if self.fatal_error || self.finished {
return Err(WriteError::FatalError(FatalWriteError::StreamClosed));
}

self.finished = true;

{
// This check should never fail because it can only be `None` in the destructor.
let heap = self.heap_data.as_mut().unwrap();

if let Some(mut current_block) = heap.current_block.take() {
if current_block.written_frames > 0 {
// Send the last bit of remaining samples to be encoded.

// Check that there is at-least one slot open.
if self.to_server_tx.is_full() {
return Err(WriteError::IOServerChannelFull);
}

current_block.restart_count = self.restart_count;
let _ = self.to_server_tx.push(ClientToServerMsg::WriteBlock {
block: current_block,
});
} else {
heap.current_block = Some(current_block);
}
}
}

// Check that there is at-least one slot open.
if self.to_server_tx.is_full() {
return Err(WriteError::IOServerChannelFull);
Expand All @@ -312,20 +342,27 @@ impl<E: Encoder> WriteDiskStream<E> {
// a previous step.
let _ = self.to_server_tx.push(ClientToServerMsg::FinishFile);

self.finished = true;

Ok(())
}

/// Delete all files created by this stream and close the stream. The stream cannot
/// be used after calling this.
/// Delete all files created by this stream and close the stream.
/// `WriteDiskStream::write()` cannot be used after calling this.
///
/// This is realtime-safe.
///
/// Because this method is realtime safe and doesn't block, the file may still be in
/// the process of finishing when this method returns. If you wish to make sure that
/// the file has successfully finished, periodically call `WriteDiskStream::poll()`
/// and then `WriteDiskStream::finish_complete()` for a response. (If
/// `WriteDiskStream::poll()` returns an error, then it may mean that the file
/// failed to be discarded correctly.)
pub fn discard_and_close(&mut self) -> Result<(), WriteError<E::FatalError>> {
if self.fatal_error || self.finished {
return Err(WriteError::FatalError(FatalWriteError::StreamClosed));
}

self.finished = true;

// Check that there is at-least one slot open.
if self.to_server_tx.is_full() {
return Err(WriteError::IOServerChannelFull);
Expand Down Expand Up @@ -373,7 +410,10 @@ impl<E: Encoder> WriteDiskStream<E> {
Ok(())
}

fn poll(&mut self) -> Result<(), WriteError<E::FatalError>> {
/// Poll for messages from the server.
///
/// This is realtime-safe.
pub fn poll(&mut self) -> Result<(), WriteError<E::FatalError>> {
if self.fatal_error {
return Err(WriteError::FatalError(FatalWriteError::StreamClosed));
}
Expand Down Expand Up @@ -416,6 +456,9 @@ impl<E: Encoder> WriteDiskStream<E> {
/// Returns true when the file has been successfully finished and closed, false
/// otherwise.
///
/// Be sure to call `WriteDiskStream::poll()` first, or else this may not be
/// accurate.
///
/// This is realtime-safe.
pub fn finish_complete(&self) -> bool {
self.finish_complete
Expand Down

0 comments on commit e1c7aff

Please sign in to comment.