Back to index

nux  3.0.0
Public Member Functions | Static Public Member Functions | Public Attributes
nux::AsyncFileWriter::Impl Class Reference

CAUTION: right now this class is not thread aware. More...

Collaboration diagram for nux::AsyncFileWriter::Impl:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 Impl (AsyncFileWriter *owner, std::string const &filename)
 ~Impl ()
void Write (std::string const &data)
void Close ()
void ProcessAsync ()

Static Public Member Functions

static void AppendAsyncCallback (GFile *source, GAsyncResult *res, Impl *impl)
static void WriteAsyncCallback (GOutputStream *source, GAsyncResult *res, Impl *impl)
static void CloseAsyncCallback (GOutputStream *source, GAsyncResult *res, Impl *impl)

Public Attributes

AsyncFileWriterowner_
GCancellable * cancel_
GFile * file_
GFileOutputStream * output_stream_
bool close_pending_
bool pending_async_call_
std::stringstream pending_content_
std::string data_to_write_

Detailed Description

CAUTION: right now this class is not thread aware.

It assumes that all the write calls are coming from a single thread. Perhaps we need to fix this?

Definition at line 39 of file AsyncFileWriter.cpp.


Constructor & Destructor Documentation

nux::AsyncFileWriter::Impl::Impl ( AsyncFileWriter owner,
std::string const &  filename 
)

Definition at line 66 of file AsyncFileWriter.cpp.

  : owner_(owner)
  , cancel_(g_cancellable_new())
  , file_(g_file_new_for_path(filename.c_str()))
  , output_stream_(0)
  , close_pending_(false)
  , pending_async_call_(true)
{
  g_file_append_to_async(file_,
                         G_FILE_CREATE_NONE,
                         G_PRIORITY_DEFAULT,
                         cancel_,
                         (GAsyncReadyCallback)&AsyncFileWriter::Impl::AppendAsyncCallback,
                         this);
}

Here is the call graph for this function:

Definition at line 82 of file AsyncFileWriter.cpp.

{
  if (pending_async_call_)
  {
    g_cancellable_cancel(cancel_);
  }
  // make sure the file is closed.
  if (output_stream_)
  {
    // If we had an output stream, sync write any pending content.
    if (pending_content_.tellp())
    {
      std::string data(pending_content_.str());
      gsize bytes_written;
      g_output_stream_write_all((GOutputStream*)output_stream_,
                                data.c_str(),
                                data.size(),
                                &bytes_written,
                                NULL, NULL);
    }
    owner_->closed.emit();
    g_object_unref(output_stream_);
  }

  g_object_unref(file_);
  g_object_unref(cancel_);
}

Member Function Documentation

void nux::AsyncFileWriter::Impl::AppendAsyncCallback ( GFile *  source,
GAsyncResult *  res,
Impl impl 
) [static]

Definition at line 110 of file AsyncFileWriter.cpp.

{
  GError* error = NULL;
  GFileOutputStream* stream = g_file_append_to_finish(source, res, &error);
  if (error) {
    // Cancelled callbacks call back, but have a cancelled error code.
    if (error->code != G_IO_ERROR_CANCELLED) {
      std::cerr << error->message << "\n";
    }
    g_error_free(error);
    return;
  }
  impl->output_stream_ = stream;
  impl->pending_async_call_ = false;
  impl->owner_->opened.emit();
  impl->ProcessAsync();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 197 of file AsyncFileWriter.cpp.

Here is the caller graph for this function:

void nux::AsyncFileWriter::Impl::CloseAsyncCallback ( GOutputStream *  source,
GAsyncResult *  res,
Impl impl 
) [static]

Definition at line 203 of file AsyncFileWriter.cpp.

{
  GError* error = NULL;
  g_output_stream_close_finish(source, res, &error);
  if (error) {
    // Cancelled callbacks call back, but have a cancelled error code.
    if (error->code != G_IO_ERROR_CANCELLED) {
      std::cerr << error->message << "\n";
    }
    g_error_free(error);
    return;
  }
  g_object_unref(impl->output_stream_);
  impl->output_stream_ = 0;
  impl->owner_->closed.emit();
}

Here is the caller graph for this function:

Definition at line 138 of file AsyncFileWriter.cpp.

{
  if (output_stream_ == NULL || pending_async_call_) return;

  if (pending_content_.tellp())
  {
    // TODO: lock the pending_content_ access
    data_to_write_ = pending_content_.str();
    g_output_stream_write_async((GOutputStream*)output_stream_,
                                data_to_write_.c_str(),
                                data_to_write_.size(),
                                G_PRIORITY_DEFAULT,
                                cancel_,
                                (GAsyncReadyCallback)&AsyncFileWriter::Impl::WriteAsyncCallback,
                                this);
    pending_async_call_ = true;
  }
  else if (close_pending_)
  {
    g_output_stream_close_async((GOutputStream*)output_stream_,
                                G_PRIORITY_DEFAULT,
                                cancel_,
                                (GAsyncReadyCallback)&AsyncFileWriter::Impl::CloseAsyncCallback,
                                this);
    pending_async_call_ = true;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nux::AsyncFileWriter::Impl::Write ( std::string const &  data)

Definition at line 130 of file AsyncFileWriter.cpp.

{
  if (close_pending_) return;
  // TODO: lock the pending_content_ access
  pending_content_ << data;
  ProcessAsync();
}

Here is the caller graph for this function:

void nux::AsyncFileWriter::Impl::WriteAsyncCallback ( GOutputStream *  source,
GAsyncResult *  res,
Impl impl 
) [static]

Definition at line 166 of file AsyncFileWriter.cpp.

{
  GError* error = NULL;
  gssize g_bytes_written = g_output_stream_write_finish(source, res, &error);
  if (error) {
    // Cancelled callbacks call back, but have a cancelled error code.
    if (error->code != G_IO_ERROR_CANCELLED) {
      std::cerr << error->message << "\n";
    }
    g_error_free(error);
    return;
  }
  // g_bytes_written is signed from gio, but only negative if there is an error.
  // The error should be set too if there was an error, so no negative bytes
  // written get past here.
  std::size_t bytes_written = g_bytes_written;
  impl->pending_async_call_ = false;
  // TODO: lock the pending_content_ access
  std::string data = impl->pending_content_.str();
  if (bytes_written >= data.size()) {
    // There should be no reason why bytes_written should be greater than the
    // number of bytes in the stream, but this is paranoia.
    impl->pending_content_.str("");
  } else {
    impl->pending_content_.str(data.substr(bytes_written));
  }
  impl->ProcessAsync();
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 55 of file AsyncFileWriter.cpp.

Definition at line 58 of file AsyncFileWriter.cpp.

Definition at line 62 of file AsyncFileWriter.cpp.

Definition at line 56 of file AsyncFileWriter.cpp.

Definition at line 57 of file AsyncFileWriter.cpp.

Definition at line 54 of file AsyncFileWriter.cpp.

Definition at line 59 of file AsyncFileWriter.cpp.

Definition at line 61 of file AsyncFileWriter.cpp.


The documentation for this class was generated from the following file: