Re: GVfs status report

On Thu, 2007-09-13 at 14:12 -0400, Havoc Pennington wrote:
> Hi,
> There's a lot of code to absorb here, a minor comment, I might expect
> GUnixFileInputStream/GWindowsFileInputStream rather than
> GLocalFileInputStream.

Well, the same class is used on both unix and windows. Its the
implementation of "native files", and I don't see any need to split it
out really. What differences would there be between the two?

> I haven't found the relevant code yet to see what it does, but a nice
> property would be to set close-on-exec by default for all streams.

I guess we could do that. Can this ever be a problem, or can we just
always do it without a way to disable it?

> A more macro thought, since there's so much code here, it would be
> worth spending some time to try and identify the parts an app (vs. a
> file manager) would usually use, and then somehow highlight those
> parts in the docs and/or header file organization. i.e. make it easy
> if "I just want to read and write a file"

Yeah, that makes sense. For you typical application that wants to load
and save files I think the following is the core API:

Creating a new GFile (which is essentially an abstract filename object):
 from native filename:
   GFile * g_file_new_for_path (const char  *path);
 from uri:
   GFile * g_file_new_for_uri (const char *uri);
 from commandline argument (absolute path, cwd relative path or uri):
   GFile * g_file_new_for_commandline_arg (const char *arg);
 from a filename/uri input entry (a utf8 string, filename, uri or iri):
   GFile * g_file_parse_name (const char *parse_name);

Ideally one should also be able to get one from the file selector.

Loading a file:
  gboolean g_file_load_contents (GFile *file,
				 GCancellable         *cancellable,
				 char                **contents,
				 gsize                *length,
				 GError              **error);

  void  g_file_load_contents_async (GFile                *file,
				    GCancellable         *cancellable,
				    GAsyncReadyCallback   callback,
			            gpointer              user_data);
  In the callback you then call g_file_load_contents_finish on the
  GAsyncResult object to get the result of the operation:
  gboolean g_file_load_contents_finish (GFile                *file,
					GAsyncResult         *res,
					char                **contents,
					gsize                *length,
					GError              **error);
  This is the async i/o API model, made so that all callbacks are the
  same type. Easy to remember, easy to bind.
  Use g_file_read or g_file_read_async to get a GFileInputStream.
  GFileInputStream is a GInputStream with added fstat and "seek"
  support. GInputStream allows both sync and async i/o calls.

Saving a file:
 Similar to reading, there are sync and async versions of this:
  gboolean g_file_replace_contents (GFile                *file,
				    const char           *contents,
				    gsize                 length,
				    const char           *etag,
				    gboolean              make_backup,
				    GCancellable         *cancellable,
				    GError              **error);
 Its pretty obvious how to use, except the etag argument. Etags are
 similar to etags in http, and mtime tags in local files. You pass in 
 one you got when reading or writing the file last time and if the file
 on disk differs from the passed in tag you get an error. 
 (I notice here that the helper API sucks, because you can't get the new
  etag when writing a file, or when reading a file.)
 You can also do this manually with streaming by using g_file_replace()
 or g_file_replace_async() and writing to the output stream.

Somewhat interesting to normal apps might be:
GFileMonitor* g_file_monitor_file (GFile                  *file,
				   GFileMonitorFlags       flags);
Call this an it returns an object that will emit the "changed" signal
when the file changes. It uses inotify or fam/gamin, or falls back to a
polling implementation if that isn't supported.

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]