gio/ docs/reference/gio Merged gio-standalone into glib.
2007-11-26 Alexander Larsson <alexl@redhat.com> * Makefile.am: * configure.in: * gio-2.0-uninstalled.pc.in: * gio-2.0.pc.in: * gio-unix-2.0-uninstalled.pc.in: * gio-unix-2.0.pc.in: * gio/ * docs/reference/gio Merged gio-standalone into glib. * glib/glibintl.h: * glib/gutils.c: Export glib_gettext so that gio can use it Add P_ (using same domain for now) Add I_ as g_intern_static_string svn path=/trunk/; revision=5941
This commit is contained in:
		
				
					committed by
					
						
						Alexander Larsson
					
				
			
			
				
	
			
			
			
						parent
						
							8bdbcb9213
						
					
				
				
					commit
					3781343738
				
			
							
								
								
									
										18
									
								
								ChangeLog
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								ChangeLog
									
									
									
									
									
								
							@@ -1,3 +1,21 @@
 | 
			
		||||
2007-11-26  Alexander Larsson  <alexl@redhat.com>
 | 
			
		||||
 | 
			
		||||
        * Makefile.am:
 | 
			
		||||
        * configure.in:
 | 
			
		||||
        * gio-2.0-uninstalled.pc.in:
 | 
			
		||||
        * gio-2.0.pc.in: 
 | 
			
		||||
        * gio-unix-2.0-uninstalled.pc.in:
 | 
			
		||||
        * gio-unix-2.0.pc.in:
 | 
			
		||||
	* gio/
 | 
			
		||||
	* docs/reference/gio
 | 
			
		||||
	Merged gio-standalone into glib.
 | 
			
		||||
	
 | 
			
		||||
        * glib/glibintl.h:
 | 
			
		||||
        * glib/gutils.c:
 | 
			
		||||
	Export glib_gettext so that gio can use it
 | 
			
		||||
	Add P_ (using same domain for now)
 | 
			
		||||
	Add I_ as g_intern_static_string
 | 
			
		||||
 | 
			
		||||
2007-11-26  Tor Lillqvist  <tml@novell.com>
 | 
			
		||||
 | 
			
		||||
	* glib/win_iconv.c: ISO8859-1 is CP28591, not CP1252.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								Makefile.am
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Makefile.am
									
									
									
									
									
								
							@@ -3,7 +3,7 @@ include $(top_srcdir)/Makefile.decl
 | 
			
		||||
 | 
			
		||||
AUTOMAKE_OPTIONS = 1.7
 | 
			
		||||
 | 
			
		||||
SUBDIRS = . m4macros glib gobject gmodule gthread tests build po docs
 | 
			
		||||
SUBDIRS = . m4macros glib gobject gmodule gthread gio tests build po docs
 | 
			
		||||
 | 
			
		||||
bin_SCRIPTS = glib-gettextize
 | 
			
		||||
 | 
			
		||||
@@ -45,11 +45,15 @@ EXTRA_DIST += 			\
 | 
			
		||||
	gmodule-export-2.0.pc.in	\
 | 
			
		||||
	gmodule-no-export-2.0.pc.in	\
 | 
			
		||||
	gthread-2.0.pc.in	\
 | 
			
		||||
	gio-2.0.pc.in		\
 | 
			
		||||
	gio-unix-2.0.pc.in	\
 | 
			
		||||
	glib-2.0-uninstalled.pc.in 	\
 | 
			
		||||
	gobject-2.0-uninstalled.pc.in 	\
 | 
			
		||||
	gmodule-2.0-uninstalled.pc.in	\
 | 
			
		||||
	gthread-2.0-uninstalled.pc.in	\
 | 
			
		||||
	gmodule-no-export-2.0-uninstalled.pc.in
 | 
			
		||||
	gmodule-no-export-2.0-uninstalled.pc.in \
 | 
			
		||||
	gio-2.0-uninstalled.pc.in		\
 | 
			
		||||
	gio-unix-2.0-uninstalled.pc.in	
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# These may be in the builddir too
 | 
			
		||||
@@ -77,7 +81,7 @@ stamp-gc-h: config.status
 | 
			
		||||
	echo timestamp > stamp-gc-h
 | 
			
		||||
 | 
			
		||||
pkgconfigdir = $(libdir)/pkgconfig
 | 
			
		||||
pkgconfig_DATA = glib-2.0.pc gobject-2.0.pc gmodule-2.0.pc gmodule-export-2.0.pc gmodule-no-export-2.0.pc gthread-2.0.pc
 | 
			
		||||
pkgconfig_DATA = glib-2.0.pc gobject-2.0.pc gmodule-2.0.pc gmodule-export-2.0.pc gmodule-no-export-2.0.pc gthread-2.0.pc gio-2.0.pc gio-unix-2.0.pc
 | 
			
		||||
 | 
			
		||||
$(pkgconfig_DATA): config.status
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										199
									
								
								configure.in
									
									
									
									
									
								
							
							
						
						
									
										199
									
								
								configure.in
									
									
									
									
									
								
							@@ -822,9 +822,15 @@ AM_CONDITIONAL(HAVE_SUNSTUDIO_VISIBILITY, [test x$g_have_sunstudio_visibility =
 | 
			
		||||
AC_C_BIGENDIAN
 | 
			
		||||
 | 
			
		||||
# check for header files
 | 
			
		||||
AC_CHECK_HEADERS([dirent.h float.h limits.h pwd.h sys/param.h sys/poll.h sys/resource.h])
 | 
			
		||||
AC_CHECK_HEADERS([dirent.h float.h limits.h pwd.h grp.h sys/param.h sys/poll.h sys/resource.h])
 | 
			
		||||
AC_CHECK_HEADERS([sys/time.h sys/times.h sys/wait.h unistd.h values.h])
 | 
			
		||||
AC_CHECK_HEADERS([sys/select.h sys/types.h stdint.h sched.h malloc.h])
 | 
			
		||||
AC_CHECK_HEADERS([sys/vfs.h sys/mount.h sys/vmount.h sys/statfs.h sys/statvfs.h])
 | 
			
		||||
AC_CHECK_HEADERS([mntent.h sys/mnttab.h sys/vfstab.h sys/mntctl.h sys/sysctl.h fstab.h])
 | 
			
		||||
 | 
			
		||||
# check for structure fields
 | 
			
		||||
AC_CHECK_MEMBERS([struct stat.st_mtimensec, struct stat.st_mtim.tv_nsec, struct stat.st_atimensec, struct stat.st_atim.tv_nsec, struct stat.st_ctimensec, struct stat.st_ctim.tv_nsec])
 | 
			
		||||
AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_blocks])
 | 
			
		||||
 | 
			
		||||
# Checks for libcharset
 | 
			
		||||
jm_LANGINFO_CODESET
 | 
			
		||||
@@ -888,6 +894,8 @@ AC_MSG_RESULT(unsigned $glib_size_type)
 | 
			
		||||
 | 
			
		||||
# Check for some functions
 | 
			
		||||
AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk)
 | 
			
		||||
AC_CHECK_FUNCS(chown lchown fchmod fchown link statvfs statfs utimes getgrgid getpwuid)
 | 
			
		||||
AC_CHECK_FUNCS(setmntent endmntent hasmntopt getmntinfo)
 | 
			
		||||
# Check for high-resolution sleep functions
 | 
			
		||||
AC_CHECK_FUNCS(nanosleep nsleep)
 | 
			
		||||
 | 
			
		||||
@@ -897,6 +905,47 @@ AC_CHECK_FUNCS(_NSGetEnviron)
 | 
			
		||||
AC_FUNC_VSNPRINTF_C99
 | 
			
		||||
AC_FUNC_PRINTF_UNIX98
 | 
			
		||||
 | 
			
		||||
dnl
 | 
			
		||||
dnl if statfs() takes 2 arguments (Posix) or 4 (Solaris)
 | 
			
		||||
dnl
 | 
			
		||||
if test "$ac_cv_func_statfs" = yes ; then
 | 
			
		||||
  AC_MSG_CHECKING([number of arguments to statfs()])
 | 
			
		||||
  AC_TRY_COMPILE([#include <unistd.h>
 | 
			
		||||
  #ifdef HAVE_SYS_PARAM_H
 | 
			
		||||
  #include <sys/param.h>
 | 
			
		||||
  #endif
 | 
			
		||||
  #ifdef HAVE_SYS_VFS_H
 | 
			
		||||
  #include <sys/vfs.h>
 | 
			
		||||
  #endif
 | 
			
		||||
  #ifdef HAVE_SYS_MOUNT_H
 | 
			
		||||
  #include <sys/mount.h>
 | 
			
		||||
  #endif
 | 
			
		||||
  #ifdef HAVE_SYS_STATFS_H
 | 
			
		||||
  #include <sys/statfs.h>
 | 
			
		||||
  #endif], [struct statfs st;
 | 
			
		||||
  statfs(NULL, &st);],[
 | 
			
		||||
    AC_MSG_RESULT([2])
 | 
			
		||||
    AC_DEFINE(STATFS_ARGS, 2, [Number of arguments to statfs()])],[
 | 
			
		||||
    AC_TRY_COMPILE([#include <unistd.h>
 | 
			
		||||
  #ifdef HAVE_SYS_PARAM_H
 | 
			
		||||
  #include <sys/param.h>
 | 
			
		||||
  #endif
 | 
			
		||||
  #ifdef HAVE_SYS_VFS_H
 | 
			
		||||
  #include <sys/vfs.h>
 | 
			
		||||
  #endif
 | 
			
		||||
  #ifdef HAVE_SYS_MOUNT_H
 | 
			
		||||
  #include <sys/mount.h>
 | 
			
		||||
  #endif
 | 
			
		||||
  #ifdef HAVE_SYS_STATFS_H
 | 
			
		||||
  #include <sys/statfs.h>
 | 
			
		||||
  #endif], [struct statfs st;
 | 
			
		||||
  statfs(NULL, &st, sizeof (st), 0);],[
 | 
			
		||||
      AC_MSG_RESULT([4])
 | 
			
		||||
      AC_DEFINE(STATFS_ARGS, 4, [Number of arguments to statfs()])],[
 | 
			
		||||
      AC_MSG_RESULT(unknown)
 | 
			
		||||
      AC_MSG_ERROR([unable to determine number of arguments to statfs()])])])
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
#
 | 
			
		||||
# Check whether to use an included printf
 | 
			
		||||
#
 | 
			
		||||
@@ -1399,6 +1448,105 @@ esac
 | 
			
		||||
AC_MSG_RESULT($GIO)
 | 
			
		||||
AC_SUBST(GIO)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dnl **********************************
 | 
			
		||||
dnl *** Check for libselinux (GIO) ***
 | 
			
		||||
dnl **********************************
 | 
			
		||||
AC_ARG_ENABLE(selinux, [  --disable-selinux       build without selinux support])
 | 
			
		||||
msg_selinux=no
 | 
			
		||||
SELINUX_LIBS=
 | 
			
		||||
if test "x$enable_selinux" != "xno"; then
 | 
			
		||||
 | 
			
		||||
 AC_CHECK_LIB(selinux, is_selinux_enabled,
 | 
			
		||||
   [AC_CHECK_HEADERS(selinux/selinux.h,
 | 
			
		||||
     [AC_SEARCH_LIBS(lgetfilecon_raw, selinux, 
 | 
			
		||||
       [AC_DEFINE(HAVE_SELINUX, 1, [Define to 1 if libselinux is available])
 | 
			
		||||
        SELINUX_LIBS="-lselinux"
 | 
			
		||||
        msg_selinux=yes])
 | 
			
		||||
     ])
 | 
			
		||||
   ])
 | 
			
		||||
fi
 | 
			
		||||
AC_SUBST(SELINUX_LIBS)
 | 
			
		||||
 | 
			
		||||
dnl *****************************
 | 
			
		||||
dnl ** Check for inotify (GIO) **
 | 
			
		||||
dnl *****************************
 | 
			
		||||
inotify_support=no
 | 
			
		||||
AC_CHECK_HEADERS([linux/inotify.h],
 | 
			
		||||
[
 | 
			
		||||
	inotify_support=yes
 | 
			
		||||
])
 | 
			
		||||
AC_CHECK_HEADERS([sys/inotify.h],
 | 
			
		||||
[
 | 
			
		||||
	inotify_support=yes
 | 
			
		||||
])
 | 
			
		||||
 | 
			
		||||
AM_CONDITIONAL(HAVE_INOTIFY, [test "$inotify_support" = "yes"])
 | 
			
		||||
 | 
			
		||||
dnl ****************************
 | 
			
		||||
dnl *** Checks for FAM (GIO) ***
 | 
			
		||||
dnl ****************************
 | 
			
		||||
 | 
			
		||||
should_disable_fam=no
 | 
			
		||||
 | 
			
		||||
AC_ARG_ENABLE(fam, [  --disable-fam          build without enabling fam for file system monitoring],
 | 
			
		||||
                         [
 | 
			
		||||
                                if test "x$enable_fam" = "xno"; then
 | 
			
		||||
                                        should_disable_fam=yes
 | 
			
		||||
                                        echo "Not building FAM support"
 | 
			
		||||
                                fi
 | 
			
		||||
                         ]
 | 
			
		||||
                         )
 | 
			
		||||
fam_support=no
 | 
			
		||||
FAM_LIBS=
 | 
			
		||||
if test "x$should_disable_fam" = "xno"; then
 | 
			
		||||
AC_CHECK_LIB(fam, FAMOpen,
 | 
			
		||||
  [AC_CHECK_HEADERS(fam.h,
 | 
			
		||||
    [AC_DEFINE(HAVE_FAM, [], [Define if we have FAM])
 | 
			
		||||
     AC_CHECK_LIB(fam, FAMNoExists,
 | 
			
		||||
     		  AC_DEFINE(HAVE_FAM_NO_EXISTS, [], [Define if we have FAMNoExists in fam]))
 | 
			
		||||
     FAM_LIBS="-lfam"]
 | 
			
		||||
     fam_support=yes,
 | 
			
		||||
    AC_MSG_WARN(*** FAM support will not be built (header files not found) ***))],
 | 
			
		||||
  AC_MSG_WARN(*** FAM support will not be built (FAM library not found) ***))
 | 
			
		||||
AC_SUBST(FAM_LIBS)
 | 
			
		||||
fi
 | 
			
		||||
AM_CONDITIONAL(HAVE_FAM, [test "$fam_support" = "yes"])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dnl *****************************
 | 
			
		||||
dnl *** Check for xattr (GIO) ***
 | 
			
		||||
dnl *****************************
 | 
			
		||||
AC_ARG_ENABLE(xattr, [  --disable-xattr           build without xattr support])
 | 
			
		||||
msg_xattr=no
 | 
			
		||||
XATTR_LIBS=
 | 
			
		||||
if test "x$enable_xattr" != "xno"; then
 | 
			
		||||
 | 
			
		||||
dnl either glibc or libattr can provide xattr support
 | 
			
		||||
 | 
			
		||||
dnl for both of them, we check for getxattr being in
 | 
			
		||||
dnl the library and a valid xattr header.
 | 
			
		||||
 | 
			
		||||
dnl try glibc
 | 
			
		||||
 AC_CHECK_LIB(c, getxattr,
 | 
			
		||||
   [AC_CHECK_HEADERS(sys/xattr.h,
 | 
			
		||||
     [AC_DEFINE(HAVE_XATTR, 1, [Define to 1 if xattr is available])
 | 
			
		||||
      msg_xattr=yes])
 | 
			
		||||
   ])
 | 
			
		||||
 | 
			
		||||
  if test "x$msg_xattr" != "xyes"; then
 | 
			
		||||
dnl   failure. try libattr
 | 
			
		||||
   AC_CHECK_LIB(attr, getxattr,
 | 
			
		||||
      [AC_CHECK_HEADERS(attr/xattr.h,
 | 
			
		||||
       [AC_DEFINE(HAVE_XATTR, 1, [Define to 1 if xattr is available])
 | 
			
		||||
        XATTR_LIBS="-lattr"
 | 
			
		||||
        msg_xattr=yes])
 | 
			
		||||
      ])
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
AC_SUBST(XATTR_LIBS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
dnl ****************************************
 | 
			
		||||
dnl *** platform dependent source checks ***
 | 
			
		||||
dnl ****************************************
 | 
			
		||||
@@ -1872,6 +2020,45 @@ int main () {
 | 
			
		||||
			fi
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
	if test "$ac_cv_header_grp_h" = "yes"; then
 | 
			
		||||
	   	AC_CACHE_CHECK([for posix getgrgid_r],
 | 
			
		||||
			ac_cv_func_posix_getgrgid_r,
 | 
			
		||||
			[AC_TRY_RUN([
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <grp.h>
 | 
			
		||||
int main () { 
 | 
			
		||||
    char buffer[10000];
 | 
			
		||||
    struct group grp, *grpptr = &grp;
 | 
			
		||||
    int error;
 | 
			
		||||
    errno = 0;
 | 
			
		||||
    error = getgrgid_r (0, &grp, buffer, 
 | 
			
		||||
                        sizeof (buffer), &grpptr);
 | 
			
		||||
   return (error < 0 && errno == ENOSYS) 
 | 
			
		||||
	   || error == ENOSYS; 
 | 
			
		||||
}                              ],
 | 
			
		||||
			       [ac_cv_func_posix_getgrgid_r=yes],
 | 
			
		||||
			       [ac_cv_func_posix_getgrgid_r=no])])
 | 
			
		||||
		GLIB_ASSERT_SET(ac_cv_func_posix_getgrgid_r)
 | 
			
		||||
		if test "$ac_cv_func_posix_getgrgid_r" = yes; then
 | 
			
		||||
		   	AC_DEFINE(HAVE_POSIX_GETGRGID_R,1,
 | 
			
		||||
				[Have POSIX function getgrgid_r])
 | 
			
		||||
		else
 | 
			
		||||
			AC_CACHE_CHECK([for nonposix getgrgid_r],
 | 
			
		||||
				ac_cv_func_nonposix_getgrgid_r,
 | 
			
		||||
				[AC_TRY_LINK([#include <grp.h>],
 | 
			
		||||
                               		[char buffer[10000];
 | 
			
		||||
					struct group grp;	
 | 
			
		||||
					getgrgid_r (0, &grp, buffer, 
 | 
			
		||||
                                       	sizeof (buffer));],
 | 
			
		||||
				[ac_cv_func_nonposix_getgrgid_r=yes],
 | 
			
		||||
				[ac_cv_func_nonposix_getgrgid_r=no])])
 | 
			
		||||
			GLIB_ASSERT_SET(ac_cv_func_nonposix_getgrgid_r)
 | 
			
		||||
			if test "$ac_cv_func_nonposix_getgrgid_r" = yes; then
 | 
			
		||||
			   	AC_DEFINE(HAVE_NONPOSIX_GETGRGID_R,1,
 | 
			
		||||
					[Have non-POSIX function getgrgid_r])
 | 
			
		||||
			fi
 | 
			
		||||
		fi
 | 
			
		||||
	fi
 | 
			
		||||
	LIBS="$G_THREAD_LIBS $LIBS"
 | 
			
		||||
	if test x"$have_threads" = xposix; then
 | 
			
		||||
		glib_save_CPPFLAGS="$CPPFLAGS"
 | 
			
		||||
@@ -2974,6 +3161,10 @@ gthread-2.0.pc
 | 
			
		||||
gthread-2.0-uninstalled.pc
 | 
			
		||||
gobject-2.0.pc
 | 
			
		||||
gobject-2.0-uninstalled.pc
 | 
			
		||||
gio-2.0.pc
 | 
			
		||||
gio-unix-2.0.pc
 | 
			
		||||
gio-2.0-uninstalled.pc
 | 
			
		||||
gio-unix-2.0-uninstalled.pc
 | 
			
		||||
glib-zip
 | 
			
		||||
glib-gettextize
 | 
			
		||||
Makefile
 | 
			
		||||
@@ -2992,6 +3183,10 @@ gmodule/gmoduleconf.h
 | 
			
		||||
gobject/Makefile
 | 
			
		||||
gobject/glib-mkenums
 | 
			
		||||
gthread/Makefile
 | 
			
		||||
gio/Makefile
 | 
			
		||||
gio/xdgmime/Makefile
 | 
			
		||||
gio/inotify/Makefile
 | 
			
		||||
gio/fam/Makefile
 | 
			
		||||
po/Makefile.in
 | 
			
		||||
docs/Makefile
 | 
			
		||||
docs/reference/Makefile
 | 
			
		||||
@@ -2999,6 +3194,8 @@ docs/reference/glib/Makefile
 | 
			
		||||
docs/reference/glib/version.xml
 | 
			
		||||
docs/reference/gobject/Makefile
 | 
			
		||||
docs/reference/gobject/version.xml
 | 
			
		||||
docs/reference/gio/Makefile
 | 
			
		||||
docs/reference/gio/version.xml
 | 
			
		||||
tests/Makefile
 | 
			
		||||
tests/gobject/Makefile
 | 
			
		||||
tests/refcount/Makefile
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,13 @@
 | 
			
		||||
2007-11-26  Alexander Larsson  <alexl@redhat.com>
 | 
			
		||||
 | 
			
		||||
        * Makefile.am:
 | 
			
		||||
        * gio/Makefile.am:
 | 
			
		||||
        * gio/gio-docs.xml:
 | 
			
		||||
        * gio/gio-sections.txt:
 | 
			
		||||
        * gio/gio.types:
 | 
			
		||||
        * gio/version.xml.in:
 | 
			
		||||
	Add gio docs
 | 
			
		||||
 | 
			
		||||
2007-11-23  Matthias Clasen <mclasen@redhat.com>
 | 
			
		||||
 | 
			
		||||
	* glib/tmpl/i18n.sgml:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,3 @@
 | 
			
		||||
include $(top_srcdir)/Makefile.decl
 | 
			
		||||
 | 
			
		||||
SUBDIRS = glib gobject
 | 
			
		||||
SUBDIRS = glib gobject gio
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										90
									
								
								docs/reference/gio/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								docs/reference/gio/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,90 @@
 | 
			
		||||
include $(top_srcdir)/Makefile.decl
 | 
			
		||||
NULL = 
 | 
			
		||||
 | 
			
		||||
# The name of the module.
 | 
			
		||||
DOC_MODULE=gio
 | 
			
		||||
 | 
			
		||||
# The top-level SGML file.
 | 
			
		||||
DOC_MAIN_SGML_FILE=gio-docs.xml
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-scan
 | 
			
		||||
SCAN_OPTIONS=--deprecated-guards="G_DISABLE_DEPRECATED"
 | 
			
		||||
 | 
			
		||||
# The directory containing the source code. Relative to $(srcdir)
 | 
			
		||||
DOC_SOURCE_DIR=$(top_srcdir)/gio
 | 
			
		||||
 | 
			
		||||
HFILE_GLOB=$(top_srcdir)/gio/*.h
 | 
			
		||||
CFILE_GLOB=$(top_srcdir)/gio/*.c
 | 
			
		||||
 | 
			
		||||
# Headers to ignore
 | 
			
		||||
IGNORE_HFILES= 		           \
 | 
			
		||||
	fam-helper.h			\
 | 
			
		||||
	gasynchelper.h			\
 | 
			
		||||
	gdesktopappinfo.h		\
 | 
			
		||||
	gdummyfile.h			\
 | 
			
		||||
	gfamdirectorymonitor.h		\
 | 
			
		||||
	gfamfilemonitor.h		\
 | 
			
		||||
	ginotifydirectorymonitor.h	\
 | 
			
		||||
	ginotifyfilemonitor.h		\
 | 
			
		||||
	glocaldirectorymonitor.h	\
 | 
			
		||||
	glocalfile.h			\
 | 
			
		||||
	glocalfileenumerator.h		\
 | 
			
		||||
	glocalfileinfo.h		\
 | 
			
		||||
	glocalfileinputstream.h		\
 | 
			
		||||
	glocalfilemonitor.h		\
 | 
			
		||||
	glocalfileoutputstream.h	\
 | 
			
		||||
	glocalvfs.h			\
 | 
			
		||||
	gnativevolumemonitor.h		\
 | 
			
		||||
	gpollfilemonitor.h		\
 | 
			
		||||
	gunionvolumemonitor.h		\
 | 
			
		||||
	gunixdrive.h			\
 | 
			
		||||
	gunixvolume.h			\
 | 
			
		||||
	gunixvolumemonitor.h		\
 | 
			
		||||
	gvolumeprivate.h		\
 | 
			
		||||
	gwin32appinfo.h			\
 | 
			
		||||
	inotify-kernel.h		\
 | 
			
		||||
	local_inotify.h			\
 | 
			
		||||
	local_inotify_syscalls.h	\
 | 
			
		||||
	xdgmime.h			\
 | 
			
		||||
	xdgmimealias.h		   	\
 | 
			
		||||
	xdgmimecache.h		   	\
 | 
			
		||||
	xdgmimeglob.h		   	\
 | 
			
		||||
	xdgmimeint.h		   	\
 | 
			
		||||
	xdgmimemagic.h		   	\
 | 
			
		||||
	xdgmimeparent.h		   	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
# CFLAGS and LDFLAGS for compiling scan program. Only needed
 | 
			
		||||
# if $(DOC_MODULE).types is non-empty.
 | 
			
		||||
INCLUDES = \
 | 
			
		||||
	-I$(srcdir) 			\
 | 
			
		||||
	-I$(top_srcdir) 		\
 | 
			
		||||
	-I$(top_srcdir)/glib 		\
 | 
			
		||||
	-I$(top_srcdir)/gobject		\
 | 
			
		||||
	-I$(top_builddir) 		\
 | 
			
		||||
	-I$(top_builddir)/glib 		\
 | 
			
		||||
	-I$(top_builddir)/gobject	\
 | 
			
		||||
	$(GLIB_DEBUG_FLAGS)
 | 
			
		||||
 | 
			
		||||
GTKDOC_LIBS = \
 | 
			
		||||
	$(top_builddir)/glib/libglib-2.0.la		\
 | 
			
		||||
	$(top_builddir)/gobject/libgobject-2.0.la	\
 | 
			
		||||
	$(top_builddir)/gmodule/libgmodule-2.0.la	\
 | 
			
		||||
	$(top_builddir)/gio/libgio-2.0.la		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
# Extra options to supply to gtkdoc-mkdb
 | 
			
		||||
MKDB_OPTIONS = --output-format=xml --sgml-mode
 | 
			
		||||
 | 
			
		||||
# Images to copy into HTML directory
 | 
			
		||||
HTML_IMAGES =
 | 
			
		||||
 | 
			
		||||
content_files = 		\
 | 
			
		||||
	version.xml
 | 
			
		||||
 | 
			
		||||
extra_files = version.xml.in
 | 
			
		||||
 | 
			
		||||
include $(top_srcdir)/gtk-doc.make
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST +=				\
 | 
			
		||||
	version.xml.in
 | 
			
		||||
							
								
								
									
										106
									
								
								docs/reference/gio/gio-docs.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								docs/reference/gio/gio-docs.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,106 @@
 | 
			
		||||
<?xml version="1.0"?>
 | 
			
		||||
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" 
 | 
			
		||||
               "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
 | 
			
		||||
<!ENTITY version SYSTEM "version.xml">
 | 
			
		||||
]>
 | 
			
		||||
<book lang="en" id="gio" xmlns:xi="http://www.w3.org/2003/XInclude">
 | 
			
		||||
<title>GIO Reference Manual</title>
 | 
			
		||||
  <bookinfo>
 | 
			
		||||
    <title>GIO Reference Manual</title>
 | 
			
		||||
    <releaseinfo>for GIO &version;</releaseinfo>
 | 
			
		||||
  </bookinfo>
 | 
			
		||||
  <part>
 | 
			
		||||
  <title>GIO Overview</title>
 | 
			
		||||
  </part>
 | 
			
		||||
  <part>
 | 
			
		||||
  <title>API Reference</title>
 | 
			
		||||
    <chapter id="file_ops">
 | 
			
		||||
    	<title>File Operations</title>
 | 
			
		||||
    	<xi:include href="xml/gfile.xml"/>
 | 
			
		||||
        <xi:include href="xml/gfileattribute.xml"/>
 | 
			
		||||
    	<xi:include href="xml/gfileinfo.xml"/>
 | 
			
		||||
	<xi:include href="xml/gfileenumerator.xml"/>
 | 
			
		||||
	<xi:include href="xml/gmountoperation.xml"/>
 | 
			
		||||
	<xi:include href="xml/gioerror.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    <chapter id="file_mon">
 | 
			
		||||
    	<title>File System Monitoring</title>
 | 
			
		||||
        <xi:include href="xml/gfilemonitor.xml"/>
 | 
			
		||||
        <xi:include href="xml/gdirectorymonitor.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    <chapter id="async">
 | 
			
		||||
        <title>Asynchronous I/O</title>
 | 
			
		||||
	<xi:include href="xml/gcancellable.xml"/>
 | 
			
		||||
	<xi:include href="xml/gasyncresult.xml"/>
 | 
			
		||||
        <xi:include href="xml/gioscheduler.xml"/>
 | 
			
		||||
	<xi:include href="xml/gsimpleasyncresult.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    
 | 
			
		||||
    <chapter id="streaming">
 | 
			
		||||
        <title>Streaming I/O</title>
 | 
			
		||||
	<xi:include href="xml/gseekable.xml"/>
 | 
			
		||||
 | 
			
		||||
        <xi:include href="xml/ginputstream.xml"/>        
 | 
			
		||||
        <xi:include href="xml/goutputstream.xml"/>
 | 
			
		||||
 | 
			
		||||
        <xi:include href="xml/gfileinputstream.xml"/>
 | 
			
		||||
        <xi:include href="xml/gfileoutputstream.xml"/>
 | 
			
		||||
 | 
			
		||||
        <xi:include href="xml/gfilterinputstream.xml"/>        
 | 
			
		||||
        <xi:include href="xml/gfilteroutputstream.xml"/>
 | 
			
		||||
	
 | 
			
		||||
        <xi:include href="xml/gmemoryinputstream.xml"/>        
 | 
			
		||||
        <xi:include href="xml/gmemoryoutputstream.xml"/>
 | 
			
		||||
        
 | 
			
		||||
        <xi:include href="xml/gbufferedinputstream.xml"/>
 | 
			
		||||
        <xi:include href="xml/gbufferedoutputstream.xml"/>
 | 
			
		||||
	
 | 
			
		||||
        <xi:include href="xml/gdatainputstream.xml"/>
 | 
			
		||||
        <xi:include href="xml/gdataoutputstream.xml"/>
 | 
			
		||||
        
 | 
			
		||||
        <xi:include href="xml/gsocketinputstream.xml"/>
 | 
			
		||||
        <xi:include href="xml/gsocketoutputstream.xml"/>
 | 
			
		||||
 | 
			
		||||
    </chapter>
 | 
			
		||||
 | 
			
		||||
    <chapter id="types">
 | 
			
		||||
        <title>File types and applications</title>
 | 
			
		||||
        <xi:include href="xml/gcontenttype.xml"/>
 | 
			
		||||
	<xi:include href="xml/gappinfo.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    
 | 
			
		||||
    <chapter id="volume_mon">
 | 
			
		||||
    	<title>Volumes and Drives</title>
 | 
			
		||||
        <xi:include href="xml/gvolumemonitor.xml"/>
 | 
			
		||||
	<xi:include href="xml/gvolume.xml"/>
 | 
			
		||||
	<xi:include href="xml/gdrive.xml"/>
 | 
			
		||||
	<xi:include href="xml/gunixmounts.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    <chapter id="icons">
 | 
			
		||||
    	<title>Icons</title>
 | 
			
		||||
    	<xi:include href="xml/gicon.xml"/>
 | 
			
		||||
    	<xi:include href="xml/gfileicon.xml"/>
 | 
			
		||||
    	<xi:include href="xml/gloadableicon.xml"/>
 | 
			
		||||
    	<xi:include href="xml/gthemedicon.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    <chapter id="utils">   
 | 
			
		||||
    	<title>Utilities</title>
 | 
			
		||||
        <xi:include href="xml/gfilenamecompleter.xml"/>
 | 
			
		||||
        <xi:include href="xml/gurifuncs.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
    <chapter id="extending">
 | 
			
		||||
    	<title>Extending GIO</title>
 | 
			
		||||
        <xi:include href="xml/gvfs.xml"/>
 | 
			
		||||
	<xi:include href="xml/giomodule.xml"/>
 | 
			
		||||
    </chapter>
 | 
			
		||||
  </part>
 | 
			
		||||
 | 
			
		||||
  <chapter id="gio-hierarchy">
 | 
			
		||||
    <title>Object Hierarchy</title>
 | 
			
		||||
      <xi:include href="xml/tree_index.sgml"/>
 | 
			
		||||
  </chapter>
 | 
			
		||||
  
 | 
			
		||||
  <index>
 | 
			
		||||
    <title id="index-all">Index</title>
 | 
			
		||||
  </index>
 | 
			
		||||
</book>
 | 
			
		||||
							
								
								
									
										1159
									
								
								docs/reference/gio/gio-sections.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1159
									
								
								docs/reference/gio/gio-sections.txt
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										51
									
								
								docs/reference/gio/gio.types
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								docs/reference/gio/gio.types
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
g_icon_get_type
 | 
			
		||||
g_seekable_get_type
 | 
			
		||||
g_unix_mount_monitor_get_type
 | 
			
		||||
g_data_output_stream_get_type
 | 
			
		||||
g_socket_output_stream_get_type
 | 
			
		||||
g_local_file_enumerator_get_type
 | 
			
		||||
g_socket_input_stream_get_type
 | 
			
		||||
g_dummy_file_get_type
 | 
			
		||||
g_memory_input_stream_get_type
 | 
			
		||||
g_volume_get_type
 | 
			
		||||
g_file_monitor_get_type
 | 
			
		||||
g_data_input_stream_get_type
 | 
			
		||||
g_vfs_get_type
 | 
			
		||||
g_mount_operation_get_type
 | 
			
		||||
g_local_directory_monitor_get_type
 | 
			
		||||
g_themed_icon_get_type
 | 
			
		||||
g_local_file_input_stream_get_type
 | 
			
		||||
g_file_enumerator_get_type
 | 
			
		||||
g_async_result_get_type
 | 
			
		||||
g_filename_completer_get_type
 | 
			
		||||
g_local_file_get_type
 | 
			
		||||
g_local_vfs_get_type
 | 
			
		||||
g_filter_output_stream_get_type
 | 
			
		||||
g_file_icon_get_type
 | 
			
		||||
g_buffered_input_stream_get_type
 | 
			
		||||
g_local_file_monitor_get_type
 | 
			
		||||
g_union_volume_monitor_get_type
 | 
			
		||||
g_output_stream_get_type
 | 
			
		||||
g_unix_drive_get_type
 | 
			
		||||
g_drive_get_type
 | 
			
		||||
g_file_input_stream_get_type
 | 
			
		||||
g_poll_file_monitor_get_type
 | 
			
		||||
g_file_get_type
 | 
			
		||||
g_filter_input_stream_get_type
 | 
			
		||||
g_volume_monitor_get_type
 | 
			
		||||
g_directory_monitor_get_type
 | 
			
		||||
g_desktop_app_info_get_type
 | 
			
		||||
g_io_module_get_type
 | 
			
		||||
g_native_volume_monitor_get_type
 | 
			
		||||
g_buffered_output_stream_get_type
 | 
			
		||||
g_unix_volume_get_type
 | 
			
		||||
g_input_stream_get_type
 | 
			
		||||
g_app_info_get_type
 | 
			
		||||
g_file_output_stream_get_type
 | 
			
		||||
g_cancellable_get_type
 | 
			
		||||
g_memory_output_stream_get_type
 | 
			
		||||
g_simple_async_result_get_type
 | 
			
		||||
g_loadable_icon_get_type
 | 
			
		||||
g_local_file_output_stream_get_type
 | 
			
		||||
g_file_info_get_type
 | 
			
		||||
g_unix_volume_monitor_get_type
 | 
			
		||||
							
								
								
									
										1
									
								
								docs/reference/gio/version.xml.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/reference/gio/version.xml.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
@VERSION@
 | 
			
		||||
							
								
								
									
										6
									
								
								gio-2.0-uninstalled.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								gio-2.0-uninstalled.pc.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
Name: GIO Uninstalled
 | 
			
		||||
Description: glib I/O library, Not Installed
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires: gobject-2.0-uninstalled,gmodule-no-export-2.0-uninstalled
 | 
			
		||||
Libs: ${pc_top_builddir}/${pcfiledir}/gio/libgio-2.0.la
 | 
			
		||||
Cflags: -I${pc_top_builddir}/${pcfiledir}/@srcdir@
 | 
			
		||||
							
								
								
									
										11
									
								
								gio-2.0.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								gio-2.0.pc.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
libdir=@libdir@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: GIO
 | 
			
		||||
Description: glib I/O library
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires: gobject-2.0,gmodule-no-export-2.0
 | 
			
		||||
Libs: -L${libdir} -lgio-2.0
 | 
			
		||||
Cflags: 
 | 
			
		||||
							
								
								
									
										6
									
								
								gio-unix-2.0-uninstalled.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								gio-unix-2.0-uninstalled.pc.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
Name: GIO unix specific APIs
 | 
			
		||||
Description: unix specific headers for glib I/O library, Not Installed
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires: gobject-2.0-uninstalled,gmodule-no-export-2.0-uninstalled,gio-2.0-uninstalled
 | 
			
		||||
Libs: ${pc_top_builddir}/${pcfiledir}/gio/libgio-2.0.la
 | 
			
		||||
Cflags: -I${pc_top_builddir}/${pcfiledir}/@srcdir@
 | 
			
		||||
							
								
								
									
										11
									
								
								gio-unix-2.0.pc.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								gio-unix-2.0.pc.in
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
prefix=@prefix@
 | 
			
		||||
exec_prefix=@exec_prefix@
 | 
			
		||||
libdir=@libdir@
 | 
			
		||||
includedir=@includedir@
 | 
			
		||||
 | 
			
		||||
Name: GIO unix specific APIs
 | 
			
		||||
Description: unix specific headers for glib I/O library
 | 
			
		||||
Version: @VERSION@
 | 
			
		||||
Requires: gobject-2.0,gmodule-no-export-2.0,gio-2.0
 | 
			
		||||
Libs: -L${libdir} -lgio-2.0
 | 
			
		||||
Cflags: -I${includedir}/gio-unix-2.0/
 | 
			
		||||
							
								
								
									
										225
									
								
								gio/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										225
									
								
								gio/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,225 @@
 | 
			
		||||
NULL =
 | 
			
		||||
 | 
			
		||||
SUBDIRS= 
 | 
			
		||||
 | 
			
		||||
if OS_UNIX
 | 
			
		||||
SUBDIRS += xdgmime
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
AM_CPPFLAGS = \
 | 
			
		||||
	-DG_LOG_DOMAIN=\"GLib-GIO\"			\
 | 
			
		||||
	-I$(top_builddir)				\
 | 
			
		||||
	-I$(top_srcdir)					\
 | 
			
		||||
	-I$(top_srcdir)/glib				\
 | 
			
		||||
	-I$(top_srcdir)/gmodule				\
 | 
			
		||||
	$(GLIB_DEBUG_FLAGS)				\
 | 
			
		||||
	-DG_DISABLE_DEPRECATED				\
 | 
			
		||||
	-DGIO_MODULE_DIR=\"$(libdir)/gio/modules\"	
 | 
			
		||||
 | 
			
		||||
lib_LTLIBRARIES = libgio-2.0.la
 | 
			
		||||
 | 
			
		||||
marshal_sources = \
 | 
			
		||||
        gio-marshal.h \
 | 
			
		||||
        gio-marshal.c \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if CROSS_COMPILING
 | 
			
		||||
  glib_genmarshal=$(GLIB_GENMARSHAL)
 | 
			
		||||
else
 | 
			
		||||
  glib_genmarshal=../gobject/glib-genmarshal
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
gio-marshal.h: gio-marshal.list
 | 
			
		||||
	$(glib_genmarshal) --prefix=_gio_marshal $(srcdir)/gio-marshal.list --header > $@
 | 
			
		||||
 | 
			
		||||
gio-marshal.c: gio-marshal.h gio-marshal.list
 | 
			
		||||
	(echo "#include \"gio-marshal.h\""; \
 | 
			
		||||
	$(glib_genmarshal) --prefix=_gio_marshal $(srcdir)/gio-marshal.list --body) > $@
 | 
			
		||||
 | 
			
		||||
local_sources = \
 | 
			
		||||
	glocaldirectorymonitor.c 	\
 | 
			
		||||
	glocaldirectorymonitor.h 	\
 | 
			
		||||
	glocalfile.c 			\
 | 
			
		||||
	glocalfile.h 			\
 | 
			
		||||
	glocalfileenumerator.c 		\
 | 
			
		||||
	glocalfileenumerator.h 		\
 | 
			
		||||
	glocalfileinfo.c 		\
 | 
			
		||||
	glocalfileinfo.h 		\
 | 
			
		||||
	glocalfileinputstream.c 	\
 | 
			
		||||
	glocalfileinputstream.h 	\
 | 
			
		||||
	glocalfilemonitor.c 		\
 | 
			
		||||
	glocalfilemonitor.h 		\
 | 
			
		||||
	glocalfileoutputstream.c 	\
 | 
			
		||||
	glocalfileoutputstream.h 	\
 | 
			
		||||
	glocalvfs.c 			\
 | 
			
		||||
	glocalvfs.h 			\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
platform_libadd =
 | 
			
		||||
appinfo_sources =
 | 
			
		||||
 | 
			
		||||
if HAVE_INOTIFY
 | 
			
		||||
SUBDIRS += inotify
 | 
			
		||||
platform_libadd += inotify/libinotify.la
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
SUBDIRS += .
 | 
			
		||||
 | 
			
		||||
if HAVE_FAM
 | 
			
		||||
SUBDIRS += fam
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if OS_UNIX
 | 
			
		||||
appinfo_sources += gdesktopappinfo.c gdesktopappinfo.h
 | 
			
		||||
platform_libadd += xdgmime/libxdgmime.la
 | 
			
		||||
unix_sources = \
 | 
			
		||||
	gunixdrive.c \
 | 
			
		||||
	gunixdrive.h \
 | 
			
		||||
	gunixmounts.c \
 | 
			
		||||
	gunixmounts.h \
 | 
			
		||||
	gunixvolume.c \
 | 
			
		||||
	gunixvolume.h \
 | 
			
		||||
	gunixvolumemonitor.c \
 | 
			
		||||
	gunixvolumemonitor.h \
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
giounixincludedir=$(includedir)/gio-unix-2.0/gio
 | 
			
		||||
giounixinclude_HEADERS = \
 | 
			
		||||
	gunixmounts.h 		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
if OS_WIN32
 | 
			
		||||
appinfo_sources += gwin32appinfo.c gwin32appinfo.h
 | 
			
		||||
platform_libadd += -lshlwapi
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
libgio_2_0_la_SOURCES =		\
 | 
			
		||||
	gappinfo.c 		\
 | 
			
		||||
	gasynchelper.c 		\
 | 
			
		||||
	gasynchelper.h 		\
 | 
			
		||||
	gasyncresult.c 		\
 | 
			
		||||
	gbufferedinputstream.c 	\
 | 
			
		||||
	gbufferedoutputstream.c \
 | 
			
		||||
	gcancellable.c 		\
 | 
			
		||||
	gcontenttype.c 		\
 | 
			
		||||
	gcontenttypeprivate.h 	\
 | 
			
		||||
	gdatainputstream.c 	\
 | 
			
		||||
	gdataoutputstream.c 	\
 | 
			
		||||
	gdirectorymonitor.c 	\
 | 
			
		||||
	gdrive.c 		\
 | 
			
		||||
	gdriveprivate.h 	\
 | 
			
		||||
	gdummyfile.c 		\
 | 
			
		||||
	gfile.c 		\
 | 
			
		||||
	gfileattribute.c 	\
 | 
			
		||||
	gfileenumerator.c 	\
 | 
			
		||||
	gfileicon.c 		\
 | 
			
		||||
	gfileinfo.c 		\
 | 
			
		||||
	gfileinputstream.c 	\
 | 
			
		||||
	gfilemonitor.c 		\
 | 
			
		||||
	gfilenamecompleter.c 	\
 | 
			
		||||
	gfileoutputstream.c 	\
 | 
			
		||||
	gfilterinputstream.c 	\
 | 
			
		||||
	gfilteroutputstream.c 	\
 | 
			
		||||
	gicon.c 		\
 | 
			
		||||
	ginputstream.c 		\
 | 
			
		||||
	gioerror.c 		\
 | 
			
		||||
	giomodule.c 		\
 | 
			
		||||
	gioscheduler.c 		\
 | 
			
		||||
	gloadableicon.c 	\
 | 
			
		||||
	gmemoryinputstream.c 	\
 | 
			
		||||
	gmemoryoutputstream.c 	\
 | 
			
		||||
	gmountoperation.c 	\
 | 
			
		||||
	gnativevolumemonitor.c 	\
 | 
			
		||||
	gnativevolumemonitor.h 	\
 | 
			
		||||
	goutputstream.c 	\
 | 
			
		||||
	gpollfilemonitor.c 	\
 | 
			
		||||
	gpollfilemonitor.h 	\
 | 
			
		||||
	gseekable.c 		\
 | 
			
		||||
	gsimpleasyncresult.c 	\
 | 
			
		||||
	gsocketinputstream.c 	\
 | 
			
		||||
	gsocketoutputstream.c 	\
 | 
			
		||||
	gthemedicon.c 		\
 | 
			
		||||
	gunionvolumemonitor.c 	\
 | 
			
		||||
	gunionvolumemonitor.h 	\
 | 
			
		||||
	gurifuncs.c 		\
 | 
			
		||||
	gvfs.c 			\
 | 
			
		||||
	gvolume.c 		\
 | 
			
		||||
	gvolumemonitor.c 	\
 | 
			
		||||
	gvolumeprivate.h 	\
 | 
			
		||||
	$(appinfo_sources) 	\
 | 
			
		||||
	$(unix_sources) 	\
 | 
			
		||||
	$(local_sources) 	\
 | 
			
		||||
	$(marshal_sources) 	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
$(libgio_2_0_la_OBJECTS): $(marshal_sources)
 | 
			
		||||
 | 
			
		||||
libgio_2_0_la_LIBADD = \
 | 
			
		||||
	$(top_builddir)/glib/libglib-2.0.la 		\
 | 
			
		||||
	$(top_builddir)/gobject/libgobject-2.0.la 	\
 | 
			
		||||
	$(top_builddir)/gmodule/libgmodule-2.0.la 	\
 | 
			
		||||
	$(platform_libadd) 				\
 | 
			
		||||
	$(SELINUX_LIBS) 				\
 | 
			
		||||
	$(GLIB_LIBS) 					\
 | 
			
		||||
	$(XATTR_LIBS) 					\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
if OS_WIN32
 | 
			
		||||
no_undefined = -no-undefined
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
libgio_2_0_la_LDFLAGS= -export-dynamic $(no_undefined) -export-symbols-regex '^g_.*'
 | 
			
		||||
 | 
			
		||||
gioincludedir=$(includedir)/glib-2.0/gio/
 | 
			
		||||
gioinclude_HEADERS = \
 | 
			
		||||
	gappinfo.h 		\
 | 
			
		||||
	gasyncresult.h 		\
 | 
			
		||||
	gbufferedinputstream.h 	\
 | 
			
		||||
	gbufferedoutputstream.h \
 | 
			
		||||
	gcancellable.h 		\
 | 
			
		||||
	gcontenttype.h 		\
 | 
			
		||||
	gdatainputstream.h 	\
 | 
			
		||||
	gdataoutputstream.h 	\
 | 
			
		||||
	gdirectorymonitor.h 	\
 | 
			
		||||
	gdrive.h 		\
 | 
			
		||||
	gdummyfile.h 		\
 | 
			
		||||
	gfile.h 		\
 | 
			
		||||
	gfileattribute.h 	\
 | 
			
		||||
	gfileenumerator.h 	\
 | 
			
		||||
	gfileicon.h 		\
 | 
			
		||||
	gfileinfo.h 		\
 | 
			
		||||
	gfileinputstream.h 	\
 | 
			
		||||
	gfilemonitor.h 		\
 | 
			
		||||
	gfilenamecompleter.h 	\
 | 
			
		||||
	gfileoutputstream.h 	\
 | 
			
		||||
	gfilterinputstream.h 	\
 | 
			
		||||
	gfilteroutputstream.h 	\
 | 
			
		||||
	gicon.h 		\
 | 
			
		||||
	ginputstream.h 		\
 | 
			
		||||
	gioerror.h 		\
 | 
			
		||||
	giomodule.h 		\
 | 
			
		||||
	gioscheduler.h 		\
 | 
			
		||||
	gloadableicon.h 	\
 | 
			
		||||
	gmemoryinputstream.h 	\
 | 
			
		||||
	gmemoryoutputstream.h 	\
 | 
			
		||||
	gmountoperation.h 	\
 | 
			
		||||
	goutputstream.h 	\
 | 
			
		||||
	gseekable.h 		\	
 | 
			
		||||
	gsimpleasyncresult.h 	\
 | 
			
		||||
	gsocketinputstream.h 	\
 | 
			
		||||
	gsocketoutputstream.h 	\
 | 
			
		||||
	gthemedicon.h 		\
 | 
			
		||||
	gurifuncs.h 		\
 | 
			
		||||
	gvfs.h 			\
 | 
			
		||||
	gvolume.h 		\
 | 
			
		||||
	gvolumemonitor.h 	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
EXTRA_DIST = 			\
 | 
			
		||||
	gio-marshal.list	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
CLEANFILES = 			\
 | 
			
		||||
	$(marshal_sources)	\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
							
								
								
									
										33
									
								
								gio/fam/Makefile.am
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								gio/fam/Makefile.am
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
NULL =
 | 
			
		||||
 | 
			
		||||
module_flags = -export_dynamic -avoid-version -module -no-undefined -export-symbols-regex '^g_io_module_(load|unload)'
 | 
			
		||||
 | 
			
		||||
giomodule_LTLIBRARIES = libgiofam.la
 | 
			
		||||
giomoduledir = $(libdir)/gio/modules
 | 
			
		||||
 | 
			
		||||
libgiofam_la_SOURCES = 		\
 | 
			
		||||
	fam-helper.c			\
 | 
			
		||||
	fam-helper.h			\
 | 
			
		||||
	fam-module.c			\
 | 
			
		||||
	gfamdirectorymonitor.c		\
 | 
			
		||||
	gfamdirectorymonitor.h		\
 | 
			
		||||
	gfamfilemonitor.c		\
 | 
			
		||||
	gfamfilemonitor.h		\
 | 
			
		||||
	$(NULL)
 | 
			
		||||
 | 
			
		||||
libgiofam_la_CFLAGS = \
 | 
			
		||||
	-DG_LOG_DOMAIN=\"GLib-GIO\"	\
 | 
			
		||||
	-I$(top_srcdir) 		\
 | 
			
		||||
	-I$(top_srcdir)/glib 		\
 | 
			
		||||
	-I$(top_srcdir)/gmodule		\
 | 
			
		||||
	-I$(top_srcdir)/gio 		\
 | 
			
		||||
	-DGIO_MODULE_DIR=\"$(libdir)/gio/modules\"  \
 | 
			
		||||
	-DG_DISABLE_DEPRECATED
 | 
			
		||||
 | 
			
		||||
libgiofam_la_LDFLAGS = $(module_flags)
 | 
			
		||||
libgiofam_la_LIBADD = \
 | 
			
		||||
		$(top_builddir)/gio/libgio-2.0.la \
 | 
			
		||||
		$(GLIB_LIBS) \
 | 
			
		||||
		$(FAM_LIBS) \
 | 
			
		||||
		$(NULL)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										245
									
								
								gio/fam/fam-helper.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										245
									
								
								gio/fam/fam-helper.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,245 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 *          John McCutchan <john@johnmccutchan.com> 
 | 
			
		||||
 *          Sebastian Dröge <slomo@circular-chaos.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "config.h"
 | 
			
		||||
#include <fam.h>
 | 
			
		||||
#include <gio/gfilemonitor.h>
 | 
			
		||||
#include <gio/gdirectorymonitor.h>
 | 
			
		||||
 | 
			
		||||
#include "fam-helper.h"
 | 
			
		||||
 | 
			
		||||
static FAMConnection* fam_connection = NULL;
 | 
			
		||||
static gint fam_watch_id = 0;
 | 
			
		||||
G_LOCK_DEFINE_STATIC(fam_connection);
 | 
			
		||||
 | 
			
		||||
struct _fam_sub
 | 
			
		||||
{
 | 
			
		||||
  gchar *pathname;
 | 
			
		||||
  gboolean directory;
 | 
			
		||||
  gpointer user_data;
 | 
			
		||||
  gboolean cancelled;
 | 
			
		||||
  FAMRequest request;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static GFileMonitorEvent 
 | 
			
		||||
fam_event_to_file_monitor_event (enum FAMCodes code)
 | 
			
		||||
{
 | 
			
		||||
  switch (code)
 | 
			
		||||
    {
 | 
			
		||||
    case FAMChanged:
 | 
			
		||||
      return G_FILE_MONITOR_EVENT_CHANGED;
 | 
			
		||||
      break;
 | 
			
		||||
    case FAMDeleted:
 | 
			
		||||
      return G_FILE_MONITOR_EVENT_DELETED;
 | 
			
		||||
      break;
 | 
			
		||||
    case FAMCreated:
 | 
			
		||||
      return G_FILE_MONITOR_EVENT_CREATED;
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      return -1;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
fam_do_iter_unlocked (void)
 | 
			
		||||
{
 | 
			
		||||
  while (fam_connection != NULL && FAMPending (fam_connection)) {
 | 
			
		||||
    FAMEvent ev;
 | 
			
		||||
    fam_sub* sub = NULL;
 | 
			
		||||
    gboolean cancelled;
 | 
			
		||||
    
 | 
			
		||||
    if (FAMNextEvent (fam_connection, &ev) != 1) {
 | 
			
		||||
      FAMClose (fam_connection);
 | 
			
		||||
      g_free (fam_connection);
 | 
			
		||||
      g_source_remove (fam_watch_id);
 | 
			
		||||
      fam_watch_id = 0;
 | 
			
		||||
      fam_connection = NULL;
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    sub = (fam_sub*)ev.userdata;
 | 
			
		||||
    cancelled = sub->cancelled;
 | 
			
		||||
    if (ev.code == FAMAcknowledge && cancelled)
 | 
			
		||||
      {
 | 
			
		||||
	g_free (sub);
 | 
			
		||||
	continue;
 | 
			
		||||
      }
 | 
			
		||||
    
 | 
			
		||||
    if (cancelled)
 | 
			
		||||
      continue;
 | 
			
		||||
    
 | 
			
		||||
    if (sub->directory)
 | 
			
		||||
      {
 | 
			
		||||
	GDirectoryMonitor* monitor = G_DIRECTORY_MONITOR (sub->user_data);
 | 
			
		||||
	GFileMonitorEvent eflags = fam_event_to_file_monitor_event (ev.code);
 | 
			
		||||
	gchar* path = NULL;
 | 
			
		||||
	GFile *child, *parent;
 | 
			
		||||
	
 | 
			
		||||
	/* unsupported event */
 | 
			
		||||
	if (eflags == -1)
 | 
			
		||||
	  continue;
 | 
			
		||||
	
 | 
			
		||||
	if (ev.filename[0] == '/')
 | 
			
		||||
	  path = g_strdup (ev.filename);
 | 
			
		||||
	else
 | 
			
		||||
	  path = g_strdup_printf ("%s/%s", sub->pathname, ev.filename);
 | 
			
		||||
 | 
			
		||||
	child = g_file_new_for_path (path);
 | 
			
		||||
	parent = g_file_get_parent (child);
 | 
			
		||||
	g_directory_monitor_emit_event (monitor, child, NULL, eflags);
 | 
			
		||||
	g_free (path);
 | 
			
		||||
	g_object_unref (child);
 | 
			
		||||
	g_object_unref (parent);
 | 
			
		||||
      } else {
 | 
			
		||||
	GFile *child;
 | 
			
		||||
	GFileMonitor* monitor = G_FILE_MONITOR (sub->user_data);
 | 
			
		||||
	GFileMonitorEvent eflags = fam_event_to_file_monitor_event (ev.code);
 | 
			
		||||
	gchar* path = NULL;
 | 
			
		||||
      
 | 
			
		||||
	if (eflags == -1)
 | 
			
		||||
	  continue;
 | 
			
		||||
	path = g_strdup (ev.filename);
 | 
			
		||||
	child = g_file_new_for_path (path);
 | 
			
		||||
	g_file_monitor_emit_event (monitor, child, NULL, eflags);
 | 
			
		||||
	g_free (path);
 | 
			
		||||
	g_object_unref (child);
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
fam_callback (GIOChannel *source,
 | 
			
		||||
              GIOCondition condition,
 | 
			
		||||
              gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  gboolean res;
 | 
			
		||||
  G_LOCK (fam_connection);
 | 
			
		||||
  
 | 
			
		||||
  res = fam_do_iter_unlocked ();
 | 
			
		||||
  
 | 
			
		||||
  G_UNLOCK (fam_connection);
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
_fam_sub_startup (void)
 | 
			
		||||
{
 | 
			
		||||
  GIOChannel *ioc;
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (fam_connection);
 | 
			
		||||
  
 | 
			
		||||
  if (fam_connection == NULL) {
 | 
			
		||||
    fam_connection = g_new0 (FAMConnection, 1);
 | 
			
		||||
    if (FAMOpen2 (fam_connection, "gvfs user") != 0) {
 | 
			
		||||
      g_warning ("FAMOpen failed, FAMErrno=%d\n", FAMErrno);
 | 
			
		||||
      g_free (fam_connection);
 | 
			
		||||
      fam_connection = NULL;
 | 
			
		||||
      G_UNLOCK (fam_connection);
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
#ifdef HAVE_FAM_NO_EXISTS
 | 
			
		||||
    /* This is a gamin extension that avoids sending all the Exists event for dir monitors */
 | 
			
		||||
    FAMNoExists (fam_connection);
 | 
			
		||||
#endif
 | 
			
		||||
    ioc = g_io_channel_unix_new (FAMCONNECTION_GETFD(fam_connection));
 | 
			
		||||
    fam_watch_id = g_io_add_watch (ioc,
 | 
			
		||||
				   G_IO_IN | G_IO_HUP | G_IO_ERR,
 | 
			
		||||
				   fam_callback, fam_connection);
 | 
			
		||||
    g_io_channel_unref (ioc);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  G_UNLOCK (fam_connection);
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fam_sub*
 | 
			
		||||
_fam_sub_add (const gchar* pathname,
 | 
			
		||||
	      gboolean directory,
 | 
			
		||||
	      gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  fam_sub *sub;
 | 
			
		||||
 | 
			
		||||
  if (!_fam_sub_startup ())
 | 
			
		||||
    return NULL;
 | 
			
		||||
  
 | 
			
		||||
  sub = g_new0 (fam_sub, 1);
 | 
			
		||||
  sub->pathname = g_strdup (pathname);
 | 
			
		||||
  sub->directory = directory;
 | 
			
		||||
  sub->user_data = user_data;
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (fam_connection);
 | 
			
		||||
  /* We need to queue up incoming messages to avoid blocking on write
 | 
			
		||||
   *  if there are many monitors being canceled */
 | 
			
		||||
  fam_do_iter_unlocked ();
 | 
			
		||||
  
 | 
			
		||||
  if (fam_connection == NULL) {
 | 
			
		||||
    G_UNLOCK (fam_connection);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  if (directory)
 | 
			
		||||
    FAMMonitorDirectory (fam_connection, pathname, &sub->request, sub);
 | 
			
		||||
  else
 | 
			
		||||
    FAMMonitorFile (fam_connection, pathname, &sub->request, sub);
 | 
			
		||||
  
 | 
			
		||||
  G_UNLOCK (fam_connection);
 | 
			
		||||
  return sub;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
_fam_sub_cancel (fam_sub* sub)
 | 
			
		||||
{
 | 
			
		||||
  if (sub->cancelled)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  
 | 
			
		||||
  sub->cancelled = TRUE;
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (fam_connection);
 | 
			
		||||
  /* We need to queue up incoming messages to avoid blocking on write
 | 
			
		||||
   *  if there are many monitors being canceled */
 | 
			
		||||
  fam_do_iter_unlocked ();
 | 
			
		||||
  
 | 
			
		||||
  if (fam_connection == NULL) {
 | 
			
		||||
    G_UNLOCK (fam_connection);
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  FAMCancelMonitor (fam_connection, &sub->request);
 | 
			
		||||
  
 | 
			
		||||
  G_UNLOCK (fam_connection);
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_fam_sub_free (fam_sub* sub)
 | 
			
		||||
{
 | 
			
		||||
  g_free (sub->pathname);
 | 
			
		||||
  g_free (sub);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										37
									
								
								gio/fam/fam-helper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								gio/fam/fam-helper.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 *          John McCutchan <john@johnmccutchan.com> 
 | 
			
		||||
 *          Sebastian Dröge <slomo@circular-chaos.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __FAM_HELPER_H__
 | 
			
		||||
#define __FAM_HELPER_H__
 | 
			
		||||
 | 
			
		||||
typedef struct _fam_sub fam_sub;
 | 
			
		||||
 | 
			
		||||
gboolean  _fam_sub_startup (void);
 | 
			
		||||
fam_sub*  _fam_sub_add     (const gchar* pathname,
 | 
			
		||||
			    gboolean     directory,
 | 
			
		||||
			    gpointer     user_data);
 | 
			
		||||
gboolean  _fam_sub_cancel  (fam_sub* sub);
 | 
			
		||||
void      _fam_sub_free    (fam_sub* sub);
 | 
			
		||||
 | 
			
		||||
#endif /* __FAM_HELPER_H__ */
 | 
			
		||||
							
								
								
									
										41
									
								
								gio/fam/fam-module.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								gio/fam/fam-module.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 * Copyright (C) 2007 Sebastian Dröge.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 *          John McCutchan <john@johnmccutchan.com> 
 | 
			
		||||
 *          Sebastian Dröge <slomo@circular-chaos.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "giomodule.h"
 | 
			
		||||
#include "gfamdirectorymonitor.h"
 | 
			
		||||
#include "gfamfilemonitor.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_io_module_load (GIOModule *module)
 | 
			
		||||
{
 | 
			
		||||
  g_fam_file_monitor_register (module);
 | 
			
		||||
  g_fam_directory_monitor_register (module);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_io_module_unload (GIOModule   *module)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										152
									
								
								gio/fam/gfamdirectorymonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										152
									
								
								gio/fam/gfamdirectorymonitor.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,152 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 * Copyright (C) 2007 Sebastian Dröge.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 *          John McCutchan <john@johnmccutchan.com> 
 | 
			
		||||
 *          Sebastian Dröge <slomo@circular-chaos.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "gfamdirectorymonitor.h"
 | 
			
		||||
#include "giomodule.h"
 | 
			
		||||
 | 
			
		||||
#include "fam-helper.h"
 | 
			
		||||
 | 
			
		||||
struct _GFamDirectoryMonitor
 | 
			
		||||
{
 | 
			
		||||
  GLocalDirectoryMonitor parent_instance;
 | 
			
		||||
  fam_sub *sub;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gboolean g_fam_directory_monitor_cancel (GDirectoryMonitor* monitor);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_DYNAMIC_TYPE (GFamDirectoryMonitor, g_fam_directory_monitor, G_TYPE_LOCAL_DIRECTORY_MONITOR)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_fam_directory_monitor_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GFamDirectoryMonitor *fam_monitor = G_FAM_DIRECTORY_MONITOR (object);
 | 
			
		||||
  fam_sub *sub = fam_monitor->sub;
 | 
			
		||||
 | 
			
		||||
  if (sub) {
 | 
			
		||||
    if (!_fam_sub_cancel (sub))
 | 
			
		||||
      g_warning ("Unexpected error cancelling fam monitor");
 | 
			
		||||
 | 
			
		||||
    _fam_sub_free (sub);
 | 
			
		||||
    fam_monitor->sub = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (g_fam_directory_monitor_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_fam_directory_monitor_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GObject *
 | 
			
		||||
g_fam_directory_monitor_constructor (GType type,
 | 
			
		||||
                                    guint n_construct_properties,
 | 
			
		||||
                                    GObjectConstructParam *construct_properties)
 | 
			
		||||
{
 | 
			
		||||
  GObject *obj;
 | 
			
		||||
  GFamDirectoryMonitorClass *klass;
 | 
			
		||||
  GObjectClass *parent_class;
 | 
			
		||||
  GFamDirectoryMonitor *fam_monitor;
 | 
			
		||||
  const gchar *dirname = NULL;
 | 
			
		||||
  fam_sub *sub = NULL;
 | 
			
		||||
  
 | 
			
		||||
  klass = G_FAM_DIRECTORY_MONITOR_CLASS (g_type_class_peek (G_TYPE_FAM_DIRECTORY_MONITOR));
 | 
			
		||||
  parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
 | 
			
		||||
  obj = parent_class->constructor (type,
 | 
			
		||||
                                   n_construct_properties,
 | 
			
		||||
                                   construct_properties);
 | 
			
		||||
 | 
			
		||||
  fam_monitor = G_FAM_DIRECTORY_MONITOR (obj);
 | 
			
		||||
 | 
			
		||||
  dirname = G_LOCAL_DIRECTORY_MONITOR (obj)->dirname;
 | 
			
		||||
  g_assert (dirname != NULL);
 | 
			
		||||
 | 
			
		||||
  sub = _fam_sub_add (dirname, TRUE, fam_monitor);
 | 
			
		||||
  /* FIXME: what to do about errors here? we can't return NULL or another
 | 
			
		||||
   * kind of error and an assertion is probably too hard */
 | 
			
		||||
  g_assert (sub != NULL);
 | 
			
		||||
 | 
			
		||||
  fam_monitor->sub = sub;
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_fam_directory_monitor_class_finalize (GFamDirectoryMonitorClass *klass)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_fam_directory_monitor_is_supported (void)
 | 
			
		||||
{
 | 
			
		||||
  return _fam_sub_startup ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_fam_directory_monitor_class_init (GFamDirectoryMonitorClass* klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass* gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  GDirectoryMonitorClass *directory_monitor_class = G_DIRECTORY_MONITOR_CLASS (klass);
 | 
			
		||||
  GLocalDirectoryMonitorClass *local_directory_monitor_class = G_LOCAL_DIRECTORY_MONITOR_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_fam_directory_monitor_finalize;
 | 
			
		||||
  gobject_class->constructor = g_fam_directory_monitor_constructor;
 | 
			
		||||
  directory_monitor_class->cancel = g_fam_directory_monitor_cancel;
 | 
			
		||||
 | 
			
		||||
  local_directory_monitor_class->prio = 10;
 | 
			
		||||
  local_directory_monitor_class->mount_notify = FALSE;
 | 
			
		||||
  local_directory_monitor_class->is_supported = g_fam_directory_monitor_is_supported;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_fam_directory_monitor_init (GFamDirectoryMonitor* monitor)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_fam_directory_monitor_cancel (GDirectoryMonitor* monitor)
 | 
			
		||||
{
 | 
			
		||||
  GFamDirectoryMonitor *fam_monitor = G_FAM_DIRECTORY_MONITOR (monitor);
 | 
			
		||||
  fam_sub *sub = fam_monitor->sub;
 | 
			
		||||
 | 
			
		||||
  if (sub) {
 | 
			
		||||
    if (!_fam_sub_cancel (sub))
 | 
			
		||||
      g_warning ("Unexpected error cancelling fam monitor");
 | 
			
		||||
 | 
			
		||||
    _fam_sub_free (sub);
 | 
			
		||||
    fam_monitor->sub = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (G_DIRECTORY_MONITOR_CLASS (g_fam_directory_monitor_parent_class)->cancel)
 | 
			
		||||
    (*G_DIRECTORY_MONITOR_CLASS (g_fam_directory_monitor_parent_class)->cancel) (monitor);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_fam_directory_monitor_register (GIOModule *module)
 | 
			
		||||
{
 | 
			
		||||
  g_fam_directory_monitor_register_type (G_TYPE_MODULE (module));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								gio/fam/gfamdirectorymonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								gio/fam/gfamdirectorymonitor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 * Copyright (C) 2007 Sebastian Dröge.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 *          John McCutchan <john@johnmccutchan.com> 
 | 
			
		||||
 *          Sebastian Dröge <slomo@circular-chaos.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FAM_DIRECTORY_MONITOR_H__
 | 
			
		||||
#define __G_FAM_DIRECTORY_MONITOR_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gio/gdirectorymonitor.h>
 | 
			
		||||
#include "glocaldirectorymonitor.h"
 | 
			
		||||
#include "giomodule.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FAM_DIRECTORY_MONITOR		(g_fam_directory_monitor_get_type ())
 | 
			
		||||
#define G_FAM_DIRECTORY_MONITOR(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FAM_DIRECTORY_MONITOR, GFamDirectoryMonitor))
 | 
			
		||||
#define G_FAM_DIRECTORY_MONITOR_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_FAM_DIRECTORY_MONITOR, GFamDirectoryMonitorClass))
 | 
			
		||||
#define G_IS_FAM_DIRECTORY_MONITOR(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FAM_DIRECTORY_MONITOR))
 | 
			
		||||
#define G_IS_FAM_DIRECTORY_MONITOR_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FAM_DIRECTORY_MONITOR))
 | 
			
		||||
 | 
			
		||||
typedef struct _GFamDirectoryMonitor      GFamDirectoryMonitor;
 | 
			
		||||
typedef struct _GFamDirectoryMonitorClass GFamDirectoryMonitorClass;
 | 
			
		||||
 | 
			
		||||
struct _GFamDirectoryMonitorClass {
 | 
			
		||||
  GLocalDirectoryMonitorClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_fam_directory_monitor_get_type (void);
 | 
			
		||||
void g_fam_directory_monitor_register (GIOModule *module);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FAM_DIRECTORY_MONITOR_H__ */
 | 
			
		||||
							
								
								
									
										150
									
								
								gio/fam/gfamfilemonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								gio/fam/gfamfilemonitor.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,150 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 * Copyright (C) 2007 Sebastian Dröge.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 *          John McCutchan <john@johnmccutchan.com> 
 | 
			
		||||
 *          Sebastian Dröge <slomo@circular-chaos.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "gfamfilemonitor.h"
 | 
			
		||||
#include "giomodule.h"
 | 
			
		||||
 | 
			
		||||
#include "fam-helper.h"
 | 
			
		||||
 | 
			
		||||
struct _GFamFileMonitor
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileMonitor parent_instance;
 | 
			
		||||
  fam_sub *sub;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gboolean g_fam_file_monitor_cancel (GFileMonitor* monitor);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_DYNAMIC_TYPE (GFamFileMonitor, g_fam_file_monitor, G_TYPE_LOCAL_FILE_MONITOR)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_fam_file_monitor_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GFamFileMonitor *fam_monitor = G_FAM_FILE_MONITOR (object);
 | 
			
		||||
  fam_sub *sub = fam_monitor->sub;
 | 
			
		||||
 | 
			
		||||
  if (sub) {
 | 
			
		||||
    if (!_fam_sub_cancel (sub))
 | 
			
		||||
      g_warning ("Unexpected error cancelling fam monitor");
 | 
			
		||||
    _fam_sub_free (sub);
 | 
			
		||||
    fam_monitor->sub = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (g_fam_file_monitor_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_fam_file_monitor_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GObject *
 | 
			
		||||
g_fam_file_monitor_constructor (GType type,
 | 
			
		||||
                                guint n_construct_properties,
 | 
			
		||||
                                GObjectConstructParam *construct_properties)
 | 
			
		||||
{
 | 
			
		||||
  GObject *obj;
 | 
			
		||||
  GFamFileMonitorClass *klass;
 | 
			
		||||
  GObjectClass *parent_class;
 | 
			
		||||
  GFamFileMonitor *fam_monitor;
 | 
			
		||||
  const gchar *filename = NULL;
 | 
			
		||||
  fam_sub *sub = NULL;
 | 
			
		||||
  
 | 
			
		||||
  klass = G_FAM_FILE_MONITOR_CLASS (g_type_class_peek (G_TYPE_FAM_FILE_MONITOR));
 | 
			
		||||
  parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
 | 
			
		||||
  obj = parent_class->constructor (type,
 | 
			
		||||
                                   n_construct_properties,
 | 
			
		||||
                                   construct_properties);
 | 
			
		||||
 | 
			
		||||
  fam_monitor = G_FAM_FILE_MONITOR (obj);
 | 
			
		||||
 | 
			
		||||
  filename = G_LOCAL_FILE_MONITOR (obj)->filename;
 | 
			
		||||
 | 
			
		||||
  g_assert (filename != NULL);
 | 
			
		||||
 | 
			
		||||
  sub = _fam_sub_add (filename, FALSE, fam_monitor);
 | 
			
		||||
  /* FIXME: what to do about errors here? we can't return NULL or another
 | 
			
		||||
   * kind of error and an assertion is probably too hard */
 | 
			
		||||
  g_assert (sub != NULL);
 | 
			
		||||
 | 
			
		||||
  fam_monitor->sub = sub;
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_fam_file_monitor_class_finalize (GFamFileMonitorClass *klass)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_fam_file_monitor_is_supported (void)
 | 
			
		||||
{
 | 
			
		||||
  return _fam_sub_startup ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_fam_file_monitor_class_init (GFamFileMonitorClass* klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass* gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  GFileMonitorClass *file_monitor_class = G_FILE_MONITOR_CLASS (klass);
 | 
			
		||||
  GLocalFileMonitorClass *local_file_monitor_class = G_LOCAL_FILE_MONITOR_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_fam_file_monitor_finalize;
 | 
			
		||||
  gobject_class->constructor = g_fam_file_monitor_constructor;
 | 
			
		||||
  file_monitor_class->cancel = g_fam_file_monitor_cancel;
 | 
			
		||||
 | 
			
		||||
  local_file_monitor_class->prio = 10;
 | 
			
		||||
  local_file_monitor_class->is_supported = g_fam_file_monitor_is_supported;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_fam_file_monitor_init (GFamFileMonitor* monitor)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_fam_file_monitor_cancel (GFileMonitor* monitor)
 | 
			
		||||
{
 | 
			
		||||
  GFamFileMonitor *fam_monitor = G_FAM_FILE_MONITOR (monitor);
 | 
			
		||||
  fam_sub *sub = fam_monitor->sub;
 | 
			
		||||
 | 
			
		||||
  if (sub) {
 | 
			
		||||
    if (!_fam_sub_cancel (sub))
 | 
			
		||||
      g_warning ("Unexpected error cancelling fam monitor");
 | 
			
		||||
    _fam_sub_free (sub);
 | 
			
		||||
    fam_monitor->sub = NULL;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (G_FILE_MONITOR_CLASS (g_fam_file_monitor_parent_class)->cancel)
 | 
			
		||||
    (*G_FILE_MONITOR_CLASS (g_fam_file_monitor_parent_class)->cancel) (monitor);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
g_fam_file_monitor_register (GIOModule *module)
 | 
			
		||||
{
 | 
			
		||||
  g_fam_file_monitor_register_type (G_TYPE_MODULE (module));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										55
									
								
								gio/fam/gfamfilemonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								gio/fam/gfamfilemonitor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 * Copyright (C) 2007 Sebastian Dröge.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Authors: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 *          John McCutchan <john@johnmccutchan.com> 
 | 
			
		||||
 *          Sebastian Dröge <slomo@circular-chaos.org>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FAM_FILE_MONITOR_H__
 | 
			
		||||
#define __G_FAM_FILE_MONITOR_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <gio/gfilemonitor.h>
 | 
			
		||||
#include "glocalfilemonitor.h"
 | 
			
		||||
#include "giomodule.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FAM_FILE_MONITOR		(g_fam_file_monitor_get_type ())
 | 
			
		||||
#define G_FAM_FILE_MONITOR(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FAM_FILE_MONITOR, GFamFileMonitor))
 | 
			
		||||
#define G_FAM_FILE_MONITOR_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_FAM_FILE_MONITOR, GFamFileMonitorClass))
 | 
			
		||||
#define G_IS_FAM_FILE_MONITOR(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FAM_FILE_MONITOR))
 | 
			
		||||
#define G_IS_FAM_FILE_MONITOR_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FAM_FILE_MONITOR))
 | 
			
		||||
 | 
			
		||||
typedef struct _GFamFileMonitor      GFamFileMonitor;
 | 
			
		||||
typedef struct _GFamFileMonitorClass GFamFileMonitorClass;
 | 
			
		||||
 | 
			
		||||
struct _GFamFileMonitorClass {
 | 
			
		||||
  GLocalFileMonitorClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_fam_file_monitor_get_type (void);
 | 
			
		||||
void g_fam_file_monitor_register (GIOModule *module);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FAM_FILE_MONITOR_H__ */
 | 
			
		||||
							
								
								
									
										535
									
								
								gio/gappinfo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										535
									
								
								gio/gappinfo.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,535 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "gappinfo.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
#include <gioerror.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void g_app_info_base_init (gpointer g_class);
 | 
			
		||||
static void g_app_info_class_init (gpointer g_class,
 | 
			
		||||
				   gpointer class_data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
g_app_info_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
  static GType app_info_type = 0;
 | 
			
		||||
 | 
			
		||||
  if (! app_info_type)
 | 
			
		||||
    {
 | 
			
		||||
      static const GTypeInfo app_info_info =
 | 
			
		||||
      {
 | 
			
		||||
        sizeof (GAppInfoIface), /* class_size */
 | 
			
		||||
	g_app_info_base_init,   /* base_init */
 | 
			
		||||
	NULL,		/* base_finalize */
 | 
			
		||||
	g_app_info_class_init,
 | 
			
		||||
	NULL,		/* class_finalize */
 | 
			
		||||
	NULL,		/* class_data */
 | 
			
		||||
	0,
 | 
			
		||||
	0,              /* n_preallocs */
 | 
			
		||||
	NULL
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      app_info_type =
 | 
			
		||||
	g_type_register_static (G_TYPE_INTERFACE, I_("GAppInfo"),
 | 
			
		||||
				&app_info_info, 0);
 | 
			
		||||
 | 
			
		||||
      g_type_interface_add_prerequisite (app_info_type, G_TYPE_OBJECT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return app_info_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_app_info_class_init (gpointer g_class,
 | 
			
		||||
		       gpointer class_data)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_app_info_base_init (gpointer g_class)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_dup:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a duplicate of @appinfo.
 | 
			
		||||
 **/
 | 
			
		||||
GAppInfo *
 | 
			
		||||
g_app_info_dup (GAppInfo *appinfo)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->dup) (appinfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_equal:
 | 
			
		||||
 * @appinfo1: the first #GAppInfo.  
 | 
			
		||||
 * @appinfo2: the second #GAppInfo.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if @appinfo1 is equal to @appinfo2. %FALSE otherwise.
 | 
			
		||||
 *  
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_equal (GAppInfo    *appinfo1,
 | 
			
		||||
		  GAppInfo    *appinfo2)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo1), FALSE);
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo2), FALSE);
 | 
			
		||||
 | 
			
		||||
  if (G_TYPE_FROM_INSTANCE (appinfo1) != G_TYPE_FROM_INSTANCE (appinfo2))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo1);
 | 
			
		||||
 | 
			
		||||
  return (* iface->equal) (appinfo1, appinfo2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_get_id:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
const char *
 | 
			
		||||
g_app_info_get_id (GAppInfo *appinfo)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_id) (appinfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_get_name:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the name of the application for @appinfo.
 | 
			
		||||
 **/
 | 
			
		||||
const char *
 | 
			
		||||
g_app_info_get_name (GAppInfo *appinfo)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_name) (appinfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_get_description:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a string containing a description of the 
 | 
			
		||||
 * application @appinfo.  
 | 
			
		||||
 * The returned string should be not freed when no longer needed.
 | 
			
		||||
 **/
 | 
			
		||||
const char *
 | 
			
		||||
g_app_info_get_description (GAppInfo *appinfo)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_description) (appinfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_get_executable:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: a string containing the @appinfo's application 
 | 
			
		||||
 * binary's name.
 | 
			
		||||
 **/
 | 
			
		||||
const char *
 | 
			
		||||
g_app_info_get_executable (GAppInfo *appinfo)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_executable) (appinfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_set_as_default_for_type:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 * @content_type: the content type.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the given @appinfo is the default 
 | 
			
		||||
 * for the given @content_type. %FALSE if not, 
 | 
			
		||||
 * or in case of an error.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_set_as_default_for_type (GAppInfo    *appinfo,
 | 
			
		||||
				    const char  *content_type,
 | 
			
		||||
				    GError     **error)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
 | 
			
		||||
  g_return_val_if_fail (content_type != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->set_as_default_for_type) (appinfo, content_type, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_set_as_default_for_extension:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 * @extension: a string containing the file extension.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the given @appinfo is the default 
 | 
			
		||||
 * for the given @extension. %FALSE if not, 
 | 
			
		||||
 * or in case of an error.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_set_as_default_for_extension (GAppInfo  *appinfo,
 | 
			
		||||
					 const char *extension,
 | 
			
		||||
					 GError **error)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
 | 
			
		||||
  g_return_val_if_fail (extension != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  if (iface->set_as_default_for_extension)
 | 
			
		||||
    return (* iface->set_as_default_for_extension) (appinfo, extension, error);
 | 
			
		||||
 | 
			
		||||
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "g_app_info_set_as_default_for_extension not supported yet");
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_add_supports_type:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 * @content_type: a string.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if @appinfo supports @content_type.
 | 
			
		||||
 * %FALSE if not, or in case of an error.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_add_supports_type (GAppInfo             *appinfo,
 | 
			
		||||
			      const char           *content_type,
 | 
			
		||||
			      GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
 | 
			
		||||
  g_return_val_if_fail (content_type != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  if (iface->add_supports_type)
 | 
			
		||||
    return (* iface->add_supports_type) (appinfo, content_type, error);
 | 
			
		||||
 | 
			
		||||
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "g_app_info_add_supports_type not supported yet");
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_can_remove_support_type:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if it is possible to remove supported 
 | 
			
		||||
 * content types from a given @appinfo, %FALSE if not.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_can_remove_supports_type (GAppInfo *appinfo)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  if (iface->can_remove_supports_type)
 | 
			
		||||
    return (* iface->can_remove_supports_type) (appinfo);
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_remove_supports_type:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 * @content_type: a string.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if @content_type support was removed
 | 
			
		||||
 * from @appinfo. %FALSE if not.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_remove_supports_type (GAppInfo *appinfo,
 | 
			
		||||
				 const char *content_type,
 | 
			
		||||
				 GError **error)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
 | 
			
		||||
  g_return_val_if_fail (content_type != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  if (iface->remove_supports_type)
 | 
			
		||||
    return (* iface->remove_supports_type) (appinfo, content_type, error);
 | 
			
		||||
 | 
			
		||||
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "g_app_info_remove_supports_type not supported yet");
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_get_icon:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: the default #GIcon for @appinfo.
 | 
			
		||||
 **/
 | 
			
		||||
GIcon *
 | 
			
		||||
g_app_info_get_icon (GAppInfo *appinfo)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_icon) (appinfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_launch:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 * @files: a #GList of #GFile objects.
 | 
			
		||||
 * @launch_context: a #GAppLaunchContext.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE on successful launch.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_launch (GAppInfo    *appinfo,
 | 
			
		||||
		   GList       *files,
 | 
			
		||||
		   GAppLaunchContext *launch_context,
 | 
			
		||||
		   GError     **error)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->launch) (appinfo, files, launch_context, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_supports_uris:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the @appinfo supports URIs.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_supports_uris (GAppInfo *appinfo)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->supports_uris) (appinfo);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_launch_uris:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 * @uris: a #GList containing URIs to launch. 
 | 
			
		||||
 * @launch_context: a #GAppLaunchContext.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the @appinfo was launched 
 | 
			
		||||
 * with the given @uris.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_launch_uris (GAppInfo    *appinfo,
 | 
			
		||||
			GList       *uris,
 | 
			
		||||
			GAppLaunchContext *launch_context,
 | 
			
		||||
			GError     **error)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->launch) (appinfo, uris, launch_context, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_info_should_show:
 | 
			
		||||
 * @appinfo: a #GAppInfo.
 | 
			
		||||
 * @desktop_env: a string.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the @GAppInfo should be shown,
 | 
			
		||||
 * %FALSE otherwise.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_app_info_should_show (GAppInfo    *appinfo,
 | 
			
		||||
			const char  *desktop_env)
 | 
			
		||||
{
 | 
			
		||||
  GAppInfoIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (appinfo), FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_APP_INFO_GET_IFACE (appinfo);
 | 
			
		||||
 | 
			
		||||
  return (* iface->should_show) (appinfo, desktop_env);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GAppLaunchContext, g_app_launch_context, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_launch_context_new:
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: A new #GAppLaunchContext.
 | 
			
		||||
 **/
 | 
			
		||||
GAppLaunchContext *
 | 
			
		||||
g_app_launch_context_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (G_TYPE_APP_LAUNCH_CONTEXT, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_app_launch_context_class_init (GAppLaunchContextClass *klass)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_app_launch_context_init (GAppLaunchContext *launch_context)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_launch_context_get_display:
 | 
			
		||||
 * @context: a #GAppLaunchContext.  
 | 
			
		||||
 * @info: a #GAppInfo. 
 | 
			
		||||
 * @files: a #GList of files.
 | 
			
		||||
 *
 | 
			
		||||
 **/
 | 
			
		||||
char *
 | 
			
		||||
g_app_launch_context_get_display (GAppLaunchContext *context,
 | 
			
		||||
				  GAppInfo          *info,
 | 
			
		||||
				  GList             *files)
 | 
			
		||||
{
 | 
			
		||||
  GAppLaunchContextClass *class;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL);
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (info), NULL);
 | 
			
		||||
 | 
			
		||||
  class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context);
 | 
			
		||||
 | 
			
		||||
  if (class->get_display == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  return class->get_display (context, info, files);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_launch_context_get_startup_notify_id:
 | 
			
		||||
 * @context: a #GAppLaunchContext.
 | 
			
		||||
 * @info: a #GAppInfo.
 | 
			
		||||
 * @files: a #GList of files.
 | 
			
		||||
 *
 | 
			
		||||
 **/
 | 
			
		||||
char *
 | 
			
		||||
g_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
 | 
			
		||||
					    GAppInfo          *info,
 | 
			
		||||
					    GList             *files)
 | 
			
		||||
{
 | 
			
		||||
  GAppLaunchContextClass *class;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_LAUNCH_CONTEXT (context), NULL);
 | 
			
		||||
  g_return_val_if_fail (G_IS_APP_INFO (info), NULL);
 | 
			
		||||
 | 
			
		||||
  class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context);
 | 
			
		||||
 | 
			
		||||
  if (class->get_startup_notify_id == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  return class->get_startup_notify_id (context, info, files);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_app_launch_context_get_startup_notify_id:
 | 
			
		||||
 * @context: a #GAppLaunchContext.
 | 
			
		||||
 * @startup_notify_id: a string containing the startup ID of the application.
 | 
			
		||||
 *
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_app_launch_context_launch_failed (GAppLaunchContext *context,
 | 
			
		||||
				    const char *startup_notify_id)
 | 
			
		||||
{
 | 
			
		||||
  GAppLaunchContextClass *class;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_APP_LAUNCH_CONTEXT (context));
 | 
			
		||||
  g_return_if_fail (startup_notify_id != NULL);
 | 
			
		||||
 | 
			
		||||
  class = G_APP_LAUNCH_CONTEXT_GET_CLASS (context);
 | 
			
		||||
 | 
			
		||||
  if (class->launch_failed != NULL)
 | 
			
		||||
    class->launch_failed (context, startup_notify_id);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										206
									
								
								gio/gappinfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								gio/gappinfo.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,206 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_APP_INFO_H__
 | 
			
		||||
#define __G_APP_INFO_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gicon.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_APP_INFO            (g_app_info_get_type ())
 | 
			
		||||
#define G_APP_INFO(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_APP_INFO, GAppInfo))
 | 
			
		||||
#define G_IS_APP_INFO(obj)	   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_APP_INFO))
 | 
			
		||||
#define G_APP_INFO_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_APP_INFO, GAppInfoIface))
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_APP_LAUNCH_CONTEXT         (g_app_launch_context_get_type ())
 | 
			
		||||
#define G_APP_LAUNCH_CONTEXT(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_APP_LAUNCH_CONTEXT, GAppLaunchContext))
 | 
			
		||||
#define G_APP_LAUNCH_CONTEXT_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_APP_LAUNCH_CONTEXT, GAppLaunchContextClass))
 | 
			
		||||
#define G_IS_APP_LAUNCH_CONTEXT(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_APP_LAUNCH_CONTEXT))
 | 
			
		||||
#define G_IS_APP_LAUNCH_CONTEXT_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_APP_LAUNCH_CONTEXT))
 | 
			
		||||
#define G_APP_LAUNCH_CONTEXT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_APP_LAUNCH_CONTEXT, GAppLaunchContextClass))
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  G_APP_INFO_CREATE_FLAGS_NONE = 0,
 | 
			
		||||
  G_APP_INFO_CREATE_NEEDS_TERMINAL = (1<<0)
 | 
			
		||||
} GAppInfoCreateFlags;
 | 
			
		||||
 | 
			
		||||
typedef struct _GAppLaunchContext        GAppLaunchContext;
 | 
			
		||||
typedef struct _GAppLaunchContextClass   GAppLaunchContextClass;
 | 
			
		||||
typedef struct _GAppLaunchContextPrivate GAppLaunchContextPrivate;
 | 
			
		||||
 | 
			
		||||
typedef struct _GAppInfo         GAppInfo; /* Dummy typedef */
 | 
			
		||||
typedef struct _GAppInfoIface    GAppInfoIface;
 | 
			
		||||
 | 
			
		||||
struct _GAppInfoIface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface g_iface;
 | 
			
		||||
 | 
			
		||||
  /* Virtual Table */
 | 
			
		||||
 | 
			
		||||
  GAppInfo *          (*dup)                (GAppInfo                *appinfo);
 | 
			
		||||
  gboolean            (*equal)              (GAppInfo                *appinfo1,
 | 
			
		||||
					     GAppInfo                *appinfo2);
 | 
			
		||||
  const char *        (*get_id)             (GAppInfo                *appinfo);
 | 
			
		||||
  const char *        (*get_name)           (GAppInfo                *appinfo);
 | 
			
		||||
  const char *        (*get_description)    (GAppInfo                *appinfo);
 | 
			
		||||
  const char *        (*get_executable)     (GAppInfo                *appinfo);
 | 
			
		||||
  GIcon *             (*get_icon)           (GAppInfo                *appinfo);
 | 
			
		||||
  gboolean            (*launch)             (GAppInfo                *appinfo,
 | 
			
		||||
					     GList                   *filenames,
 | 
			
		||||
					     GAppLaunchContext       *launch_context,
 | 
			
		||||
					     GError                 **error);
 | 
			
		||||
  gboolean            (*supports_uris)      (GAppInfo                *appinfo);
 | 
			
		||||
  gboolean            (*launch_uris)        (GAppInfo                *appinfo,
 | 
			
		||||
					     GList                   *uris,
 | 
			
		||||
					     GAppLaunchContext       *launch_context,
 | 
			
		||||
					     GError                 **error);
 | 
			
		||||
  gboolean            (*should_show)        (GAppInfo                *appinfo,
 | 
			
		||||
					     const char              *desktop_env);
 | 
			
		||||
  gboolean            (*supports_xdg_startup_notify) (GAppInfo       *appinfo);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* For changing associations */
 | 
			
		||||
  gboolean  (*set_as_default_for_type)      (GAppInfo           *appinfo,
 | 
			
		||||
					     const char         *content_type,
 | 
			
		||||
					     GError            **error);
 | 
			
		||||
  gboolean  (*set_as_default_for_extension) (GAppInfo           *appinfo,
 | 
			
		||||
					     const char         *extension,
 | 
			
		||||
					     GError            **error);
 | 
			
		||||
  gboolean  (*add_supports_type)            (GAppInfo           *appinfo,
 | 
			
		||||
					     const char         *content_type,
 | 
			
		||||
					     GError            **error);
 | 
			
		||||
  gboolean  (*can_remove_supports_type)     (GAppInfo           *appinfo);
 | 
			
		||||
  gboolean  (*remove_supports_type)         (GAppInfo           *appinfo,
 | 
			
		||||
					     const char         *content_type,
 | 
			
		||||
					     GError            **error);
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
  void (*_g_reserved6) (void);
 | 
			
		||||
  void (*_g_reserved7) (void);
 | 
			
		||||
  void (*_g_reserved8) (void);
 | 
			
		||||
  void (*_g_reserved9) (void);
 | 
			
		||||
  void (*_g_reserved10) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_app_info_get_type (void) G_GNUC_CONST;
 | 
			
		||||
GType g_app_launch_context_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GAppInfo *  g_app_info_create_from_commandline      (const char           *commandline,
 | 
			
		||||
						     const char           *application_name,
 | 
			
		||||
						     GAppInfoCreateFlags   flags,
 | 
			
		||||
						     GError              **error);
 | 
			
		||||
GAppInfo *  g_app_info_dup                          (GAppInfo             *appinfo);
 | 
			
		||||
gboolean    g_app_info_equal                        (GAppInfo             *appinfo1,
 | 
			
		||||
						     GAppInfo             *appinfo2);
 | 
			
		||||
const char *g_app_info_get_id                       (GAppInfo             *appinfo);
 | 
			
		||||
const char *g_app_info_get_name                     (GAppInfo             *appinfo);
 | 
			
		||||
const char *g_app_info_get_description              (GAppInfo             *appinfo);
 | 
			
		||||
const char *g_app_info_get_executable               (GAppInfo             *appinfo);
 | 
			
		||||
GIcon *     g_app_info_get_icon                     (GAppInfo             *appinfo);
 | 
			
		||||
gboolean    g_app_info_launch                       (GAppInfo             *appinfo,
 | 
			
		||||
						     GList                *files,
 | 
			
		||||
						     GAppLaunchContext    *launch_context,
 | 
			
		||||
						     GError              **error);
 | 
			
		||||
gboolean    g_app_info_supports_uris                (GAppInfo             *appinfo);
 | 
			
		||||
gboolean    g_app_info_launch_uris                  (GAppInfo             *appinfo,
 | 
			
		||||
						     GList                *uris,
 | 
			
		||||
						     GAppLaunchContext    *launch_context,
 | 
			
		||||
						     GError              **error);
 | 
			
		||||
gboolean    g_app_info_should_show                  (GAppInfo             *appinfo,
 | 
			
		||||
						     const char           *desktop_env);
 | 
			
		||||
 | 
			
		||||
gboolean    g_app_info_set_as_default_for_type      (GAppInfo             *appinfo,
 | 
			
		||||
						     const char           *content_type,
 | 
			
		||||
						     GError              **error);
 | 
			
		||||
gboolean    g_app_info_set_as_default_for_extension (GAppInfo             *appinfo,
 | 
			
		||||
						     const char           *extension,
 | 
			
		||||
						     GError              **error);
 | 
			
		||||
gboolean    g_app_info_add_supports_type            (GAppInfo             *appinfo,
 | 
			
		||||
						     const char           *content_type,
 | 
			
		||||
						     GError              **error);
 | 
			
		||||
gboolean    g_app_info_can_remove_supports_type     (GAppInfo             *appinfo);
 | 
			
		||||
gboolean    g_app_info_remove_supports_type         (GAppInfo             *appinfo,
 | 
			
		||||
						     const char           *content_type,
 | 
			
		||||
						     GError              **error);
 | 
			
		||||
 | 
			
		||||
GList *   g_app_info_get_all                     (void);
 | 
			
		||||
GList *   g_app_info_get_all_for_type            (const char  *content_type);
 | 
			
		||||
GAppInfo *g_app_info_get_default_for_type        (const char  *content_type,
 | 
			
		||||
						  gboolean     must_support_uris);
 | 
			
		||||
GAppInfo *g_app_info_get_default_for_uri_scheme  (const char  *uri_scheme);
 | 
			
		||||
 | 
			
		||||
/* TODO: missing operations:
 | 
			
		||||
   add app as supporting a content type, but don't make it default
 | 
			
		||||
   implement set_as_default_for_extension
 | 
			
		||||
 | 
			
		||||
   can_remove, remove (as in, don't support a specific mimetype)
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _GAppLaunchContext
 | 
			
		||||
{
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
 | 
			
		||||
  GAppLaunchContextPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GAppLaunchContextClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  char * (*get_display)           (GAppLaunchContext *context,
 | 
			
		||||
				   GAppInfo *info,
 | 
			
		||||
				   GList *files);
 | 
			
		||||
  char * (*get_startup_notify_id) (GAppLaunchContext *context,
 | 
			
		||||
				   GAppInfo *info,
 | 
			
		||||
				   GList *files);
 | 
			
		||||
  void   (*launch_failed)         (GAppLaunchContext *context,
 | 
			
		||||
				   const char *startup_notify_id);
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GAppLaunchContext *g_app_launch_context_new                   (void);
 | 
			
		||||
char *             g_app_launch_context_get_display           (GAppLaunchContext *context,
 | 
			
		||||
							       GAppInfo          *info,
 | 
			
		||||
							       GList             *files);
 | 
			
		||||
char *             g_app_launch_context_get_startup_notify_id (GAppLaunchContext *context,
 | 
			
		||||
							       GAppInfo          *info,
 | 
			
		||||
							       GList             *files);
 | 
			
		||||
void               g_app_launch_context_launch_failed         (GAppLaunchContext *context,
 | 
			
		||||
							       const char *       startup_notify_id);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_APP_INFO_H__ */
 | 
			
		||||
							
								
								
									
										163
									
								
								gio/gasynchelper.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								gio/gasynchelper.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "gasynchelper.h"
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_result_free (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  GAsyncResultData *res = data;
 | 
			
		||||
 | 
			
		||||
  if (res->error)
 | 
			
		||||
    g_error_free (res->error);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (res->async_object);
 | 
			
		||||
  
 | 
			
		||||
  g_free (res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_g_queue_async_result (GAsyncResultData *result,
 | 
			
		||||
		       gpointer        async_object,
 | 
			
		||||
		       GError         *error,
 | 
			
		||||
		       gpointer        user_data,
 | 
			
		||||
		       GSourceFunc     source_func)
 | 
			
		||||
{
 | 
			
		||||
  GSource *source;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_OBJECT (async_object));
 | 
			
		||||
  
 | 
			
		||||
  result->async_object = g_object_ref (async_object);
 | 
			
		||||
  result->user_data = user_data;
 | 
			
		||||
  result->error = error;
 | 
			
		||||
 | 
			
		||||
  source = g_idle_source_new ();
 | 
			
		||||
  g_source_set_priority (source, G_PRIORITY_DEFAULT);
 | 
			
		||||
  g_source_set_callback (source, source_func, result, async_result_free);
 | 
			
		||||
  g_source_attach (source, NULL);
 | 
			
		||||
  g_source_unref (source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*************************************************************************
 | 
			
		||||
 *             fd source                                                 *
 | 
			
		||||
 ************************************************************************/
 | 
			
		||||
 | 
			
		||||
typedef struct 
 | 
			
		||||
{
 | 
			
		||||
  GSource source;
 | 
			
		||||
  GPollFD pollfd;
 | 
			
		||||
  GCancellable *cancellable;
 | 
			
		||||
  gulong cancelled_tag;
 | 
			
		||||
} FDSource;
 | 
			
		||||
 | 
			
		||||
static gboolean 
 | 
			
		||||
fd_source_prepare (GSource  *source,
 | 
			
		||||
		   gint     *timeout)
 | 
			
		||||
{
 | 
			
		||||
  FDSource *fd_source = (FDSource *)source;
 | 
			
		||||
  *timeout = -1;
 | 
			
		||||
  
 | 
			
		||||
  return g_cancellable_is_cancelled (fd_source->cancellable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean 
 | 
			
		||||
fd_source_check (GSource  *source)
 | 
			
		||||
{
 | 
			
		||||
  FDSource *fd_source = (FDSource *)source;
 | 
			
		||||
 | 
			
		||||
  return
 | 
			
		||||
    g_cancellable_is_cancelled  (fd_source->cancellable) ||
 | 
			
		||||
    fd_source->pollfd.revents != 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
fd_source_dispatch (GSource     *source,
 | 
			
		||||
		    GSourceFunc  callback,
 | 
			
		||||
		    gpointer     user_data)
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
  GFDSourceFunc func = (GFDSourceFunc)callback;
 | 
			
		||||
  FDSource *fd_source = (FDSource *)source;
 | 
			
		||||
 | 
			
		||||
  g_assert (func != NULL);
 | 
			
		||||
 | 
			
		||||
  return (*func) (user_data, fd_source->pollfd.revents, fd_source->pollfd.fd);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
fd_source_finalize (GSource *source)
 | 
			
		||||
{
 | 
			
		||||
  FDSource *fd_source = (FDSource *)source;
 | 
			
		||||
 | 
			
		||||
  if (fd_source->cancelled_tag)
 | 
			
		||||
    g_signal_handler_disconnect (fd_source->cancellable,
 | 
			
		||||
				 fd_source->cancelled_tag);
 | 
			
		||||
 | 
			
		||||
  if (fd_source->cancellable)
 | 
			
		||||
    g_object_unref (fd_source->cancellable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GSourceFuncs fd_source_funcs = {
 | 
			
		||||
  fd_source_prepare,
 | 
			
		||||
  fd_source_check,
 | 
			
		||||
  fd_source_dispatch,
 | 
			
		||||
  fd_source_finalize
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Might be called on another thread */
 | 
			
		||||
static void
 | 
			
		||||
fd_source_cancelled_cb (GCancellable *cancellable,
 | 
			
		||||
			gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  /* Wake up the mainloop in case we're waiting on async calls with FDSource */
 | 
			
		||||
  g_main_context_wakeup (NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GSource *
 | 
			
		||||
_g_fd_source_new (int fd,
 | 
			
		||||
		  gushort events,
 | 
			
		||||
		  GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  GSource *source;
 | 
			
		||||
  FDSource *fd_source;
 | 
			
		||||
 | 
			
		||||
  source = g_source_new (&fd_source_funcs, sizeof (FDSource));
 | 
			
		||||
  fd_source = (FDSource *)source;
 | 
			
		||||
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    fd_source->cancellable = g_object_ref (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  fd_source->pollfd.fd = fd;
 | 
			
		||||
  fd_source->pollfd.events = events;
 | 
			
		||||
  g_source_add_poll (source, &fd_source->pollfd);
 | 
			
		||||
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    fd_source->cancelled_tag =
 | 
			
		||||
      g_signal_connect_data (cancellable, "cancelled",
 | 
			
		||||
			     (GCallback)fd_source_cancelled_cb,
 | 
			
		||||
			     NULL, NULL,
 | 
			
		||||
			     0);
 | 
			
		||||
  
 | 
			
		||||
  return source;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										53
									
								
								gio/gasynchelper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								gio/gasynchelper.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_ASYNC_HELPER_H__
 | 
			
		||||
#define __G_ASYNC_HELPER_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include "gcancellable.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  gpointer       async_object;
 | 
			
		||||
  GError *       error;
 | 
			
		||||
  gpointer       user_data;
 | 
			
		||||
} GAsyncResultData;
 | 
			
		||||
 | 
			
		||||
typedef gboolean (*GFDSourceFunc) (gpointer user_data,
 | 
			
		||||
				   GIOCondition condition,
 | 
			
		||||
				   int fd);
 | 
			
		||||
 | 
			
		||||
void     _g_queue_async_result (GAsyncResultData *result,
 | 
			
		||||
				gpointer         async_object,
 | 
			
		||||
				GError          *error,
 | 
			
		||||
				gpointer         user_data,
 | 
			
		||||
				GSourceFunc      source_func);
 | 
			
		||||
 | 
			
		||||
GSource *_g_fd_source_new      (int              fd,
 | 
			
		||||
				gushort          events,
 | 
			
		||||
				GCancellable    *cancellable);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_ASYNC_HELPER_H__ */
 | 
			
		||||
							
								
								
									
										107
									
								
								gio/gasyncresult.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								gio/gasyncresult.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "gasyncresult.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
static void g_async_result_base_init (gpointer g_class);
 | 
			
		||||
static void g_async_result_class_init (gpointer g_class,
 | 
			
		||||
				       gpointer class_data);
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
g_async_result_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
  static GType async_result_type = 0;
 | 
			
		||||
 | 
			
		||||
  if (! async_result_type)
 | 
			
		||||
    {
 | 
			
		||||
      static const GTypeInfo async_result_info =
 | 
			
		||||
      {
 | 
			
		||||
        sizeof (GAsyncResultIface), /* class_size */
 | 
			
		||||
	g_async_result_base_init,   /* base_init */
 | 
			
		||||
	NULL,		            /* base_finalize */
 | 
			
		||||
	g_async_result_class_init,
 | 
			
		||||
	NULL,		/* class_finalize */
 | 
			
		||||
	NULL,		/* class_data */
 | 
			
		||||
	0,
 | 
			
		||||
	0,              /* n_preallocs */
 | 
			
		||||
	NULL
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      async_result_type =
 | 
			
		||||
	g_type_register_static (G_TYPE_INTERFACE, I_("GAsyncResult"),
 | 
			
		||||
				&async_result_info, 0);
 | 
			
		||||
 | 
			
		||||
      g_type_interface_add_prerequisite (async_result_type, G_TYPE_OBJECT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return async_result_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_async_result_class_init (gpointer g_class,
 | 
			
		||||
			   gpointer class_data)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_async_result_base_init (gpointer g_class)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_async_result_get_user_data:
 | 
			
		||||
 * @res: a #GAsyncResult.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: the user data for the given @res, or
 | 
			
		||||
 * %NULL on failure. 
 | 
			
		||||
 **/
 | 
			
		||||
gpointer
 | 
			
		||||
g_async_result_get_user_data (GAsyncResult *res)
 | 
			
		||||
{
 | 
			
		||||
  GAsyncResultIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_ASYNC_RESULT_GET_IFACE (res);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_user_data) (res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_async_result_get_source_object:
 | 
			
		||||
 * @res: a #GAsyncResult.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: the source object for the @res.
 | 
			
		||||
 **/
 | 
			
		||||
GObject *
 | 
			
		||||
g_async_result_get_source_object (GAsyncResult *res)
 | 
			
		||||
{
 | 
			
		||||
  GAsyncResultIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_ASYNC_RESULT_GET_IFACE (res);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_source_object) (res);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								gio/gasyncresult.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								gio/gasyncresult.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_ASYNC_RESULT_H__
 | 
			
		||||
#define __G_ASYNC_RESULT_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_ASYNC_RESULT            (g_async_result_get_type ())
 | 
			
		||||
#define G_ASYNC_RESULT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_ASYNC_RESULT, GAsyncResult))
 | 
			
		||||
#define G_IS_ASYNC_RESULT(obj)	       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_ASYNC_RESULT))
 | 
			
		||||
#define G_ASYNC_RESULT_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_ASYNC_RESULT, GAsyncResultIface))
 | 
			
		||||
 | 
			
		||||
typedef struct _GAsyncResult         GAsyncResult; /* Dummy typedef */
 | 
			
		||||
typedef struct _GAsyncResultIface    GAsyncResultIface;
 | 
			
		||||
 | 
			
		||||
typedef void (*GAsyncReadyCallback) (GObject *source_object,
 | 
			
		||||
				     GAsyncResult *res,
 | 
			
		||||
				     gpointer user_data);
 | 
			
		||||
 | 
			
		||||
struct _GAsyncResultIface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface g_iface;
 | 
			
		||||
 | 
			
		||||
  /* Virtual Table */
 | 
			
		||||
 | 
			
		||||
  gpointer   (*get_user_data)      (GAsyncResult                *async_result);
 | 
			
		||||
  GObject *  (*get_source_object)  (GAsyncResult                *async_result);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_async_result_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
gpointer g_async_result_get_user_data     (GAsyncResult *res);
 | 
			
		||||
GObject *g_async_result_get_source_object (GAsyncResult *res);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_ASYNC_RESULT_H__ */
 | 
			
		||||
							
								
								
									
										1230
									
								
								gio/gbufferedinputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1230
									
								
								gio/gbufferedinputstream.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										110
									
								
								gio/gbufferedinputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								gio/gbufferedinputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Christian Kellner <gicmo@gnome.org> 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_BUFFERED_INPUT_STREAM_H__
 | 
			
		||||
#define __G_BUFFERED_INPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gfilterinputstream.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_BUFFERED_INPUT_STREAM         (g_buffered_input_stream_get_type ())
 | 
			
		||||
#define G_BUFFERED_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_BUFFERED_INPUT_STREAM, GBufferedInputStream))
 | 
			
		||||
#define G_BUFFERED_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_BUFFERED_INPUT_STREAM, GBufferedInputStreamClass))
 | 
			
		||||
#define G_IS_BUFFERED_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_BUFFERED_INPUT_STREAM))
 | 
			
		||||
#define G_IS_BUFFERED_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_BUFFERED_INPUT_STREAM))
 | 
			
		||||
#define G_BUFFERED_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_BUFFERED_INPUT_STREAM, GBufferedInputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GBufferedInputStream         GBufferedInputStream;
 | 
			
		||||
typedef struct _GBufferedInputStreamClass    GBufferedInputStreamClass;
 | 
			
		||||
typedef struct _GBufferedInputStreamPrivate  GBufferedInputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GBufferedInputStream
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream parent;
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GBufferedInputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GBufferedInputStreamClass
 | 
			
		||||
{
 | 
			
		||||
 GFilterInputStreamClass parent_class;
 | 
			
		||||
 | 
			
		||||
  gssize   (* fill)        (GBufferedInputStream *stream,
 | 
			
		||||
			    gssize                count,
 | 
			
		||||
			    GCancellable         *cancellable,
 | 
			
		||||
			    GError              **error);
 | 
			
		||||
 | 
			
		||||
  /* Async ops: (optional in derived classes) */
 | 
			
		||||
  void     (* fill_async)  (GBufferedInputStream *stream,
 | 
			
		||||
			    gssize                count,
 | 
			
		||||
			    int                   io_priority,
 | 
			
		||||
			    GCancellable         *cancellable,
 | 
			
		||||
			    GAsyncReadyCallback   callback,
 | 
			
		||||
			    gpointer              user_data);
 | 
			
		||||
  gssize   (* fill_finish) (GBufferedInputStream *stream,
 | 
			
		||||
			    GAsyncResult         *result,
 | 
			
		||||
			    GError              **error);
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GType         g_buffered_input_stream_get_type        (void) G_GNUC_CONST;
 | 
			
		||||
GInputStream* g_buffered_input_stream_new             (GInputStream          *base_stream);
 | 
			
		||||
GInputStream* g_buffered_input_stream_new_sized       (GInputStream          *base_stream,
 | 
			
		||||
						       gsize                  size);
 | 
			
		||||
 | 
			
		||||
gsize         g_buffered_input_stream_get_buffer_size (GBufferedInputStream  *stream);
 | 
			
		||||
void          g_buffered_input_stream_set_buffer_size (GBufferedInputStream  *stream,
 | 
			
		||||
						       gsize                  size);
 | 
			
		||||
gsize         g_buffered_input_stream_get_available   (GBufferedInputStream  *stream);
 | 
			
		||||
gsize         g_buffered_input_stream_peek            (GBufferedInputStream  *stream,
 | 
			
		||||
						       void                  *buffer,
 | 
			
		||||
						       gsize                  offset,
 | 
			
		||||
						       gsize                  count);
 | 
			
		||||
 | 
			
		||||
gssize        g_buffered_input_stream_fill            (GBufferedInputStream  *stream,
 | 
			
		||||
						       gssize                 count,
 | 
			
		||||
						       GCancellable          *cancellable,
 | 
			
		||||
						       GError               **error);
 | 
			
		||||
void          g_buffered_input_stream_fill_async      (GBufferedInputStream  *stream,
 | 
			
		||||
						       gssize                 count,
 | 
			
		||||
						       int                    io_priority,
 | 
			
		||||
						       GCancellable          *cancellable,
 | 
			
		||||
						       GAsyncReadyCallback    callback,
 | 
			
		||||
						       gpointer               user_data);
 | 
			
		||||
gssize        g_buffered_input_stream_fill_finish     (GBufferedInputStream  *stream,
 | 
			
		||||
						       GAsyncResult          *result,
 | 
			
		||||
						       GError               **error);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_BUFFERED_INPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										734
									
								
								gio/gbufferedoutputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										734
									
								
								gio/gbufferedoutputstream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,734 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Christian Kellner <gicmo@gnome.org> 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "gbufferedoutputstream.h"
 | 
			
		||||
#include "goutputstream.h"
 | 
			
		||||
#include "gsimpleasyncresult.h"
 | 
			
		||||
#include "string.h"
 | 
			
		||||
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_BUFFER_SIZE 4096
 | 
			
		||||
 | 
			
		||||
struct _GBufferedOutputStreamPrivate {
 | 
			
		||||
  guint8 *buffer; 
 | 
			
		||||
  gsize   len;
 | 
			
		||||
  goffset pos;
 | 
			
		||||
  gboolean auto_grow;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  PROP_0,
 | 
			
		||||
  PROP_BUFSIZE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void     g_buffered_output_stream_set_property (GObject      *object,
 | 
			
		||||
                                                       guint         prop_id,
 | 
			
		||||
                                                       const GValue *value,
 | 
			
		||||
                                                       GParamSpec   *pspec);
 | 
			
		||||
 | 
			
		||||
static void     g_buffered_output_stream_get_property (GObject    *object,
 | 
			
		||||
                                                       guint       prop_id,
 | 
			
		||||
                                                       GValue     *value,
 | 
			
		||||
                                                       GParamSpec *pspec);
 | 
			
		||||
static void     g_buffered_output_stream_finalize     (GObject *object);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static gssize   g_buffered_output_stream_write        (GOutputStream *stream,
 | 
			
		||||
                                                       const void    *buffer,
 | 
			
		||||
                                                       gsize          count,
 | 
			
		||||
                                                       GCancellable  *cancellable,
 | 
			
		||||
                                                       GError       **error);
 | 
			
		||||
static gboolean g_buffered_output_stream_flush        (GOutputStream    *stream,
 | 
			
		||||
                                                       GCancellable  *cancellable,
 | 
			
		||||
                                                       GError          **error);
 | 
			
		||||
static gboolean g_buffered_output_stream_close        (GOutputStream  *stream,
 | 
			
		||||
                                                       GCancellable   *cancellable,
 | 
			
		||||
                                                       GError        **error);
 | 
			
		||||
 | 
			
		||||
static void     g_buffered_output_stream_write_async  (GOutputStream        *stream,
 | 
			
		||||
                                                       const void           *buffer,
 | 
			
		||||
                                                       gsize                 count,
 | 
			
		||||
                                                       int                   io_priority,
 | 
			
		||||
                                                       GCancellable         *cancellable,
 | 
			
		||||
                                                       GAsyncReadyCallback   callback,
 | 
			
		||||
                                                       gpointer              data);
 | 
			
		||||
static gssize   g_buffered_output_stream_write_finish (GOutputStream        *stream,
 | 
			
		||||
                                                       GAsyncResult         *result,
 | 
			
		||||
                                                       GError              **error);
 | 
			
		||||
static void     g_buffered_output_stream_flush_async  (GOutputStream        *stream,
 | 
			
		||||
                                                       int                   io_priority,
 | 
			
		||||
                                                       GCancellable         *cancellable,
 | 
			
		||||
                                                       GAsyncReadyCallback   callback,
 | 
			
		||||
                                                       gpointer              data);
 | 
			
		||||
static gboolean g_buffered_output_stream_flush_finish (GOutputStream        *stream,
 | 
			
		||||
                                                       GAsyncResult         *result,
 | 
			
		||||
                                                       GError              **error);
 | 
			
		||||
static void     g_buffered_output_stream_close_async  (GOutputStream        *stream,
 | 
			
		||||
                                                       int                   io_priority,
 | 
			
		||||
                                                       GCancellable         *cancellable,
 | 
			
		||||
                                                       GAsyncReadyCallback   callback,
 | 
			
		||||
                                                       gpointer              data);
 | 
			
		||||
static gboolean g_buffered_output_stream_close_finish (GOutputStream        *stream,
 | 
			
		||||
                                                       GAsyncResult         *result,
 | 
			
		||||
                                                       GError              **error);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GBufferedOutputStream,
 | 
			
		||||
               g_buffered_output_stream,
 | 
			
		||||
               G_TYPE_FILTER_OUTPUT_STREAM)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_buffered_output_stream_class_init (GBufferedOutputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class;
 | 
			
		||||
  GOutputStreamClass *ostream_class;
 | 
			
		||||
 
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GBufferedOutputStreamPrivate));
 | 
			
		||||
 | 
			
		||||
  object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  object_class->get_property = g_buffered_output_stream_get_property;
 | 
			
		||||
  object_class->set_property = g_buffered_output_stream_set_property;
 | 
			
		||||
  object_class->finalize     = g_buffered_output_stream_finalize;
 | 
			
		||||
 | 
			
		||||
  ostream_class = G_OUTPUT_STREAM_CLASS (klass);
 | 
			
		||||
  ostream_class->write = g_buffered_output_stream_write;
 | 
			
		||||
  ostream_class->flush = g_buffered_output_stream_flush;
 | 
			
		||||
  ostream_class->close = g_buffered_output_stream_close;
 | 
			
		||||
  ostream_class->write_async  = g_buffered_output_stream_write_async;
 | 
			
		||||
  ostream_class->write_finish = g_buffered_output_stream_write_finish;
 | 
			
		||||
  ostream_class->flush_async  = g_buffered_output_stream_flush_async;
 | 
			
		||||
  ostream_class->flush_finish = g_buffered_output_stream_flush_finish;
 | 
			
		||||
  ostream_class->close_async  = g_buffered_output_stream_close_async;
 | 
			
		||||
  ostream_class->close_finish = g_buffered_output_stream_close_finish;
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_BUFSIZE,
 | 
			
		||||
                                   g_param_spec_uint ("buffer-size",
 | 
			
		||||
                                                      P_("Buffer Size"),
 | 
			
		||||
                                                      P_("The size of the backend buffer"),
 | 
			
		||||
                                                      1,
 | 
			
		||||
                                                      G_MAXUINT,
 | 
			
		||||
                                                      DEFAULT_BUFFER_SIZE,
 | 
			
		||||
                                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
 | 
			
		||||
                                                      G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_buffered_output_stream_get_buffer_size:
 | 
			
		||||
 * @stream: a #GBufferedOutputStream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: the current size of the buffer.
 | 
			
		||||
 **/
 | 
			
		||||
gsize
 | 
			
		||||
g_buffered_output_stream_get_buffer_size (GBufferedOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream), -1);
 | 
			
		||||
 | 
			
		||||
  return stream->priv->len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_buffered_output_stream_set_buffer_size:
 | 
			
		||||
 * @stream: a #GBufferedOutputStream.
 | 
			
		||||
 * @size: a #gsize.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the size of the internal buffer to @size.
 | 
			
		||||
 * 
 | 
			
		||||
 **/    
 | 
			
		||||
void
 | 
			
		||||
g_buffered_output_stream_set_buffer_size (GBufferedOutputStream *stream,
 | 
			
		||||
					 gsize                 size)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
  guint8 *buffer;
 | 
			
		||||
  
 | 
			
		||||
  g_return_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream));
 | 
			
		||||
 | 
			
		||||
  priv = stream->priv;
 | 
			
		||||
  
 | 
			
		||||
  if (priv->buffer)
 | 
			
		||||
    {
 | 
			
		||||
      size = MAX (size, priv->pos);
 | 
			
		||||
 | 
			
		||||
      buffer = g_malloc (size);
 | 
			
		||||
      memcpy (buffer, priv->buffer, priv->pos);
 | 
			
		||||
      g_free (priv->buffer);
 | 
			
		||||
      priv->buffer = buffer;
 | 
			
		||||
      priv->len = size;
 | 
			
		||||
      /* Keep old pos */
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      priv->buffer = g_malloc (size);
 | 
			
		||||
      priv->len = size;
 | 
			
		||||
      priv->pos = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_buffered_output_stream_get_auto_grow:
 | 
			
		||||
 * @stream: a #GBufferedOutputStream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if the @stream's buffer automatically grows,
 | 
			
		||||
 * %FALSE otherwise.
 | 
			
		||||
 **/  
 | 
			
		||||
gboolean
 | 
			
		||||
g_buffered_output_stream_get_auto_grow (GBufferedOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  return stream->priv->auto_grow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_buffered_output_stream_set_auto_grow:
 | 
			
		||||
 * @stream: a #GBufferedOutputStream.
 | 
			
		||||
 * @auto_grow: a boolean.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets whether or not the @stream's buffer should automatically grow.
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_buffered_output_stream_set_auto_grow (GBufferedOutputStream *stream,
 | 
			
		||||
				       gboolean              auto_grow)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_BUFFERED_OUTPUT_STREAM (stream));
 | 
			
		||||
 | 
			
		||||
  stream->priv->auto_grow = auto_grow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_buffered_output_stream_set_property (GObject         *object,
 | 
			
		||||
                                       guint            prop_id,
 | 
			
		||||
                                       const GValue    *value,
 | 
			
		||||
                                       GParamSpec      *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStream *buffered_stream;
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  buffered_stream = G_BUFFERED_OUTPUT_STREAM (object);
 | 
			
		||||
  priv = buffered_stream->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id) 
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    case PROP_BUFSIZE:
 | 
			
		||||
      g_buffered_output_stream_set_buffer_size (buffered_stream, g_value_get_uint (value));
 | 
			
		||||
      break;    
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_buffered_output_stream_get_property (GObject    *object,
 | 
			
		||||
                                       guint       prop_id,
 | 
			
		||||
                                       GValue     *value,
 | 
			
		||||
                                       GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStream *buffered_stream;
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  buffered_stream = G_BUFFERED_OUTPUT_STREAM (object);
 | 
			
		||||
  priv = buffered_stream->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    case PROP_BUFSIZE:
 | 
			
		||||
      g_value_set_uint (value, priv->len);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_buffered_output_stream_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStream *stream;
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
 | 
			
		||||
  stream = G_BUFFERED_OUTPUT_STREAM (object);
 | 
			
		||||
  priv = stream->priv;
 | 
			
		||||
 | 
			
		||||
  g_free (priv->buffer);
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (g_buffered_output_stream_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_buffered_output_stream_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_buffered_output_stream_init (GBufferedOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
 | 
			
		||||
                                              G_TYPE_BUFFERED_OUTPUT_STREAM,
 | 
			
		||||
                                              GBufferedOutputStreamPrivate);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_buffered_output_stream_new:
 | 
			
		||||
 * @base_stream: a #GOutputStream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a #GOutputStream for the given @base_stream.
 | 
			
		||||
 **/  
 | 
			
		||||
GOutputStream *
 | 
			
		||||
g_buffered_output_stream_new (GOutputStream *base_stream)
 | 
			
		||||
{
 | 
			
		||||
  GOutputStream *stream;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL);
 | 
			
		||||
 | 
			
		||||
  stream = g_object_new (G_TYPE_BUFFERED_OUTPUT_STREAM,
 | 
			
		||||
                         "base-stream", base_stream,
 | 
			
		||||
                         NULL);
 | 
			
		||||
 | 
			
		||||
  return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_buffered_output_stream_new_sized:
 | 
			
		||||
 * @base_stream: a #GOutputStream.
 | 
			
		||||
 * @size: a #gsize.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a #GOutputStream with an internal buffer set to @size.
 | 
			
		||||
 **/  
 | 
			
		||||
GOutputStream *
 | 
			
		||||
g_buffered_output_stream_new_sized (GOutputStream *base_stream,
 | 
			
		||||
                                    guint          size)
 | 
			
		||||
{
 | 
			
		||||
  GOutputStream *stream;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL);
 | 
			
		||||
 | 
			
		||||
  stream = g_object_new (G_TYPE_BUFFERED_OUTPUT_STREAM,
 | 
			
		||||
                         "base-stream", base_stream,
 | 
			
		||||
                         "buffer-size", size,
 | 
			
		||||
                         NULL);
 | 
			
		||||
 | 
			
		||||
  return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
flush_buffer (GBufferedOutputStream  *stream,
 | 
			
		||||
              GCancellable           *cancellable,
 | 
			
		||||
              GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
  GOutputStream                *base_stream;
 | 
			
		||||
  gboolean                      res;
 | 
			
		||||
  gsize                         bytes_written;
 | 
			
		||||
  gsize                         count;
 | 
			
		||||
 | 
			
		||||
  priv = stream->priv;
 | 
			
		||||
  bytes_written = 0;
 | 
			
		||||
  base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  res = g_output_stream_write_all (base_stream,
 | 
			
		||||
                                   priv->buffer,
 | 
			
		||||
                                   priv->pos,
 | 
			
		||||
                                   &bytes_written,
 | 
			
		||||
                                   cancellable,
 | 
			
		||||
                                   error);
 | 
			
		||||
 | 
			
		||||
  count = priv->pos - bytes_written;
 | 
			
		||||
 | 
			
		||||
  if (count > 0)
 | 
			
		||||
    g_memmove (priv->buffer, priv->buffer + bytes_written, count);
 | 
			
		||||
  
 | 
			
		||||
  priv->pos -= bytes_written;
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_buffered_output_stream_write  (GOutputStream *stream,
 | 
			
		||||
                                 const void    *buffer,
 | 
			
		||||
                                 gsize          count,
 | 
			
		||||
                                 GCancellable  *cancellable,
 | 
			
		||||
                                 GError       **error)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStream        *bstream;
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
  gsize    n;
 | 
			
		||||
  gsize new_size;
 | 
			
		||||
 | 
			
		||||
  bstream = G_BUFFERED_OUTPUT_STREAM (stream);
 | 
			
		||||
  priv = bstream->priv;
 | 
			
		||||
 | 
			
		||||
  n = priv->len - priv->pos;
 | 
			
		||||
 | 
			
		||||
  if (priv->auto_grow && n < count)
 | 
			
		||||
    {
 | 
			
		||||
      new_size = MAX (priv->len * 2, priv->len + count);
 | 
			
		||||
      g_buffered_output_stream_set_buffer_size (bstream, new_size);
 | 
			
		||||
    }
 | 
			
		||||
  else if (n == 0)
 | 
			
		||||
    {
 | 
			
		||||
      res = flush_buffer (bstream, cancellable, error);
 | 
			
		||||
      
 | 
			
		||||
      if (res == FALSE)
 | 
			
		||||
	return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  n = priv->len - priv->pos;
 | 
			
		||||
  
 | 
			
		||||
  count = MIN (count, n);
 | 
			
		||||
  memcpy (priv->buffer + priv->pos, buffer, count);
 | 
			
		||||
  priv->pos += count;
 | 
			
		||||
 | 
			
		||||
  return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_buffered_output_stream_flush (GOutputStream  *stream,
 | 
			
		||||
                                GCancellable   *cancellable,
 | 
			
		||||
                                GError        **error)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStream *bstream;
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
  GOutputStream                *base_stream;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  bstream = G_BUFFERED_OUTPUT_STREAM (stream);
 | 
			
		||||
  priv = bstream->priv;
 | 
			
		||||
  base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
 | 
			
		||||
 | 
			
		||||
  res = flush_buffer (bstream, cancellable, error);
 | 
			
		||||
 | 
			
		||||
  if (res == FALSE) {
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  res = g_output_stream_flush (base_stream,
 | 
			
		||||
                               cancellable,
 | 
			
		||||
                               error);
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_buffered_output_stream_close (GOutputStream  *stream,
 | 
			
		||||
                                GCancellable   *cancellable,
 | 
			
		||||
                                GError        **error)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStream        *bstream;
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
  GOutputStream                *base_stream;
 | 
			
		||||
  gboolean                      res;
 | 
			
		||||
 | 
			
		||||
  bstream = G_BUFFERED_OUTPUT_STREAM (stream);
 | 
			
		||||
  priv = bstream->priv;
 | 
			
		||||
  base_stream = G_FILTER_OUTPUT_STREAM (bstream)->base_stream;
 | 
			
		||||
 | 
			
		||||
  res = flush_buffer (bstream, cancellable, error);
 | 
			
		||||
 | 
			
		||||
  /* report the first error but still close the stream */
 | 
			
		||||
  if (res)
 | 
			
		||||
    {
 | 
			
		||||
      res = g_output_stream_close (base_stream,
 | 
			
		||||
                                   cancellable,
 | 
			
		||||
                                   error); 
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      g_output_stream_close (base_stream,
 | 
			
		||||
                             cancellable,
 | 
			
		||||
                             NULL); 
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ************************** */
 | 
			
		||||
/* Async stuff implementation */
 | 
			
		||||
/* ************************** */
 | 
			
		||||
 | 
			
		||||
/* TODO: This should be using the base class async ops, not threads */
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
 | 
			
		||||
  guint flush_stream : 1;
 | 
			
		||||
  guint close_stream : 1;
 | 
			
		||||
 | 
			
		||||
} FlushData;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
free_flush_data (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  g_slice_free (FlushData, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function is used by all three (i.e. 
 | 
			
		||||
 * _write, _flush, _close) functions since
 | 
			
		||||
 * all of them will need to flush the buffer
 | 
			
		||||
 * and so closing and writing is just a special
 | 
			
		||||
 * case of flushing + some addition stuff */
 | 
			
		||||
static void
 | 
			
		||||
flush_buffer_thread (GSimpleAsyncResult *result,
 | 
			
		||||
                     GObject            *object,
 | 
			
		||||
                     GCancellable       *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStream *stream;
 | 
			
		||||
  GOutputStream *base_stream;
 | 
			
		||||
  FlushData     *fdata;
 | 
			
		||||
  gboolean       res;
 | 
			
		||||
  GError        *error = NULL;
 | 
			
		||||
 | 
			
		||||
  stream = G_BUFFERED_OUTPUT_STREAM (object);
 | 
			
		||||
  fdata = g_simple_async_result_get_op_res_gpointer (result);
 | 
			
		||||
  base_stream = G_FILTER_OUTPUT_STREAM (stream)->base_stream;
 | 
			
		||||
 | 
			
		||||
  res = flush_buffer (stream, cancellable, &error);
 | 
			
		||||
 | 
			
		||||
  /* if flushing the buffer didn't work don't even bother
 | 
			
		||||
   * to flush the stream but just report that error */
 | 
			
		||||
  if (res && fdata->flush_stream)
 | 
			
		||||
    {
 | 
			
		||||
      res = g_output_stream_flush (base_stream,
 | 
			
		||||
                                   cancellable,
 | 
			
		||||
                                   &error);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (fdata->close_stream) 
 | 
			
		||||
    {
 | 
			
		||||
     
 | 
			
		||||
      /* if flushing the buffer or the stream returned 
 | 
			
		||||
       * an error report that first error but still try 
 | 
			
		||||
       * close the stream */
 | 
			
		||||
      if (res == FALSE)
 | 
			
		||||
        {
 | 
			
		||||
          g_output_stream_close (base_stream,
 | 
			
		||||
                                 cancellable,
 | 
			
		||||
                                 NULL);
 | 
			
		||||
        } 
 | 
			
		||||
      else 
 | 
			
		||||
        {
 | 
			
		||||
          res = g_output_stream_close (base_stream,
 | 
			
		||||
                                       cancellable,
 | 
			
		||||
                                       &error);
 | 
			
		||||
        } 
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (res == FALSE)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_result_set_from_error (result, error);
 | 
			
		||||
      g_error_free (error);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    
 | 
			
		||||
  FlushData fdata;
 | 
			
		||||
 | 
			
		||||
  gsize  count;
 | 
			
		||||
  const void  *buffer;
 | 
			
		||||
 | 
			
		||||
} WriteData;
 | 
			
		||||
 | 
			
		||||
static void 
 | 
			
		||||
free_write_data (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  g_slice_free (WriteData, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_buffered_output_stream_write_async (GOutputStream        *stream,
 | 
			
		||||
                                      const void           *buffer,
 | 
			
		||||
                                      gsize                 count,
 | 
			
		||||
                                      int                   io_priority,
 | 
			
		||||
                                      GCancellable         *cancellable,
 | 
			
		||||
                                      GAsyncReadyCallback   callback,
 | 
			
		||||
                                      gpointer              data)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStream *buffered_stream;
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
  GSimpleAsyncResult *res;
 | 
			
		||||
  WriteData *wdata;
 | 
			
		||||
 | 
			
		||||
  buffered_stream = G_BUFFERED_OUTPUT_STREAM (stream);
 | 
			
		||||
  priv = buffered_stream->priv;
 | 
			
		||||
 | 
			
		||||
  wdata = g_slice_new (WriteData);
 | 
			
		||||
  wdata->count  = count;
 | 
			
		||||
  wdata->buffer = buffer;
 | 
			
		||||
 | 
			
		||||
  res = g_simple_async_result_new (G_OBJECT (stream),
 | 
			
		||||
                                   callback,
 | 
			
		||||
                                   data,
 | 
			
		||||
                                   g_buffered_output_stream_write_async);
 | 
			
		||||
 | 
			
		||||
  g_simple_async_result_set_op_res_gpointer (res, wdata, free_write_data);
 | 
			
		||||
 | 
			
		||||
  /* if we have space left directly call the
 | 
			
		||||
   * callback (from idle) otherwise schedule a buffer 
 | 
			
		||||
   * flush in the thread. In both cases the actual
 | 
			
		||||
   * copying of the data to the buffer will be done in
 | 
			
		||||
   * the write_finish () func since that should
 | 
			
		||||
   * be fast enough */
 | 
			
		||||
  if (priv->len - priv->pos > 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_result_complete_in_idle (res);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      wdata->fdata.flush_stream = FALSE;
 | 
			
		||||
      wdata->fdata.close_stream = FALSE;
 | 
			
		||||
      g_simple_async_result_run_in_thread (res, 
 | 
			
		||||
                                           flush_buffer_thread, 
 | 
			
		||||
                                           io_priority,
 | 
			
		||||
                                           cancellable);
 | 
			
		||||
      g_object_unref (res);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_buffered_output_stream_write_finish (GOutputStream        *stream,
 | 
			
		||||
                                       GAsyncResult         *result,
 | 
			
		||||
                                       GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
  GBufferedOutputStream        *buffered_stream;
 | 
			
		||||
  GSimpleAsyncResult *simple;
 | 
			
		||||
  WriteData          *wdata;
 | 
			
		||||
  gssize              count;
 | 
			
		||||
 | 
			
		||||
  simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
  buffered_stream = G_BUFFERED_OUTPUT_STREAM (stream);
 | 
			
		||||
  priv = buffered_stream->priv;
 | 
			
		||||
 | 
			
		||||
  g_assert (g_simple_async_result_get_source_tag (simple) == 
 | 
			
		||||
            g_buffered_output_stream_write_async);
 | 
			
		||||
 | 
			
		||||
  wdata = g_simple_async_result_get_op_res_gpointer (simple);
 | 
			
		||||
 | 
			
		||||
  /* Now do the real copying of data to the buffer */
 | 
			
		||||
  count = priv->len - priv->pos; 
 | 
			
		||||
  count = MIN (wdata->count, count);
 | 
			
		||||
 | 
			
		||||
  memcpy (priv->buffer + priv->pos, wdata->buffer, count);
 | 
			
		||||
  
 | 
			
		||||
  priv->pos += count;
 | 
			
		||||
 | 
			
		||||
  return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_buffered_output_stream_flush_async (GOutputStream        *stream,
 | 
			
		||||
                                      int                   io_priority,
 | 
			
		||||
                                      GCancellable         *cancellable,
 | 
			
		||||
                                      GAsyncReadyCallback   callback,
 | 
			
		||||
                                      gpointer              data)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *res;
 | 
			
		||||
  FlushData          *fdata;
 | 
			
		||||
 | 
			
		||||
  fdata = g_slice_new (FlushData);
 | 
			
		||||
  fdata->flush_stream = TRUE;
 | 
			
		||||
  fdata->close_stream = FALSE;
 | 
			
		||||
 | 
			
		||||
  res = g_simple_async_result_new (G_OBJECT (stream),
 | 
			
		||||
                                   callback,
 | 
			
		||||
                                   data,
 | 
			
		||||
                                   g_buffered_output_stream_flush_async);
 | 
			
		||||
 | 
			
		||||
  g_simple_async_result_set_op_res_gpointer (res, fdata, free_flush_data);
 | 
			
		||||
 | 
			
		||||
  g_simple_async_result_run_in_thread (res, 
 | 
			
		||||
                                       flush_buffer_thread, 
 | 
			
		||||
                                       io_priority,
 | 
			
		||||
                                       cancellable);
 | 
			
		||||
  g_object_unref (res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_buffered_output_stream_flush_finish (GOutputStream        *stream,
 | 
			
		||||
                                       GAsyncResult         *result,
 | 
			
		||||
                                       GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple;
 | 
			
		||||
 | 
			
		||||
  simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
 | 
			
		||||
  g_assert (g_simple_async_result_get_source_tag (simple) == 
 | 
			
		||||
            g_buffered_output_stream_flush_async);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_buffered_output_stream_close_async (GOutputStream        *stream,
 | 
			
		||||
                                      int                   io_priority,
 | 
			
		||||
                                      GCancellable         *cancellable,
 | 
			
		||||
                                      GAsyncReadyCallback   callback,
 | 
			
		||||
                                      gpointer              data)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *res;
 | 
			
		||||
  FlushData          *fdata;
 | 
			
		||||
 | 
			
		||||
  fdata = g_slice_new (FlushData);
 | 
			
		||||
  fdata->close_stream = TRUE;
 | 
			
		||||
 | 
			
		||||
  res = g_simple_async_result_new (G_OBJECT (stream),
 | 
			
		||||
                                   callback,
 | 
			
		||||
                                   data,
 | 
			
		||||
                                   g_buffered_output_stream_close_async);
 | 
			
		||||
 | 
			
		||||
  g_simple_async_result_set_op_res_gpointer (res, fdata, free_flush_data);
 | 
			
		||||
 | 
			
		||||
  g_simple_async_result_run_in_thread (res, 
 | 
			
		||||
                                       flush_buffer_thread, 
 | 
			
		||||
                                       io_priority,
 | 
			
		||||
                                       cancellable);
 | 
			
		||||
  g_object_unref (res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_buffered_output_stream_close_finish (GOutputStream        *stream,
 | 
			
		||||
                                       GAsyncResult         *result,
 | 
			
		||||
                                       GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple;
 | 
			
		||||
 | 
			
		||||
  simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
 | 
			
		||||
  g_assert (g_simple_async_result_get_source_tag (simple) == 
 | 
			
		||||
            g_buffered_output_stream_flush_async);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* vim: ts=2 sw=2 et */
 | 
			
		||||
							
								
								
									
										76
									
								
								gio/gbufferedoutputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								gio/gbufferedoutputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,76 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Christian Kellner <gicmo@gnome.org> 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_BUFFERED_OUTPUT_STREAM_H__
 | 
			
		||||
#define __G_BUFFERED_OUTPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gfilteroutputstream.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_BUFFERED_OUTPUT_STREAM         (g_buffered_output_stream_get_type ())
 | 
			
		||||
#define G_BUFFERED_OUTPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_BUFFERED_OUTPUT_STREAM, GBufferedOutputStream))
 | 
			
		||||
#define G_BUFFERED_OUTPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_BUFFERED_OUTPUT_STREAM, GBufferedOutputStreamClass))
 | 
			
		||||
#define G_IS_BUFFERED_OUTPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_BUFFERED_OUTPUT_STREAM))
 | 
			
		||||
#define G_IS_BUFFERED_OUTPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_BUFFERED_OUTPUT_STREAM))
 | 
			
		||||
#define G_BUFFERED_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_BUFFERED_OUTPUT_STREAM, GBufferedOutputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GBufferedOutputStream         GBufferedOutputStream;
 | 
			
		||||
typedef struct _GBufferedOutputStreamClass    GBufferedOutputStreamClass;
 | 
			
		||||
typedef struct _GBufferedOutputStreamPrivate  GBufferedOutputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GBufferedOutputStream
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream parent;
 | 
			
		||||
 | 
			
		||||
  /*< protected >*/
 | 
			
		||||
  GBufferedOutputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GBufferedOutputStreamClass
 | 
			
		||||
{
 | 
			
		||||
 GOutputStreamClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GType           g_buffered_output_stream_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
GOutputStream* g_buffered_output_stream_new             (GOutputStream         *base_stream);
 | 
			
		||||
GOutputStream* g_buffered_output_stream_new_sized       (GOutputStream         *base_stream,
 | 
			
		||||
							 guint                  size);
 | 
			
		||||
gsize          g_buffered_output_stream_get_buffer_size (GBufferedOutputStream *stream);
 | 
			
		||||
void           g_buffered_output_stream_set_buffer_size (GBufferedOutputStream *stream,
 | 
			
		||||
							 gsize                  size);
 | 
			
		||||
gboolean       g_buffered_output_stream_get_auto_grow   (GBufferedOutputStream *stream);
 | 
			
		||||
void           g_buffered_output_stream_set_auto_grow   (GBufferedOutputStream *stream,
 | 
			
		||||
							 gboolean               auto_grow);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_BUFFERED_OUTPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										322
									
								
								gio/gcancellable.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										322
									
								
								gio/gcancellable.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,322 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <gioerror.h>
 | 
			
		||||
#include "gcancellable.h"
 | 
			
		||||
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * GCancellable is a thread-safe operation cancellation stack used 
 | 
			
		||||
 * throughout GIO to allow for cancellation of asynchronous operations.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  CANCELLED,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GCancellable
 | 
			
		||||
{
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
 | 
			
		||||
  guint cancelled : 1;
 | 
			
		||||
  guint allocated_pipe : 1;
 | 
			
		||||
  int cancel_pipe[2];
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GCancellable, g_cancellable, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
static GStaticPrivate current_cancellable = G_STATIC_PRIVATE_INIT;
 | 
			
		||||
G_LOCK_DEFINE_STATIC(cancellable);
 | 
			
		||||
  
 | 
			
		||||
static void
 | 
			
		||||
g_cancellable_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GCancellable *cancellable = G_CANCELLABLE (object);
 | 
			
		||||
 | 
			
		||||
  if (cancellable->cancel_pipe[0] != -1)
 | 
			
		||||
    close (cancellable->cancel_pipe[0]);
 | 
			
		||||
  
 | 
			
		||||
  if (cancellable->cancel_pipe[1] != -1)
 | 
			
		||||
    close (cancellable->cancel_pipe[1]);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_cancellable_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_cancellable_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_cancellable_class_init (GCancellableClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_cancellable_finalize;
 | 
			
		||||
 | 
			
		||||
  signals[CANCELLED] =
 | 
			
		||||
    g_signal_new (I_("cancelled"),
 | 
			
		||||
		  G_TYPE_FROM_CLASS (gobject_class),
 | 
			
		||||
		  G_SIGNAL_RUN_LAST,
 | 
			
		||||
		  G_STRUCT_OFFSET (GCancellableClass, cancelled),
 | 
			
		||||
		  NULL, NULL,
 | 
			
		||||
		  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
		  G_TYPE_NONE, 0);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
set_fd_nonblocking (int fd)
 | 
			
		||||
{
 | 
			
		||||
#ifdef F_GETFL
 | 
			
		||||
  glong fcntl_flags;
 | 
			
		||||
  fcntl_flags = fcntl (fd, F_GETFL);
 | 
			
		||||
 | 
			
		||||
#ifdef O_NONBLOCK
 | 
			
		||||
  fcntl_flags |= O_NONBLOCK;
 | 
			
		||||
#else
 | 
			
		||||
  fcntl_flags |= O_NDELAY;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  fcntl (fd, F_SETFL, fcntl_flags);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_cancellable_open_pipe (GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  if (pipe (cancellable->cancel_pipe) == 0)
 | 
			
		||||
    {
 | 
			
		||||
      /* Make them nonblocking, just to be sure we don't block
 | 
			
		||||
       * on errors and stuff
 | 
			
		||||
       */
 | 
			
		||||
      set_fd_nonblocking (cancellable->cancel_pipe[0]);
 | 
			
		||||
      set_fd_nonblocking (cancellable->cancel_pipe[1]);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    g_warning ("Failed to create pipe for GCancellable. Out of file descriptors?");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_cancellable_init (GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  cancellable->cancel_pipe[0] = -1;
 | 
			
		||||
  cancellable->cancel_pipe[1] = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_cancellable_new:
 | 
			
		||||
 *  
 | 
			
		||||
 * Returns: a new #GCancellable object.
 | 
			
		||||
 **/
 | 
			
		||||
GCancellable *
 | 
			
		||||
g_cancellable_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (G_TYPE_CANCELLABLE, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_push_current_cancellable:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * 
 | 
			
		||||
 * Pushes @cancellable onto the cancellable stack.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_push_current_cancellable (GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  GSList *l;
 | 
			
		||||
 | 
			
		||||
  g_assert (cancellable != NULL);
 | 
			
		||||
  
 | 
			
		||||
  l = g_static_private_get (¤t_cancellable);
 | 
			
		||||
  l = g_slist_prepend (l, cancellable);
 | 
			
		||||
  g_static_private_set (¤t_cancellable, l, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_pop_current_cancellable:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 *
 | 
			
		||||
 * Pops @cancellable off the cancellable stack if @cancellable 
 | 
			
		||||
 * is on the top of the stack.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_pop_current_cancellable (GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  GSList *l;
 | 
			
		||||
  
 | 
			
		||||
  l = g_static_private_get (¤t_cancellable);
 | 
			
		||||
  
 | 
			
		||||
  g_assert (l != NULL);
 | 
			
		||||
  g_assert (l->data == cancellable);
 | 
			
		||||
 | 
			
		||||
  l = g_slist_delete_link (l, l);
 | 
			
		||||
  g_static_private_set (¤t_cancellable, l, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_cancellable_get_current:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a #GCancellable from the top of the stack, or %NULL
 | 
			
		||||
 * if the stack is empty. 
 | 
			
		||||
 **/
 | 
			
		||||
GCancellable *
 | 
			
		||||
g_cancellable_get_current  (void)
 | 
			
		||||
{
 | 
			
		||||
  GSList *l;
 | 
			
		||||
  
 | 
			
		||||
  l = g_static_private_get (¤t_cancellable);
 | 
			
		||||
  if (l == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  return G_CANCELLABLE (l->data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_cancellable_reset:
 | 
			
		||||
 * @cancellable: a #GCancellable object.
 | 
			
		||||
 * 
 | 
			
		||||
 * Resets @cancellable to its uncancelled state. 
 | 
			
		||||
 *
 | 
			
		||||
 **/
 | 
			
		||||
void 
 | 
			
		||||
g_cancellable_reset (GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_CANCELLABLE (cancellable));
 | 
			
		||||
 | 
			
		||||
  G_LOCK(cancellable);
 | 
			
		||||
  /* Make sure we're not leaving old cancel state around */
 | 
			
		||||
  if (cancellable->cancelled)
 | 
			
		||||
    {
 | 
			
		||||
      char ch;
 | 
			
		||||
      if (cancellable->cancel_pipe[0] != -1)
 | 
			
		||||
	read (cancellable->cancel_pipe[0], &ch, 1);
 | 
			
		||||
      cancellable->cancelled = FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  G_UNLOCK(cancellable);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_cancellable_is_cancelled:
 | 
			
		||||
 * @cancellable: a #GCancellable or NULL.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @cancellable is is cancelled, 
 | 
			
		||||
 * FALSE if called with %NULL or if item is not cancelled. 
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_cancellable_is_cancelled (GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  return cancellable != NULL && cancellable->cancelled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_cancellable_set_error_if_cancelled:
 | 
			
		||||
 * @cancellable: a #GCancellable object.
 | 
			
		||||
 * @error: #GError to append error state to.
 | 
			
		||||
 * 
 | 
			
		||||
 * Sets the current error to notify that the operation was cancelled.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @cancellable was cancelled, %FALSE if it was not.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_cancellable_set_error_if_cancelled (GCancellable  *cancellable,
 | 
			
		||||
				      GError       **error)
 | 
			
		||||
{
 | 
			
		||||
  if (g_cancellable_is_cancelled (cancellable))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error,
 | 
			
		||||
		   G_IO_ERROR,
 | 
			
		||||
		   G_IO_ERROR_CANCELLED,
 | 
			
		||||
		   _("Operation was cancelled"));
 | 
			
		||||
      return TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_cancellable_get_fd:
 | 
			
		||||
 * @cancellable: a #GCancellable.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: A valid file descriptor. -1 if the file descriptor 
 | 
			
		||||
 * is not supported, or on errors. 
 | 
			
		||||
 **/
 | 
			
		||||
int
 | 
			
		||||
g_cancellable_get_fd (GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  int fd;
 | 
			
		||||
  if (cancellable == NULL)
 | 
			
		||||
    return -1;
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK(cancellable);
 | 
			
		||||
  if (!cancellable->allocated_pipe)
 | 
			
		||||
    {
 | 
			
		||||
      cancellable->allocated_pipe = TRUE;
 | 
			
		||||
      g_cancellable_open_pipe (cancellable);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  fd = cancellable->cancel_pipe[0];
 | 
			
		||||
  G_UNLOCK(cancellable);
 | 
			
		||||
  
 | 
			
		||||
  return fd;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_cancellable_cancel:
 | 
			
		||||
 * @cancellable: a #GCancellable object.
 | 
			
		||||
 * 
 | 
			
		||||
 * Will set @cancellable to cancelled, and will emit the CANCELLED
 | 
			
		||||
 * signal. This function is thread-safe.
 | 
			
		||||
 *  
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_cancellable_cancel (GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  gboolean cancel;
 | 
			
		||||
 | 
			
		||||
  cancel = FALSE;
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK(cancellable);
 | 
			
		||||
  if (cancellable != NULL &&
 | 
			
		||||
      !cancellable->cancelled)
 | 
			
		||||
    {
 | 
			
		||||
      char ch = 'x';
 | 
			
		||||
      cancel = TRUE;
 | 
			
		||||
      cancellable->cancelled = TRUE;
 | 
			
		||||
      if (cancellable->cancel_pipe[1] != -1)
 | 
			
		||||
	write (cancellable->cancel_pipe[1], &ch, 1);
 | 
			
		||||
    }
 | 
			
		||||
  G_UNLOCK(cancellable);
 | 
			
		||||
 | 
			
		||||
  if (cancel)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_ref (cancellable);
 | 
			
		||||
      g_signal_emit (cancellable, signals[CANCELLED], 0);
 | 
			
		||||
      g_object_unref (cancellable);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										74
									
								
								gio/gcancellable.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								gio/gcancellable.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_CANCELLABLE_H__
 | 
			
		||||
#define __G_CANCELLABLE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_CANCELLABLE         (g_cancellable_get_type ())
 | 
			
		||||
#define G_CANCELLABLE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_CANCELLABLE, GCancellable))
 | 
			
		||||
#define G_CANCELLABLE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_CANCELLABLE, GCancellableClass))
 | 
			
		||||
#define G_IS_CANCELLABLE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_CANCELLABLE))
 | 
			
		||||
#define G_IS_CANCELLABLE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_CANCELLABLE))
 | 
			
		||||
#define G_CANCELLABLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_CANCELLABLE, GCancellableClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GCancellable        GCancellable;
 | 
			
		||||
typedef struct _GCancellableClass   GCancellableClass;
 | 
			
		||||
 | 
			
		||||
struct _GCancellableClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  void (* cancelled) (GCancellable *cancellable);
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_cancellable_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GCancellable *g_cancellable_new          (void);
 | 
			
		||||
 | 
			
		||||
/* These are only safe to call inside a cancellable op */
 | 
			
		||||
gboolean      g_cancellable_is_cancelled           (GCancellable  *cancellable);
 | 
			
		||||
gboolean      g_cancellable_set_error_if_cancelled (GCancellable  *cancellable,
 | 
			
		||||
						    GError       **error);
 | 
			
		||||
int           g_cancellable_get_fd                 (GCancellable  *cancellable);
 | 
			
		||||
GCancellable *g_cancellable_get_current            (void);
 | 
			
		||||
void          g_push_current_cancellable           (GCancellable  *cancellable);
 | 
			
		||||
void          g_pop_current_cancellable            (GCancellable  *cancellable);
 | 
			
		||||
void          g_cancellable_reset                  (GCancellable  *cancellable);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* This is safe to call from another thread */
 | 
			
		||||
void          g_cancellable_cancel       (GCancellable  *cancellable);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_CANCELLABLE_H__ */
 | 
			
		||||
							
								
								
									
										861
									
								
								gio/gcontenttype.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										861
									
								
								gio/gcontenttype.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,861 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <dirent.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "gcontenttypeprivate.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
/* A content type is a platform specific string that defines the type
 | 
			
		||||
   of a file. On unix it is a mime type, on win32 it is an extension string
 | 
			
		||||
   like ".doc", ".txt" or a percieved string like "audio". Such strings
 | 
			
		||||
   can be looked up in the registry at HKEY_CLASSES_ROOT.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifdef G_OS_WIN32
 | 
			
		||||
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
get_registry_classes_key (const char *subdir,
 | 
			
		||||
			  const wchar_t *key_name)
 | 
			
		||||
{
 | 
			
		||||
  wchar_t *wc_key;
 | 
			
		||||
  HKEY reg_key = NULL;
 | 
			
		||||
  DWORD key_type;
 | 
			
		||||
  DWORD nbytes;
 | 
			
		||||
  char *value_utf8;
 | 
			
		||||
 | 
			
		||||
  value_utf8 = NULL;
 | 
			
		||||
  
 | 
			
		||||
  nbytes = 0;
 | 
			
		||||
  wc_key = g_utf8_to_utf16 (subdir, -1, NULL, NULL, NULL);
 | 
			
		||||
  if (RegOpenKeyExW (HKEY_CLASSES_ROOT, wc_key, 0,
 | 
			
		||||
		     KEY_QUERY_VALUE, ®_key) == ERROR_SUCCESS &&
 | 
			
		||||
      RegQueryValueExW (reg_key, key_name, 0,
 | 
			
		||||
			&key_type, NULL, &nbytes) == ERROR_SUCCESS &&
 | 
			
		||||
      key_type == REG_SZ)
 | 
			
		||||
    {
 | 
			
		||||
      wchar_t *wc_temp = g_new (wchar_t, (nbytes+1)/2 + 1);
 | 
			
		||||
      RegQueryValueExW (reg_key, key_name, 0,
 | 
			
		||||
			&key_type, (LPBYTE) wc_temp, &nbytes);
 | 
			
		||||
      wc_temp[nbytes/2] = '\0';
 | 
			
		||||
      value_utf8 = g_utf16_to_utf8 (wc_temp, -1, NULL, NULL, NULL);
 | 
			
		||||
      g_free (wc_temp);
 | 
			
		||||
    }
 | 
			
		||||
  g_free (wc_key);
 | 
			
		||||
  
 | 
			
		||||
  if (reg_key != NULL)
 | 
			
		||||
    RegCloseKey (reg_key);
 | 
			
		||||
 | 
			
		||||
  return value_utf8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_type_equals:
 | 
			
		||||
 * @type1: a content type string.
 | 
			
		||||
 * @type2: a content type string.
 | 
			
		||||
 *
 | 
			
		||||
 * Compares two content types for equality.
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if the two strings are identical or equivalent,
 | 
			
		||||
 * %FALSE otherwise.
 | 
			
		||||
 **/  
 | 
			
		||||
gboolean
 | 
			
		||||
g_content_type_equals (const char *type1,
 | 
			
		||||
		       const char *type2)
 | 
			
		||||
{
 | 
			
		||||
  char *progid1, *progid2;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (type1 != NULL, FALSE);
 | 
			
		||||
  g_return_val_if_fail (type2 != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  if (g_ascii_strcasecmp (type1, type2) == 0)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  res = FALSE;
 | 
			
		||||
  progid1 = get_registry_classes_key (type1, NULL);
 | 
			
		||||
  progid2 = get_registry_classes_key (type2, NULL);
 | 
			
		||||
  if (progid1 != NULL && progid2 != NULL &&
 | 
			
		||||
      strcmp (progid1, progid2) == 0)
 | 
			
		||||
    res = TRUE;
 | 
			
		||||
  g_free (progid1);
 | 
			
		||||
  g_free (progid2);
 | 
			
		||||
  
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_type_is_a:
 | 
			
		||||
 * @type: a content type string. a content type string.
 | 
			
		||||
 * @supertype: a string.
 | 
			
		||||
 *
 | 
			
		||||
 * Determines if @type is a subset of @supertype.  
 | 
			
		||||
 *
 | 
			
		||||
 * Returns: %TRUE if @type is a kind of @supertype,
 | 
			
		||||
 * %FALSE otherwise. 
 | 
			
		||||
 **/  
 | 
			
		||||
gboolean
 | 
			
		||||
g_content_type_is_a (const char   *type,
 | 
			
		||||
		     const char   *supertype)
 | 
			
		||||
{
 | 
			
		||||
  gboolean res;
 | 
			
		||||
  char *value_utf8;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (type != NULL, FALSE);
 | 
			
		||||
  g_return_val_if_fail (supertype != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  if (g_content_type_equals (type, supertype))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  res = FALSE;
 | 
			
		||||
  value_utf8 = get_registry_classes_key (type, L"PerceivedType");
 | 
			
		||||
  if (value_utf8 && strcmp (value_utf8, supertype) == 0)
 | 
			
		||||
    res = TRUE;
 | 
			
		||||
  g_free (value_utf8);
 | 
			
		||||
  
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_type_is_unknown:
 | 
			
		||||
 * @type: a content type string. a content type string.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns:
 | 
			
		||||
 **/  
 | 
			
		||||
gboolean
 | 
			
		||||
g_content_type_is_unknown (const char *type)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (type != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  return strcmp ("*", type) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_type_get_description:
 | 
			
		||||
 * @type: a content type string. a content type string.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a short description of the content type @type. 
 | 
			
		||||
 **/  
 | 
			
		||||
char *
 | 
			
		||||
g_content_type_get_description (const char *type)
 | 
			
		||||
{
 | 
			
		||||
  char *progid;
 | 
			
		||||
  char *description;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (type != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  progid = get_registry_classes_key (type, NULL);
 | 
			
		||||
  if (progid)
 | 
			
		||||
    {
 | 
			
		||||
      description = get_registry_classes_key (progid, NULL);
 | 
			
		||||
      g_free (progid);
 | 
			
		||||
 | 
			
		||||
      if (description)
 | 
			
		||||
	return description;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (g_content_type_is_unknown (type))
 | 
			
		||||
    return g_strdup (_("Unknown type"));
 | 
			
		||||
  return g_strdup_printf (_("%s filetype"), type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_type_get_mime_type:
 | 
			
		||||
 * @type: a content type string. a content type string.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: the registered mime-type for the given @type.
 | 
			
		||||
 **/  
 | 
			
		||||
char *
 | 
			
		||||
g_content_type_get_mime_type (const char   *type)
 | 
			
		||||
{
 | 
			
		||||
  char *mime;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (type != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  mime = get_registry_classes_key (type, L"Content Type");
 | 
			
		||||
  if (mime)
 | 
			
		||||
    return mime;
 | 
			
		||||
  else if (g_content_type_is_unknown (type))
 | 
			
		||||
    return g_strdup ("application/octet-stream");
 | 
			
		||||
  else if (*type == '.')
 | 
			
		||||
    return g_strdup_printf ("application/x-ext-%s", type+1);
 | 
			
		||||
  /* TODO: Map "image" to "image/ *", etc? */
 | 
			
		||||
 | 
			
		||||
  return g_strdup ("application/octet-stream");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_type_get_icon:
 | 
			
		||||
 * @type: a content type string. a content type string.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: #GIcon corresponding to the content type.
 | 
			
		||||
 **/  
 | 
			
		||||
GIcon *
 | 
			
		||||
g_content_type_get_icon (const char   *type)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (type != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  /* TODO: How do we represent icons???
 | 
			
		||||
     In the registry they are the default value of
 | 
			
		||||
     HKEY_CLASSES_ROOT\<progid>\DefaultIcon with typical values like:
 | 
			
		||||
     <type>: <value>
 | 
			
		||||
     REG_EXPAND_SZ: %SystemRoot%\System32\Wscript.exe,3
 | 
			
		||||
     REG_SZ: shimgvw.dll,3
 | 
			
		||||
  */
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_type_can_be_executable:
 | 
			
		||||
 * @type: a content type string.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if the file type corresponds to something that
 | 
			
		||||
 * can be executable, %FALSE otherwise. Note that for instance
 | 
			
		||||
 * things like textfiles can be executables (i.e. scripts)
 | 
			
		||||
 **/  
 | 
			
		||||
gboolean
 | 
			
		||||
g_content_type_can_be_executable (const char   *type)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (type != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  if (strcmp (type, ".exe") == 0 ||
 | 
			
		||||
      strcmp (type, ".com") == 0 ||
 | 
			
		||||
      strcmp (type, ".bat") == 0)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
looks_like_text (const guchar *data, gsize data_size)
 | 
			
		||||
{
 | 
			
		||||
  gsize i;
 | 
			
		||||
  guchar c;
 | 
			
		||||
  for (i = 0; i < data_size; i++)
 | 
			
		||||
    {
 | 
			
		||||
      c = data[i];
 | 
			
		||||
      if (g_ascii_iscntrl (c) && !g_ascii_isspace (c))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_type_guess:
 | 
			
		||||
 * @filename: a string.
 | 
			
		||||
 * @data: a stream of data.
 | 
			
		||||
 * @data_size: the size of @data.
 | 
			
		||||
 * @result_uncertain: a flag indicating the certainty of the 
 | 
			
		||||
 * result.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a string indicating a guessed content type for the 
 | 
			
		||||
 * given data. If the function is uncertain, @result_uncertain 
 | 
			
		||||
 * will be set to %TRUE.
 | 
			
		||||
 **/  
 | 
			
		||||
char *
 | 
			
		||||
g_content_type_guess (const char   *filename,
 | 
			
		||||
		      const guchar *data,
 | 
			
		||||
		      gsize         data_size,
 | 
			
		||||
		      gboolean     *result_uncertain)
 | 
			
		||||
{
 | 
			
		||||
  char *basename;
 | 
			
		||||
  char *type;
 | 
			
		||||
  char *dot;
 | 
			
		||||
 | 
			
		||||
  type = NULL;
 | 
			
		||||
 | 
			
		||||
  if (filename)
 | 
			
		||||
    {
 | 
			
		||||
      basename = g_path_get_basename (filename);
 | 
			
		||||
      dot = strrchr (basename, '.');
 | 
			
		||||
      if (dot)
 | 
			
		||||
	type = g_strdup (dot);
 | 
			
		||||
      g_free (basename);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (type)
 | 
			
		||||
    return type;
 | 
			
		||||
 | 
			
		||||
  if (data && looks_like_text (data, data_size))
 | 
			
		||||
    return g_strdup (".txt");
 | 
			
		||||
 | 
			
		||||
  return g_strdup ("*");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_types_get_registered:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: #GList of the registered content types.
 | 
			
		||||
 **/  
 | 
			
		||||
GList *
 | 
			
		||||
g_content_types_get_registered (void)
 | 
			
		||||
{
 | 
			
		||||
  DWORD index;
 | 
			
		||||
  wchar_t keyname[256];
 | 
			
		||||
  DWORD key_len;
 | 
			
		||||
  char *key_utf8;
 | 
			
		||||
  GList *types;
 | 
			
		||||
 | 
			
		||||
  types = NULL;
 | 
			
		||||
  index = 0;
 | 
			
		||||
  key_len = 256;
 | 
			
		||||
  while (RegEnumKeyExW(HKEY_CLASSES_ROOT,
 | 
			
		||||
		       index,
 | 
			
		||||
		       keyname,
 | 
			
		||||
		       &key_len,
 | 
			
		||||
		       NULL,
 | 
			
		||||
		       NULL,
 | 
			
		||||
		       NULL,
 | 
			
		||||
		       NULL) == ERROR_SUCCESS)
 | 
			
		||||
    {
 | 
			
		||||
      key_utf8 = g_utf16_to_utf8 (keyname, -1, NULL, NULL, NULL);
 | 
			
		||||
      if (key_utf8)
 | 
			
		||||
	{
 | 
			
		||||
	  if (*key_utf8 == '.')
 | 
			
		||||
	    types = g_list_prepend (types, key_utf8);
 | 
			
		||||
	  else
 | 
			
		||||
	    g_free (key_utf8);
 | 
			
		||||
	}
 | 
			
		||||
      index++;
 | 
			
		||||
      key_len = 256;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return g_list_reverse (types);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else /* !G_OS_WIN32 - Unix specific version */
 | 
			
		||||
 | 
			
		||||
#define XDG_PREFIX _gio_xdg
 | 
			
		||||
#include "xdgmime/xdgmime.h"
 | 
			
		||||
 | 
			
		||||
/* We lock this mutex whenever we modify global state in this module.  */
 | 
			
		||||
G_LOCK_DEFINE_STATIC (gio_xdgmime);
 | 
			
		||||
 | 
			
		||||
gsize
 | 
			
		||||
_g_unix_content_type_get_sniff_len (void)
 | 
			
		||||
{
 | 
			
		||||
  gsize size;
 | 
			
		||||
 | 
			
		||||
  G_LOCK (gio_xdgmime);
 | 
			
		||||
  size = xdg_mime_get_max_buffer_extents ();
 | 
			
		||||
  G_UNLOCK (gio_xdgmime);
 | 
			
		||||
 | 
			
		||||
  return size;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
_g_unix_content_type_unalias (const char *type)
 | 
			
		||||
{
 | 
			
		||||
  char *res;
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (gio_xdgmime);
 | 
			
		||||
  res = g_strdup (xdg_mime_unalias_mime_type (type));
 | 
			
		||||
  G_UNLOCK (gio_xdgmime);
 | 
			
		||||
  
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char **
 | 
			
		||||
_g_unix_content_type_get_parents (const char *type)
 | 
			
		||||
{
 | 
			
		||||
  const char *umime;
 | 
			
		||||
  const char **parents;
 | 
			
		||||
  GPtrArray *array;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  array = g_ptr_array_new ();
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (gio_xdgmime);
 | 
			
		||||
  
 | 
			
		||||
  umime = xdg_mime_unalias_mime_type (type);
 | 
			
		||||
  g_ptr_array_add (array, g_strdup (umime));
 | 
			
		||||
  
 | 
			
		||||
  parents = xdg_mime_get_mime_parents (umime);
 | 
			
		||||
  for (i = 0; parents && parents[i] != NULL; i++)
 | 
			
		||||
    g_ptr_array_add (array, g_strdup (parents[i]));
 | 
			
		||||
  
 | 
			
		||||
  G_UNLOCK (gio_xdgmime);
 | 
			
		||||
  
 | 
			
		||||
  g_ptr_array_add (array, NULL);
 | 
			
		||||
  
 | 
			
		||||
  return (char **)g_ptr_array_free (array, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
g_content_type_equals (const char   *type1,
 | 
			
		||||
		       const char   *type2)
 | 
			
		||||
{
 | 
			
		||||
  gboolean res;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (type1 != NULL, FALSE);
 | 
			
		||||
  g_return_val_if_fail (type2 != NULL, FALSE);
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (gio_xdgmime);
 | 
			
		||||
  res = xdg_mime_mime_type_equal (type1, type2);
 | 
			
		||||
  G_UNLOCK (gio_xdgmime);
 | 
			
		||||
	
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
g_content_type_is_a (const char   *type,
 | 
			
		||||
		     const char   *supertype)
 | 
			
		||||
{
 | 
			
		||||
  gboolean res;
 | 
			
		||||
    
 | 
			
		||||
  g_return_val_if_fail (type != NULL, FALSE);
 | 
			
		||||
  g_return_val_if_fail (supertype != NULL, FALSE);
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (gio_xdgmime);
 | 
			
		||||
  res = xdg_mime_mime_type_subclass (type, supertype);
 | 
			
		||||
  G_UNLOCK (gio_xdgmime);
 | 
			
		||||
	
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
gboolean
 | 
			
		||||
g_content_type_is_unknown (const char *type)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (type != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  return strcmp (XDG_MIME_TYPE_UNKNOWN, type) == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  MIME_TAG_TYPE_OTHER,
 | 
			
		||||
  MIME_TAG_TYPE_COMMENT
 | 
			
		||||
} MimeTagType;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  int current_type;
 | 
			
		||||
  int current_lang_level;
 | 
			
		||||
  int comment_lang_level;
 | 
			
		||||
  char *comment;
 | 
			
		||||
} MimeParser;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
language_level (const char *lang)
 | 
			
		||||
{
 | 
			
		||||
  const char * const *lang_list;
 | 
			
		||||
  int i;
 | 
			
		||||
  
 | 
			
		||||
  /* The returned list is sorted from most desirable to least
 | 
			
		||||
     desirable and always contains the default locale "C". */
 | 
			
		||||
  lang_list = g_get_language_names ();
 | 
			
		||||
  
 | 
			
		||||
  for (i = 0; lang_list[i]; i++)
 | 
			
		||||
    if (strcmp (lang_list[i], lang) == 0)
 | 
			
		||||
      return 1000-i;
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mime_info_start_element (GMarkupParseContext *context,
 | 
			
		||||
			 const gchar         *element_name,
 | 
			
		||||
			 const gchar        **attribute_names,
 | 
			
		||||
			 const gchar        **attribute_values,
 | 
			
		||||
			 gpointer             user_data,
 | 
			
		||||
			 GError             **error)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  const char *lang;
 | 
			
		||||
  MimeParser *parser = user_data;
 | 
			
		||||
  
 | 
			
		||||
  if (strcmp (element_name, "comment") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      lang = "C";
 | 
			
		||||
      for (i = 0; attribute_names[i]; i++)
 | 
			
		||||
	if (strcmp (attribute_names[i], "xml:lang") == 0)
 | 
			
		||||
	  {
 | 
			
		||||
	    lang = attribute_values[i];
 | 
			
		||||
	    break;
 | 
			
		||||
	  }
 | 
			
		||||
      
 | 
			
		||||
      parser->current_lang_level = language_level (lang);
 | 
			
		||||
      parser->current_type = MIME_TAG_TYPE_COMMENT;
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    parser->current_type = MIME_TAG_TYPE_OTHER;
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mime_info_end_element (GMarkupParseContext *context,
 | 
			
		||||
		       const gchar         *element_name,
 | 
			
		||||
		       gpointer             user_data,
 | 
			
		||||
		       GError             **error)
 | 
			
		||||
{
 | 
			
		||||
  MimeParser *parser = user_data;
 | 
			
		||||
  
 | 
			
		||||
  parser->current_type = MIME_TAG_TYPE_OTHER;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mime_info_text (GMarkupParseContext *context,
 | 
			
		||||
		const gchar         *text,
 | 
			
		||||
		gsize                text_len,  
 | 
			
		||||
		gpointer             user_data,
 | 
			
		||||
		GError             **error)
 | 
			
		||||
{
 | 
			
		||||
  MimeParser *parser = user_data;
 | 
			
		||||
 | 
			
		||||
  if (parser->current_type == MIME_TAG_TYPE_COMMENT &&
 | 
			
		||||
      parser->current_lang_level > parser->comment_lang_level)
 | 
			
		||||
    {
 | 
			
		||||
      g_free (parser->comment);
 | 
			
		||||
      parser->comment = g_strndup (text, text_len);
 | 
			
		||||
      parser->comment_lang_level = parser->current_lang_level;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
load_comment_for_mime_helper (const char *dir, const char *basename)
 | 
			
		||||
{
 | 
			
		||||
  GMarkupParseContext *context;
 | 
			
		||||
  char *filename, *data;
 | 
			
		||||
  gsize len;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
  MimeParser parse_data = {0};
 | 
			
		||||
  GMarkupParser parser = {
 | 
			
		||||
    mime_info_start_element,
 | 
			
		||||
    mime_info_end_element,
 | 
			
		||||
    mime_info_text
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  filename = g_build_filename (dir, "mime", basename, NULL);
 | 
			
		||||
  
 | 
			
		||||
  res = g_file_get_contents (filename,  &data,  &len,  NULL);
 | 
			
		||||
  g_free (filename);
 | 
			
		||||
  if (!res)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  
 | 
			
		||||
  context = g_markup_parse_context_new   (&parser, 0, &parse_data, NULL);
 | 
			
		||||
  res = g_markup_parse_context_parse (context, data, len, NULL);
 | 
			
		||||
  g_free (data);
 | 
			
		||||
  g_markup_parse_context_free (context);
 | 
			
		||||
  
 | 
			
		||||
  if (!res)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  return parse_data.comment;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
load_comment_for_mime (const char *mimetype)
 | 
			
		||||
{
 | 
			
		||||
  const char * const* dirs;
 | 
			
		||||
  char *basename;
 | 
			
		||||
  char *comment;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  basename = g_strdup_printf ("%s.xml", mimetype);
 | 
			
		||||
 | 
			
		||||
  comment = load_comment_for_mime_helper (g_get_user_data_dir (), basename);
 | 
			
		||||
  if (comment)
 | 
			
		||||
    {
 | 
			
		||||
      g_free (basename);
 | 
			
		||||
      return comment;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  dirs = g_get_system_data_dirs ();
 | 
			
		||||
 | 
			
		||||
  for (i = 0; dirs[i] != NULL; i++)
 | 
			
		||||
    {
 | 
			
		||||
      comment = load_comment_for_mime_helper (dirs[i], basename);
 | 
			
		||||
      if (comment)
 | 
			
		||||
	{
 | 
			
		||||
	  g_free (basename);
 | 
			
		||||
	  return comment;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  g_free (basename);
 | 
			
		||||
  
 | 
			
		||||
  return g_strdup_printf (_("%s type"), mimetype);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
g_content_type_get_description (const char *type)
 | 
			
		||||
{
 | 
			
		||||
  static GHashTable *type_comment_cache = NULL;
 | 
			
		||||
  char *comment;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (type != NULL, NULL);
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (gio_xdgmime);
 | 
			
		||||
  if (type_comment_cache == NULL)
 | 
			
		||||
    type_comment_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
 | 
			
		||||
 | 
			
		||||
  comment = g_hash_table_lookup (type_comment_cache, type);
 | 
			
		||||
  comment = g_strdup (comment);
 | 
			
		||||
  G_UNLOCK (gio_xdgmime);
 | 
			
		||||
  
 | 
			
		||||
  if (comment != NULL)
 | 
			
		||||
    return comment;
 | 
			
		||||
 | 
			
		||||
  comment = load_comment_for_mime (type);
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (gio_xdgmime);
 | 
			
		||||
  g_hash_table_insert (type_comment_cache,
 | 
			
		||||
		       g_strdup (type),
 | 
			
		||||
		       g_strdup (comment));
 | 
			
		||||
  G_UNLOCK (gio_xdgmime);
 | 
			
		||||
 | 
			
		||||
  return comment;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
g_content_type_get_mime_type (const char   *type)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (type != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  return g_strdup (type);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GIcon *
 | 
			
		||||
g_content_type_get_icon (const char   *type)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (type != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  /* TODO: Implement */
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_content_type_can_be_executable:
 | 
			
		||||
 * @type: a content type string.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if the file type corresponds to something that
 | 
			
		||||
 * can be executable, %FALSE otherwise. Note that for instance
 | 
			
		||||
 * things like textfiles can be executables (i.e. scripts)
 | 
			
		||||
 **/  
 | 
			
		||||
gboolean
 | 
			
		||||
g_content_type_can_be_executable (const char   *type)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (type != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  if (g_content_type_is_a (type, "application/x-executable")  ||
 | 
			
		||||
      g_content_type_is_a (type, "text/plain"))
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
looks_like_text (const guchar *data, gsize data_size)
 | 
			
		||||
{
 | 
			
		||||
  gsize i;
 | 
			
		||||
  for (i = 0; i < data_size; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if g_ascii_iscntrl (data[i])
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
g_content_type_guess (const char   *filename,
 | 
			
		||||
		      const guchar *data,
 | 
			
		||||
		      gsize         data_size,
 | 
			
		||||
		      gboolean     *result_uncertain)
 | 
			
		||||
{
 | 
			
		||||
  char *basename;
 | 
			
		||||
  const char *name_mimetypes[10], *sniffed_mimetype;
 | 
			
		||||
  char *mimetype;
 | 
			
		||||
  int i;
 | 
			
		||||
  int n_name_mimetypes;
 | 
			
		||||
  int sniffed_prio;
 | 
			
		||||
 | 
			
		||||
  sniffed_prio = 0;
 | 
			
		||||
  n_name_mimetypes = 0;
 | 
			
		||||
  sniffed_mimetype = XDG_MIME_TYPE_UNKNOWN;
 | 
			
		||||
 | 
			
		||||
  if (result_uncertain)
 | 
			
		||||
    *result_uncertain = FALSE;
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (gio_xdgmime);
 | 
			
		||||
  
 | 
			
		||||
  if (filename)
 | 
			
		||||
    {
 | 
			
		||||
      basename = g_path_get_basename (filename);
 | 
			
		||||
      n_name_mimetypes = xdg_mime_get_mime_types_from_file_name (basename, name_mimetypes, 10);
 | 
			
		||||
      g_free (basename);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Got an extension match, and no conflicts. This is it. */
 | 
			
		||||
  if (n_name_mimetypes == 1)
 | 
			
		||||
    {
 | 
			
		||||
      G_UNLOCK (gio_xdgmime);
 | 
			
		||||
      return g_strdup (name_mimetypes[0]);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (data)
 | 
			
		||||
    {
 | 
			
		||||
      sniffed_mimetype = xdg_mime_get_mime_type_for_data (data, data_size, &sniffed_prio);
 | 
			
		||||
      if (sniffed_mimetype == XDG_MIME_TYPE_UNKNOWN &&
 | 
			
		||||
	  data &&
 | 
			
		||||
	  looks_like_text (data, data_size))
 | 
			
		||||
	sniffed_mimetype = "text/plain";
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (n_name_mimetypes == 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (sniffed_mimetype == XDG_MIME_TYPE_UNKNOWN &&
 | 
			
		||||
	  result_uncertain)
 | 
			
		||||
	*result_uncertain = TRUE;
 | 
			
		||||
      
 | 
			
		||||
      mimetype = g_strdup (sniffed_mimetype);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      mimetype = NULL;
 | 
			
		||||
      if (sniffed_mimetype != XDG_MIME_TYPE_UNKNOWN)
 | 
			
		||||
	{
 | 
			
		||||
	  if (sniffed_prio >= 80) /* High priority sniffing match, use that */
 | 
			
		||||
	    mimetype = g_strdup (sniffed_mimetype);
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
	      /* There are conflicts between the name matches and we have a sniffed
 | 
			
		||||
		 type, use that as a tie breaker. */
 | 
			
		||||
	      
 | 
			
		||||
	      for (i = 0; i < n_name_mimetypes; i++)
 | 
			
		||||
		{
 | 
			
		||||
		  if ( xdg_mime_mime_type_subclass (name_mimetypes[i], sniffed_mimetype))
 | 
			
		||||
		    {
 | 
			
		||||
		      /* This nametype match is derived from (or the same as) the sniffed type).
 | 
			
		||||
			 This is probably it. */
 | 
			
		||||
		      mimetype = g_strdup (name_mimetypes[i]);
 | 
			
		||||
		      break;
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      if (mimetype == NULL)
 | 
			
		||||
	{
 | 
			
		||||
	  /* Conflicts, and sniffed type was no help or not there. guess on the first one */
 | 
			
		||||
	  mimetype = g_strdup (name_mimetypes[0]);
 | 
			
		||||
	  if (result_uncertain)
 | 
			
		||||
	    *result_uncertain = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  G_UNLOCK (gio_xdgmime);
 | 
			
		||||
 | 
			
		||||
  return mimetype;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
foreach_mimetype (gpointer  key,
 | 
			
		||||
		  gpointer  value,
 | 
			
		||||
		  gpointer  user_data)
 | 
			
		||||
{
 | 
			
		||||
  GList **l = user_data;
 | 
			
		||||
 | 
			
		||||
  *l = g_list_prepend (*l, (char *)key);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
enumerate_mimetypes_subdir (const char *dir, const char *prefix, GHashTable *mimetypes)
 | 
			
		||||
{
 | 
			
		||||
  DIR *d;
 | 
			
		||||
  struct dirent *ent;
 | 
			
		||||
  char *mimetype;
 | 
			
		||||
 | 
			
		||||
  d = opendir (dir);
 | 
			
		||||
  if (d)
 | 
			
		||||
    {
 | 
			
		||||
      while ((ent = readdir (d)) != NULL)
 | 
			
		||||
	{
 | 
			
		||||
	  if (g_str_has_suffix (ent->d_name, ".xml"))
 | 
			
		||||
	    {
 | 
			
		||||
	      mimetype = g_strdup_printf ("%s/%.*s", prefix, (int) strlen (ent->d_name) - 4, ent->d_name);
 | 
			
		||||
	      g_hash_table_insert (mimetypes, mimetype, NULL);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
      closedir (d);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
enumerate_mimetypes_dir (const char *dir, GHashTable *mimetypes)
 | 
			
		||||
{
 | 
			
		||||
  DIR *d;
 | 
			
		||||
  struct dirent *ent;
 | 
			
		||||
  char *mimedir;
 | 
			
		||||
  char *name;
 | 
			
		||||
 | 
			
		||||
  mimedir = g_build_filename (dir, "mime", NULL);
 | 
			
		||||
  
 | 
			
		||||
  d = opendir (mimedir);
 | 
			
		||||
  if (d)
 | 
			
		||||
    {
 | 
			
		||||
      while ((ent = readdir (d)) != NULL)
 | 
			
		||||
	{
 | 
			
		||||
	  if (strcmp (ent->d_name, "packages") != 0)
 | 
			
		||||
	    {
 | 
			
		||||
	      name = g_build_filename (mimedir, ent->d_name, NULL);
 | 
			
		||||
	      if (g_file_test (name, G_FILE_TEST_IS_DIR))
 | 
			
		||||
		enumerate_mimetypes_subdir (name, ent->d_name, mimetypes);
 | 
			
		||||
	      g_free (name);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
      closedir (d);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  g_free (mimedir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GList *
 | 
			
		||||
g_content_types_get_registered (void)
 | 
			
		||||
{
 | 
			
		||||
  const char * const* dirs;
 | 
			
		||||
  GHashTable *mimetypes;
 | 
			
		||||
  int i;
 | 
			
		||||
  GList *l;
 | 
			
		||||
 | 
			
		||||
  mimetypes = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 | 
			
		||||
 | 
			
		||||
  enumerate_mimetypes_dir (g_get_user_data_dir (), mimetypes);
 | 
			
		||||
  dirs = g_get_system_data_dirs ();
 | 
			
		||||
 | 
			
		||||
  for (i = 0; dirs[i] != NULL; i++)
 | 
			
		||||
    enumerate_mimetypes_dir (dirs[i], mimetypes);
 | 
			
		||||
 | 
			
		||||
  l = NULL;
 | 
			
		||||
  g_hash_table_foreach_steal (mimetypes, foreach_mimetype, &l);
 | 
			
		||||
  g_hash_table_destroy (mimetypes);
 | 
			
		||||
 | 
			
		||||
  return l;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif /* Unix version */
 | 
			
		||||
							
								
								
									
										50
									
								
								gio/gcontenttype.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								gio/gcontenttype.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_CONTENT_TYPE_H__
 | 
			
		||||
#define __G_CONTENT_TYPE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <gio/gicon.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
gboolean g_content_type_equals            (const char   *type1,
 | 
			
		||||
					   const char   *type2);
 | 
			
		||||
gboolean g_content_type_is_a              (const char   *type,
 | 
			
		||||
					   const char   *supertype);
 | 
			
		||||
gboolean g_content_type_is_unknown        (const char   *type);
 | 
			
		||||
char *   g_content_type_get_description   (const char   *type);
 | 
			
		||||
char *   g_content_type_get_mime_type     (const char   *type);
 | 
			
		||||
GIcon *  g_content_type_get_icon          (const char   *type);
 | 
			
		||||
gboolean g_content_type_can_be_executable (const char   *type);
 | 
			
		||||
 | 
			
		||||
char *   g_content_type_guess             (const char   *filename,
 | 
			
		||||
					   const guchar *data,
 | 
			
		||||
					   gsize         data_size,
 | 
			
		||||
					   gboolean     *result_uncertain );
 | 
			
		||||
 | 
			
		||||
GList *  g_content_types_get_registered   (void);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_CONTENT_TYPE_H__ */
 | 
			
		||||
							
								
								
									
										36
									
								
								gio/gcontenttypeprivate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								gio/gcontenttypeprivate.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_CONTENT_TYPE_PRIVATE_H__
 | 
			
		||||
#define __G_CONTENT_TYPE_PRIVATE_H__
 | 
			
		||||
 | 
			
		||||
#include "gcontenttype.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
gsize  _g_unix_content_type_get_sniff_len (void);
 | 
			
		||||
char * _g_unix_content_type_unalias       (const char *type);
 | 
			
		||||
char **_g_unix_content_type_get_parents   (const char *type);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_CONTENT_TYPE_PRIVATE_H__ */
 | 
			
		||||
							
								
								
									
										718
									
								
								gio/gdatainputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										718
									
								
								gio/gdatainputstream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,718 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "gdatainputstream.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
struct _GDataInputStreamPrivate {
 | 
			
		||||
  GDataStreamByteOrder byte_order;
 | 
			
		||||
  GDataStreamNewlineType newline_type;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  PROP_0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void g_data_input_stream_set_property (GObject      *object,
 | 
			
		||||
					      guint         prop_id,
 | 
			
		||||
					      const GValue *value,
 | 
			
		||||
					      GParamSpec   *pspec);
 | 
			
		||||
static void g_data_input_stream_get_property (GObject      *object,
 | 
			
		||||
					      guint         prop_id,
 | 
			
		||||
					      GValue       *value,
 | 
			
		||||
					      GParamSpec   *pspec);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GDataInputStream,
 | 
			
		||||
               g_data_input_stream,
 | 
			
		||||
               G_TYPE_BUFFERED_INPUT_STREAM)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_data_input_stream_class_init (GDataInputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GDataInputStreamPrivate));
 | 
			
		||||
 | 
			
		||||
  object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  object_class->get_property = g_data_input_stream_get_property;
 | 
			
		||||
  object_class->set_property = g_data_input_stream_set_property;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_data_input_stream_set_property (GObject         *object,
 | 
			
		||||
				  guint            prop_id,
 | 
			
		||||
				  const GValue    *value,
 | 
			
		||||
				  GParamSpec      *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GDataInputStreamPrivate *priv;
 | 
			
		||||
  GDataInputStream        *dstream;
 | 
			
		||||
 | 
			
		||||
  dstream = G_DATA_INPUT_STREAM (object);
 | 
			
		||||
  priv = dstream->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id) 
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_data_input_stream_get_property (GObject    *object,
 | 
			
		||||
                                      guint       prop_id,
 | 
			
		||||
                                      GValue     *value,
 | 
			
		||||
                                      GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GDataInputStreamPrivate *priv;
 | 
			
		||||
  GDataInputStream        *dstream;
 | 
			
		||||
 | 
			
		||||
  dstream = G_DATA_INPUT_STREAM (object);
 | 
			
		||||
  priv = dstream->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    { 
 | 
			
		||||
  
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
static void
 | 
			
		||||
g_data_input_stream_init (GDataInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
 | 
			
		||||
                                              G_TYPE_DATA_INPUT_STREAM,
 | 
			
		||||
                                              GDataInputStreamPrivate);
 | 
			
		||||
 | 
			
		||||
  stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
 | 
			
		||||
  stream->priv->newline_type = G_DATA_STREAM_NEWLINE_TYPE_LF;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_new:
 | 
			
		||||
 * @base_stream: a given #GInputStream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a new #GDataInputStream.
 | 
			
		||||
 **/
 | 
			
		||||
GDataInputStream *
 | 
			
		||||
g_data_input_stream_new (GInputStream *base_stream)
 | 
			
		||||
{
 | 
			
		||||
  GDataInputStream *stream;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_INPUT_STREAM (base_stream), NULL);
 | 
			
		||||
 | 
			
		||||
  stream = g_object_new (G_TYPE_DATA_INPUT_STREAM,
 | 
			
		||||
                         "base-stream", base_stream,
 | 
			
		||||
                         NULL);
 | 
			
		||||
 | 
			
		||||
  return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_set_byte_order:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @order: a #GDataStreamByteOrder to set.
 | 
			
		||||
 * 
 | 
			
		||||
 * This function sets the byte order for the given @stream. All subsequent
 | 
			
		||||
 * reads from the @stream will be read in the given @order.
 | 
			
		||||
 *  
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_data_input_stream_set_byte_order (GDataInputStream *stream,
 | 
			
		||||
				    GDataStreamByteOrder order)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
 | 
			
		||||
 | 
			
		||||
  stream->priv->byte_order = order;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_get_byte_order:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns the @stream's current #GDataStreamByteOrder. 
 | 
			
		||||
 **/
 | 
			
		||||
GDataStreamByteOrder
 | 
			
		||||
g_data_input_stream_get_byte_order (GDataInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN);
 | 
			
		||||
 | 
			
		||||
  return stream->priv->byte_order;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_set_newline_type:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @type: the type of new line return as #GDataStreamNewlineType.
 | 
			
		||||
 * 
 | 
			
		||||
 * Sets the newline type for the @stream.
 | 
			
		||||
 * 
 | 
			
		||||
 * TODO: is it valid to set this to G_DATA_STREAM_NEWLINE_TYPE_ANY, or
 | 
			
		||||
 * should it always be set to {_LF, _CR, _CR_LF}
 | 
			
		||||
 *  
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_data_input_stream_set_newline_type (GDataInputStream        *stream,
 | 
			
		||||
				      GDataStreamNewlineType   type)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_DATA_INPUT_STREAM (stream));
 | 
			
		||||
 | 
			
		||||
  stream->priv->newline_type = type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_get_newline_type:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Gets the current newline type for the @stream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: #GDataStreamNewlineType for the given @stream.
 | 
			
		||||
 **/
 | 
			
		||||
GDataStreamNewlineType
 | 
			
		||||
g_data_input_stream_get_newline_type (GDataInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), G_DATA_STREAM_NEWLINE_TYPE_ANY);
 | 
			
		||||
 | 
			
		||||
  return stream->priv->newline_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
read_data (GDataInputStream *stream,
 | 
			
		||||
	  void *buffer,
 | 
			
		||||
	  gsize size,
 | 
			
		||||
	  GCancellable *cancellable,
 | 
			
		||||
	  GError **error)
 | 
			
		||||
{
 | 
			
		||||
  gsize available;
 | 
			
		||||
  gssize res;
 | 
			
		||||
 | 
			
		||||
  while ((available = g_buffered_input_stream_get_available (G_BUFFERED_INPUT_STREAM (stream))) < size)
 | 
			
		||||
    {
 | 
			
		||||
      res = g_buffered_input_stream_fill (G_BUFFERED_INPUT_STREAM (stream),
 | 
			
		||||
					  size - available,
 | 
			
		||||
					  cancellable, error);
 | 
			
		||||
      if (res < 0)
 | 
			
		||||
	return FALSE;
 | 
			
		||||
      if (res == 0)
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
 | 
			
		||||
		       _("Unexpected early end-of-stream"));
 | 
			
		||||
	  return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  /* This should always succeed, since its in the buffer */
 | 
			
		||||
  res = g_input_stream_read (G_INPUT_STREAM (stream),
 | 
			
		||||
			     buffer, size,
 | 
			
		||||
			     NULL, NULL);
 | 
			
		||||
  g_assert (res == size);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_read_byte:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: #GError for error reporting.
 | 
			
		||||
 * 
 | 
			
		||||
 * In order to get the correct byte order for this read operation, 
 | 
			
		||||
 * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: an unsigned 8-bit/1-byte value read from the @stream or %0 
 | 
			
		||||
 * if an error occured.
 | 
			
		||||
 **/
 | 
			
		||||
 | 
			
		||||
guchar
 | 
			
		||||
g_data_input_stream_read_byte (GDataInputStream        *stream,
 | 
			
		||||
			      GCancellable            *cancellable,
 | 
			
		||||
			      GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  guchar c;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), '\0');
 | 
			
		||||
  
 | 
			
		||||
  if (read_data (stream, &c, 1, cancellable, error))
 | 
			
		||||
      return c;
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_read_int16:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: #GError for error reporting.
 | 
			
		||||
 * 
 | 
			
		||||
 * In order to get the correct byte order for this read operation, 
 | 
			
		||||
 * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns a signed 16-bit/2-byte value read from @stream or %0 if 
 | 
			
		||||
 * an error occured.
 | 
			
		||||
 **/
 | 
			
		||||
gint16
 | 
			
		||||
g_data_input_stream_read_int16 (GDataInputStream        *stream,
 | 
			
		||||
			       GCancellable            *cancellable,
 | 
			
		||||
			       GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  gint16 v;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
 | 
			
		||||
  
 | 
			
		||||
  if (read_data (stream, &v, 2, cancellable, error))
 | 
			
		||||
    {
 | 
			
		||||
      switch (stream->priv->byte_order)
 | 
			
		||||
	{
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
	  v = GINT16_FROM_BE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
	  v = GINT16_FROM_LE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
	default:
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
      return v;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_read_uint16:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: #GError for error reporting.
 | 
			
		||||
 *
 | 
			
		||||
 * In order to get the correct byte order for this read operation, 
 | 
			
		||||
 * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order(). 
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns an unsigned 16-bit/2-byte value read from the @stream or %0 if 
 | 
			
		||||
 * an error occured. 
 | 
			
		||||
 **/
 | 
			
		||||
guint16
 | 
			
		||||
g_data_input_stream_read_uint16 (GDataInputStream        *stream,
 | 
			
		||||
				GCancellable            *cancellable,
 | 
			
		||||
				GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  guint16 v;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
 | 
			
		||||
  
 | 
			
		||||
  if (read_data (stream, &v, 2, cancellable, error))
 | 
			
		||||
    {
 | 
			
		||||
      switch (stream->priv->byte_order)
 | 
			
		||||
	{
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
	  v = GUINT16_FROM_BE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
	  v = GUINT16_FROM_LE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
	default:
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
      return v;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_read_int32:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: #GError for error reporting.
 | 
			
		||||
 * 
 | 
			
		||||
 * In order to get the correct byte order for this read operation, 
 | 
			
		||||
 * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
 | 
			
		||||
 *   
 | 
			
		||||
 * Returns a signed 32-bit/4-byte value read from the @stream or %0 if 
 | 
			
		||||
 * an error occured. 
 | 
			
		||||
 **/
 | 
			
		||||
gint32
 | 
			
		||||
g_data_input_stream_read_int32 (GDataInputStream        *stream,
 | 
			
		||||
			       GCancellable            *cancellable,
 | 
			
		||||
			       GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  gint32 v;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
 | 
			
		||||
  
 | 
			
		||||
  if (read_data (stream, &v, 4, cancellable, error))
 | 
			
		||||
    {
 | 
			
		||||
      switch (stream->priv->byte_order)
 | 
			
		||||
	{
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
	  v = GINT32_FROM_BE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
	  v = GINT32_FROM_LE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
	default:
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
      return v;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_read_uint32:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: #GError for error reporting.
 | 
			
		||||
 * 
 | 
			
		||||
 * In order to get the correct byte order for this read operation, 
 | 
			
		||||
 * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns an unsigned 32-bit/4-byte value read from the @stream or %0 if 
 | 
			
		||||
 * an error occured. 
 | 
			
		||||
 **/
 | 
			
		||||
guint32
 | 
			
		||||
g_data_input_stream_read_uint32 (GDataInputStream        *stream,
 | 
			
		||||
				GCancellable            *cancellable,
 | 
			
		||||
				GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  guint32 v;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
 | 
			
		||||
  
 | 
			
		||||
  if (read_data (stream, &v, 4, cancellable, error))
 | 
			
		||||
    {
 | 
			
		||||
      switch (stream->priv->byte_order)
 | 
			
		||||
	{
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
	  v = GUINT32_FROM_BE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
	  v = GUINT32_FROM_LE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
	default:
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
      return v;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_read_int64:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: #GError for error reporting.
 | 
			
		||||
 * 
 | 
			
		||||
 * In order to get the correct byte order for this read operation, 
 | 
			
		||||
 * see g_data_stream_get_byte_order() and g_data_stream_set_byte_order().
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns a signed 64-bit/8-byte value read from @stream or %0 if 
 | 
			
		||||
 * an error occured.  
 | 
			
		||||
 **/
 | 
			
		||||
gint64
 | 
			
		||||
g_data_input_stream_read_int64 (GDataInputStream        *stream,
 | 
			
		||||
			       GCancellable            *cancellable,
 | 
			
		||||
			       GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  gint64 v;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
 | 
			
		||||
  
 | 
			
		||||
  if (read_data (stream, &v, 8, cancellable, error))
 | 
			
		||||
    {
 | 
			
		||||
      switch (stream->priv->byte_order)
 | 
			
		||||
	{
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
	  v = GINT64_FROM_BE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
	  v = GINT64_FROM_LE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
	default:
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
      return v;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_read_uint64:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: #GError for error reporting.
 | 
			
		||||
 * 
 | 
			
		||||
 * In order to get the correct byte order for this read operation, 
 | 
			
		||||
 * see g_data_stream_get_byte_order().
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns an unsigned 64-bit/8-byte read from @stream or %0 if 
 | 
			
		||||
 * an error occured. 
 | 
			
		||||
 **/
 | 
			
		||||
guint64
 | 
			
		||||
g_data_input_stream_read_uint64 (GDataInputStream        *stream,
 | 
			
		||||
				GCancellable            *cancellable,
 | 
			
		||||
				GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  guint64 v;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), 0);
 | 
			
		||||
  
 | 
			
		||||
  if (read_data (stream, &v, 8, cancellable, error))
 | 
			
		||||
    {
 | 
			
		||||
      switch (stream->priv->byte_order)
 | 
			
		||||
	{
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
	  v = GUINT64_FROM_BE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
	  v = GUINT64_FROM_LE (v);
 | 
			
		||||
	  break;
 | 
			
		||||
	case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
	default:
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
      return v;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
scan_for_newline (GDataInputStream *stream,
 | 
			
		||||
		  gsize *checked_out,
 | 
			
		||||
		  gboolean *last_saw_cr_out,
 | 
			
		||||
		  int *newline_len_out)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedInputStream *bstream;
 | 
			
		||||
  GDataInputStreamPrivate *priv;
 | 
			
		||||
  char buffer[100];
 | 
			
		||||
  gsize start, end, peeked;
 | 
			
		||||
  int i;
 | 
			
		||||
  gssize found_pos;
 | 
			
		||||
  int newline_len;
 | 
			
		||||
  gsize available, checked;
 | 
			
		||||
  gboolean last_saw_cr;
 | 
			
		||||
 | 
			
		||||
  priv = stream->priv;
 | 
			
		||||
  
 | 
			
		||||
  bstream = G_BUFFERED_INPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  available = g_buffered_input_stream_get_available (bstream);
 | 
			
		||||
 | 
			
		||||
  checked = *checked_out;
 | 
			
		||||
  last_saw_cr = *last_saw_cr_out;
 | 
			
		||||
  found_pos = -1;
 | 
			
		||||
  newline_len = 0;
 | 
			
		||||
  
 | 
			
		||||
  while (checked < available)
 | 
			
		||||
    {
 | 
			
		||||
      start = checked;
 | 
			
		||||
      end = MIN (start + sizeof(buffer), available);
 | 
			
		||||
      peeked = g_buffered_input_stream_peek (bstream, buffer, start, end - start);
 | 
			
		||||
      end = start + peeked;
 | 
			
		||||
 | 
			
		||||
      for (i = 0; i < peeked; i++)
 | 
			
		||||
	{
 | 
			
		||||
	  switch (priv->newline_type)
 | 
			
		||||
	    {
 | 
			
		||||
	    case G_DATA_STREAM_NEWLINE_TYPE_LF:
 | 
			
		||||
	      if (buffer[i] == 10)
 | 
			
		||||
		{
 | 
			
		||||
		  found_pos = start + i;
 | 
			
		||||
		  newline_len = 1;
 | 
			
		||||
		}
 | 
			
		||||
	      break;
 | 
			
		||||
	    case G_DATA_STREAM_NEWLINE_TYPE_CR:
 | 
			
		||||
	      if (buffer[i] == 13)
 | 
			
		||||
		{
 | 
			
		||||
		  found_pos = start + i;
 | 
			
		||||
		  newline_len = 1;
 | 
			
		||||
		}
 | 
			
		||||
	      break;
 | 
			
		||||
	    case G_DATA_STREAM_NEWLINE_TYPE_CR_LF:
 | 
			
		||||
	      if (last_saw_cr && buffer[i] == 10)
 | 
			
		||||
		{
 | 
			
		||||
		  found_pos = start + i - 1;
 | 
			
		||||
		  newline_len = 2;
 | 
			
		||||
		}
 | 
			
		||||
	      break;
 | 
			
		||||
	    default:
 | 
			
		||||
	    case G_DATA_STREAM_NEWLINE_TYPE_ANY:
 | 
			
		||||
	      if (buffer[i] == 10) /* LF */
 | 
			
		||||
		{
 | 
			
		||||
		  if (last_saw_cr)
 | 
			
		||||
		    {
 | 
			
		||||
		      /* CR LF */
 | 
			
		||||
		      found_pos = start + i - 1;
 | 
			
		||||
		      newline_len = 2;
 | 
			
		||||
		    }
 | 
			
		||||
		  else
 | 
			
		||||
		    {
 | 
			
		||||
		      /* LF */
 | 
			
		||||
		      found_pos = start + i;
 | 
			
		||||
		      newline_len = 1;
 | 
			
		||||
		    }
 | 
			
		||||
		}
 | 
			
		||||
	      else if (last_saw_cr)
 | 
			
		||||
		{
 | 
			
		||||
		  /* Last was cr, this is not LF, end is CR */
 | 
			
		||||
		  found_pos = start + i - 1;
 | 
			
		||||
		  newline_len = 1;
 | 
			
		||||
		}
 | 
			
		||||
	      /* Don't check for CR here, instead look at last_saw_cr on next byte */
 | 
			
		||||
	      break;
 | 
			
		||||
	    }
 | 
			
		||||
	  
 | 
			
		||||
	  last_saw_cr = (buffer[i] == 13);
 | 
			
		||||
 | 
			
		||||
	  if (found_pos != -1)
 | 
			
		||||
	    {
 | 
			
		||||
	      *newline_len_out = newline_len;
 | 
			
		||||
	      return found_pos;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
      checked = end;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  *checked_out = checked;
 | 
			
		||||
  *last_saw_cr_out = last_saw_cr;
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
		  
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_read_line:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @length: a #gsize to get the length of the data read in.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: #GError for error reporting.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns a string with the line that was read in. Set @length to 
 | 
			
		||||
 * a #gsize to get the length of the read line. This function will 
 | 
			
		||||
 * return %NULL on an error.
 | 
			
		||||
 **/
 | 
			
		||||
char *
 | 
			
		||||
g_data_input_stream_read_line (GDataInputStream        *stream,
 | 
			
		||||
			      gsize                   *length,
 | 
			
		||||
			      GCancellable            *cancellable,
 | 
			
		||||
			      GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  GBufferedInputStream *bstream;
 | 
			
		||||
  gsize checked;
 | 
			
		||||
  gboolean last_saw_cr;
 | 
			
		||||
  gssize found_pos;
 | 
			
		||||
  gssize res;
 | 
			
		||||
  int newline_len;
 | 
			
		||||
  char *line;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_INPUT_STREAM (stream), NULL);  
 | 
			
		||||
 | 
			
		||||
  bstream = G_BUFFERED_INPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  newline_len = 0;
 | 
			
		||||
  checked = 0;
 | 
			
		||||
  last_saw_cr = FALSE;
 | 
			
		||||
 | 
			
		||||
  while ((found_pos = scan_for_newline (stream, &checked, &last_saw_cr, &newline_len)) == -1)
 | 
			
		||||
    {
 | 
			
		||||
      if (g_buffered_input_stream_get_available (bstream) ==
 | 
			
		||||
	  g_buffered_input_stream_get_buffer_size (bstream))
 | 
			
		||||
	g_buffered_input_stream_set_buffer_size (bstream,
 | 
			
		||||
						 2 * g_buffered_input_stream_get_buffer_size (bstream));
 | 
			
		||||
 | 
			
		||||
      res = g_buffered_input_stream_fill (bstream, -1, cancellable, error);
 | 
			
		||||
      if (res < 0)
 | 
			
		||||
	return NULL;
 | 
			
		||||
      if (res == 0)
 | 
			
		||||
	{
 | 
			
		||||
	  /* End of stream */
 | 
			
		||||
	  if (g_buffered_input_stream_get_available (bstream) == 0)
 | 
			
		||||
	    {
 | 
			
		||||
	      if (length)
 | 
			
		||||
		*length = 0;
 | 
			
		||||
	      return NULL;
 | 
			
		||||
	    }
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
	      found_pos = checked;
 | 
			
		||||
	      newline_len = 0;
 | 
			
		||||
	      break;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  line = g_malloc (found_pos + newline_len + 1);
 | 
			
		||||
 | 
			
		||||
  res = g_input_stream_read (G_INPUT_STREAM (stream),
 | 
			
		||||
			     line,
 | 
			
		||||
			     found_pos + newline_len,
 | 
			
		||||
			     NULL, NULL);
 | 
			
		||||
  if (length)
 | 
			
		||||
    *length = (gsize)found_pos;
 | 
			
		||||
  g_assert (res == found_pos + newline_len);
 | 
			
		||||
  line[found_pos] = 0;
 | 
			
		||||
  
 | 
			
		||||
  return line;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_input_stream_read_until:
 | 
			
		||||
 * @stream: a given #GDataInputStream.
 | 
			
		||||
 * @stop_char: character to terminate the read.
 | 
			
		||||
 * @length: a #gsize to get the length of the data read in.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: #GError for error reporting.
 | 
			
		||||
 * 
 | 
			
		||||
 * NOTE: not supported for #GDataInputStream.
 | 
			
		||||
 * Returns %NULL.
 | 
			
		||||
 **/
 | 
			
		||||
char *
 | 
			
		||||
g_data_input_stream_read_until (GDataInputStream        *stream,
 | 
			
		||||
			       gchar                    stop_char,
 | 
			
		||||
			       gsize                   *length,
 | 
			
		||||
			       GCancellable            *cancellable,
 | 
			
		||||
			       GError                 **error)
 | 
			
		||||
{
 | 
			
		||||
  /* TODO: should be implemented */
 | 
			
		||||
  g_assert_not_reached ();
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										117
									
								
								gio/gdatainputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								gio/gdatainputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,117 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_DATA_INPUT_STREAM_H__
 | 
			
		||||
#define __G_DATA_INPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gbufferedinputstream.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_DATA_INPUT_STREAM         (g_data_input_stream_get_type ())
 | 
			
		||||
#define G_DATA_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DATA_INPUT_STREAM, GDataInputStream))
 | 
			
		||||
#define G_DATA_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DATA_INPUT_STREAM, GDataInputStreamClass))
 | 
			
		||||
#define G_IS_DATA_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DATA_INPUT_STREAM))
 | 
			
		||||
#define G_IS_DATA_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DATA_INPUT_STREAM))
 | 
			
		||||
#define G_DATA_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DATA_INPUT_STREAM, GDataInputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GDataInputStream         GDataInputStream;
 | 
			
		||||
typedef struct _GDataInputStreamClass    GDataInputStreamClass;
 | 
			
		||||
typedef struct _GDataInputStreamPrivate  GDataInputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GDataInputStream
 | 
			
		||||
{
 | 
			
		||||
  GBufferedInputStream parent;
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GDataInputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GDataInputStreamClass
 | 
			
		||||
{
 | 
			
		||||
 GBufferedInputStreamClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef enum  {
 | 
			
		||||
  G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN,
 | 
			
		||||
  G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN,
 | 
			
		||||
  G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN
 | 
			
		||||
} GDataStreamByteOrder;
 | 
			
		||||
 | 
			
		||||
typedef enum  {
 | 
			
		||||
  G_DATA_STREAM_NEWLINE_TYPE_LF,
 | 
			
		||||
  G_DATA_STREAM_NEWLINE_TYPE_CR,
 | 
			
		||||
  G_DATA_STREAM_NEWLINE_TYPE_CR_LF,
 | 
			
		||||
  G_DATA_STREAM_NEWLINE_TYPE_ANY
 | 
			
		||||
} GDataStreamNewlineType;
 | 
			
		||||
 | 
			
		||||
GType          g_data_input_stream_get_type   (void) G_GNUC_CONST;
 | 
			
		||||
GDataInputStream*  g_data_input_stream_new        (GInputStream *base_stream);
 | 
			
		||||
 | 
			
		||||
void                   g_data_input_stream_set_byte_order   (GDataInputStream        *stream,
 | 
			
		||||
							     GDataStreamByteOrder     order);
 | 
			
		||||
GDataStreamByteOrder   g_data_input_stream_get_byte_order   (GDataInputStream        *stream);
 | 
			
		||||
void                   g_data_input_stream_set_newline_type (GDataInputStream        *data_stream,
 | 
			
		||||
							     GDataStreamNewlineType   type);
 | 
			
		||||
GDataStreamNewlineType g_data_input_stream_get_newline_type (GDataInputStream        *stream);
 | 
			
		||||
guchar                 g_data_input_stream_read_byte        (GDataInputStream        *stream,
 | 
			
		||||
							     GCancellable            *cancellable,
 | 
			
		||||
							     GError                 **error);
 | 
			
		||||
gint16                 g_data_input_stream_read_int16       (GDataInputStream        *stream,
 | 
			
		||||
							     GCancellable            *cancellable,
 | 
			
		||||
							     GError                 **error);
 | 
			
		||||
guint16                g_data_input_stream_read_uint16      (GDataInputStream        *stream,
 | 
			
		||||
							     GCancellable            *cancellable,
 | 
			
		||||
							     GError                 **error);
 | 
			
		||||
gint32                 g_data_input_stream_read_int32       (GDataInputStream        *stream,
 | 
			
		||||
							     GCancellable            *cancellable,
 | 
			
		||||
							     GError                 **error);
 | 
			
		||||
guint32                g_data_input_stream_read_uint32      (GDataInputStream        *stream,
 | 
			
		||||
							     GCancellable            *cancellable,
 | 
			
		||||
							     GError                 **error);
 | 
			
		||||
gint64                 g_data_input_stream_read_int64       (GDataInputStream        *stream,
 | 
			
		||||
							     GCancellable            *cancellable,
 | 
			
		||||
							     GError                 **error);
 | 
			
		||||
guint64                g_data_input_stream_read_uint64      (GDataInputStream        *stream,
 | 
			
		||||
							     GCancellable            *cancellable,
 | 
			
		||||
							     GError                 **error);
 | 
			
		||||
char *                 g_data_input_stream_read_line        (GDataInputStream        *stream,
 | 
			
		||||
							     gsize                   *length,
 | 
			
		||||
							     GCancellable            *cancellable,
 | 
			
		||||
							     GError                 **error);
 | 
			
		||||
char *                 g_data_input_stream_read_until       (GDataInputStream        *stream,
 | 
			
		||||
							     gchar                    stop_char,
 | 
			
		||||
							     gsize                   *length,
 | 
			
		||||
							     GCancellable            *cancellable,
 | 
			
		||||
							     GError                 **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_DATA_INPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										441
									
								
								gio/gdataoutputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								gio/gdataoutputstream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,441 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "gdataoutputstream.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
struct _GDataOutputStreamPrivate {
 | 
			
		||||
  GDataStreamByteOrder byte_order;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  PROP_0
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void g_data_output_stream_set_property (GObject      *object,
 | 
			
		||||
					       guint         prop_id,
 | 
			
		||||
					       const GValue *value,
 | 
			
		||||
					       GParamSpec   *pspec);
 | 
			
		||||
static void g_data_output_stream_get_property (GObject      *object,
 | 
			
		||||
					       guint         prop_id,
 | 
			
		||||
					       GValue       *value,
 | 
			
		||||
					       GParamSpec   *pspec);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GDataOutputStream,
 | 
			
		||||
               g_data_output_stream,
 | 
			
		||||
               G_TYPE_FILTER_OUTPUT_STREAM)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_data_output_stream_class_init (GDataOutputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class;
 | 
			
		||||
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GDataOutputStreamPrivate));
 | 
			
		||||
 | 
			
		||||
  object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  object_class->get_property = g_data_output_stream_get_property;
 | 
			
		||||
  object_class->set_property = g_data_output_stream_set_property;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_data_output_stream_set_property (GObject         *object,
 | 
			
		||||
				  guint            prop_id,
 | 
			
		||||
				  const GValue    *value,
 | 
			
		||||
				  GParamSpec      *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GDataOutputStreamPrivate *priv;
 | 
			
		||||
  GDataOutputStream        *dstream;
 | 
			
		||||
 | 
			
		||||
  dstream = G_DATA_OUTPUT_STREAM (object);
 | 
			
		||||
  priv = dstream->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id) 
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_data_output_stream_get_property (GObject    *object,
 | 
			
		||||
				   guint       prop_id,
 | 
			
		||||
				   GValue     *value,
 | 
			
		||||
				   GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GDataOutputStreamPrivate *priv;
 | 
			
		||||
  GDataOutputStream        *dstream;
 | 
			
		||||
 | 
			
		||||
  dstream = G_DATA_OUTPUT_STREAM (object);
 | 
			
		||||
  priv = dstream->priv;
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    { 
 | 
			
		||||
  
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
static void
 | 
			
		||||
g_data_output_stream_init (GDataOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
 | 
			
		||||
                                              G_TYPE_DATA_OUTPUT_STREAM,
 | 
			
		||||
                                              GDataOutputStreamPrivate);
 | 
			
		||||
 | 
			
		||||
  stream->priv->byte_order = G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_new:
 | 
			
		||||
 * @base_stream: a #GOutputStream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: #GDataOutputStream.
 | 
			
		||||
 **/
 | 
			
		||||
GDataOutputStream *
 | 
			
		||||
g_data_output_stream_new (GOutputStream *base_stream)
 | 
			
		||||
{
 | 
			
		||||
  GDataOutputStream *stream;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_OUTPUT_STREAM (base_stream), NULL);
 | 
			
		||||
 | 
			
		||||
  stream = g_object_new (G_TYPE_DATA_OUTPUT_STREAM,
 | 
			
		||||
                         "base-stream", base_stream,
 | 
			
		||||
                         NULL);
 | 
			
		||||
 | 
			
		||||
  return stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_set_byte_order:
 | 
			
		||||
 * @stream: a #GDataOutputStream. a #GDataOutputStream.
 | 
			
		||||
 * @order: a %GDataStreamByteOrder.
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_data_output_stream_set_byte_order (GDataOutputStream *stream,
 | 
			
		||||
				    GDataStreamByteOrder order)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_DATA_OUTPUT_STREAM (stream));
 | 
			
		||||
 | 
			
		||||
  stream->priv->byte_order = order;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_get_byte_order:
 | 
			
		||||
 * @stream: a #GDataOutputStream. a #GDataOutputStream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: the %GDataStreamByteOrder for the @stream.
 | 
			
		||||
 **/
 | 
			
		||||
GDataStreamByteOrder
 | 
			
		||||
g_data_output_stream_get_byte_order (GDataOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN);
 | 
			
		||||
 | 
			
		||||
  return stream->priv->byte_order;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_put_byte:
 | 
			
		||||
 * @data_stream: a #GDataOutputStream.
 | 
			
		||||
 * @data: a #guchar.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @data was successfully added to the @stream.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_data_output_stream_put_byte (GDataOutputStream     *data_stream,
 | 
			
		||||
			       guchar                 data,
 | 
			
		||||
			       GCancellable          *cancellable,
 | 
			
		||||
			       GError               **error)
 | 
			
		||||
{
 | 
			
		||||
  gsize bytes_written;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (data_stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  return g_output_stream_write_all (G_OUTPUT_STREAM (data_stream),
 | 
			
		||||
				    &data, 1,
 | 
			
		||||
				    &bytes_written,
 | 
			
		||||
				    cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_put_int16:
 | 
			
		||||
 * @stream: a #GDataOutputStream. a #GDataOutputStream.
 | 
			
		||||
 * @data: a #gint16.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @data was successfully added to the @stream.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_data_output_stream_put_int16 (GDataOutputStream     *stream,
 | 
			
		||||
				gint16                 data,
 | 
			
		||||
				GCancellable          *cancellable,
 | 
			
		||||
				GError               **error)
 | 
			
		||||
{
 | 
			
		||||
  gsize bytes_written;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  switch (stream->priv->byte_order)
 | 
			
		||||
    {
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
      data = GINT16_TO_BE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
      data = GINT16_TO_LE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
 | 
			
		||||
				    &data, 2,
 | 
			
		||||
				    &bytes_written,
 | 
			
		||||
				    cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_put_uint16:
 | 
			
		||||
 * @stream: a #GDataOutputStream. a #GDataOutputStream.
 | 
			
		||||
 * @data: a #guint16.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @data was successfully added to the @stream.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_data_output_stream_put_uint16 (GDataOutputStream     *stream,
 | 
			
		||||
				 guint16                data,
 | 
			
		||||
				 GCancellable          *cancellable,
 | 
			
		||||
				 GError               **error)
 | 
			
		||||
{
 | 
			
		||||
  gsize bytes_written;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  switch (stream->priv->byte_order)
 | 
			
		||||
    {
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
      data = GUINT16_TO_BE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
      data = GUINT16_TO_LE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
 | 
			
		||||
				    &data, 2,
 | 
			
		||||
				    &bytes_written,
 | 
			
		||||
				    cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_put_int32:
 | 
			
		||||
 * @stream: a #GDataOutputStream. a #GDataOutputStream.
 | 
			
		||||
 * @data: a #gint32.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @data was successfully added to the @stream.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_data_output_stream_put_int32 (GDataOutputStream     *stream,
 | 
			
		||||
				gint32                 data,
 | 
			
		||||
				GCancellable          *cancellable,
 | 
			
		||||
				GError               **error)
 | 
			
		||||
{
 | 
			
		||||
  gsize bytes_written;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  switch (stream->priv->byte_order)
 | 
			
		||||
    {
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
      data = GINT32_TO_BE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
      data = GINT32_TO_LE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
 | 
			
		||||
				    &data, 4,
 | 
			
		||||
				    &bytes_written,
 | 
			
		||||
				    cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_put_uint32:
 | 
			
		||||
 * @stream: a #GDataOutputStream. a #GDataOutputStream.
 | 
			
		||||
 * @data: a #guint32.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @data was successfully added to the @stream.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_data_output_stream_put_uint32 (GDataOutputStream     *stream,
 | 
			
		||||
				 guint32                data,
 | 
			
		||||
				 GCancellable          *cancellable,
 | 
			
		||||
				 GError               **error)
 | 
			
		||||
{
 | 
			
		||||
  gsize bytes_written;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  switch (stream->priv->byte_order)
 | 
			
		||||
    {
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
      data = GUINT32_TO_BE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
      data = GUINT32_TO_LE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
 | 
			
		||||
				    &data, 4,
 | 
			
		||||
				    &bytes_written,
 | 
			
		||||
				    cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_put_int64:
 | 
			
		||||
 * @stream: a #GDataOutputStream. a #GDataOutputStream.
 | 
			
		||||
 * @data: a #gint64.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @data was successfully added to the @stream.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_data_output_stream_put_int64 (GDataOutputStream     *stream,
 | 
			
		||||
				gint64                 data,
 | 
			
		||||
				GCancellable          *cancellable,
 | 
			
		||||
				GError               **error)
 | 
			
		||||
{
 | 
			
		||||
  gsize bytes_written;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  switch (stream->priv->byte_order)
 | 
			
		||||
    {
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
      data = GINT64_TO_BE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
      data = GINT64_TO_LE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
 | 
			
		||||
				    &data, 8,
 | 
			
		||||
				    &bytes_written,
 | 
			
		||||
				    cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_put_uint64:
 | 
			
		||||
 * @stream: a #GDataOutputStream. a #GDataOutputStream.
 | 
			
		||||
 * @data: a #guint64.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @data was successfully added to the @stream.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_data_output_stream_put_uint64 (GDataOutputStream     *stream,
 | 
			
		||||
				 guint64                data,
 | 
			
		||||
				 GCancellable          *cancellable,
 | 
			
		||||
				 GError               **error)
 | 
			
		||||
{
 | 
			
		||||
  gsize bytes_written;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  switch (stream->priv->byte_order)
 | 
			
		||||
    {
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN:
 | 
			
		||||
      data = GUINT64_TO_BE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN:
 | 
			
		||||
      data = GUINT64_TO_LE (data);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN:
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
 | 
			
		||||
				    &data, 8,
 | 
			
		||||
				    &bytes_written,
 | 
			
		||||
				    cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_data_output_stream_put_string:
 | 
			
		||||
 * @stream: a #GDataOutputStream.
 | 
			
		||||
 * @str: a string.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @data was successfully added to the @stream.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_data_output_stream_put_string (GDataOutputStream     *stream,
 | 
			
		||||
				 const char            *str,
 | 
			
		||||
				 GCancellable          *cancellable,
 | 
			
		||||
				 GError               **error)
 | 
			
		||||
{
 | 
			
		||||
  gsize bytes_written;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DATA_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
  g_return_val_if_fail (str != NULL, FALSE);
 | 
			
		||||
 | 
			
		||||
  return g_output_stream_write_all (G_OUTPUT_STREAM (stream),
 | 
			
		||||
				    str, strlen (str),
 | 
			
		||||
				    &bytes_written,
 | 
			
		||||
				    cancellable, error);
 | 
			
		||||
}  
 | 
			
		||||
							
								
								
									
										108
									
								
								gio/gdataoutputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								gio/gdataoutputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_DATA_OUTPUT_STREAM_H__
 | 
			
		||||
#define __G_DATA_OUTPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gfilteroutputstream.h>
 | 
			
		||||
#include <gio/gdatainputstream.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_DATA_OUTPUT_STREAM         (g_data_output_stream_get_type ())
 | 
			
		||||
#define G_DATA_OUTPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DATA_OUTPUT_STREAM, GDataOutputStream))
 | 
			
		||||
#define G_DATA_OUTPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DATA_OUTPUT_STREAM, GDataOutputStreamClass))
 | 
			
		||||
#define G_IS_DATA_OUTPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DATA_OUTPUT_STREAM))
 | 
			
		||||
#define G_IS_DATA_OUTPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DATA_OUTPUT_STREAM))
 | 
			
		||||
#define G_DATA_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DATA_OUTPUT_STREAM, GDataOutputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GDataOutputStream         GDataOutputStream;
 | 
			
		||||
typedef struct _GDataOutputStreamClass    GDataOutputStreamClass;
 | 
			
		||||
typedef struct _GDataOutputStreamPrivate  GDataOutputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GDataOutputStream
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream parent;
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GDataOutputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GDataOutputStreamClass
 | 
			
		||||
{
 | 
			
		||||
 GFilterOutputStreamClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GType          g_data_output_stream_get_type   (void) G_GNUC_CONST;
 | 
			
		||||
GDataOutputStream*  g_data_output_stream_new        (GOutputStream *base_stream);
 | 
			
		||||
 | 
			
		||||
void                 g_data_output_stream_set_byte_order (GDataOutputStream     *data_stream,
 | 
			
		||||
							  GDataStreamByteOrder   order);
 | 
			
		||||
GDataStreamByteOrder g_data_output_stream_get_byte_order (GDataOutputStream     *stream);
 | 
			
		||||
void                 g_data_output_stream_set_expand_buffer (GDataOutputStream     *data_stream,
 | 
			
		||||
							     gboolean               expand_buffer);
 | 
			
		||||
 | 
			
		||||
gboolean             g_data_output_stream_put_byte       (GDataOutputStream     *data_stream,
 | 
			
		||||
							  guchar                 data,
 | 
			
		||||
							  GCancellable          *cancellable,
 | 
			
		||||
							  GError               **error);
 | 
			
		||||
gboolean             g_data_output_stream_put_int16      (GDataOutputStream     *stream,
 | 
			
		||||
							  gint16                 data,
 | 
			
		||||
							  GCancellable          *cancellable,
 | 
			
		||||
							  GError               **error);
 | 
			
		||||
gboolean             g_data_output_stream_put_uint16     (GDataOutputStream     *stream,
 | 
			
		||||
							  guint16                data,
 | 
			
		||||
							  GCancellable          *cancellable,
 | 
			
		||||
							  GError               **error);
 | 
			
		||||
gboolean             g_data_output_stream_put_int32      (GDataOutputStream     *stream,
 | 
			
		||||
							  gint32                 data,
 | 
			
		||||
							  GCancellable          *cancellable,
 | 
			
		||||
							  GError               **error);
 | 
			
		||||
gboolean             g_data_output_stream_put_uint32     (GDataOutputStream     *stream,
 | 
			
		||||
							  guint32                data,
 | 
			
		||||
							  GCancellable          *cancellable,
 | 
			
		||||
							  GError               **error);
 | 
			
		||||
gboolean             g_data_output_stream_put_int64      (GDataOutputStream     *stream,
 | 
			
		||||
							  gint64                 data,
 | 
			
		||||
							  GCancellable          *cancellable,
 | 
			
		||||
							  GError               **error);
 | 
			
		||||
gboolean             g_data_output_stream_put_uint64     (GDataOutputStream     *stream,
 | 
			
		||||
							  guint64                data,
 | 
			
		||||
							  GCancellable          *cancellable,
 | 
			
		||||
							  GError               **error);
 | 
			
		||||
gboolean             g_data_output_stream_put_string     (GDataOutputStream     *stream,
 | 
			
		||||
							  const char            *str,
 | 
			
		||||
							  GCancellable          *cancellable,
 | 
			
		||||
							  GError               **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_DATA_OUTPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										2185
									
								
								gio/gdesktopappinfo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2185
									
								
								gio/gdesktopappinfo.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										54
									
								
								gio/gdesktopappinfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								gio/gdesktopappinfo.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_DESKTOP_APP_INFO_H__
 | 
			
		||||
#define __G_DESKTOP_APP_INFO_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gappinfo.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_DESKTOP_APP_INFO         (g_desktop_app_info_get_type ())
 | 
			
		||||
#define G_DESKTOP_APP_INFO(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DESKTOP_APP_INFO, GDesktopAppInfo))
 | 
			
		||||
#define G_DESKTOP_APP_INFO_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DESKTOP_APP_INFO, GDesktopAppInfoClass))
 | 
			
		||||
#define G_IS_DESKTOP_APP_INFO(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DESKTOP_APP_INFO))
 | 
			
		||||
#define G_IS_DESKTOP_APP_INFO_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DESKTOP_APP_INFO))
 | 
			
		||||
#define G_DESKTOP_APP_INFO_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DESKTOP_APP_INFO, GDesktopAppInfoClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GDesktopAppInfo        GDesktopAppInfo;
 | 
			
		||||
typedef struct _GDesktopAppInfoClass   GDesktopAppInfoClass;
 | 
			
		||||
 | 
			
		||||
struct _GDesktopAppInfoClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_desktop_app_info_get_type (void) G_GNUC_CONST;
 | 
			
		||||
  
 | 
			
		||||
GDesktopAppInfo *g_desktop_app_info_new_from_filename (const char      *filename);
 | 
			
		||||
GDesktopAppInfo *g_desktop_app_info_new               (const char      *desktop_id);
 | 
			
		||||
gboolean         g_desktop_app_info_get_is_hidden     (GDesktopAppInfo *info);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __G_DESKTOP_APP_INFO_H__ */
 | 
			
		||||
							
								
								
									
										472
									
								
								gio/gdirectorymonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										472
									
								
								gio/gdirectorymonitor.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,472 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "gdirectorymonitor.h"
 | 
			
		||||
#include "gio-marshal.h"
 | 
			
		||||
#include "gfile.h"
 | 
			
		||||
#include "gvfs.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  CHANGED,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (GDirectoryMonitor, g_directory_monitor, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  GFile *file;
 | 
			
		||||
  guint32 last_sent_change_time; /* 0 == not sent */
 | 
			
		||||
  guint32 send_delayed_change_at; /* 0 == never */
 | 
			
		||||
  guint32 send_virtual_changes_done_at; /* 0 == never */
 | 
			
		||||
} RateLimiter;
 | 
			
		||||
 | 
			
		||||
struct _GDirectoryMonitorPrivate {
 | 
			
		||||
  gboolean cancelled;
 | 
			
		||||
  int rate_limit_msec;
 | 
			
		||||
 | 
			
		||||
  GHashTable *rate_limiter;
 | 
			
		||||
  
 | 
			
		||||
  GSource *timeout;
 | 
			
		||||
  guint32 timeout_fires_at;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_RATE_LIMIT_MSECS 800
 | 
			
		||||
#define DEFAULT_VIRTUAL_CHANGES_DONE_DELAY_SECS 2
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
rate_limiter_free (RateLimiter *limiter)
 | 
			
		||||
{
 | 
			
		||||
  g_object_unref (limiter->file);
 | 
			
		||||
  g_free (limiter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_directory_monitor_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GDirectoryMonitor *monitor;
 | 
			
		||||
 | 
			
		||||
  monitor = G_DIRECTORY_MONITOR (object);
 | 
			
		||||
 | 
			
		||||
  if (monitor->priv->timeout)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_destroy (monitor->priv->timeout);
 | 
			
		||||
      g_source_unref (monitor->priv->timeout);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_hash_table_destroy (monitor->priv->rate_limiter);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_directory_monitor_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_directory_monitor_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_directory_monitor_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GDirectoryMonitor *monitor;
 | 
			
		||||
  
 | 
			
		||||
  monitor = G_DIRECTORY_MONITOR (object);
 | 
			
		||||
 | 
			
		||||
  /* Make sure we cancel on last unref */
 | 
			
		||||
  if (!monitor->priv->cancelled)
 | 
			
		||||
    g_directory_monitor_cancel (monitor);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_directory_monitor_parent_class)->dispose)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_directory_monitor_parent_class)->dispose) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_directory_monitor_class_init (GDirectoryMonitorClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GDirectoryMonitorPrivate));
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_directory_monitor_finalize;
 | 
			
		||||
  gobject_class->dispose = g_directory_monitor_dispose;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * GDirectoryMonitor::changed:
 | 
			
		||||
   * @monitor: the #GDirectoryMonitor
 | 
			
		||||
   * @child: the #GFile which changed
 | 
			
		||||
   * @other_file: the other #GFile which changed
 | 
			
		||||
   * @event_type: a #GFileMonitorEvent indicating what the event was
 | 
			
		||||
   *
 | 
			
		||||
   * Emitted when a child file changes.
 | 
			
		||||
   */
 | 
			
		||||
  signals[CHANGED] =
 | 
			
		||||
    g_signal_new (I_("changed"),
 | 
			
		||||
		  G_TYPE_DIRECTORY_MONITOR,
 | 
			
		||||
		  G_SIGNAL_RUN_LAST,
 | 
			
		||||
		  G_STRUCT_OFFSET (GDirectoryMonitorClass, changed),
 | 
			
		||||
		  NULL, NULL,
 | 
			
		||||
		  _gio_marshal_VOID__OBJECT_OBJECT_INT,
 | 
			
		||||
		  G_TYPE_NONE,3,
 | 
			
		||||
		  G_TYPE_FILE,
 | 
			
		||||
		  G_TYPE_FILE,
 | 
			
		||||
		  G_TYPE_INT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_directory_monitor_init (GDirectoryMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
  monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
 | 
			
		||||
					       G_TYPE_DIRECTORY_MONITOR,
 | 
			
		||||
					       GDirectoryMonitorPrivate);
 | 
			
		||||
 | 
			
		||||
  monitor->priv->rate_limit_msec = DEFAULT_RATE_LIMIT_MSECS;
 | 
			
		||||
  monitor->priv->rate_limiter = g_hash_table_new_full (g_file_hash, (GEqualFunc)g_file_equal,
 | 
			
		||||
						       NULL, (GDestroyNotify) rate_limiter_free);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_directory_monitor_cancel:
 | 
			
		||||
 * @monitor:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_directory_monitor_cancel (GDirectoryMonitor* monitor)
 | 
			
		||||
{
 | 
			
		||||
  GDirectoryMonitorClass *class;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DIRECTORY_MONITOR (monitor), FALSE);
 | 
			
		||||
  
 | 
			
		||||
  if (monitor->priv->cancelled)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  
 | 
			
		||||
  monitor->priv->cancelled = TRUE;
 | 
			
		||||
  
 | 
			
		||||
  class = G_DIRECTORY_MONITOR_GET_CLASS (monitor);
 | 
			
		||||
  return (* class->cancel) (monitor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_directory_monitor_set_rate_limit:
 | 
			
		||||
 * @monitor:
 | 
			
		||||
 * @limit_msecs:
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_directory_monitor_set_rate_limit (GDirectoryMonitor *monitor,
 | 
			
		||||
				    int limit_msecs)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_DIRECTORY_MONITOR (monitor));
 | 
			
		||||
 | 
			
		||||
  monitor->priv->rate_limit_msec = limit_msecs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_directory_monitor_is_cancelled:
 | 
			
		||||
 * @monitor:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_directory_monitor_is_cancelled (GDirectoryMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_DIRECTORY_MONITOR (monitor), FALSE);
 | 
			
		||||
 | 
			
		||||
  return monitor->priv->cancelled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static guint32
 | 
			
		||||
get_time_msecs (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_thread_gettime() / (1000 * 1000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static guint32
 | 
			
		||||
time_difference (guint32 from, guint32 to)
 | 
			
		||||
{
 | 
			
		||||
  if (from > to)
 | 
			
		||||
    return 0;
 | 
			
		||||
  return to - from;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static RateLimiter *
 | 
			
		||||
new_limiter (GDirectoryMonitor *monitor,
 | 
			
		||||
	     GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  RateLimiter *limiter;
 | 
			
		||||
 | 
			
		||||
  limiter = g_new0 (RateLimiter, 1);
 | 
			
		||||
  limiter->file = g_object_ref (file);
 | 
			
		||||
  g_hash_table_insert (monitor->priv->rate_limiter, file, limiter);
 | 
			
		||||
  
 | 
			
		||||
  return limiter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
rate_limiter_send_virtual_changes_done_now (GDirectoryMonitor *monitor, RateLimiter *limiter)
 | 
			
		||||
{
 | 
			
		||||
  if (limiter->send_virtual_changes_done_at != 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_emit (monitor, signals[CHANGED], 0, limiter->file, NULL, G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT);
 | 
			
		||||
      limiter->send_virtual_changes_done_at = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
rate_limiter_send_delayed_change_now (GDirectoryMonitor *monitor, RateLimiter *limiter, guint32 time_now)
 | 
			
		||||
{
 | 
			
		||||
  if (limiter->send_delayed_change_at != 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_emit (monitor, signals[CHANGED], 0, limiter->file, NULL, G_FILE_MONITOR_EVENT_CHANGED);
 | 
			
		||||
      limiter->send_delayed_change_at = 0;
 | 
			
		||||
      limiter->last_sent_change_time = time_now;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  guint32 min_time;
 | 
			
		||||
  guint32 time_now;
 | 
			
		||||
  GDirectoryMonitor *monitor;
 | 
			
		||||
} ForEachData;
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
calc_min_time (GDirectoryMonitor *monitor, RateLimiter *limiter, guint32 time_now, guint32 *min_time)
 | 
			
		||||
{
 | 
			
		||||
  gboolean delete_me;
 | 
			
		||||
  guint32 expire_at;
 | 
			
		||||
 | 
			
		||||
  delete_me = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (limiter->last_sent_change_time != 0)
 | 
			
		||||
    {
 | 
			
		||||
      /* Set a timeout at 2*rate limit so that we can clear out the change from the hash eventualy */
 | 
			
		||||
      expire_at = limiter->last_sent_change_time + 2 * monitor->priv->rate_limit_msec;
 | 
			
		||||
 | 
			
		||||
      if (time_difference (time_now, expire_at) > 0)
 | 
			
		||||
	{
 | 
			
		||||
	  delete_me = FALSE;
 | 
			
		||||
	  *min_time = MIN (*min_time,
 | 
			
		||||
			   time_difference (time_now, expire_at));
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (limiter->send_delayed_change_at != 0)
 | 
			
		||||
    {
 | 
			
		||||
      delete_me = FALSE;
 | 
			
		||||
      *min_time = MIN (*min_time,
 | 
			
		||||
		       time_difference (time_now, limiter->send_delayed_change_at));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (limiter->send_virtual_changes_done_at != 0)
 | 
			
		||||
    {
 | 
			
		||||
      delete_me = FALSE;
 | 
			
		||||
      *min_time = MIN (*min_time,
 | 
			
		||||
		       time_difference (time_now, limiter->send_virtual_changes_done_at));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return delete_me;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
foreach_rate_limiter_fire (gpointer  key,
 | 
			
		||||
			   gpointer  value,
 | 
			
		||||
			   gpointer  user_data)
 | 
			
		||||
{
 | 
			
		||||
  RateLimiter *limiter = value;
 | 
			
		||||
  ForEachData *data = user_data;
 | 
			
		||||
 | 
			
		||||
  if (limiter->send_delayed_change_at != 0 &&
 | 
			
		||||
      time_difference (data->time_now, limiter->send_delayed_change_at) == 0)
 | 
			
		||||
    rate_limiter_send_delayed_change_now (data->monitor, limiter, data->time_now);
 | 
			
		||||
 | 
			
		||||
  if (limiter->send_virtual_changes_done_at != 0 &&
 | 
			
		||||
      time_difference (data->time_now, limiter->send_virtual_changes_done_at) == 0)
 | 
			
		||||
    rate_limiter_send_virtual_changes_done_now (data->monitor, limiter);
 | 
			
		||||
 | 
			
		||||
  return calc_min_time (data->monitor, limiter, data->time_now, &data->min_time);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean 
 | 
			
		||||
rate_limiter_timeout (gpointer timeout_data)
 | 
			
		||||
{
 | 
			
		||||
  GDirectoryMonitor *monitor = timeout_data;
 | 
			
		||||
  ForEachData data;
 | 
			
		||||
  GSource *source;
 | 
			
		||||
  
 | 
			
		||||
  data.min_time = G_MAXUINT32;
 | 
			
		||||
  data.monitor = monitor;
 | 
			
		||||
  data.time_now = get_time_msecs ();
 | 
			
		||||
  g_hash_table_foreach_remove (monitor->priv->rate_limiter,
 | 
			
		||||
			       foreach_rate_limiter_fire,
 | 
			
		||||
			       &data);
 | 
			
		||||
 | 
			
		||||
  /* Remove old timeout */
 | 
			
		||||
  if (monitor->priv->timeout)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_destroy (monitor->priv->timeout);
 | 
			
		||||
      g_source_unref (monitor->priv->timeout);
 | 
			
		||||
      monitor->priv->timeout = NULL;
 | 
			
		||||
      monitor->priv->timeout_fires_at = 0;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  /* Set up new timeout */
 | 
			
		||||
  if (data.min_time != G_MAXUINT32)
 | 
			
		||||
    {
 | 
			
		||||
      source = g_timeout_source_new (data.min_time + 1); /* + 1 to make sure we've really passed the time */
 | 
			
		||||
      g_source_set_callback (source, rate_limiter_timeout, monitor, NULL);
 | 
			
		||||
      g_source_attach (source, NULL);
 | 
			
		||||
      
 | 
			
		||||
      monitor->priv->timeout = source;
 | 
			
		||||
      monitor->priv->timeout_fires_at = data.time_now + data.min_time; 
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
foreach_rate_limiter_update (gpointer  key,
 | 
			
		||||
			     gpointer  value,
 | 
			
		||||
			     gpointer  user_data)
 | 
			
		||||
{
 | 
			
		||||
  RateLimiter *limiter = value;
 | 
			
		||||
  ForEachData *data = user_data;
 | 
			
		||||
 | 
			
		||||
  return calc_min_time (data->monitor, limiter, data->time_now, &data->min_time);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_rate_limiter_timeout (GDirectoryMonitor *monitor, guint new_time)
 | 
			
		||||
{
 | 
			
		||||
  ForEachData data;
 | 
			
		||||
  GSource *source;
 | 
			
		||||
  
 | 
			
		||||
  if (monitor->priv->timeout_fires_at != 0 && new_time != 0 &&
 | 
			
		||||
      time_difference (new_time, monitor->priv->timeout_fires_at) == 0)
 | 
			
		||||
    return; /* Nothing to do, we already fire earlier than that */
 | 
			
		||||
 | 
			
		||||
  data.min_time = G_MAXUINT32;
 | 
			
		||||
  data.monitor = monitor;
 | 
			
		||||
  data.time_now = get_time_msecs ();
 | 
			
		||||
  g_hash_table_foreach_remove (monitor->priv->rate_limiter,
 | 
			
		||||
			       foreach_rate_limiter_update,
 | 
			
		||||
			       &data);
 | 
			
		||||
 | 
			
		||||
  /* Remove old timeout */
 | 
			
		||||
  if (monitor->priv->timeout)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_destroy (monitor->priv->timeout);
 | 
			
		||||
      g_source_unref (monitor->priv->timeout);
 | 
			
		||||
      monitor->priv->timeout_fires_at = 0;
 | 
			
		||||
      monitor->priv->timeout = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Set up new timeout */
 | 
			
		||||
  if (data.min_time != G_MAXUINT32)
 | 
			
		||||
    {
 | 
			
		||||
      source = g_timeout_source_new (data.min_time + 1);  /* + 1 to make sure we've really passed the time */
 | 
			
		||||
      g_source_set_callback (source, rate_limiter_timeout, monitor, NULL);
 | 
			
		||||
      g_source_attach (source, NULL);
 | 
			
		||||
      
 | 
			
		||||
      monitor->priv->timeout = source;
 | 
			
		||||
      monitor->priv->timeout_fires_at = data.time_now + data.min_time; 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_directory_monitor_emit_event:
 | 
			
		||||
 * @monitor:
 | 
			
		||||
 * @child:
 | 
			
		||||
 * @other_file:
 | 
			
		||||
 * @event_type:
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_directory_monitor_emit_event (GDirectoryMonitor *monitor,
 | 
			
		||||
				GFile *child,
 | 
			
		||||
				GFile *other_file,
 | 
			
		||||
				GFileMonitorEvent event_type)
 | 
			
		||||
{
 | 
			
		||||
  guint32 time_now, since_last;
 | 
			
		||||
  gboolean emit_now;
 | 
			
		||||
  RateLimiter *limiter;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_DIRECTORY_MONITOR (monitor));
 | 
			
		||||
  g_return_if_fail (G_IS_FILE (child));
 | 
			
		||||
 | 
			
		||||
  limiter = g_hash_table_lookup (monitor->priv->rate_limiter, child);
 | 
			
		||||
 | 
			
		||||
  if (event_type != G_FILE_MONITOR_EVENT_CHANGED)
 | 
			
		||||
    {
 | 
			
		||||
      if (limiter)
 | 
			
		||||
	{
 | 
			
		||||
	  rate_limiter_send_delayed_change_now (monitor, limiter, get_time_msecs ());
 | 
			
		||||
	  if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
 | 
			
		||||
	    limiter->send_virtual_changes_done_at = 0;
 | 
			
		||||
	  else
 | 
			
		||||
	    rate_limiter_send_virtual_changes_done_now (monitor, limiter);
 | 
			
		||||
	  update_rate_limiter_timeout (monitor, 0);
 | 
			
		||||
	}
 | 
			
		||||
      g_signal_emit (monitor, signals[CHANGED], 0, child, other_file, event_type);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* Changed event, rate limit */
 | 
			
		||||
      time_now = get_time_msecs ();
 | 
			
		||||
      emit_now = TRUE;
 | 
			
		||||
      
 | 
			
		||||
      if (limiter)
 | 
			
		||||
	{
 | 
			
		||||
	  since_last = time_difference (limiter->last_sent_change_time, time_now);
 | 
			
		||||
	  if (since_last < monitor->priv->rate_limit_msec)
 | 
			
		||||
	    {
 | 
			
		||||
	      /* We ignore this change, but arm a timer so that we can fire it later if we
 | 
			
		||||
		 don't get any other events (that kill this timeout) */
 | 
			
		||||
	      emit_now = FALSE;
 | 
			
		||||
	      if (limiter->send_delayed_change_at == 0)
 | 
			
		||||
		{
 | 
			
		||||
		  limiter->send_delayed_change_at = time_now + monitor->priv->rate_limit_msec;
 | 
			
		||||
		  update_rate_limiter_timeout (monitor, limiter->send_delayed_change_at);
 | 
			
		||||
		}
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      if (limiter == NULL)
 | 
			
		||||
	limiter = new_limiter (monitor, child);
 | 
			
		||||
      
 | 
			
		||||
      if (emit_now)
 | 
			
		||||
	{
 | 
			
		||||
	  g_signal_emit (monitor, signals[CHANGED], 0, child, other_file, event_type);
 | 
			
		||||
 | 
			
		||||
	  limiter->last_sent_change_time = time_now;
 | 
			
		||||
	  limiter->send_delayed_change_at = 0;
 | 
			
		||||
	  /* Set a timeout of 2*rate limit so that we can clear out the change from the hash eventualy */
 | 
			
		||||
	  update_rate_limiter_timeout (monitor, time_now + 2 * monitor->priv->rate_limit_msec);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      /* Schedule a virtual change done. This is removed if we get a real one, and
 | 
			
		||||
	 postponed if we get more change events. */
 | 
			
		||||
 | 
			
		||||
      limiter->send_virtual_changes_done_at = time_now + DEFAULT_VIRTUAL_CHANGES_DONE_DELAY_SECS * 1000;
 | 
			
		||||
      update_rate_limiter_timeout (monitor, limiter->send_virtual_changes_done_at);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										86
									
								
								gio/gdirectorymonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								gio/gdirectorymonitor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_DIRECTORY_MONITOR_H__
 | 
			
		||||
#define __G_DIRECTORY_MONITOR_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gfile.h>
 | 
			
		||||
#include <gio/gfilemonitor.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_DIRECTORY_MONITOR         (g_directory_monitor_get_type ())
 | 
			
		||||
#define G_DIRECTORY_MONITOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DIRECTORY_MONITOR, GDirectoryMonitor))
 | 
			
		||||
#define G_DIRECTORY_MONITOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DIRECTORY_MONITOR, GDirectoryMonitorClass))
 | 
			
		||||
#define G_IS_DIRECTORY_MONITOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DIRECTORY_MONITOR))
 | 
			
		||||
#define G_IS_DIRECTORY_MONITOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DIRECTORY_MONITOR))
 | 
			
		||||
#define G_DIRECTORY_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DIRECTORY_MONITOR, GDirectoryMonitorClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GDirectoryMonitorClass	 GDirectoryMonitorClass;
 | 
			
		||||
typedef struct _GDirectoryMonitorPrivate GDirectoryMonitorPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GDirectoryMonitor
 | 
			
		||||
{
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GDirectoryMonitorPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GDirectoryMonitorClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
  
 | 
			
		||||
  /* Signals */
 | 
			
		||||
  void (* changed) (GDirectoryMonitor* monitor,
 | 
			
		||||
		    GFile *child,
 | 
			
		||||
		    GFile *other_file,
 | 
			
		||||
		    GFileMonitorEvent event_type);
 | 
			
		||||
  
 | 
			
		||||
  /* Virtual Table */
 | 
			
		||||
  gboolean	(*cancel)(GDirectoryMonitor* monitor);
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_directory_monitor_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
gboolean g_directory_monitor_cancel         (GDirectoryMonitor *monitor);
 | 
			
		||||
gboolean g_directory_monitor_is_cancelled   (GDirectoryMonitor *monitor);
 | 
			
		||||
void     g_directory_monitor_set_rate_limit (GDirectoryMonitor *monitor,
 | 
			
		||||
					     int                limit_msecs);
 | 
			
		||||
 | 
			
		||||
/* For implementations */
 | 
			
		||||
void g_directory_monitor_emit_event (GDirectoryMonitor      *monitor,
 | 
			
		||||
				     GFile                  *child,
 | 
			
		||||
				     GFile                  *other_file,
 | 
			
		||||
				     GFileMonitorEvent       event_type);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_DIRECTORY_MONITOR_H__ */
 | 
			
		||||
							
								
								
									
										348
									
								
								gio/gdrive.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										348
									
								
								gio/gdrive.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,348 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "gdrive.h"
 | 
			
		||||
#include "gsimpleasyncresult.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
static void g_drive_base_init (gpointer g_class);
 | 
			
		||||
static void g_drive_class_init (gpointer g_class,
 | 
			
		||||
				 gpointer class_data);
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
g_drive_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
  static GType drive_type = 0;
 | 
			
		||||
 | 
			
		||||
  if (! drive_type)
 | 
			
		||||
    {
 | 
			
		||||
      static const GTypeInfo drive_info =
 | 
			
		||||
      {
 | 
			
		||||
        sizeof (GDriveIface), /* class_size */
 | 
			
		||||
	g_drive_base_init,   /* base_init */
 | 
			
		||||
	NULL,		/* base_finalize */
 | 
			
		||||
	g_drive_class_init,
 | 
			
		||||
	NULL,		/* class_finalize */
 | 
			
		||||
	NULL,		/* class_data */
 | 
			
		||||
	0,
 | 
			
		||||
	0,              /* n_preallocs */
 | 
			
		||||
	NULL
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      drive_type =
 | 
			
		||||
	g_type_register_static (G_TYPE_INTERFACE, I_("GDrive"),
 | 
			
		||||
				&drive_info, 0);
 | 
			
		||||
 | 
			
		||||
      g_type_interface_add_prerequisite (drive_type, G_TYPE_OBJECT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return drive_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_drive_class_init (gpointer g_class,
 | 
			
		||||
		   gpointer class_data)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_drive_base_init (gpointer g_class)
 | 
			
		||||
{
 | 
			
		||||
  static gboolean initialized = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (! initialized)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_new (I_("changed"),
 | 
			
		||||
                    G_TYPE_DRIVE,
 | 
			
		||||
                    G_SIGNAL_RUN_LAST,
 | 
			
		||||
                    G_STRUCT_OFFSET (GDriveIface, changed),
 | 
			
		||||
                    NULL, NULL,
 | 
			
		||||
                    g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
                    G_TYPE_NONE, 0);
 | 
			
		||||
 | 
			
		||||
      initialized = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_get_name:
 | 
			
		||||
 * @drive: a #GDrive.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: string containing @drive's name.
 | 
			
		||||
 *
 | 
			
		||||
 * The returned string should be freed when no longer needed
 | 
			
		||||
 **/
 | 
			
		||||
char *
 | 
			
		||||
g_drive_get_name (GDrive *drive)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DRIVE (drive), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_name) (drive);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_get_icon:
 | 
			
		||||
 * @drive: a #GDrive.
 | 
			
		||||
 * 
 | 
			
		||||
 * Gets the icon for @drive.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: #GIcon for the @drive.
 | 
			
		||||
 **/
 | 
			
		||||
GIcon *
 | 
			
		||||
g_drive_get_icon (GDrive *drive)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_DRIVE (drive), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_icon) (drive);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_has_volumes:
 | 
			
		||||
 * @drive: a #GDrive.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @drive contains volumes, %FALSE otherwise.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_drive_has_volumes (GDrive *drive)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
 | 
			
		||||
  return (* iface->has_volumes) (drive);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_get_volumes:
 | 
			
		||||
 * @drive: a #GDrive.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: #GList containing any #GVolume s on the given @drive.
 | 
			
		||||
 * NOTE: Fact-check this.
 | 
			
		||||
 **/
 | 
			
		||||
GList *
 | 
			
		||||
g_drive_get_volumes (GDrive *drive)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DRIVE (drive), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
 | 
			
		||||
  return (* iface->get_volumes) (drive);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_is_automounted:
 | 
			
		||||
 * @drive: a #GDrive.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if the drive was automounted. %FALSE otherwise.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_drive_is_automounted (GDrive *drive)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
 | 
			
		||||
  return (* iface->is_automounted) (drive);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_can_mount:
 | 
			
		||||
 * @drive: a #GDrive.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if the @drive can be mounted. %FALSE otherwise.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_drive_can_mount (GDrive *drive)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
 | 
			
		||||
  if (iface->can_mount == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return (* iface->can_mount) (drive);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_can_eject:
 | 
			
		||||
 * @drive: pointer to a #GDrive.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if the @drive can be ejected. %FALSE otherwise.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_drive_can_eject (GDrive *drive)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
 | 
			
		||||
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
 | 
			
		||||
  if (iface->can_eject == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return (* iface->can_eject) (drive);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_mount:
 | 
			
		||||
 * @drive: a #GDrive.
 | 
			
		||||
 * @mount_operation: a #GMountOperation.
 | 
			
		||||
 * @callback: a #GAsyncReadyCallback.
 | 
			
		||||
 * @user_data: a #gpointer.
 | 
			
		||||
 * 
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_drive_mount (GDrive         *drive,
 | 
			
		||||
	       GMountOperation *mount_operation,
 | 
			
		||||
	       GCancellable *cancellable,
 | 
			
		||||
	       GAsyncReadyCallback callback,
 | 
			
		||||
	       gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_DRIVE (drive));
 | 
			
		||||
  g_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
 | 
			
		||||
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
 | 
			
		||||
  if (iface->mount == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
					   _("drive doesn't implement mount"));
 | 
			
		||||
      
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  (* iface->mount) (drive, mount_operation, cancellable, callback, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_mount_finish:
 | 
			
		||||
 * @drive: pointer to a #GDrive.
 | 
			
		||||
 * @result: a #GAsyncResult.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE, %FALSE if operation failed.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_drive_mount_finish (GDrive               *drive,
 | 
			
		||||
		      GAsyncResult         *result,
 | 
			
		||||
		      GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
 | 
			
		||||
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
 | 
			
		||||
 | 
			
		||||
  if (G_IS_SIMPLE_ASYNC_RESULT (result))
 | 
			
		||||
    {
 | 
			
		||||
      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
      if (g_simple_async_result_propagate_error (simple, error))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
  return (* iface->mount_finish) (drive, result, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_eject:
 | 
			
		||||
 * @drive: a #GDrive.
 | 
			
		||||
 * @callback: a #GAsyncReadyCallback.
 | 
			
		||||
 * @user_data: a #gpointer.
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_drive_eject (GDrive         *drive,
 | 
			
		||||
	       GCancellable *cancellable,
 | 
			
		||||
	       GAsyncReadyCallback  callback,
 | 
			
		||||
	       gpointer         user_data)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_DRIVE (drive));
 | 
			
		||||
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
 | 
			
		||||
  if (iface->eject == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
					   _("drive doesn't implement eject"));
 | 
			
		||||
      
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  (* iface->eject) (drive, cancellable, callback, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_drive_eject_finish
 | 
			
		||||
 * @drive: a #GDrive.
 | 
			
		||||
 * @result: a #GAsyncResult.
 | 
			
		||||
 * @error: a #GError.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if the drive has been ejected successfully,
 | 
			
		||||
 * %FALSE otherwise.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_drive_eject_finish (GDrive               *drive,
 | 
			
		||||
		      GAsyncResult         *result,
 | 
			
		||||
		      GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GDriveIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
 | 
			
		||||
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
 | 
			
		||||
 | 
			
		||||
  if (G_IS_SIMPLE_ASYNC_RESULT (result))
 | 
			
		||||
    {
 | 
			
		||||
      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
      if (g_simple_async_result_propagate_error (simple, error))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  iface = G_DRIVE_GET_IFACE (drive);
 | 
			
		||||
  
 | 
			
		||||
  return (* iface->mount_finish) (drive, result, error);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										99
									
								
								gio/gdrive.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								gio/gdrive.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_DRIVE_H__
 | 
			
		||||
#define __G_DRIVE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gvolume.h>
 | 
			
		||||
#include <gio/gmountoperation.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_DRIVE           (g_drive_get_type ())
 | 
			
		||||
#define G_DRIVE(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_DRIVE, GDrive))
 | 
			
		||||
#define G_IS_DRIVE(obj)	       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_DRIVE))
 | 
			
		||||
#define G_DRIVE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_DRIVE, GDriveIface))
 | 
			
		||||
 | 
			
		||||
typedef struct _GDriveIface    GDriveIface;
 | 
			
		||||
 | 
			
		||||
struct _GDriveIface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface g_iface;
 | 
			
		||||
 | 
			
		||||
  /* signals */
 | 
			
		||||
  void (*changed)            (GVolume *volume);
 | 
			
		||||
  
 | 
			
		||||
  /* Virtual Table */
 | 
			
		||||
  
 | 
			
		||||
  char *   (*get_name)    (GDrive         *drive);
 | 
			
		||||
  GIcon *  (*get_icon)    (GDrive         *drive);
 | 
			
		||||
  gboolean (*has_volumes) (GDrive         *drive);
 | 
			
		||||
  GList *  (*get_volumes) (GDrive         *drive);
 | 
			
		||||
  gboolean (*is_automounted)(GDrive       *drive);
 | 
			
		||||
  gboolean (*can_mount)   (GDrive         *drive);
 | 
			
		||||
  gboolean (*can_eject)   (GDrive         *drive);
 | 
			
		||||
  void     (*mount)       (GDrive         *drive,
 | 
			
		||||
			   GMountOperation *mount_operation,
 | 
			
		||||
			   GCancellable   *cancellable,
 | 
			
		||||
			   GAsyncReadyCallback callback,
 | 
			
		||||
			   gpointer        user_data);
 | 
			
		||||
  gboolean (*mount_finish)(GDrive         *drive,
 | 
			
		||||
			   GAsyncResult   *result,
 | 
			
		||||
			   GError        **error);
 | 
			
		||||
  void     (*eject)       (GDrive         *drive,
 | 
			
		||||
			   GCancellable   *cancellable,
 | 
			
		||||
			   GAsyncReadyCallback callback,
 | 
			
		||||
			   gpointer        user_data);
 | 
			
		||||
  gboolean (*eject_finish)(GDrive         *drive,
 | 
			
		||||
			   GAsyncResult   *result,
 | 
			
		||||
			   GError        **error);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_drive_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
char *   g_drive_get_name       (GDrive               *drive);
 | 
			
		||||
GIcon *  g_drive_get_icon       (GDrive               *drive);
 | 
			
		||||
gboolean g_drive_has_volumes    (GDrive               *drive);
 | 
			
		||||
GList  * g_drive_get_volumes    (GDrive               *drive);
 | 
			
		||||
gboolean g_drive_is_automounted (GDrive               *drive);
 | 
			
		||||
gboolean g_drive_can_mount      (GDrive               *drive);
 | 
			
		||||
gboolean g_drive_can_eject      (GDrive               *drive);
 | 
			
		||||
void     g_drive_mount          (GDrive               *drive,
 | 
			
		||||
				 GMountOperation      *mount_operation,
 | 
			
		||||
				 GCancellable         *cancellable,
 | 
			
		||||
				 GAsyncReadyCallback   callback,
 | 
			
		||||
				 gpointer              user_data);
 | 
			
		||||
gboolean g_drive_mount_finish   (GDrive               *drive,
 | 
			
		||||
				 GAsyncResult         *result,
 | 
			
		||||
				 GError              **error);
 | 
			
		||||
void     g_drive_eject          (GDrive               *drive,
 | 
			
		||||
				 GCancellable         *cancellable,
 | 
			
		||||
				 GAsyncReadyCallback   callback,
 | 
			
		||||
				 gpointer              user_data);
 | 
			
		||||
gboolean g_drive_eject_finish   (GDrive               *drive,
 | 
			
		||||
				 GAsyncResult         *result,
 | 
			
		||||
				 GError              **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_DRIVE_H__ */
 | 
			
		||||
							
								
								
									
										32
									
								
								gio/gdriveprivate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								gio/gdriveprivate.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,32 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_DRIVEPRIV_H__
 | 
			
		||||
#define __G_DRIVEPRIV_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gdrive.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_DRIVEPRIV_H__ */
 | 
			
		||||
							
								
								
									
										752
									
								
								gio/gdummyfile.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										752
									
								
								gio/gdummyfile.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,752 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "gdummyfile.h"
 | 
			
		||||
 | 
			
		||||
static void g_dummy_file_file_iface_init (GFileIface       *iface);
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  char *scheme;
 | 
			
		||||
  char *userinfo;
 | 
			
		||||
  char *host;
 | 
			
		||||
  int port; /* -1 => not in uri */
 | 
			
		||||
  char *path;
 | 
			
		||||
  char *query;
 | 
			
		||||
  char *fragment;
 | 
			
		||||
} GDecodedUri;
 | 
			
		||||
 | 
			
		||||
struct _GDummyFile
 | 
			
		||||
{
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
 | 
			
		||||
  GDecodedUri *decoded_uri;
 | 
			
		||||
  char *text_uri;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (GDummyFile, g_dummy_file, G_TYPE_OBJECT,
 | 
			
		||||
			 G_IMPLEMENT_INTERFACE (G_TYPE_FILE,
 | 
			
		||||
						g_dummy_file_file_iface_init))
 | 
			
		||||
 | 
			
		||||
#define SUB_DELIM_CHARS  "!$&'()*+,;="
 | 
			
		||||
 | 
			
		||||
static char *       _g_encode_uri       (GDecodedUri *decoded);
 | 
			
		||||
static void         _g_decoded_uri_free (GDecodedUri *decoded);
 | 
			
		||||
static GDecodedUri *_g_decode_uri       (const char  *uri);
 | 
			
		||||
static GDecodedUri *_g_decoded_uri_new  (void);
 | 
			
		||||
 | 
			
		||||
static char * unescape_string (const gchar *escaped_string,
 | 
			
		||||
			       const gchar *escaped_string_end,
 | 
			
		||||
			       const gchar *illegal_characters);
 | 
			
		||||
 | 
			
		||||
static void g_string_append_encoded (GString *string, const char *encoded,
 | 
			
		||||
				     const char *reserved_chars_allowed);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_dummy_file_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy;
 | 
			
		||||
 | 
			
		||||
  dummy = G_DUMMY_FILE (object);
 | 
			
		||||
 | 
			
		||||
  if (dummy->decoded_uri)
 | 
			
		||||
    _g_decoded_uri_free (dummy->decoded_uri);
 | 
			
		||||
  
 | 
			
		||||
  g_free (dummy->text_uri);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_dummy_file_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_dummy_file_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_dummy_file_class_init (GDummyFileClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  gobject_class->finalize = g_dummy_file_finalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_dummy_file_init (GDummyFile *dummy)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_dummy_file_new:
 | 
			
		||||
 * @uri: Universal Resource Identifier for the dummy file object.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a new #GFile. 
 | 
			
		||||
 **/
 | 
			
		||||
GFile *
 | 
			
		||||
g_dummy_file_new (const char *uri)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (uri != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  dummy = g_object_new (G_TYPE_DUMMY_FILE, NULL);
 | 
			
		||||
  dummy->text_uri = g_strdup (uri);
 | 
			
		||||
  dummy->decoded_uri = _g_decode_uri (uri);
 | 
			
		||||
  
 | 
			
		||||
  return G_FILE (dummy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_dummy_file_is_native (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
g_dummy_file_get_basename (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy = G_DUMMY_FILE (file);
 | 
			
		||||
  
 | 
			
		||||
  if (dummy->decoded_uri)
 | 
			
		||||
    return g_path_get_basename (dummy->decoded_uri->path);
 | 
			
		||||
  return g_strdup (dummy->text_uri);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
g_dummy_file_get_path (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy = G_DUMMY_FILE (file);
 | 
			
		||||
 | 
			
		||||
  if (dummy->decoded_uri)
 | 
			
		||||
    return g_strdup (dummy->decoded_uri->path);
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
g_dummy_file_get_uri (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  return g_strdup (G_DUMMY_FILE (file)->text_uri);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
g_dummy_file_get_parse_name (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  return g_strdup (G_DUMMY_FILE (file)->text_uri);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFile *
 | 
			
		||||
g_dummy_file_get_parent (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy = G_DUMMY_FILE (file);
 | 
			
		||||
  GFile *parent;
 | 
			
		||||
  char *dirname;
 | 
			
		||||
  char *uri;
 | 
			
		||||
  GDecodedUri new_decoded_uri;
 | 
			
		||||
 | 
			
		||||
  if (dummy->decoded_uri == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  dirname = g_path_get_dirname (dummy->decoded_uri->path);
 | 
			
		||||
  
 | 
			
		||||
  if (strcmp (dirname, ".") == 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_free (dirname);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  new_decoded_uri = *dummy->decoded_uri;
 | 
			
		||||
  new_decoded_uri.path = dirname;
 | 
			
		||||
  uri = _g_encode_uri (&new_decoded_uri);
 | 
			
		||||
  g_free (dirname);
 | 
			
		||||
  
 | 
			
		||||
  parent = g_dummy_file_new (uri);
 | 
			
		||||
  g_free (uri);
 | 
			
		||||
  
 | 
			
		||||
  return parent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFile *
 | 
			
		||||
g_dummy_file_dup (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy = G_DUMMY_FILE (file);
 | 
			
		||||
 | 
			
		||||
  return g_dummy_file_new (dummy->text_uri);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static guint
 | 
			
		||||
g_dummy_file_hash (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy = G_DUMMY_FILE (file);
 | 
			
		||||
  
 | 
			
		||||
  return g_str_hash (dummy->text_uri);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_dummy_file_equal (GFile *file1,
 | 
			
		||||
		    GFile *file2)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy1 = G_DUMMY_FILE (file1);
 | 
			
		||||
  GDummyFile *dummy2 = G_DUMMY_FILE (file2);
 | 
			
		||||
 | 
			
		||||
  return g_str_equal (dummy1->text_uri, dummy2->text_uri);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
safe_strcmp (const char *a, const char *b)
 | 
			
		||||
{
 | 
			
		||||
  if (a == NULL)
 | 
			
		||||
    a = "";
 | 
			
		||||
  if (b == NULL)
 | 
			
		||||
    b = "";
 | 
			
		||||
 | 
			
		||||
  return strcmp (a, b);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
uri_same_except_path (GDecodedUri *a,
 | 
			
		||||
		      GDecodedUri *b)
 | 
			
		||||
{
 | 
			
		||||
  if (safe_strcmp (a->scheme, b->scheme) != 0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  if (safe_strcmp (a->userinfo, b->userinfo) != 0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  if (safe_strcmp (a->host, b->host) != 0)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  if (a->port != b->port)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const char *
 | 
			
		||||
match_prefix (const char *path, const char *prefix)
 | 
			
		||||
{
 | 
			
		||||
  int prefix_len;
 | 
			
		||||
 | 
			
		||||
  prefix_len = strlen (prefix);
 | 
			
		||||
  if (strncmp (path, prefix, prefix_len) != 0)
 | 
			
		||||
    return NULL;
 | 
			
		||||
  return path + prefix_len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_dummy_file_contains_file (GFile *parent,
 | 
			
		||||
			    GFile *descendant)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *parent_dummy = G_DUMMY_FILE (parent);
 | 
			
		||||
  GDummyFile *descendant_dummy = G_DUMMY_FILE (descendant);
 | 
			
		||||
  const char *remainder;
 | 
			
		||||
 | 
			
		||||
  if (parent_dummy->decoded_uri != NULL &&
 | 
			
		||||
      descendant_dummy->decoded_uri != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (uri_same_except_path (parent_dummy->decoded_uri,
 | 
			
		||||
				descendant_dummy->decoded_uri)) {
 | 
			
		||||
	remainder = match_prefix (descendant_dummy->decoded_uri->path,
 | 
			
		||||
				  parent_dummy->decoded_uri->path);
 | 
			
		||||
	if (remainder != NULL && *remainder == '/')
 | 
			
		||||
	  {
 | 
			
		||||
	    while (*remainder == '/')
 | 
			
		||||
	      remainder++;
 | 
			
		||||
	    if (*remainder != 0)
 | 
			
		||||
	      return TRUE;
 | 
			
		||||
	  }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      remainder = match_prefix (descendant_dummy->text_uri,
 | 
			
		||||
				parent_dummy->text_uri);
 | 
			
		||||
      if (remainder != NULL && *remainder == '/')
 | 
			
		||||
	  {
 | 
			
		||||
	    while (*remainder == '/')
 | 
			
		||||
	      remainder++;
 | 
			
		||||
	    if (*remainder != 0)
 | 
			
		||||
	      return TRUE;
 | 
			
		||||
	  }
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
g_dummy_file_get_relative_path (GFile *parent,
 | 
			
		||||
				GFile *descendant)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *parent_dummy = G_DUMMY_FILE (parent);
 | 
			
		||||
  GDummyFile *descendant_dummy = G_DUMMY_FILE (descendant);
 | 
			
		||||
  const char *remainder;
 | 
			
		||||
 | 
			
		||||
  if (parent_dummy->decoded_uri != NULL &&
 | 
			
		||||
      descendant_dummy->decoded_uri != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (uri_same_except_path (parent_dummy->decoded_uri,
 | 
			
		||||
				descendant_dummy->decoded_uri)) {
 | 
			
		||||
	remainder = match_prefix (descendant_dummy->decoded_uri->path,
 | 
			
		||||
				  parent_dummy->decoded_uri->path);
 | 
			
		||||
	if (remainder != NULL && *remainder == '/')
 | 
			
		||||
	  {
 | 
			
		||||
	    while (*remainder == '/')
 | 
			
		||||
	      remainder++;
 | 
			
		||||
	    if (*remainder != 0)
 | 
			
		||||
	      return g_strdup (remainder);
 | 
			
		||||
	  }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      remainder = match_prefix (descendant_dummy->text_uri,
 | 
			
		||||
				parent_dummy->text_uri);
 | 
			
		||||
      if (remainder != NULL && *remainder == '/')
 | 
			
		||||
	  {
 | 
			
		||||
	    while (*remainder == '/')
 | 
			
		||||
	      remainder++;
 | 
			
		||||
	    if (*remainder != 0)
 | 
			
		||||
	      return unescape_string (remainder, NULL, "/");
 | 
			
		||||
	  }
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GFile *
 | 
			
		||||
g_dummy_file_resolve_relative_path (GFile *file,
 | 
			
		||||
				    const char *relative_path)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy = G_DUMMY_FILE (file);
 | 
			
		||||
  GFile *child;
 | 
			
		||||
  char *uri;
 | 
			
		||||
  GDecodedUri new_decoded_uri;
 | 
			
		||||
  GString *str;
 | 
			
		||||
 | 
			
		||||
  if (dummy->decoded_uri == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      str = g_string_new (dummy->text_uri);
 | 
			
		||||
      g_string_append (str, "/");
 | 
			
		||||
      g_string_append_encoded (str, relative_path, SUB_DELIM_CHARS ":@/");
 | 
			
		||||
      child = g_dummy_file_new (str->str);
 | 
			
		||||
      g_string_free (str, TRUE);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      new_decoded_uri = *dummy->decoded_uri;
 | 
			
		||||
      
 | 
			
		||||
      if (g_path_is_absolute (relative_path))
 | 
			
		||||
	new_decoded_uri.path = g_strdup (relative_path);
 | 
			
		||||
      else
 | 
			
		||||
	new_decoded_uri.path = g_build_filename (new_decoded_uri.path, relative_path, NULL);
 | 
			
		||||
      
 | 
			
		||||
      uri = _g_encode_uri (&new_decoded_uri);
 | 
			
		||||
      g_free (new_decoded_uri.path);
 | 
			
		||||
      
 | 
			
		||||
      child = g_dummy_file_new (uri);
 | 
			
		||||
      g_free (uri);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return child;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFile *
 | 
			
		||||
g_dummy_file_get_child_for_display_name (GFile        *file,
 | 
			
		||||
					 const char   *display_name,
 | 
			
		||||
					 GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  return g_file_get_child (file, display_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_dummy_file_has_uri_scheme (GFile *file,
 | 
			
		||||
			     const char *uri_scheme)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy = G_DUMMY_FILE (file);
 | 
			
		||||
  
 | 
			
		||||
  if (dummy->decoded_uri)
 | 
			
		||||
    return g_ascii_strcasecmp (uri_scheme, dummy->decoded_uri->scheme) == 0;
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
g_dummy_file_get_uri_scheme (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  GDummyFile *dummy = G_DUMMY_FILE (file);
 | 
			
		||||
 | 
			
		||||
  if (dummy->decoded_uri)
 | 
			
		||||
    return g_strdup (dummy->decoded_uri->scheme);
 | 
			
		||||
    
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_dummy_file_file_iface_init (GFileIface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->dup = g_dummy_file_dup;
 | 
			
		||||
  iface->hash = g_dummy_file_hash;
 | 
			
		||||
  iface->equal = g_dummy_file_equal;
 | 
			
		||||
  iface->is_native = g_dummy_file_is_native;
 | 
			
		||||
  iface->has_uri_scheme = g_dummy_file_has_uri_scheme;
 | 
			
		||||
  iface->get_uri_scheme = g_dummy_file_get_uri_scheme;
 | 
			
		||||
  iface->get_basename = g_dummy_file_get_basename;
 | 
			
		||||
  iface->get_path = g_dummy_file_get_path;
 | 
			
		||||
  iface->get_uri = g_dummy_file_get_uri;
 | 
			
		||||
  iface->get_parse_name = g_dummy_file_get_parse_name;
 | 
			
		||||
  iface->get_parent = g_dummy_file_get_parent;
 | 
			
		||||
  iface->contains_file = g_dummy_file_contains_file;
 | 
			
		||||
  iface->get_relative_path = g_dummy_file_get_relative_path;
 | 
			
		||||
  iface->resolve_relative_path = g_dummy_file_resolve_relative_path;
 | 
			
		||||
  iface->get_child_for_display_name = g_dummy_file_get_child_for_display_name;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Uri handling helper functions: */
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
unescape_character (const char *scanner)
 | 
			
		||||
{
 | 
			
		||||
  int first_digit;
 | 
			
		||||
  int second_digit;
 | 
			
		||||
  
 | 
			
		||||
  first_digit = g_ascii_xdigit_value (*scanner++);
 | 
			
		||||
  if (first_digit < 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  second_digit = g_ascii_xdigit_value (*scanner++);
 | 
			
		||||
  if (second_digit < 0)
 | 
			
		||||
    return -1;
 | 
			
		||||
 | 
			
		||||
  return (first_digit << 4) | second_digit;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
unescape_string (const gchar *escaped_string,
 | 
			
		||||
		 const gchar *escaped_string_end,
 | 
			
		||||
		 const gchar *illegal_characters)
 | 
			
		||||
{
 | 
			
		||||
  const gchar *in;
 | 
			
		||||
  gchar *out, *result;
 | 
			
		||||
  gint character;
 | 
			
		||||
  
 | 
			
		||||
  if (escaped_string == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (escaped_string_end == NULL)
 | 
			
		||||
    escaped_string_end = escaped_string + strlen (escaped_string);
 | 
			
		||||
  
 | 
			
		||||
  result = g_malloc (escaped_string_end - escaped_string + 1);
 | 
			
		||||
	
 | 
			
		||||
  out = result;
 | 
			
		||||
  for (in = escaped_string; in < escaped_string_end; in++) {
 | 
			
		||||
    character = *in;
 | 
			
		||||
    if (*in == '%') {
 | 
			
		||||
      in++;
 | 
			
		||||
      if (escaped_string_end - in < 2)
 | 
			
		||||
	{
 | 
			
		||||
	  g_free (result);
 | 
			
		||||
	  return NULL;
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      character = unescape_character (in);
 | 
			
		||||
      
 | 
			
		||||
      /* Check for an illegal character. We consider '\0' illegal here. */
 | 
			
		||||
      if (character <= 0 ||
 | 
			
		||||
	  (illegal_characters != NULL &&
 | 
			
		||||
	   strchr (illegal_characters, (char)character) != NULL))
 | 
			
		||||
	{
 | 
			
		||||
	  g_free (result);
 | 
			
		||||
	  return NULL;
 | 
			
		||||
	}
 | 
			
		||||
      in++; /* The other char will be eaten in the loop header */
 | 
			
		||||
    }
 | 
			
		||||
    *out++ = (char)character;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  *out = '\0';
 | 
			
		||||
  g_assert (out - result <= strlen (escaped_string));
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
_g_decoded_uri_free (GDecodedUri *decoded)
 | 
			
		||||
{
 | 
			
		||||
  if (decoded == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  g_free (decoded->scheme);
 | 
			
		||||
  g_free (decoded->query);
 | 
			
		||||
  g_free (decoded->fragment);
 | 
			
		||||
  g_free (decoded->userinfo);
 | 
			
		||||
  g_free (decoded->host);
 | 
			
		||||
  g_free (decoded->path);
 | 
			
		||||
  g_free (decoded);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GDecodedUri *
 | 
			
		||||
_g_decoded_uri_new (void)
 | 
			
		||||
{
 | 
			
		||||
  GDecodedUri *uri;
 | 
			
		||||
 | 
			
		||||
  uri = g_new0 (GDecodedUri, 1);
 | 
			
		||||
  uri->port = -1;
 | 
			
		||||
 | 
			
		||||
  return uri;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GDecodedUri *
 | 
			
		||||
_g_decode_uri (const char *uri)
 | 
			
		||||
{
 | 
			
		||||
  GDecodedUri *decoded;
 | 
			
		||||
  const char *p, *in, *hier_part_start, *hier_part_end, *query_start, *fragment_start;
 | 
			
		||||
  char *out;
 | 
			
		||||
  char c;
 | 
			
		||||
 | 
			
		||||
  /* From RFC 3986 Decodes:
 | 
			
		||||
   * URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
 | 
			
		||||
   */ 
 | 
			
		||||
 | 
			
		||||
  p = uri;
 | 
			
		||||
  
 | 
			
		||||
  /* Decode scheme:
 | 
			
		||||
     scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  if (!g_ascii_isalpha (*p))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  while (1)
 | 
			
		||||
    {
 | 
			
		||||
      c = *p++;
 | 
			
		||||
 | 
			
		||||
      if (c == ':')
 | 
			
		||||
	break;
 | 
			
		||||
      
 | 
			
		||||
      if (!(g_ascii_isalnum(c) ||
 | 
			
		||||
	    c == '+' ||
 | 
			
		||||
	    c == '-' ||
 | 
			
		||||
	    c == '.'))
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  decoded = _g_decoded_uri_new ();
 | 
			
		||||
  
 | 
			
		||||
  decoded->scheme = g_malloc (p - uri);
 | 
			
		||||
  out = decoded->scheme;
 | 
			
		||||
  for (in = uri; in < p - 1; in++)
 | 
			
		||||
    *out++ = g_ascii_tolower (*in);
 | 
			
		||||
  *out = 0;
 | 
			
		||||
 | 
			
		||||
  hier_part_start = p;
 | 
			
		||||
 | 
			
		||||
  query_start = strchr (p, '?');
 | 
			
		||||
  if (query_start)
 | 
			
		||||
    {
 | 
			
		||||
      hier_part_end = query_start++;
 | 
			
		||||
      fragment_start = strchr (query_start, '#');
 | 
			
		||||
      if (fragment_start)
 | 
			
		||||
	{
 | 
			
		||||
	  decoded->query = g_strndup (query_start, fragment_start - query_start);
 | 
			
		||||
	  decoded->fragment = g_strdup (fragment_start+1);
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  decoded->query = g_strdup (query_start);
 | 
			
		||||
	  decoded->fragment = NULL;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* No query */
 | 
			
		||||
      decoded->query = NULL;
 | 
			
		||||
      fragment_start = strchr (p, '#');
 | 
			
		||||
      if (fragment_start)
 | 
			
		||||
	{
 | 
			
		||||
	  hier_part_end = fragment_start++;
 | 
			
		||||
	  decoded->fragment = g_strdup (fragment_start);
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  hier_part_end = p + strlen (p);
 | 
			
		||||
	  decoded->fragment = NULL;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /*  3:
 | 
			
		||||
      hier-part   = "//" authority path-abempty
 | 
			
		||||
                  / path-absolute
 | 
			
		||||
                  / path-rootless
 | 
			
		||||
                  / path-empty
 | 
			
		||||
 | 
			
		||||
  */
 | 
			
		||||
 | 
			
		||||
  if (hier_part_start[0] == '/' &&
 | 
			
		||||
      hier_part_start[1] == '/')
 | 
			
		||||
    {
 | 
			
		||||
      const char *authority_start, *authority_end;
 | 
			
		||||
      const char *userinfo_start, *userinfo_end;
 | 
			
		||||
      const char *host_start, *host_end;
 | 
			
		||||
      const char *port_start;
 | 
			
		||||
      
 | 
			
		||||
      authority_start = hier_part_start + 2;
 | 
			
		||||
      /* authority is always followed by / or nothing */
 | 
			
		||||
      authority_end = memchr (authority_start, '/', hier_part_end - authority_start);
 | 
			
		||||
      if (authority_end == NULL)
 | 
			
		||||
	authority_end = hier_part_end;
 | 
			
		||||
 | 
			
		||||
      /* 3.2:
 | 
			
		||||
	      authority   = [ userinfo "@" ] host [ ":" port ]
 | 
			
		||||
      */
 | 
			
		||||
 | 
			
		||||
      userinfo_end = memchr (authority_start, '@', authority_end - authority_start);
 | 
			
		||||
      if (userinfo_end)
 | 
			
		||||
	{
 | 
			
		||||
	  userinfo_start = authority_start;
 | 
			
		||||
	  decoded->userinfo = unescape_string (userinfo_start, userinfo_end, NULL);
 | 
			
		||||
	  if (decoded->userinfo == NULL)
 | 
			
		||||
	    {
 | 
			
		||||
	      _g_decoded_uri_free (decoded);
 | 
			
		||||
	      return NULL;
 | 
			
		||||
	    }
 | 
			
		||||
	  host_start = userinfo_end + 1;
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	host_start = authority_start;
 | 
			
		||||
 | 
			
		||||
      port_start = memchr (host_start, ':', authority_end - host_start);
 | 
			
		||||
      if (port_start)
 | 
			
		||||
	{
 | 
			
		||||
	  host_end = port_start++;
 | 
			
		||||
 | 
			
		||||
	  decoded->port = atoi(port_start);
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  host_end = authority_end;
 | 
			
		||||
	  decoded->port = -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      decoded->host = g_strndup (host_start, host_end - host_start);
 | 
			
		||||
 | 
			
		||||
      hier_part_start = authority_end;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  decoded->path = unescape_string (hier_part_start, hier_part_end, "/");
 | 
			
		||||
 | 
			
		||||
  if (decoded->path == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      _g_decoded_uri_free (decoded);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return decoded;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_valid (char c, const char *reserved_chars_allowed)
 | 
			
		||||
{
 | 
			
		||||
  if (g_ascii_isalnum (c) ||
 | 
			
		||||
      c == '-' ||
 | 
			
		||||
      c == '.' ||
 | 
			
		||||
      c == '_' ||
 | 
			
		||||
      c == '~')
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  if (reserved_chars_allowed &&
 | 
			
		||||
      strchr (reserved_chars_allowed, c) != NULL)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_string_append_encoded (GString *string, const char *encoded,
 | 
			
		||||
			 const char *reserved_chars_allowed)
 | 
			
		||||
{
 | 
			
		||||
  unsigned char c;
 | 
			
		||||
  const char *end;
 | 
			
		||||
  static const gchar hex[16] = "0123456789ABCDEF";
 | 
			
		||||
 | 
			
		||||
  end = encoded + strlen (encoded);
 | 
			
		||||
  
 | 
			
		||||
  while ((c = *encoded) != 0)
 | 
			
		||||
    {
 | 
			
		||||
      if (is_valid (c, reserved_chars_allowed))
 | 
			
		||||
	{
 | 
			
		||||
	  g_string_append_c (string, c);
 | 
			
		||||
	  encoded++;
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  g_string_append_c (string, '%');
 | 
			
		||||
	  g_string_append_c (string, hex[((guchar)c) >> 4]);
 | 
			
		||||
	  g_string_append_c (string, hex[((guchar)c) & 0xf]);
 | 
			
		||||
	  encoded++;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
_g_encode_uri (GDecodedUri *decoded)
 | 
			
		||||
{
 | 
			
		||||
  GString *uri;
 | 
			
		||||
 | 
			
		||||
  uri = g_string_new (NULL);
 | 
			
		||||
 | 
			
		||||
  g_string_append (uri, decoded->scheme);
 | 
			
		||||
  g_string_append (uri, "://");
 | 
			
		||||
 | 
			
		||||
  if (decoded->host != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      if (decoded->userinfo)
 | 
			
		||||
	{
 | 
			
		||||
	  /* userinfo    = *( unreserved / pct-encoded / sub-delims / ":" ) */
 | 
			
		||||
	  g_string_append_encoded (uri, decoded->userinfo, SUB_DELIM_CHARS ":");
 | 
			
		||||
	  g_string_append_c (uri, '@');
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      g_string_append (uri, decoded->host);
 | 
			
		||||
      
 | 
			
		||||
      if (decoded->port != -1)
 | 
			
		||||
	{
 | 
			
		||||
	  g_string_append_c (uri, ':');
 | 
			
		||||
	  g_string_append_printf (uri, "%d", decoded->port);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_string_append_encoded (uri, decoded->path, SUB_DELIM_CHARS ":@/");
 | 
			
		||||
  
 | 
			
		||||
  if (decoded->query)
 | 
			
		||||
    {
 | 
			
		||||
      g_string_append_c (uri, '?');
 | 
			
		||||
      g_string_append (uri, decoded->query);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  if (decoded->fragment)
 | 
			
		||||
    {
 | 
			
		||||
      g_string_append_c (uri, '#');
 | 
			
		||||
      g_string_append (uri, decoded->fragment);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return g_string_free (uri, FALSE);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										51
									
								
								gio/gdummyfile.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								gio/gdummyfile.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_DUMMY_FILE_H__
 | 
			
		||||
#define __G_DUMMY_FILE_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gfile.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_DUMMY_FILE         (g_dummy_file_get_type ())
 | 
			
		||||
#define G_DUMMY_FILE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_DUMMY_FILE, GDummyFile))
 | 
			
		||||
#define G_DUMMY_FILE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_DUMMY_FILE, GDummyFileClass))
 | 
			
		||||
#define G_IS_DUMMY_FILE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_DUMMY_FILE))
 | 
			
		||||
#define G_IS_DUMMY_FILE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_DUMMY_FILE))
 | 
			
		||||
#define G_DUMMY_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_DUMMY_FILE, GDummyFileClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GDummyFile        GDummyFile;
 | 
			
		||||
typedef struct _GDummyFileClass   GDummyFileClass;
 | 
			
		||||
 | 
			
		||||
struct _GDummyFileClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_dummy_file_get_type (void) G_GNUC_CONST;
 | 
			
		||||
  
 | 
			
		||||
GFile * g_dummy_file_new (const char *uri);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_DUMMY_FILE_H__ */
 | 
			
		||||
							
								
								
									
										4345
									
								
								gio/gfile.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4345
									
								
								gio/gfile.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										676
									
								
								gio/gfile.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										676
									
								
								gio/gfile.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,676 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILE_H__
 | 
			
		||||
#define __G_FILE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gfileinfo.h>
 | 
			
		||||
#include <gio/gfileenumerator.h>
 | 
			
		||||
#include <gio/gfileinputstream.h>
 | 
			
		||||
#include <gio/gfileoutputstream.h>
 | 
			
		||||
#include <gio/gmountoperation.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILE            (g_file_get_type ())
 | 
			
		||||
#define G_FILE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_FILE, GFile))
 | 
			
		||||
#define G_IS_FILE(obj)	       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_FILE))
 | 
			
		||||
#define G_FILE_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_FILE, GFileIface))
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS = (1<<0)
 | 
			
		||||
} GFileQueryInfoFlags;
 | 
			
		||||
 | 
			
		||||
typedef enum  {
 | 
			
		||||
  G_FILE_CREATE_FLAGS_NONE = 0,
 | 
			
		||||
  G_FILE_CREATE_FLAGS_PRIVATE = (1<<0)
 | 
			
		||||
} GFileCreateFlags;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  G_FILE_COPY_OVERWRITE = (1<<0),
 | 
			
		||||
  G_FILE_COPY_BACKUP = (1<<1),
 | 
			
		||||
  G_FILE_COPY_NOFOLLOW_SYMLINKS = (1<<2),
 | 
			
		||||
  G_FILE_COPY_ALL_METADATA = (1<<3)
 | 
			
		||||
} GFileCopyFlags;
 | 
			
		||||
 | 
			
		||||
typedef enum  {
 | 
			
		||||
  G_FILE_MONITOR_FLAGS_NONE = 0,
 | 
			
		||||
  G_FILE_MONITOR_FLAGS_MONITOR_MOUNTS = (1<<0)
 | 
			
		||||
} GFileMonitorFlags;
 | 
			
		||||
 | 
			
		||||
typedef struct _GFile         		GFile; /* Dummy typedef */
 | 
			
		||||
typedef struct _GFileIface    		GFileIface;
 | 
			
		||||
typedef struct _GDirectoryMonitor       GDirectoryMonitor;
 | 
			
		||||
typedef struct _GFileMonitor            GFileMonitor;
 | 
			
		||||
typedef struct _GVolume         GVolume; /* Dummy typedef */
 | 
			
		||||
 | 
			
		||||
typedef void (*GFileProgressCallback) (goffset current_num_bytes,
 | 
			
		||||
				       goffset total_num_bytes,
 | 
			
		||||
				       gpointer user_data);
 | 
			
		||||
typedef gboolean (* GFileReadMoreCallback) (const char *file_contents,
 | 
			
		||||
					    goffset file_size,
 | 
			
		||||
					    gpointer callback_data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _GFileIface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface g_iface;
 | 
			
		||||
 | 
			
		||||
  /* Virtual Table */
 | 
			
		||||
 | 
			
		||||
  GFile *             (*dup)                        (GFile         *file);
 | 
			
		||||
  guint               (*hash)                       (GFile         *file);
 | 
			
		||||
  gboolean            (*equal)                      (GFile         *file1,
 | 
			
		||||
						     GFile         *file2);
 | 
			
		||||
  gboolean            (*is_native)                  (GFile         *file);
 | 
			
		||||
  gboolean            (*has_uri_scheme)             (GFile         *file,
 | 
			
		||||
						     const char    *uri_scheme);
 | 
			
		||||
  char *              (*get_uri_scheme)             (GFile         *file);
 | 
			
		||||
  char *              (*get_basename)               (GFile         *file);
 | 
			
		||||
  char *              (*get_path)                   (GFile         *file);
 | 
			
		||||
  char *              (*get_uri)                    (GFile         *file);
 | 
			
		||||
  char *              (*get_parse_name)             (GFile         *file);
 | 
			
		||||
  GFile *             (*get_parent)                 (GFile         *file);
 | 
			
		||||
  gboolean            (*contains_file)              (GFile         *parent,
 | 
			
		||||
						     GFile         *descendant);
 | 
			
		||||
  char *              (*get_relative_path)          (GFile         *parent,
 | 
			
		||||
						     GFile         *descendant);
 | 
			
		||||
  GFile *             (*resolve_relative_path)      (GFile        *file,
 | 
			
		||||
						     const char   *relative_path);
 | 
			
		||||
  GFile *             (*get_child_for_display_name) (GFile        *file,
 | 
			
		||||
						     const char   *display_name,
 | 
			
		||||
						     GError      **error);
 | 
			
		||||
  
 | 
			
		||||
  GFileEnumerator *   (*enumerate_children)        (GFile                *file,
 | 
			
		||||
						    const char           *attributes,
 | 
			
		||||
						    GFileQueryInfoFlags   flags,
 | 
			
		||||
						    GCancellable         *cancellable,
 | 
			
		||||
						    GError              **error);
 | 
			
		||||
  void                (*enumerate_children_async)  (GFile                      *file,
 | 
			
		||||
						    const char                 *attributes,
 | 
			
		||||
						    GFileQueryInfoFlags         flags,
 | 
			
		||||
						    int                         io_priority,
 | 
			
		||||
						    GCancellable               *cancellable,
 | 
			
		||||
						    GAsyncReadyCallback         callback,
 | 
			
		||||
						    gpointer                    user_data);
 | 
			
		||||
  GFileEnumerator *   (*enumerate_children_finish) (GFile                      *file,
 | 
			
		||||
						    GAsyncResult               *res,
 | 
			
		||||
						    GError                    **error);
 | 
			
		||||
  
 | 
			
		||||
  GFileInfo *         (*query_info)         (GFile                *file,
 | 
			
		||||
					     const char           *attributes,
 | 
			
		||||
					     GFileQueryInfoFlags   flags,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  void                (*query_info_async)   (GFile                *file,
 | 
			
		||||
					     const char           *attributes,
 | 
			
		||||
					     GFileQueryInfoFlags   flags,
 | 
			
		||||
					     int                   io_priority,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GAsyncReadyCallback   callback,
 | 
			
		||||
					     gpointer              user_data);
 | 
			
		||||
  GFileInfo *         (*query_info_finish)  (GFile                *file,
 | 
			
		||||
					     GAsyncResult         *res,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  
 | 
			
		||||
  GFileInfo *         (*query_filesystem_info)(GFile                *file,
 | 
			
		||||
					     const char           *attributes,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  void                (*_query_filesystem_info_async) (void);
 | 
			
		||||
  void                (*_query_filesystem_info_finish) (void);
 | 
			
		||||
  
 | 
			
		||||
  GVolume *           (*find_enclosing_volume)(GFile              *file,
 | 
			
		||||
					       GCancellable       *cancellable,
 | 
			
		||||
					       GError            **error);
 | 
			
		||||
  void                (*find_enclosing_volume_async)(GFile              *file,
 | 
			
		||||
						     int                   io_priority,
 | 
			
		||||
						     GCancellable         *cancellable,
 | 
			
		||||
						     GAsyncReadyCallback   callback,
 | 
			
		||||
						     gpointer              user_data);
 | 
			
		||||
  GVolume *           (*find_enclosing_volume_finish)(GFile              *file,
 | 
			
		||||
						      GAsyncResult         *res,
 | 
			
		||||
						      GError            **error);
 | 
			
		||||
  
 | 
			
		||||
  GFile *             (*set_display_name)         (GFile                *file,
 | 
			
		||||
						   const char           *display_name,
 | 
			
		||||
						   GCancellable         *cancellable,
 | 
			
		||||
						   GError              **error);
 | 
			
		||||
  void                (*set_display_name_async)   (GFile                      *file,
 | 
			
		||||
						   const char                 *display_name,
 | 
			
		||||
						   int                         io_priority,
 | 
			
		||||
						   GCancellable               *cancellable,
 | 
			
		||||
						   GAsyncReadyCallback         callback,
 | 
			
		||||
						   gpointer                    user_data);
 | 
			
		||||
  GFile *              (*set_display_name_finish) (GFile                      *file,
 | 
			
		||||
						   GAsyncResult               *res,
 | 
			
		||||
						   GError                    **error);
 | 
			
		||||
  
 | 
			
		||||
  GFileAttributeInfoList * (*query_settable_attributes) (GFile        *file,
 | 
			
		||||
							 GCancellable *cancellable,
 | 
			
		||||
							 GError      **error);
 | 
			
		||||
  void                (*_query_settable_attributes_async) (void);
 | 
			
		||||
  void                (*_query_settable_attributes_finish) (void);
 | 
			
		||||
  
 | 
			
		||||
  GFileAttributeInfoList * (*query_writable_namespaces) (GFile        *file,
 | 
			
		||||
							 GCancellable *cancellable,
 | 
			
		||||
							 GError      **error);
 | 
			
		||||
  void                (*_query_writable_namespaces_async) (void);
 | 
			
		||||
  void                (*_query_writable_namespaces_finish) (void);
 | 
			
		||||
  
 | 
			
		||||
  gboolean            (*set_attribute)            (GFile                *file,
 | 
			
		||||
						   const char           *attribute,
 | 
			
		||||
						   const GFileAttributeValue *value,
 | 
			
		||||
						   GFileQueryInfoFlags   flags,
 | 
			
		||||
						   GCancellable         *cancellable,
 | 
			
		||||
						   GError              **error);
 | 
			
		||||
  gboolean            (*set_attributes_from_info) (GFile          *file,
 | 
			
		||||
						   GFileInfo            *info,
 | 
			
		||||
						   GFileQueryInfoFlags   flags,
 | 
			
		||||
						   GCancellable         *cancellable,
 | 
			
		||||
						   GError              **error);
 | 
			
		||||
  void                (*set_attributes_async)     (GFile                      *file,
 | 
			
		||||
						   GFileInfo                  *info,
 | 
			
		||||
						   GFileQueryInfoFlags        flags,
 | 
			
		||||
						   int                         io_priority,
 | 
			
		||||
						   GCancellable               *cancellable,
 | 
			
		||||
						   GAsyncReadyCallback         callback,
 | 
			
		||||
						   gpointer                    user_data);
 | 
			
		||||
  gboolean            (*set_attributes_finish)    (GFile                      *file,
 | 
			
		||||
						   GAsyncResult               *result,
 | 
			
		||||
						   GFileInfo                 **info,
 | 
			
		||||
						   GError                    **error);
 | 
			
		||||
  
 | 
			
		||||
  GFileInputStream *  (*read)               (GFile                *file,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  void                (*read_async)         (GFile                *file,
 | 
			
		||||
					     int                   io_priority,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GAsyncReadyCallback   callback,
 | 
			
		||||
					     gpointer              user_data);
 | 
			
		||||
  GFileInputStream *  (*read_finish)        (GFile                *file,
 | 
			
		||||
					     GAsyncResult         *res,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  
 | 
			
		||||
  GFileOutputStream * (*append_to)          (GFile                *file,
 | 
			
		||||
					     GFileCreateFlags      flags,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError               **error);
 | 
			
		||||
  void                 (*append_to_async)   (GFile                      *file,
 | 
			
		||||
					     GFileCreateFlags            flags,
 | 
			
		||||
					     int                         io_priority,
 | 
			
		||||
					     GCancellable               *cancellable,
 | 
			
		||||
					     GAsyncReadyCallback         callback,
 | 
			
		||||
					     gpointer                    user_data);
 | 
			
		||||
  GFileOutputStream *  (*append_to_finish)  (GFile                      *file,
 | 
			
		||||
					     GAsyncResult               *res,
 | 
			
		||||
					     GError                    **error);
 | 
			
		||||
  
 | 
			
		||||
  GFileOutputStream * (*create)             (GFile                *file,
 | 
			
		||||
					     GFileCreateFlags      flags,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError               **error);
 | 
			
		||||
  void                 (*create_async)      (GFile                      *file,
 | 
			
		||||
					     GFileCreateFlags            flags,
 | 
			
		||||
					     int                         io_priority,
 | 
			
		||||
					     GCancellable               *cancellable,
 | 
			
		||||
					     GAsyncReadyCallback         callback,
 | 
			
		||||
					     gpointer                    user_data);
 | 
			
		||||
  GFileOutputStream *  (*create_finish)     (GFile                      *file,
 | 
			
		||||
					     GAsyncResult               *res,
 | 
			
		||||
					     GError                    **error);
 | 
			
		||||
  
 | 
			
		||||
  GFileOutputStream *  (*replace)           (GFile                *file,
 | 
			
		||||
					     const char           *etag,
 | 
			
		||||
					     gboolean              make_backup,
 | 
			
		||||
					     GFileCreateFlags      flags,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  void                 (*replace_async)     (GFile                      *file,
 | 
			
		||||
					     const char                 *etag,
 | 
			
		||||
					     gboolean                    make_backup,
 | 
			
		||||
					     GFileCreateFlags            flags,
 | 
			
		||||
					     int                         io_priority,
 | 
			
		||||
					     GCancellable               *cancellable,
 | 
			
		||||
					     GAsyncReadyCallback         callback,
 | 
			
		||||
					     gpointer                    user_data);
 | 
			
		||||
  GFileOutputStream *  (*replace_finish)    (GFile                      *file,
 | 
			
		||||
					     GAsyncResult               *res,
 | 
			
		||||
					     GError                    **error);
 | 
			
		||||
  
 | 
			
		||||
  gboolean            (*delete_file)        (GFile                *file,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  void                (*_delete_file_async) (void);
 | 
			
		||||
  void                (*_delete_file_finish) (void);
 | 
			
		||||
  
 | 
			
		||||
  gboolean            (*trash)              (GFile                *file,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  void                (*_trash_async) (void);
 | 
			
		||||
  void                (*_trash_finish) (void);
 | 
			
		||||
  
 | 
			
		||||
  gboolean            (*make_directory)     (GFile                *file,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  void                (*_make_directory_async) (void);
 | 
			
		||||
  void                (*_make_directory_finish) (void);
 | 
			
		||||
  
 | 
			
		||||
  gboolean            (*make_symbolic_link) (GFile                *file,
 | 
			
		||||
					     const char           *symlink_value,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  void                (*_make_symbolic_link_async) (void);
 | 
			
		||||
  void                (*_make_symbolic_link_finish) (void);
 | 
			
		||||
  
 | 
			
		||||
  gboolean            (*copy)               (GFile                *source,
 | 
			
		||||
					     GFile                *destination,
 | 
			
		||||
					     GFileCopyFlags        flags,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GFileProgressCallback progress_callback,
 | 
			
		||||
					     gpointer              progress_callback_data,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
  void                (*_copy_async) (void);
 | 
			
		||||
  void                (*_copy_finish) (void);
 | 
			
		||||
  
 | 
			
		||||
  gboolean            (*move)               (GFile                *source,
 | 
			
		||||
					     GFile                *destination,
 | 
			
		||||
					     GFileCopyFlags        flags,
 | 
			
		||||
					     GCancellable         *cancellable,
 | 
			
		||||
					     GFileProgressCallback progress_callback,
 | 
			
		||||
					     gpointer              progress_callback_data,
 | 
			
		||||
					     GError              **error);
 | 
			
		||||
 | 
			
		||||
  void                (*_move_async) (void);
 | 
			
		||||
  void                (*_move_finish) (void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  void                (*mount_mountable)           (GFile               *file,
 | 
			
		||||
						    GMountOperation     *mount_operation,
 | 
			
		||||
						    GCancellable         *cancellable,
 | 
			
		||||
						    GAsyncReadyCallback  callback,
 | 
			
		||||
						    gpointer             user_data);
 | 
			
		||||
  GFile *             (*mount_mountable_finish)    (GFile               *file,
 | 
			
		||||
						    GAsyncResult        *result,
 | 
			
		||||
						    GError             **error);
 | 
			
		||||
  void                (*unmount_mountable)         (GFile               *file,
 | 
			
		||||
						    GCancellable         *cancellable,
 | 
			
		||||
						    GAsyncReadyCallback  callback,
 | 
			
		||||
						    gpointer             user_data);
 | 
			
		||||
  gboolean            (*unmount_mountable_finish)  (GFile               *file,
 | 
			
		||||
						    GAsyncResult        *result,
 | 
			
		||||
						    GError             **error);
 | 
			
		||||
  void                (*eject_mountable)           (GFile               *file,
 | 
			
		||||
						    GCancellable        *cancellable,
 | 
			
		||||
						    GAsyncReadyCallback  callback,
 | 
			
		||||
						    gpointer             user_data);
 | 
			
		||||
  gboolean            (*eject_mountable_finish)    (GFile               *file,
 | 
			
		||||
						    GAsyncResult        *result,
 | 
			
		||||
						    GError             **error);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  void     (*mount_for_location)        (GFile *location,
 | 
			
		||||
					 GMountOperation *mount_operation,
 | 
			
		||||
					 GCancellable *cancellable,
 | 
			
		||||
					 GAsyncReadyCallback callback,
 | 
			
		||||
					 gpointer user_data);
 | 
			
		||||
  gboolean (*mount_for_location_finish) (GFile *location,
 | 
			
		||||
					 GAsyncResult *result,
 | 
			
		||||
					 GError **error);
 | 
			
		||||
  
 | 
			
		||||
  GDirectoryMonitor* (*monitor_dir)         (GFile                  *file,
 | 
			
		||||
					     GFileMonitorFlags       flags,
 | 
			
		||||
					     GCancellable           *cancellable);
 | 
			
		||||
 | 
			
		||||
  GFileMonitor*      (*monitor_file)        (GFile                  *file,
 | 
			
		||||
					     GFileMonitorFlags       flags,
 | 
			
		||||
					     GCancellable           *cancellable);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_file_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GFile *                 g_file_new_for_path               (const char                 *path);
 | 
			
		||||
GFile *                 g_file_new_for_uri                (const char                 *uri);
 | 
			
		||||
GFile *                 g_file_new_for_commandline_arg    (const char                 *arg);
 | 
			
		||||
GFile *                 g_file_parse_name                 (const char                 *parse_name);
 | 
			
		||||
GFile *                 g_file_dup                        (GFile                      *file);
 | 
			
		||||
guint                   g_file_hash                       (gconstpointer               file);
 | 
			
		||||
gboolean                g_file_equal                      (GFile                      *file1,
 | 
			
		||||
							   GFile                      *file2);
 | 
			
		||||
char *                  g_file_get_basename               (GFile                      *file);
 | 
			
		||||
char *                  g_file_get_path                   (GFile                      *file);
 | 
			
		||||
char *                  g_file_get_uri                    (GFile                      *file);
 | 
			
		||||
char *                  g_file_get_parse_name             (GFile                      *file);
 | 
			
		||||
GFile *                 g_file_get_parent                 (GFile                      *file);
 | 
			
		||||
GFile *                 g_file_get_child                  (GFile                      *file,
 | 
			
		||||
							   const char                 *name);
 | 
			
		||||
GFile *                 g_file_get_child_for_display_name (GFile                      *file,
 | 
			
		||||
							   const char                 *display_name,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_contains_file              (GFile                      *parent,
 | 
			
		||||
							   GFile                      *descendant);
 | 
			
		||||
char *                  g_file_get_relative_path          (GFile                      *parent,
 | 
			
		||||
							   GFile                      *descendant);
 | 
			
		||||
GFile *                 g_file_resolve_relative_path      (GFile                      *file,
 | 
			
		||||
							   const char                 *relative_path);
 | 
			
		||||
gboolean                g_file_is_native                  (GFile                      *file);
 | 
			
		||||
gboolean                g_file_has_uri_scheme             (GFile                      *file,
 | 
			
		||||
							   const char                 *uri_scheme);
 | 
			
		||||
char *                  g_file_get_uri_scheme             (GFile                      *file);
 | 
			
		||||
GFileInputStream *      g_file_read                       (GFile                      *file,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_read_async                 (GFile                      *file,
 | 
			
		||||
							   int                         io_priority,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
GFileInputStream *      g_file_read_finish                (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *res,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GFileOutputStream *     g_file_append_to                  (GFile                      *file,
 | 
			
		||||
							   GFileCreateFlags             flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GFileOutputStream *     g_file_create                     (GFile                      *file,
 | 
			
		||||
							   GFileCreateFlags             flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GFileOutputStream *     g_file_replace                    (GFile                      *file,
 | 
			
		||||
							   const char                 *etag,
 | 
			
		||||
							   gboolean                    make_backup,
 | 
			
		||||
							   GFileCreateFlags            flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_append_to_async            (GFile                      *file,
 | 
			
		||||
							   GFileCreateFlags            flags,
 | 
			
		||||
							   int                         io_priority,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
GFileOutputStream *     g_file_append_to_finish           (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *res,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_create_async               (GFile                      *file,
 | 
			
		||||
							   GFileCreateFlags            flags,
 | 
			
		||||
							   int                         io_priority,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
GFileOutputStream *     g_file_create_finish              (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *res,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_replace_async              (GFile                      *file,
 | 
			
		||||
							   const char                 *etag,
 | 
			
		||||
							   gboolean                    make_backup,
 | 
			
		||||
							   GFileCreateFlags            flags,
 | 
			
		||||
							   int                         io_priority,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
GFileOutputStream *     g_file_replace_finish             (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *res,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GFileInfo *             g_file_query_info                 (GFile                      *file,
 | 
			
		||||
							   const char                 *attributes,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_query_info_async           (GFile                      *file,
 | 
			
		||||
							   const char                 *attributes,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   int                         io_priority,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
GFileInfo *             g_file_query_info_finish          (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *res,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GFileInfo *             g_file_query_filesystem_info      (GFile                      *file,
 | 
			
		||||
							   const char                 *attributes,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GVolume *               g_file_find_enclosing_volume      (GFile                      *file,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GFileEnumerator *       g_file_enumerate_children         (GFile                      *file,
 | 
			
		||||
							   const char                 *attributes,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_enumerate_children_async   (GFile                      *file,
 | 
			
		||||
							   const char                 *attributes,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   int                         io_priority,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
GFileEnumerator *       g_file_enumerate_children_finish  (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *res,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GFile *                 g_file_set_display_name           (GFile                      *file,
 | 
			
		||||
							   const char                 *display_name,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_set_display_name_async     (GFile                      *file,
 | 
			
		||||
							   const char                 *display_name,
 | 
			
		||||
							   int                         io_priority,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
GFile *                 g_file_set_display_name_finish    (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *res,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_delete                     (GFile                      *file,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_trash                      (GFile                      *file,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_copy                       (GFile                      *source,
 | 
			
		||||
							   GFile                      *destination,
 | 
			
		||||
							   GFileCopyFlags              flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GFileProgressCallback       progress_callback,
 | 
			
		||||
							   gpointer                    progress_callback_data,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_move                       (GFile                      *source,
 | 
			
		||||
							   GFile                      *destination,
 | 
			
		||||
							   GFileCopyFlags              flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GFileProgressCallback       progress_callback,
 | 
			
		||||
							   gpointer                    progress_callback_data,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_make_directory             (GFile                      *file,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_make_symbolic_link         (GFile                      *file,
 | 
			
		||||
							   const char                 *symlink_value,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GFileAttributeInfoList *g_file_query_settable_attributes  (GFile                      *file,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
GFileAttributeInfoList *g_file_query_writable_namespaces  (GFile                      *file,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_set_attribute              (GFile                      *file,
 | 
			
		||||
							   const char                 *attribute,
 | 
			
		||||
							   const GFileAttributeValue  *value,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_set_attributes_from_info   (GFile                      *file,
 | 
			
		||||
							   GFileInfo                  *info,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_set_attributes_async       (GFile                      *file,
 | 
			
		||||
							   GFileInfo                  *info,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   int                         io_priority,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
gboolean                g_file_set_attributes_finish      (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *result,
 | 
			
		||||
							   GFileInfo                 **info,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_set_attribute_string       (GFile                      *file,
 | 
			
		||||
							   const char                 *attribute,
 | 
			
		||||
							   const char                 *value,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_set_attribute_byte_string  (GFile                      *file,
 | 
			
		||||
							   const char                 *attribute,
 | 
			
		||||
							   const char                 *value,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_set_attribute_uint32       (GFile                      *file,
 | 
			
		||||
							   const char                 *attribute,
 | 
			
		||||
							   guint32                     value,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_set_attribute_int32        (GFile                      *file,
 | 
			
		||||
							   const char                 *attribute,
 | 
			
		||||
							   gint32                      value,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_set_attribute_uint64       (GFile                      *file,
 | 
			
		||||
							   const char                 *attribute,
 | 
			
		||||
							   guint64                     value,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
gboolean                g_file_set_attribute_int64        (GFile                      *file,
 | 
			
		||||
							   const char                 *attribute,
 | 
			
		||||
							   gint64                      value,
 | 
			
		||||
							   GFileQueryInfoFlags         flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_mount_for_location              (GFile                      *location,
 | 
			
		||||
							   GMountOperation            *mount_operation,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
gboolean                g_mount_for_location_finish       (GFile                      *location,
 | 
			
		||||
							   GAsyncResult               *result,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_mount_mountable            (GFile                      *file,
 | 
			
		||||
							   GMountOperation            *mount_operation,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
GFile *                 g_file_mount_mountable_finish     (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *result,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_unmount_mountable          (GFile                      *file,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
gboolean                g_file_unmount_mountable_finish   (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *result,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
void                    g_file_eject_mountable            (GFile                      *file,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GAsyncReadyCallback         callback,
 | 
			
		||||
							   gpointer                    user_data);
 | 
			
		||||
gboolean                g_file_eject_mountable_finish     (GFile                      *file,
 | 
			
		||||
							   GAsyncResult               *result,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
 | 
			
		||||
gboolean                g_file_copy_attributes            (GFile                      *source,
 | 
			
		||||
							   GFile                      *destination,
 | 
			
		||||
							   GFileCopyFlags              flags,
 | 
			
		||||
							   GCancellable               *cancellable,
 | 
			
		||||
							   GError                    **error);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GDirectoryMonitor* g_file_monitor_directory          (GFile                  *file,
 | 
			
		||||
						      GFileMonitorFlags       flags,
 | 
			
		||||
						      GCancellable           *cancellable);
 | 
			
		||||
GFileMonitor*      g_file_monitor_file               (GFile                  *file,
 | 
			
		||||
						      GFileMonitorFlags       flags,
 | 
			
		||||
						      GCancellable           *cancellable);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Utilities */
 | 
			
		||||
 | 
			
		||||
gboolean g_file_load_contents                (GFile                  *file,
 | 
			
		||||
					      GCancellable           *cancellable,
 | 
			
		||||
					      char                  **contents,
 | 
			
		||||
					      gsize                  *length,
 | 
			
		||||
					      char                  **etag_out,
 | 
			
		||||
					      GError                **error);
 | 
			
		||||
void     g_file_load_contents_async          (GFile                  *file,
 | 
			
		||||
					      GCancellable           *cancellable,
 | 
			
		||||
					      GAsyncReadyCallback     callback,
 | 
			
		||||
					      gpointer                user_data);
 | 
			
		||||
gboolean g_file_load_contents_finish         (GFile                  *file,
 | 
			
		||||
					      GAsyncResult           *res,
 | 
			
		||||
					      char                  **contents,
 | 
			
		||||
					      gsize                  *length,
 | 
			
		||||
					      char                  **etag_out,
 | 
			
		||||
					      GError                **error);
 | 
			
		||||
void     g_file_load_partial_contents_async  (GFile                  *file,
 | 
			
		||||
					      GCancellable           *cancellable,
 | 
			
		||||
					      GFileReadMoreCallback   read_more_callback,
 | 
			
		||||
					      GAsyncReadyCallback     callback,
 | 
			
		||||
					      gpointer                user_data);
 | 
			
		||||
gboolean g_file_load_partial_contents_finish (GFile                  *file,
 | 
			
		||||
					      GAsyncResult           *res,
 | 
			
		||||
					      char                  **contents,
 | 
			
		||||
					      gsize                  *length,
 | 
			
		||||
					      char                  **etag_out,
 | 
			
		||||
					      GError                **error);
 | 
			
		||||
gboolean g_file_replace_contents             (GFile                  *file,
 | 
			
		||||
					      const char             *contents,
 | 
			
		||||
					      gsize                   length,
 | 
			
		||||
					      const char             *etag,
 | 
			
		||||
					      gboolean                make_backup,
 | 
			
		||||
					      GFileCreateFlags        flags,
 | 
			
		||||
					      char                  **new_etag,
 | 
			
		||||
					      GCancellable           *cancellable,
 | 
			
		||||
					      GError                **error);
 | 
			
		||||
void     g_file_replace_contents_async       (GFile                  *file,
 | 
			
		||||
					      const char             *contents,
 | 
			
		||||
					      gsize                   length,
 | 
			
		||||
					      const char             *etag,
 | 
			
		||||
					      gboolean                make_backup,
 | 
			
		||||
					      GFileCreateFlags        flags,
 | 
			
		||||
					      GCancellable           *cancellable,
 | 
			
		||||
					      GAsyncReadyCallback     callback,
 | 
			
		||||
					      gpointer                user_data);
 | 
			
		||||
gboolean g_file_replace_contents_finish      (GFile                  *file,
 | 
			
		||||
					      GAsyncResult           *res,
 | 
			
		||||
					      char                  **new_etag,
 | 
			
		||||
					      GError                **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_H__ */
 | 
			
		||||
							
								
								
									
										704
									
								
								gio/gfileattribute.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										704
									
								
								gio/gfileattribute.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,704 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "gfileattribute.h"
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_free:
 | 
			
		||||
 * @attr: a #GFileAttributeValue. 
 | 
			
		||||
 * 
 | 
			
		||||
 * Frees the memory used by @attr.
 | 
			
		||||
 *
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_free (GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  g_free (attr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_clear:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 *
 | 
			
		||||
 * Clears the value of @attr and sets its type to 
 | 
			
		||||
 * %G_FILE_ATTRIBUTE_TYPE_INVALID.
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_clear (GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
 | 
			
		||||
  if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING ||
 | 
			
		||||
      attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING)
 | 
			
		||||
    g_free (attr->u.string);
 | 
			
		||||
  
 | 
			
		||||
  if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT &&
 | 
			
		||||
      attr->u.obj != NULL)
 | 
			
		||||
    g_object_unref (attr->u.obj);
 | 
			
		||||
  
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_set:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * @new_value:
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_set (GFileAttributeValue *attr,
 | 
			
		||||
			    const GFileAttributeValue *new_value)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
  g_return_if_fail (new_value != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  *attr = *new_value;
 | 
			
		||||
 | 
			
		||||
  if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING ||
 | 
			
		||||
      attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING)
 | 
			
		||||
    attr->u.string = g_strdup (attr->u.string);
 | 
			
		||||
  
 | 
			
		||||
  if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT &&
 | 
			
		||||
      attr->u.obj != NULL)
 | 
			
		||||
    g_object_ref (attr->u.obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_new:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a new #GFileAttributeValue.
 | 
			
		||||
 **/
 | 
			
		||||
GFileAttributeValue *
 | 
			
		||||
g_file_attribute_value_new (void)
 | 
			
		||||
{
 | 
			
		||||
  GFileAttributeValue *attr;
 | 
			
		||||
 | 
			
		||||
  attr = g_new (GFileAttributeValue, 1);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID;
 | 
			
		||||
  return attr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_dup:
 | 
			
		||||
 * @other: a #GFileAttributeValue to duplicate.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a duplicate of the @other.
 | 
			
		||||
 **/
 | 
			
		||||
GFileAttributeValue *
 | 
			
		||||
g_file_attribute_value_dup (const GFileAttributeValue *other)
 | 
			
		||||
{
 | 
			
		||||
  GFileAttributeValue *attr;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (other != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  attr = g_new (GFileAttributeValue, 1);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID;
 | 
			
		||||
  g_file_attribute_value_set (attr, other);
 | 
			
		||||
  return attr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
valid_char (char c)
 | 
			
		||||
{
 | 
			
		||||
  return c >= 32 && c <= 126 && c != '\\';
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
escape_byte_string (const char *str)
 | 
			
		||||
{
 | 
			
		||||
  size_t len;
 | 
			
		||||
  int num_invalid, i;
 | 
			
		||||
  char *escaped_val, *p;
 | 
			
		||||
  unsigned char c;
 | 
			
		||||
  char *hex_digits = "0123456789abcdef";
 | 
			
		||||
  
 | 
			
		||||
  len = strlen (str);
 | 
			
		||||
  
 | 
			
		||||
  num_invalid = 0;
 | 
			
		||||
  for (i = 0; i < len; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (!valid_char (str[i]))
 | 
			
		||||
	num_invalid++;
 | 
			
		||||
    }
 | 
			
		||||
	
 | 
			
		||||
  if (num_invalid == 0)
 | 
			
		||||
    return g_strdup (str);
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      escaped_val = g_malloc (len + num_invalid*3 + 1);
 | 
			
		||||
 | 
			
		||||
      p = escaped_val;
 | 
			
		||||
      for (i = 0; i < len; i++)
 | 
			
		||||
	{
 | 
			
		||||
	  c = str[i];
 | 
			
		||||
	  if (valid_char (c))
 | 
			
		||||
	    *p++ = c;
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
	      *p++ = '\\';
 | 
			
		||||
	      *p++ = 'x';
 | 
			
		||||
	      *p++ = hex_digits[(c >> 8) & 0xf];
 | 
			
		||||
	      *p++ = hex_digits[c & 0xf];
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
      *p++ = 0;
 | 
			
		||||
      return escaped_val;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_as_string:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 *
 | 
			
		||||
 * Converts a #GFileAttributeValue to a string for display.
 | 
			
		||||
 * The returned string should be freed when no longer needed
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a string from the @attr, %NULL on error, or "<invalid>" if 
 | 
			
		||||
 * @attr is of type %G_FILE_ATTRIBUTE_TYPE_INVALID.
 | 
			
		||||
 **/
 | 
			
		||||
char *
 | 
			
		||||
g_file_attribute_value_as_string (const GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  char *str;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (attr != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  switch (attr->type)
 | 
			
		||||
    {
 | 
			
		||||
    case G_FILE_ATTRIBUTE_TYPE_STRING:
 | 
			
		||||
      str = g_strdup (attr->u.string);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
 | 
			
		||||
      str = escape_byte_string (attr->u.string);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_FILE_ATTRIBUTE_TYPE_BOOLEAN:
 | 
			
		||||
      str = g_strdup_printf ("%s", attr->u.boolean?"TRUE":"FALSE");
 | 
			
		||||
      break;
 | 
			
		||||
    case G_FILE_ATTRIBUTE_TYPE_UINT32:
 | 
			
		||||
      str = g_strdup_printf ("%u", (unsigned int)attr->u.uint32);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_FILE_ATTRIBUTE_TYPE_INT32:
 | 
			
		||||
      str = g_strdup_printf ("%i", (int)attr->u.int32);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_FILE_ATTRIBUTE_TYPE_UINT64:
 | 
			
		||||
      str = g_strdup_printf ("%"G_GUINT64_FORMAT, attr->u.uint64);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_FILE_ATTRIBUTE_TYPE_INT64:
 | 
			
		||||
      str = g_strdup_printf ("%"G_GINT64_FORMAT, attr->u.int64);
 | 
			
		||||
      break;
 | 
			
		||||
    case G_FILE_ATTRIBUTE_TYPE_OBJECT:
 | 
			
		||||
      str = g_strdup_printf ("%s:%p", g_type_name_from_instance
 | 
			
		||||
                                          ((GTypeInstance *) attr->u.obj),
 | 
			
		||||
                                      attr->u.obj);
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      g_warning ("Invalid type in GFileInfo attribute");
 | 
			
		||||
      str = g_strdup ("<invalid>");
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return str;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_get_string:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
const char *
 | 
			
		||||
g_file_attribute_value_get_string (const GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  if (attr == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING, NULL);
 | 
			
		||||
 | 
			
		||||
  return attr->u.string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_get_byte_string:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
const char *
 | 
			
		||||
g_file_attribute_value_get_byte_string (const GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  if (attr == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, NULL);
 | 
			
		||||
 | 
			
		||||
  return attr->u.string;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_get_boolean:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_attribute_value_get_boolean (const GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  if (attr == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BOOLEAN, FALSE);
 | 
			
		||||
 | 
			
		||||
  return attr->u.boolean;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_get_uint32:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
guint32
 | 
			
		||||
g_file_attribute_value_get_uint32 (const GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  if (attr == NULL)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT32, 0);
 | 
			
		||||
 | 
			
		||||
  return attr->u.uint32;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_get_int32:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
gint32
 | 
			
		||||
g_file_attribute_value_get_int32 (const GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  if (attr == NULL)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_INT32, 0);
 | 
			
		||||
 | 
			
		||||
  return attr->u.int32;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_get_uint64:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/  
 | 
			
		||||
guint64
 | 
			
		||||
g_file_attribute_value_get_uint64 (const GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  if (attr == NULL)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT64, 0);
 | 
			
		||||
 | 
			
		||||
  return attr->u.uint64;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_get_int64:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
gint64
 | 
			
		||||
g_file_attribute_value_get_int64 (const GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  if (attr == NULL)
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_INT64, 0);
 | 
			
		||||
 | 
			
		||||
  return attr->u.int64;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_get_object:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
GObject *
 | 
			
		||||
g_file_attribute_value_get_object (const GFileAttributeValue *attr)
 | 
			
		||||
{
 | 
			
		||||
  if (attr == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT, NULL);
 | 
			
		||||
 | 
			
		||||
  return attr->u.obj;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_set_string:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * @string:
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_set_string (GFileAttributeValue *attr,
 | 
			
		||||
				   const char          *string)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
  g_return_if_fail (string != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_STRING;
 | 
			
		||||
  attr->u.string = g_strdup (string);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_set_byte_string:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * @string:
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_set_byte_string (GFileAttributeValue *attr,
 | 
			
		||||
					const char          *string)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
  g_return_if_fail (string != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_BYTE_STRING;
 | 
			
		||||
  attr->u.string = g_strdup (string);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_set_boolean:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * @value:
 | 
			
		||||
 *  
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_set_boolean (GFileAttributeValue *attr,
 | 
			
		||||
				    gboolean             value)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_BOOLEAN;
 | 
			
		||||
  attr->u.boolean = !!value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_set_uint32:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * @value:
 | 
			
		||||
 * 
 | 
			
		||||
 **/ 
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_set_uint32 (GFileAttributeValue *attr,
 | 
			
		||||
				   guint32              value)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_UINT32;
 | 
			
		||||
  attr->u.uint32 = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_set_int32:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * @value:
 | 
			
		||||
 *  
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_set_int32 (GFileAttributeValue *attr,
 | 
			
		||||
				  gint32               value)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_INT32;
 | 
			
		||||
  attr->u.int32 = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_set_uint64:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * @value:
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_set_uint64 (GFileAttributeValue *attr,
 | 
			
		||||
				   guint64              value)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_UINT64;
 | 
			
		||||
  attr->u.uint64 = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_set_int64:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * @value: a #gint64 to set the value to.
 | 
			
		||||
 *  
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_set_int64 (GFileAttributeValue *attr,
 | 
			
		||||
				  gint64               value)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_INT64;
 | 
			
		||||
  attr->u.int64 = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_value_set_object:
 | 
			
		||||
 * @attr: a #GFileAttributeValue.
 | 
			
		||||
 * @obj: a #GObject.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the file attribute @attr to contain the value @obj.
 | 
			
		||||
 * The @attr references the object internally.
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_value_set_object (GFileAttributeValue *attr,
 | 
			
		||||
				   GObject             *obj)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (attr != NULL);
 | 
			
		||||
  g_return_if_fail (obj != NULL);
 | 
			
		||||
 | 
			
		||||
  g_file_attribute_value_clear (attr);
 | 
			
		||||
  attr->type = G_FILE_ATTRIBUTE_TYPE_OBJECT;
 | 
			
		||||
  attr->u.obj = g_object_ref (obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  GFileAttributeInfoList public;
 | 
			
		||||
  GArray *array;
 | 
			
		||||
  int ref_count;
 | 
			
		||||
} GFileAttributeInfoListPriv;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
list_update_public (GFileAttributeInfoListPriv *priv)
 | 
			
		||||
{
 | 
			
		||||
  priv->public.infos = (GFileAttributeInfo *)priv->array->data;
 | 
			
		||||
  priv->public.n_infos = priv->array->len;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_info_list_new:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns a new #GFileAttributeInfoList.
 | 
			
		||||
 **/
 | 
			
		||||
GFileAttributeInfoList *
 | 
			
		||||
g_file_attribute_info_list_new (void)
 | 
			
		||||
{
 | 
			
		||||
  GFileAttributeInfoListPriv *priv;
 | 
			
		||||
 | 
			
		||||
  priv = g_new0 (GFileAttributeInfoListPriv, 1);
 | 
			
		||||
  
 | 
			
		||||
  priv->ref_count = 1;
 | 
			
		||||
  priv->array = g_array_new (TRUE, FALSE, sizeof (GFileAttributeInfo));
 | 
			
		||||
  
 | 
			
		||||
  list_update_public (priv);
 | 
			
		||||
  
 | 
			
		||||
  return (GFileAttributeInfoList *)priv;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_info_list_dup:
 | 
			
		||||
 * @list: a #GFileAttributeInfoList to duplicate.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns a duplicate of the given @list. 
 | 
			
		||||
 **/
 | 
			
		||||
GFileAttributeInfoList *
 | 
			
		||||
g_file_attribute_info_list_dup (GFileAttributeInfoList *list)
 | 
			
		||||
{
 | 
			
		||||
  GFileAttributeInfoListPriv *new;
 | 
			
		||||
  int i;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (list != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  new = g_new0 (GFileAttributeInfoListPriv, 1);
 | 
			
		||||
  new->ref_count = 1;
 | 
			
		||||
  new->array = g_array_new (TRUE, FALSE, sizeof (GFileAttributeInfo));
 | 
			
		||||
 | 
			
		||||
  g_array_set_size (new->array, list->n_infos);
 | 
			
		||||
  list_update_public (new);
 | 
			
		||||
  for (i = 0; i < list->n_infos; i++)
 | 
			
		||||
    {
 | 
			
		||||
      new->public.infos[i].name = g_strdup (list->infos[i].name);
 | 
			
		||||
      new->public.infos[i].type = list->infos[i].type;
 | 
			
		||||
      new->public.infos[i].flags = list->infos[i].flags;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return (GFileAttributeInfoList *)new;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_info_list_ref:
 | 
			
		||||
 * @list: a #GFileAttributeInfoList to reference.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: #GFileAttributeInfoList or %NULL on error.
 | 
			
		||||
 **/
 | 
			
		||||
GFileAttributeInfoList *
 | 
			
		||||
g_file_attribute_info_list_ref (GFileAttributeInfoList *list)
 | 
			
		||||
{
 | 
			
		||||
  GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (list != NULL, NULL);
 | 
			
		||||
  g_return_val_if_fail (priv->ref_count > 0, NULL);
 | 
			
		||||
  
 | 
			
		||||
  g_atomic_int_inc (&priv->ref_count);
 | 
			
		||||
  
 | 
			
		||||
  return list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_info_list_unref:
 | 
			
		||||
 * @list: The #GFileAttributeInfoList to unreference.
 | 
			
		||||
 * 
 | 
			
		||||
 * Removes a reference from the given @list. If the reference count
 | 
			
		||||
 * falls to zero, the @list is deleted.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_info_list_unref (GFileAttributeInfoList *list)
 | 
			
		||||
{
 | 
			
		||||
  GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list;
 | 
			
		||||
  int i;
 | 
			
		||||
  
 | 
			
		||||
  g_return_if_fail (list != NULL);
 | 
			
		||||
  g_return_if_fail (priv->ref_count > 0);
 | 
			
		||||
  
 | 
			
		||||
  if (g_atomic_int_dec_and_test (&priv->ref_count))
 | 
			
		||||
    {
 | 
			
		||||
      for (i = 0; i < list->n_infos; i++)
 | 
			
		||||
        g_free (list->infos[i].name);
 | 
			
		||||
      g_array_free (priv->array, TRUE);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
g_file_attribute_info_list_bsearch (GFileAttributeInfoList *list,
 | 
			
		||||
				    const char             *name)
 | 
			
		||||
{
 | 
			
		||||
  int start, end, mid;
 | 
			
		||||
  
 | 
			
		||||
  start = 0;
 | 
			
		||||
  end = list->n_infos;
 | 
			
		||||
 | 
			
		||||
  while (start != end)
 | 
			
		||||
    {
 | 
			
		||||
      mid = start + (end - start) / 2;
 | 
			
		||||
 | 
			
		||||
      if (strcmp (name, list->infos[mid].name) < 0)
 | 
			
		||||
	end = mid;
 | 
			
		||||
      else if (strcmp (name, list->infos[mid].name) > 0)
 | 
			
		||||
	start = mid + 1;
 | 
			
		||||
      else
 | 
			
		||||
	return mid;
 | 
			
		||||
    }
 | 
			
		||||
  return start;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_info_list_lookup:
 | 
			
		||||
 * @list: a #GFileAttributeInfoList.
 | 
			
		||||
 * @name: the name of the attribute to lookup.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a #GFileAttributeInfo for the @name, or %NULL if an 
 | 
			
		||||
 * attribute isn't found.
 | 
			
		||||
 **/
 | 
			
		||||
const GFileAttributeInfo *
 | 
			
		||||
g_file_attribute_info_list_lookup (GFileAttributeInfoList *list,
 | 
			
		||||
				   const char             *name)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (list != NULL, NULL);
 | 
			
		||||
  g_return_val_if_fail (name != NULL, NULL);
 | 
			
		||||
  
 | 
			
		||||
  i = g_file_attribute_info_list_bsearch (list, name);
 | 
			
		||||
 | 
			
		||||
  if (i < list->n_infos && strcmp (list->infos[i].name, name) == 0)
 | 
			
		||||
    return &list->infos[i];
 | 
			
		||||
  
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_attribute_info_list_add:
 | 
			
		||||
 * @list: a #GFileAttributeInfoList.
 | 
			
		||||
 * @name: the name of the attribute to add.
 | 
			
		||||
 * @type: the #GFileAttributeType for the attribute.
 | 
			
		||||
 * @flags: #GFileAttributeFlags for the attribute.
 | 
			
		||||
 * 
 | 
			
		||||
 * Adds a new attribute with @name to the @list, setting
 | 
			
		||||
 * its @type and @flags. 
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_attribute_info_list_add    (GFileAttributeInfoList *list,
 | 
			
		||||
				   const char             *name,
 | 
			
		||||
				   GFileAttributeType      type,
 | 
			
		||||
				   GFileAttributeFlags     flags)
 | 
			
		||||
{
 | 
			
		||||
  GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list;
 | 
			
		||||
  GFileAttributeInfo info;
 | 
			
		||||
  int i;
 | 
			
		||||
  
 | 
			
		||||
  g_return_if_fail (list != NULL);
 | 
			
		||||
  g_return_if_fail (name != NULL);
 | 
			
		||||
 | 
			
		||||
  i = g_file_attribute_info_list_bsearch (list, name);
 | 
			
		||||
 | 
			
		||||
  if (i < list->n_infos && strcmp (list->infos[i].name, name) == 0)
 | 
			
		||||
    {
 | 
			
		||||
      list->infos[i].type = type;
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  info.name = g_strdup (name);
 | 
			
		||||
  info.type = type;
 | 
			
		||||
  info.flags = flags;
 | 
			
		||||
  g_array_insert_vals (priv->array, i, &info, 1);
 | 
			
		||||
 | 
			
		||||
  list_update_public (priv);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										132
									
								
								gio/gfileattribute.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								gio/gfileattribute.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILE_ATTRIBUTE_H__
 | 
			
		||||
#define __G_FILE_ATTRIBUTE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  G_FILE_ATTRIBUTE_TYPE_INVALID = 0,
 | 
			
		||||
  G_FILE_ATTRIBUTE_TYPE_STRING,
 | 
			
		||||
  G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, /* zero terminated string of non-zero bytes */
 | 
			
		||||
  G_FILE_ATTRIBUTE_TYPE_BOOLEAN,
 | 
			
		||||
  G_FILE_ATTRIBUTE_TYPE_UINT32,
 | 
			
		||||
  G_FILE_ATTRIBUTE_TYPE_INT32,
 | 
			
		||||
  G_FILE_ATTRIBUTE_TYPE_UINT64,
 | 
			
		||||
  G_FILE_ATTRIBUTE_TYPE_INT64,
 | 
			
		||||
  G_FILE_ATTRIBUTE_TYPE_OBJECT
 | 
			
		||||
} GFileAttributeType;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  G_FILE_ATTRIBUTE_FLAGS_NONE = 0,
 | 
			
		||||
  G_FILE_ATTRIBUTE_FLAGS_COPY_WITH_FILE = 1 << 0,
 | 
			
		||||
  G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED = 1 << 1
 | 
			
		||||
} GFileAttributeFlags;
 | 
			
		||||
 | 
			
		||||
/* Used by g_file_set_attributes_from_info */
 | 
			
		||||
typedef enum {
 | 
			
		||||
  G_FILE_ATTRIBUTE_STATUS_UNSET = 0,
 | 
			
		||||
  G_FILE_ATTRIBUTE_STATUS_SET,
 | 
			
		||||
  G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING
 | 
			
		||||
} GFileAttributeStatus;
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_VALUE_INIT {0}
 | 
			
		||||
 | 
			
		||||
typedef struct  {
 | 
			
		||||
  GFileAttributeType type : 8;
 | 
			
		||||
  GFileAttributeStatus status : 8;
 | 
			
		||||
  union {
 | 
			
		||||
    gboolean boolean;
 | 
			
		||||
    gint32 int32;
 | 
			
		||||
    guint32 uint32;
 | 
			
		||||
    gint64 int64;
 | 
			
		||||
    guint64 uint64;
 | 
			
		||||
    char *string;
 | 
			
		||||
    GQuark quark;
 | 
			
		||||
    GObject *obj;
 | 
			
		||||
  } u;
 | 
			
		||||
} GFileAttributeValue;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  char *name;
 | 
			
		||||
  GFileAttributeType type;
 | 
			
		||||
  GFileAttributeFlags flags;
 | 
			
		||||
} GFileAttributeInfo;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  GFileAttributeInfo *infos;
 | 
			
		||||
  int n_infos;
 | 
			
		||||
} GFileAttributeInfoList;
 | 
			
		||||
 | 
			
		||||
GFileAttributeValue *g_file_attribute_value_new             (void);
 | 
			
		||||
void                 g_file_attribute_value_free            (GFileAttributeValue *attr);
 | 
			
		||||
void                 g_file_attribute_value_clear           (GFileAttributeValue *attr);
 | 
			
		||||
void                 g_file_attribute_value_set             (GFileAttributeValue *attr,
 | 
			
		||||
							     const GFileAttributeValue *new_value);
 | 
			
		||||
GFileAttributeValue *g_file_attribute_value_dup             (const GFileAttributeValue *other);
 | 
			
		||||
 | 
			
		||||
char *               g_file_attribute_value_as_string       (const GFileAttributeValue *attr);
 | 
			
		||||
 | 
			
		||||
const char *         g_file_attribute_value_get_string      (const GFileAttributeValue *attr);
 | 
			
		||||
const char *         g_file_attribute_value_get_byte_string (const GFileAttributeValue *attr);
 | 
			
		||||
gboolean             g_file_attribute_value_get_boolean     (const GFileAttributeValue *attr);
 | 
			
		||||
guint32              g_file_attribute_value_get_uint32      (const GFileAttributeValue *attr);
 | 
			
		||||
gint32               g_file_attribute_value_get_int32       (const GFileAttributeValue *attr);
 | 
			
		||||
guint64              g_file_attribute_value_get_uint64      (const GFileAttributeValue *attr);
 | 
			
		||||
gint64               g_file_attribute_value_get_int64       (const GFileAttributeValue *attr);
 | 
			
		||||
GObject *            g_file_attribute_value_get_object      (const GFileAttributeValue *attr);
 | 
			
		||||
 | 
			
		||||
void                 g_file_attribute_value_set_string      (GFileAttributeValue *attr,
 | 
			
		||||
							     const char          *string);
 | 
			
		||||
void                 g_file_attribute_value_set_byte_string (GFileAttributeValue *attr,
 | 
			
		||||
							     const char          *string);
 | 
			
		||||
void                 g_file_attribute_value_set_boolean     (GFileAttributeValue *attr,
 | 
			
		||||
							     gboolean             value);
 | 
			
		||||
void                 g_file_attribute_value_set_uint32      (GFileAttributeValue *attr,
 | 
			
		||||
							     guint32              value);
 | 
			
		||||
void                 g_file_attribute_value_set_int32       (GFileAttributeValue *attr,
 | 
			
		||||
							     gint32               value);
 | 
			
		||||
void                 g_file_attribute_value_set_uint64      (GFileAttributeValue *attr,
 | 
			
		||||
							     guint64              value);
 | 
			
		||||
void                 g_file_attribute_value_set_int64       (GFileAttributeValue *attr,
 | 
			
		||||
							     gint64               value);
 | 
			
		||||
void                 g_file_attribute_value_set_object      (GFileAttributeValue *attr,
 | 
			
		||||
							     GObject             *obj);
 | 
			
		||||
 | 
			
		||||
GFileAttributeInfoList *  g_file_attribute_info_list_new    (void);
 | 
			
		||||
GFileAttributeInfoList *  g_file_attribute_info_list_ref    (GFileAttributeInfoList *list);
 | 
			
		||||
void                      g_file_attribute_info_list_unref  (GFileAttributeInfoList *list);
 | 
			
		||||
GFileAttributeInfoList *  g_file_attribute_info_list_dup    (GFileAttributeInfoList *list);
 | 
			
		||||
const GFileAttributeInfo *g_file_attribute_info_list_lookup (GFileAttributeInfoList *list,
 | 
			
		||||
							     const char             *name);
 | 
			
		||||
void                      g_file_attribute_info_list_add    (GFileAttributeInfoList *list,
 | 
			
		||||
							     const char             *name,
 | 
			
		||||
							     GFileAttributeType      type,
 | 
			
		||||
							     GFileAttributeFlags     flags);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_INFO_H__ */
 | 
			
		||||
							
								
								
									
										617
									
								
								gio/gfileenumerator.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										617
									
								
								gio/gfileenumerator.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,617 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "gfileenumerator.h"
 | 
			
		||||
#include "gioscheduler.h"
 | 
			
		||||
#include "gasynchelper.h"
 | 
			
		||||
#include "gsimpleasyncresult.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GFileEnumerator, g_file_enumerator, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
struct _GFileEnumeratorPrivate {
 | 
			
		||||
  /* TODO: Should be public for subclasses? */
 | 
			
		||||
  guint closed : 1;
 | 
			
		||||
  guint pending : 1;
 | 
			
		||||
  GAsyncReadyCallback outstanding_callback;
 | 
			
		||||
  GError *outstanding_error;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void     g_file_enumerator_real_next_files_async  (GFileEnumerator      *enumerator,
 | 
			
		||||
							  int                   num_files,
 | 
			
		||||
							  int                   io_priority,
 | 
			
		||||
							  GCancellable         *cancellable,
 | 
			
		||||
							  GAsyncReadyCallback   callback,
 | 
			
		||||
							  gpointer              user_data);
 | 
			
		||||
static GList *  g_file_enumerator_real_next_files_finish (GFileEnumerator      *enumerator,
 | 
			
		||||
							  GAsyncResult         *res,
 | 
			
		||||
							  GError              **error);
 | 
			
		||||
static void     g_file_enumerator_real_close_async       (GFileEnumerator      *enumerator,
 | 
			
		||||
							  int                   io_priority,
 | 
			
		||||
							  GCancellable         *cancellable,
 | 
			
		||||
							  GAsyncReadyCallback   callback,
 | 
			
		||||
							  gpointer              user_data);
 | 
			
		||||
static gboolean g_file_enumerator_real_close_finish      (GFileEnumerator      *enumerator,
 | 
			
		||||
							  GAsyncResult         *res,
 | 
			
		||||
							  GError              **error);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_enumerator_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumerator *enumerator;
 | 
			
		||||
 | 
			
		||||
  enumerator = G_FILE_ENUMERATOR (object);
 | 
			
		||||
  
 | 
			
		||||
  if (!enumerator->priv->closed)
 | 
			
		||||
    g_file_enumerator_close (enumerator, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (g_file_enumerator_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_file_enumerator_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_enumerator_class_init (GFileEnumeratorClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GFileEnumeratorPrivate));
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_file_enumerator_finalize;
 | 
			
		||||
 | 
			
		||||
  klass->next_files_async = g_file_enumerator_real_next_files_async;
 | 
			
		||||
  klass->next_files_finish = g_file_enumerator_real_next_files_finish;
 | 
			
		||||
  klass->close_async = g_file_enumerator_real_close_async;
 | 
			
		||||
  klass->close_finish = g_file_enumerator_real_close_finish;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_enumerator_init (GFileEnumerator *enumerator)
 | 
			
		||||
{
 | 
			
		||||
  enumerator->priv = G_TYPE_INSTANCE_GET_PRIVATE (enumerator,
 | 
			
		||||
						  G_TYPE_FILE_ENUMERATOR,
 | 
			
		||||
						  GFileEnumeratorPrivate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_enumerator_next_file:
 | 
			
		||||
 * @enumerator: a #GFileEnumerator.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @error: location to store the error occuring, or %NULL to ignore
 | 
			
		||||
 *
 | 
			
		||||
 * Returns information for the next file in the enumerated object.
 | 
			
		||||
 * Will block until the information is available.
 | 
			
		||||
 *
 | 
			
		||||
 * On error, returns %NULL and sets @error to the error. If the
 | 
			
		||||
 * enumerator is at the end, %NULL will be returned and @error will
 | 
			
		||||
 * be unset.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: A #GFileInfo or %NULL on error or end of enumerator
 | 
			
		||||
 **/
 | 
			
		||||
GFileInfo *
 | 
			
		||||
g_file_enumerator_next_file (GFileEnumerator *enumerator,
 | 
			
		||||
			     GCancellable *cancellable,
 | 
			
		||||
			     GError **error)
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumeratorClass *class;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), NULL);
 | 
			
		||||
  g_return_val_if_fail (enumerator != NULL, NULL);
 | 
			
		||||
  
 | 
			
		||||
  if (enumerator->priv->closed)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
		   _("Enumerator is closed"));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (enumerator->priv->pending)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
		   _("File enumerator has outstanding operation"));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (enumerator->priv->outstanding_error)
 | 
			
		||||
    {
 | 
			
		||||
      g_propagate_error (error, enumerator->priv->outstanding_error);
 | 
			
		||||
      enumerator->priv->outstanding_error = NULL;
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
 | 
			
		||||
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_push_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  enumerator->priv->pending = TRUE;
 | 
			
		||||
  info = (* class->next_file) (enumerator, cancellable, error);
 | 
			
		||||
  enumerator->priv->pending = FALSE;
 | 
			
		||||
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_pop_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  return info;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_enumerator_close:
 | 
			
		||||
 * @enumerator: a #GFileEnumerator.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: location to store the error occuring, or %NULL to ignore
 | 
			
		||||
 *
 | 
			
		||||
 * Releases all resources used by this enumerator, making the
 | 
			
		||||
 * enumerator return %G_IO_ERROR_CLOSED on all calls.
 | 
			
		||||
 *
 | 
			
		||||
 * This will be automatically called when the last reference
 | 
			
		||||
 * is dropped, but you might want to call make sure resources
 | 
			
		||||
 * are released as early as possible.
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: #TRUE on success or #FALSE on error.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_enumerator_close (GFileEnumerator *enumerator,
 | 
			
		||||
			 GCancellable *cancellable,
 | 
			
		||||
			 GError **error)
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumeratorClass *class;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), FALSE);
 | 
			
		||||
  g_return_val_if_fail (enumerator != NULL, FALSE);
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
 | 
			
		||||
 | 
			
		||||
  if (enumerator->priv->closed)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  
 | 
			
		||||
  if (enumerator->priv->pending)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
		   _("File enumerator has outstanding operation"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_push_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  enumerator->priv->pending = TRUE;
 | 
			
		||||
  (* class->close) (enumerator, cancellable, error);
 | 
			
		||||
  enumerator->priv->pending = FALSE;
 | 
			
		||||
  enumerator->priv->closed = TRUE;
 | 
			
		||||
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_pop_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
next_async_callback_wrapper (GObject *source_object,
 | 
			
		||||
			     GAsyncResult *res,
 | 
			
		||||
			     gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumerator *enumerator = G_FILE_ENUMERATOR (source_object);
 | 
			
		||||
 | 
			
		||||
  enumerator->priv->pending = FALSE;
 | 
			
		||||
  if (enumerator->priv->outstanding_callback)
 | 
			
		||||
    (*enumerator->priv->outstanding_callback) (source_object, res, user_data);
 | 
			
		||||
  g_object_unref (enumerator);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_enumerator_next_files_async:
 | 
			
		||||
 * @enumerator: a #GFileEnumerator.
 | 
			
		||||
 * @num_files: the number of file info objects to request
 | 
			
		||||
 * @io_priority: the io priority of the request. the io priority of the request
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 * @callback: callback to call when the request is satisfied
 | 
			
		||||
 * @user_data: the user_data to pass to callback function 
 | 
			
		||||
 *
 | 
			
		||||
 * Request information for a number of files from the enumerator asynchronously.
 | 
			
		||||
 * When all i/o for the operation is finished the @callback will be called with
 | 
			
		||||
 * the requested information.
 | 
			
		||||
 *
 | 
			
		||||
 * The callback can be called with less than @num_files files in case of error
 | 
			
		||||
 * or at the end of the enumerator. In case of a partial error the callback will
 | 
			
		||||
 * be called with any succeeding items and no error, and on the next request the
 | 
			
		||||
 * error will be reported. If a request is cancelled the callback will be called
 | 
			
		||||
 * with %G_IO_ERROR_CANCELLED.
 | 
			
		||||
 *
 | 
			
		||||
 * During an async request no other sync and async calls are allowed, and will
 | 
			
		||||
 * result in %G_IO_ERROR_PENDING errors. 
 | 
			
		||||
 *
 | 
			
		||||
 * Any outstanding i/o request with higher priority (lower numerical value) will
 | 
			
		||||
 * be executed before an outstanding request with lower priority. Default
 | 
			
		||||
 * priority is %G_PRIORITY_DEFAULT.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_enumerator_next_files_async  (GFileEnumerator                *enumerator,
 | 
			
		||||
				     int                             num_files,
 | 
			
		||||
				     int                             io_priority,
 | 
			
		||||
				     GCancellable                   *cancellable,
 | 
			
		||||
				     GAsyncReadyCallback             callback,
 | 
			
		||||
				     gpointer                        user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumeratorClass *class;
 | 
			
		||||
  GSimpleAsyncResult *simple;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator));
 | 
			
		||||
  g_return_if_fail (enumerator != NULL);
 | 
			
		||||
  g_return_if_fail (num_files >= 0);
 | 
			
		||||
 | 
			
		||||
  if (num_files == 0)
 | 
			
		||||
    {
 | 
			
		||||
      simple = g_simple_async_result_new (G_OBJECT (enumerator),
 | 
			
		||||
					  callback,
 | 
			
		||||
					  user_data,
 | 
			
		||||
					  g_file_enumerator_next_files_async);
 | 
			
		||||
      g_simple_async_result_complete_in_idle (simple);
 | 
			
		||||
      g_object_unref (simple);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (enumerator->priv->closed)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (enumerator),
 | 
			
		||||
					   callback,
 | 
			
		||||
					   user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
					   _("File enumerator is already closed"));
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (enumerator->priv->pending)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (enumerator),
 | 
			
		||||
					   callback,
 | 
			
		||||
					   user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
					   _("File enumerator has outstanding operation"));
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
 | 
			
		||||
  
 | 
			
		||||
  enumerator->priv->pending = TRUE;
 | 
			
		||||
  enumerator->priv->outstanding_callback = callback;
 | 
			
		||||
  g_object_ref (enumerator);
 | 
			
		||||
  (* class->next_files_async) (enumerator, num_files, io_priority, cancellable, 
 | 
			
		||||
			       next_async_callback_wrapper, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_enumerator_next_files_finish:
 | 
			
		||||
 * @enumerator: a #GFileEnumerator.
 | 
			
		||||
 * @result: a #GAsyncResult.
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
GList *
 | 
			
		||||
g_file_enumerator_next_files_finish  (GFileEnumerator *enumerator,
 | 
			
		||||
				      GAsyncResult *result,
 | 
			
		||||
				      GError **error)
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumeratorClass *class;
 | 
			
		||||
  GSimpleAsyncResult *simple;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), NULL);
 | 
			
		||||
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
 | 
			
		||||
  
 | 
			
		||||
  if (G_IS_SIMPLE_ASYNC_RESULT (result))
 | 
			
		||||
    {
 | 
			
		||||
      simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
      if (g_simple_async_result_propagate_error (simple, error))
 | 
			
		||||
	return NULL;
 | 
			
		||||
      
 | 
			
		||||
      /* Special case read of 0 files */
 | 
			
		||||
      if (g_simple_async_result_get_source_tag (simple) == g_file_enumerator_next_files_async)
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
 | 
			
		||||
  return class->next_files_finish (enumerator, result, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
close_async_callback_wrapper (GObject *source_object,
 | 
			
		||||
			      GAsyncResult *res,
 | 
			
		||||
			      gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumerator *enumerator = G_FILE_ENUMERATOR (source_object);
 | 
			
		||||
  
 | 
			
		||||
  enumerator->priv->pending = FALSE;
 | 
			
		||||
  enumerator->priv->closed = TRUE;
 | 
			
		||||
  if (enumerator->priv->outstanding_callback)
 | 
			
		||||
    (*enumerator->priv->outstanding_callback) (source_object, res, user_data);
 | 
			
		||||
  g_object_unref (enumerator);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_enumerator_close_async:
 | 
			
		||||
 * @enumerator: a #GFileEnumerator.
 | 
			
		||||
 * @io_priority: the io priority of the request. the io priority of the request
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @callback: callback to call when the request is satisfied
 | 
			
		||||
 * @user_data: the user_data to pass to callback function 
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_enumerator_close_async (GFileEnumerator                *enumerator,
 | 
			
		||||
			       int                             io_priority,
 | 
			
		||||
			       GCancellable                   *cancellable,
 | 
			
		||||
			       GAsyncReadyCallback             callback,
 | 
			
		||||
			       gpointer                        user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumeratorClass *class;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator));
 | 
			
		||||
 | 
			
		||||
  if (enumerator->priv->closed)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (enumerator),
 | 
			
		||||
					   callback,
 | 
			
		||||
					   user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
					   _("File enumerator is already closed"));
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (enumerator->priv->pending)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (enumerator),
 | 
			
		||||
					   callback,
 | 
			
		||||
					   user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
					   _("File enumerator has outstanding operation"));
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
 | 
			
		||||
  
 | 
			
		||||
  enumerator->priv->pending = TRUE;
 | 
			
		||||
  enumerator->priv->outstanding_callback = callback;
 | 
			
		||||
  g_object_ref (enumerator);
 | 
			
		||||
  (* class->close_async) (enumerator, io_priority, cancellable,
 | 
			
		||||
			  close_async_callback_wrapper, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_enumerator_close_finish:
 | 
			
		||||
 * @enumerator: a #GFileEnumerator.
 | 
			
		||||
 * @result: a #GAsyncResult.
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: %TRUE if the close operation has finished successfully.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_enumerator_close_finish (GFileEnumerator                *enumerator,
 | 
			
		||||
				GAsyncResult                   *result,
 | 
			
		||||
				GError                        **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple;
 | 
			
		||||
  GFileEnumeratorClass *class;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), FALSE);
 | 
			
		||||
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
 | 
			
		||||
  
 | 
			
		||||
  if (G_IS_SIMPLE_ASYNC_RESULT (result))
 | 
			
		||||
    {
 | 
			
		||||
      simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
      if (g_simple_async_result_propagate_error (simple, error))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_ENUMERATOR_GET_CLASS (enumerator);
 | 
			
		||||
  return class->close_finish (enumerator, result, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_enumerator_is_closed:
 | 
			
		||||
 * @enumerator: a #GFileEnumerator.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if the @enumerator is closed.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_enumerator_is_closed (GFileEnumerator *enumerator)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), TRUE);
 | 
			
		||||
  
 | 
			
		||||
  return enumerator->priv->closed;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_enumerator_has_pending:
 | 
			
		||||
 * @enumerator: a #GFileEnumerator.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if the @enumerator has pending operations.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_enumerator_has_pending (GFileEnumerator *enumerator)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_ENUMERATOR (enumerator), TRUE);
 | 
			
		||||
  
 | 
			
		||||
  return enumerator->priv->pending;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_enumerator_set_pending:
 | 
			
		||||
 * @enumerator: a #GFileEnumerator.
 | 
			
		||||
 * @pending: a boolean value.
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_enumerator_set_pending (GFileEnumerator              *enumerator,
 | 
			
		||||
			       gboolean                   pending)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_FILE_ENUMERATOR (enumerator));
 | 
			
		||||
  
 | 
			
		||||
  enumerator->priv->pending = pending;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  int                num_files;
 | 
			
		||||
  GList             *files;
 | 
			
		||||
} NextAsyncOp;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
next_files_thread (GSimpleAsyncResult *res,
 | 
			
		||||
		   GObject *object,
 | 
			
		||||
		   GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  NextAsyncOp *op;
 | 
			
		||||
  GFileEnumeratorClass *class;
 | 
			
		||||
  GError *error = NULL;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
  GFileEnumerator *enumerator;
 | 
			
		||||
  int i;
 | 
			
		||||
 | 
			
		||||
  enumerator = G_FILE_ENUMERATOR (object);
 | 
			
		||||
  op = g_simple_async_result_get_op_res_gpointer (res);
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_ENUMERATOR_GET_CLASS (object);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < op->num_files; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (g_cancellable_set_error_if_cancelled (cancellable, &error))
 | 
			
		||||
	info = NULL;
 | 
			
		||||
      else
 | 
			
		||||
	info = class->next_file (enumerator, cancellable, &error);
 | 
			
		||||
      
 | 
			
		||||
      if (info == NULL)
 | 
			
		||||
	{
 | 
			
		||||
	  /* If we get an error after first file, return that on next operation */
 | 
			
		||||
	  if (error != NULL && i > 0)
 | 
			
		||||
	    {
 | 
			
		||||
	      if (error->domain == G_IO_ERROR &&
 | 
			
		||||
		  error->code == G_IO_ERROR_CANCELLED)
 | 
			
		||||
		g_error_free (error); /* Never propagate cancel errors to other call */
 | 
			
		||||
	      else
 | 
			
		||||
		enumerator->priv->outstanding_error = error;
 | 
			
		||||
	      error = NULL;
 | 
			
		||||
	    }
 | 
			
		||||
	      
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	op->files = g_list_prepend (op->files, info);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_enumerator_real_next_files_async (GFileEnumerator                *enumerator,
 | 
			
		||||
					 int                             num_files,
 | 
			
		||||
					 int                             io_priority,
 | 
			
		||||
					 GCancellable                   *cancellable,
 | 
			
		||||
					 GAsyncReadyCallback             callback,
 | 
			
		||||
					 gpointer                        user_data)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *res;
 | 
			
		||||
  NextAsyncOp *op;
 | 
			
		||||
 | 
			
		||||
  op = g_new0 (NextAsyncOp, 1);
 | 
			
		||||
 | 
			
		||||
  op->num_files = num_files;
 | 
			
		||||
  op->files = NULL;
 | 
			
		||||
 | 
			
		||||
  res = g_simple_async_result_new (G_OBJECT (enumerator), callback, user_data, g_file_enumerator_real_next_files_async);
 | 
			
		||||
  g_simple_async_result_set_op_res_gpointer (res, op, g_free);
 | 
			
		||||
  
 | 
			
		||||
  g_simple_async_result_run_in_thread (res, next_files_thread, io_priority, cancellable);
 | 
			
		||||
  g_object_unref (res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GList *
 | 
			
		||||
g_file_enumerator_real_next_files_finish (GFileEnumerator                *enumerator,
 | 
			
		||||
					  GAsyncResult                   *result,
 | 
			
		||||
					  GError                        **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
  NextAsyncOp *op;
 | 
			
		||||
 | 
			
		||||
  g_assert (g_simple_async_result_get_source_tag (simple) == 
 | 
			
		||||
	    g_file_enumerator_real_next_files_async);
 | 
			
		||||
 | 
			
		||||
  op = g_simple_async_result_get_op_res_gpointer (simple);
 | 
			
		||||
 | 
			
		||||
  return op->files;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
close_async_thread (GSimpleAsyncResult *res,
 | 
			
		||||
		    GObject *object,
 | 
			
		||||
		    GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumeratorClass *class;
 | 
			
		||||
  GError *error = NULL;
 | 
			
		||||
  gboolean result;
 | 
			
		||||
 | 
			
		||||
  /* Auto handling of cancelation disabled, and ignore
 | 
			
		||||
     cancellation, since we want to close things anyway, although
 | 
			
		||||
     possibly in a quick-n-dirty way. At least we never want to leak
 | 
			
		||||
     open handles */
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_ENUMERATOR_GET_CLASS (object);
 | 
			
		||||
  result = class->close (G_FILE_ENUMERATOR (object), cancellable, &error);
 | 
			
		||||
  if (!result)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_result_set_from_error (res, error);
 | 
			
		||||
      g_error_free (error);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_enumerator_real_close_async (GFileEnumerator      *enumerator,
 | 
			
		||||
				    int                   io_priority,
 | 
			
		||||
				    GCancellable         *cancellable,
 | 
			
		||||
				    GAsyncReadyCallback   callback,
 | 
			
		||||
				    gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *res;
 | 
			
		||||
  
 | 
			
		||||
  res = g_simple_async_result_new (G_OBJECT (enumerator),
 | 
			
		||||
				   callback,
 | 
			
		||||
				   user_data,
 | 
			
		||||
				   g_file_enumerator_real_close_async);
 | 
			
		||||
 | 
			
		||||
  g_simple_async_result_set_handle_cancellation (res, FALSE);
 | 
			
		||||
  
 | 
			
		||||
  g_simple_async_result_run_in_thread (res,
 | 
			
		||||
				       close_async_thread,
 | 
			
		||||
				       io_priority,
 | 
			
		||||
				       cancellable);
 | 
			
		||||
  g_object_unref (res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_enumerator_real_close_finish      (GFileEnumerator      *enumerator,
 | 
			
		||||
					  GAsyncResult         *result,
 | 
			
		||||
					  GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
  g_assert (g_simple_async_result_get_source_tag (simple) == 
 | 
			
		||||
	    g_file_enumerator_real_close_async);
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										130
									
								
								gio/gfileenumerator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								gio/gfileenumerator.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,130 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILE_ENUMERATOR_H__
 | 
			
		||||
#define __G_FILE_ENUMERATOR_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gioerror.h>
 | 
			
		||||
#include <gio/gcancellable.h>
 | 
			
		||||
#include <gio/gfileinfo.h>
 | 
			
		||||
#include <gio/gasyncresult.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILE_ENUMERATOR         (g_file_enumerator_get_type ())
 | 
			
		||||
#define G_FILE_ENUMERATOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_ENUMERATOR, GFileEnumerator))
 | 
			
		||||
#define G_FILE_ENUMERATOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_ENUMERATOR, GFileEnumeratorClass))
 | 
			
		||||
#define G_IS_FILE_ENUMERATOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_ENUMERATOR))
 | 
			
		||||
#define G_IS_FILE_ENUMERATOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_ENUMERATOR))
 | 
			
		||||
#define G_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_ENUMERATOR, GFileEnumeratorClass))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _GFileEnumerator         GFileEnumerator;
 | 
			
		||||
typedef struct _GFileEnumeratorClass    GFileEnumeratorClass;
 | 
			
		||||
typedef struct _GFileEnumeratorPrivate  GFileEnumeratorPrivate;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _GFileEnumerator
 | 
			
		||||
{
 | 
			
		||||
  GObject parent;
 | 
			
		||||
  
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GFileEnumeratorPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GFileEnumeratorClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* Virtual Table */
 | 
			
		||||
 | 
			
		||||
  GFileInfo *(*next_file)         (GFileEnumerator              *enumerator,
 | 
			
		||||
				   GCancellable                 *cancellable,
 | 
			
		||||
				   GError                      **error);
 | 
			
		||||
  gboolean   (*close)             (GFileEnumerator              *enumerator,
 | 
			
		||||
				   GCancellable                 *cancellable,
 | 
			
		||||
				   GError                      **error);
 | 
			
		||||
 | 
			
		||||
  void       (*next_files_async)  (GFileEnumerator                *enumerator,
 | 
			
		||||
				   int                             num_files,
 | 
			
		||||
				   int                             io_priority,
 | 
			
		||||
				   GCancellable                   *cancellable,
 | 
			
		||||
				   GAsyncReadyCallback             callback,
 | 
			
		||||
				   gpointer                        user_data);
 | 
			
		||||
  GList *    (*next_files_finish) (GFileEnumerator                *enumerator,
 | 
			
		||||
				   GAsyncResult                   *res,
 | 
			
		||||
				   GError                        **error);
 | 
			
		||||
  void       (*close_async)       (GFileEnumerator                *enumerator,
 | 
			
		||||
				   int                             io_priority,
 | 
			
		||||
				   GCancellable                   *cancellable,
 | 
			
		||||
				   GAsyncReadyCallback             callback,
 | 
			
		||||
				   gpointer                        user_data);
 | 
			
		||||
  gboolean   (*close_finish)      (GFileEnumerator                *enumerator,
 | 
			
		||||
				   GAsyncResult                   *res,
 | 
			
		||||
				   GError                        **error);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
  void (*_g_reserved6) (void);
 | 
			
		||||
  void (*_g_reserved7) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_file_enumerator_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GFileInfo *g_file_enumerator_next_file         (GFileEnumerator      *enumerator,
 | 
			
		||||
						GCancellable         *cancellable,
 | 
			
		||||
						GError              **error);
 | 
			
		||||
gboolean   g_file_enumerator_close             (GFileEnumerator      *enumerator,
 | 
			
		||||
						GCancellable         *cancellable,
 | 
			
		||||
						GError              **error);
 | 
			
		||||
void       g_file_enumerator_next_files_async  (GFileEnumerator      *enumerator,
 | 
			
		||||
						int                   num_files,
 | 
			
		||||
						int                   io_priority,
 | 
			
		||||
						GCancellable         *cancellable,
 | 
			
		||||
						GAsyncReadyCallback   callback,
 | 
			
		||||
						gpointer              user_data);
 | 
			
		||||
GList *    g_file_enumerator_next_files_finish (GFileEnumerator      *enumerator,
 | 
			
		||||
						GAsyncResult         *result,
 | 
			
		||||
						GError              **error);
 | 
			
		||||
void       g_file_enumerator_close_async       (GFileEnumerator      *enumerator,
 | 
			
		||||
						int                   io_priority,
 | 
			
		||||
						GCancellable         *cancellable,
 | 
			
		||||
						GAsyncReadyCallback   callback,
 | 
			
		||||
						gpointer              user_data);
 | 
			
		||||
gboolean   g_file_enumerator_close_finish      (GFileEnumerator      *enumerator,
 | 
			
		||||
						GAsyncResult         *result,
 | 
			
		||||
						GError              **error);
 | 
			
		||||
gboolean   g_file_enumerator_is_closed         (GFileEnumerator      *enumerator);
 | 
			
		||||
gboolean   g_file_enumerator_has_pending       (GFileEnumerator      *enumerator);
 | 
			
		||||
void       g_file_enumerator_set_pending       (GFileEnumerator      *enumerator,
 | 
			
		||||
						gboolean              pending);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_ENUMERATOR_H__ */
 | 
			
		||||
							
								
								
									
										257
									
								
								gio/gfileicon.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								gio/gfileicon.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,257 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "gfileicon.h"
 | 
			
		||||
#include "gsimpleasyncresult.h"
 | 
			
		||||
 | 
			
		||||
static void g_file_icon_icon_iface_init          (GIconIface          *iface);
 | 
			
		||||
static void g_file_icon_loadable_icon_iface_init (GLoadableIconIface  *iface);
 | 
			
		||||
static void g_file_icon_load_async               (GLoadableIcon       *icon,
 | 
			
		||||
						  int                  size,
 | 
			
		||||
						  GCancellable        *cancellable,
 | 
			
		||||
						  GAsyncReadyCallback  callback,
 | 
			
		||||
						  gpointer             user_data);
 | 
			
		||||
 | 
			
		||||
struct _GFileIcon
 | 
			
		||||
{
 | 
			
		||||
  GObject parent_instance;
 | 
			
		||||
 | 
			
		||||
  GFile *file;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GFileIconClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (GFileIcon, g_file_icon, G_TYPE_OBJECT,
 | 
			
		||||
			 G_IMPLEMENT_INTERFACE (G_TYPE_ICON,
 | 
			
		||||
						g_file_icon_icon_iface_init);
 | 
			
		||||
			 G_IMPLEMENT_INTERFACE (G_TYPE_LOADABLE_ICON,
 | 
			
		||||
						g_file_icon_loadable_icon_iface_init);
 | 
			
		||||
			 )
 | 
			
		||||
  
 | 
			
		||||
static void
 | 
			
		||||
g_file_icon_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GFileIcon *icon;
 | 
			
		||||
 | 
			
		||||
  icon = G_FILE_ICON (object);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (icon->file);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_file_icon_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_file_icon_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_icon_class_init (GFileIconClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_file_icon_finalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_icon_init (GFileIcon *file)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_icon_new:
 | 
			
		||||
 * @file:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
GIcon *
 | 
			
		||||
g_file_icon_new (GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  GFileIcon *icon;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE (file), NULL);
 | 
			
		||||
 | 
			
		||||
  icon = g_object_new (G_TYPE_FILE_ICON, NULL);
 | 
			
		||||
  icon->file = g_object_ref (file);
 | 
			
		||||
  
 | 
			
		||||
  return G_ICON (icon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_icon_get_file:
 | 
			
		||||
 * @icon:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
GFile *
 | 
			
		||||
g_file_icon_get_file (GFileIcon *icon)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_ICON (icon), NULL);
 | 
			
		||||
 | 
			
		||||
  return icon->file;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static guint
 | 
			
		||||
g_file_icon_hash (GIcon *icon)
 | 
			
		||||
{
 | 
			
		||||
  GFileIcon *file_icon = G_FILE_ICON (icon);
 | 
			
		||||
 | 
			
		||||
  return g_file_hash (file_icon->file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_icon_equal (GIcon *icon1,
 | 
			
		||||
		   GIcon *icon2)
 | 
			
		||||
{
 | 
			
		||||
  GFileIcon *file1 = G_FILE_ICON (icon1);
 | 
			
		||||
  GFileIcon *file2 = G_FILE_ICON (icon2);
 | 
			
		||||
  
 | 
			
		||||
  return g_file_equal (file1->file, file2->file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_icon_icon_iface_init (GIconIface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->hash = g_file_icon_hash;
 | 
			
		||||
  iface->equal = g_file_icon_equal;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GInputStream *
 | 
			
		||||
g_file_icon_load (GLoadableIcon        *icon,
 | 
			
		||||
		  int                   size,
 | 
			
		||||
		  char                **type,
 | 
			
		||||
		  GCancellable         *cancellable,
 | 
			
		||||
		  GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStream *stream;
 | 
			
		||||
  GFileIcon *file_icon = G_FILE_ICON (icon);
 | 
			
		||||
 | 
			
		||||
  stream = g_file_read (file_icon->file,
 | 
			
		||||
			cancellable,
 | 
			
		||||
			error);
 | 
			
		||||
  
 | 
			
		||||
  return G_INPUT_STREAM (stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  GLoadableIcon *icon;
 | 
			
		||||
  GAsyncReadyCallback callback;
 | 
			
		||||
  gpointer user_data;
 | 
			
		||||
} LoadData;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_data_free (LoadData *data)
 | 
			
		||||
{
 | 
			
		||||
  g_object_unref (data->icon);
 | 
			
		||||
  g_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_async_callback (GObject *source_object,
 | 
			
		||||
		     GAsyncResult *res,
 | 
			
		||||
		     gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStream *stream;
 | 
			
		||||
  GError *error = NULL;
 | 
			
		||||
  GSimpleAsyncResult *simple;
 | 
			
		||||
  LoadData *data = user_data;
 | 
			
		||||
 | 
			
		||||
  stream = g_file_read_finish (G_FILE (source_object), res, &error);
 | 
			
		||||
  
 | 
			
		||||
  if (stream == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      simple = g_simple_async_result_new_from_error (G_OBJECT (data->icon),
 | 
			
		||||
						     data->callback,
 | 
			
		||||
						     data->user_data,
 | 
			
		||||
						     error);
 | 
			
		||||
      g_error_free (error);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      simple = g_simple_async_result_new (G_OBJECT (data->icon),
 | 
			
		||||
					  data->callback,
 | 
			
		||||
					  data->user_data,
 | 
			
		||||
					  g_file_icon_load_async);
 | 
			
		||||
      
 | 
			
		||||
      g_simple_async_result_set_op_res_gpointer (simple,
 | 
			
		||||
						 stream,
 | 
			
		||||
						 g_object_unref);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  g_simple_async_result_complete (simple);
 | 
			
		||||
  
 | 
			
		||||
  load_data_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_icon_load_async  (GLoadableIcon        *icon,
 | 
			
		||||
			 int                   size,
 | 
			
		||||
			 GCancellable         *cancellable,
 | 
			
		||||
			 GAsyncReadyCallback   callback,
 | 
			
		||||
			 gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileIcon *file_icon = G_FILE_ICON (icon);
 | 
			
		||||
  LoadData *data;
 | 
			
		||||
 | 
			
		||||
  data = g_new0 (LoadData, 1);
 | 
			
		||||
  data->icon = g_object_ref (icon);
 | 
			
		||||
  data->callback = callback;
 | 
			
		||||
  data->user_data = user_data;
 | 
			
		||||
  
 | 
			
		||||
  g_file_read_async (file_icon->file, 0,
 | 
			
		||||
		     cancellable,
 | 
			
		||||
		     load_async_callback, data);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GInputStream *
 | 
			
		||||
g_file_icon_load_finish (GLoadableIcon        *icon,
 | 
			
		||||
			 GAsyncResult         *res,
 | 
			
		||||
			 char                **type,
 | 
			
		||||
			 GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
 | 
			
		||||
  gpointer op;
 | 
			
		||||
 | 
			
		||||
  g_assert (g_simple_async_result_get_source_tag (simple) == g_file_icon_load_async);
 | 
			
		||||
 | 
			
		||||
  if (type)
 | 
			
		||||
    *type = NULL;
 | 
			
		||||
  
 | 
			
		||||
  op = g_simple_async_result_get_op_res_gpointer (simple);
 | 
			
		||||
  if (op)
 | 
			
		||||
    return g_object_ref (op);
 | 
			
		||||
  
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_icon_loadable_icon_iface_init (GLoadableIconIface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->load = g_file_icon_load;
 | 
			
		||||
  iface->load_async = g_file_icon_load_async;
 | 
			
		||||
  iface->load_finish = g_file_icon_load_finish;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								gio/gfileicon.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								gio/gfileicon.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILE_ICON_H__
 | 
			
		||||
#define __G_FILE_ICON_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gloadableicon.h>
 | 
			
		||||
#include <gio/gfile.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILE_ICON         (g_file_icon_get_type ())
 | 
			
		||||
#define G_FILE_ICON(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_ICON, GFileIcon))
 | 
			
		||||
#define G_FILE_ICON_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_ICON, GFileIconClass))
 | 
			
		||||
#define G_IS_FILE_ICON(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_ICON))
 | 
			
		||||
#define G_IS_FILE_ICON_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_ICON))
 | 
			
		||||
#define G_FILE_ICON_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_ICON, GFileIconClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GFileIcon        GFileIcon;
 | 
			
		||||
typedef struct _GFileIconClass   GFileIconClass;
 | 
			
		||||
 | 
			
		||||
GType g_file_icon_get_type (void) G_GNUC_CONST;
 | 
			
		||||
  
 | 
			
		||||
GIcon *g_file_icon_new (GFile *file);
 | 
			
		||||
 | 
			
		||||
GFile *g_file_icon_get_file (GFileIcon *icon);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_ICON_H__ */
 | 
			
		||||
							
								
								
									
										1924
									
								
								gio/gfileinfo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1924
									
								
								gio/gfileinfo.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										280
									
								
								gio/gfileinfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										280
									
								
								gio/gfileinfo.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,280 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILE_INFO_H__
 | 
			
		||||
#define __G_FILE_INFO_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gfileattribute.h>
 | 
			
		||||
#include <gio/gicon.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILE_INFO         (g_file_info_get_type ())
 | 
			
		||||
#define G_FILE_INFO(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_INFO, GFileInfo))
 | 
			
		||||
#define G_FILE_INFO_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_INFO, GFileInfoClass))
 | 
			
		||||
#define G_IS_FILE_INFO(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_INFO))
 | 
			
		||||
#define G_IS_FILE_INFO_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_INFO))
 | 
			
		||||
#define G_FILE_INFO_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_INFO, GFileInfoClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GFileInfo        GFileInfo;
 | 
			
		||||
typedef struct _GFileInfoClass   GFileInfoClass;
 | 
			
		||||
typedef struct _GFileAttributeMatcher GFileAttributeMatcher;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  G_FILE_TYPE_UNKNOWN = 0,
 | 
			
		||||
  G_FILE_TYPE_REGULAR,
 | 
			
		||||
  G_FILE_TYPE_DIRECTORY,
 | 
			
		||||
  G_FILE_TYPE_SYMBOLIC_LINK,
 | 
			
		||||
  G_FILE_TYPE_SPECIAL, /* socket, fifo, blockdev, chardev */
 | 
			
		||||
  G_FILE_TYPE_SHORTCUT,
 | 
			
		||||
  G_FILE_TYPE_MOUNTABLE
 | 
			
		||||
} GFileType;
 | 
			
		||||
 | 
			
		||||
/* Common Attributes:  */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_TYPE "std:type"                     /* uint32 (GFileType) */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_IS_HIDDEN "std:is_hidden"           /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_IS_BACKUP "std:is_backup"           /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_IS_SYMLINK "std:is_symlink"         /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_IS_VIRTUAL "std:is_virtual"         /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_NAME "std:name"                     /* byte string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_DISPLAY_NAME "std:display_name"     /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_EDIT_NAME "std:edit_name"           /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_COPY_NAME "std:copy_name"           /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_ICON "std:icon"                     /* object (GIcon) */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_CONTENT_TYPE "std:content_type"     /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_FAST_CONTENT_TYPE "std:fast_content_type" /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_SIZE "std:size"                     /* uint64 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET "std:symlink_target" /* byte string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_TARGET_URI "std:target_uri"         /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_STD_SORT_ORDER "std:sort_order"         /* int32  */
 | 
			
		||||
 | 
			
		||||
/* Entity tags, used to avoid missing updates on save */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_ETAG_VALUE "etag:value"                 /* string */
 | 
			
		||||
 | 
			
		||||
/* File identifier, for e.g. avoiding loops when doing recursive directory scanning */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_ID_FILE "id:file"                     /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_ID_FS "id:fs"                         /* string */
 | 
			
		||||
 | 
			
		||||
/* Calculated Access Rights for current user */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_ACCESS_CAN_READ "access:can_read"       /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_ACCESS_CAN_WRITE "access:can_write"     /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_ACCESS_CAN_EXECUTE "access:can_execute" /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_ACCESS_CAN_DELETE "access:can_delete"   /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_ACCESS_CAN_TRASH "access:can_trash"     /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_ACCESS_CAN_RENAME "access:can_rename"   /* boolean */ 
 | 
			
		||||
/* TODO: Should we have special version for directories? can_enumerate, etc */
 | 
			
		||||
 | 
			
		||||
/* Mountable attributes */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_MOUNT "mountable:can_mount"     /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_UNMOUNT "mountable:can_unmount" /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_MOUNTABLE_CAN_EJECT "mountable:can_eject"     /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_MOUNTABLE_UNIX_DEVICE "mountable:unix_device" /* uint32 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_MOUNTABLE_HAL_UDI "mountable:hal_udi"         /* string */
 | 
			
		||||
 | 
			
		||||
/* Time attributes */
 | 
			
		||||
 | 
			
		||||
  /* The last time the file content or an attribute was modified */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_TIME_MODIFIED "time:modified"           /* uint64 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC "time:modified_usec" /* uint32 */
 | 
			
		||||
  /* The last time the file was read */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_TIME_ACCESS "time:access"               /* uint64 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_TIME_ACCESS_USEC "time:access_usec"     /* uint32 */
 | 
			
		||||
  /* The last time a file attribute was changed (e.g. unix ctime) */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_TIME_CHANGED "time:changed"             /* uint64 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_TIME_CHANGED_USEC "time:changed_usec"   /* uint32 */
 | 
			
		||||
  /* When the file was originally created (e.g. ntfs ctime) */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_TIME_CREATED "time:created"             /* uint64 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_TIME_CREATED_USEC "time:created_usec"   /* uint32 */
 | 
			
		||||
 | 
			
		||||
/* Unix specific attributes */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_DEVICE "unix:device"               /* uint32 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_INODE "unix:inode"                 /* uint64 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_MODE "unix:mode"                   /* uint32 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_NLINK "unix:nlink"                 /* uint32 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_UID "unix:uid"                     /* uint32 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_GID "unix:gid"                     /* uint32 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_RDEV "unix:rdev"                   /* uint32 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_BLOCK_SIZE "unix:block_size"       /* uint32 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_BLOCKS "unix:blocks"               /* uint64 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_UNIX_IS_MOUNTPOINT "unix:is_mountpoint" /* boolean */
 | 
			
		||||
 | 
			
		||||
/* DOS specific attributes */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_DOS_IS_ARCHIVE "dos:is_archive"         /* boolean */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_DOS_IS_SYSTEM "dos:is_system"           /* boolean */
 | 
			
		||||
 | 
			
		||||
/* Owner attributes */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_OWNER_USER "owner:user"                 /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_OWNER_USER_REAL "owner:user_real"       /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_OWNER_GROUP "owner:group"               /* string */
 | 
			
		||||
 | 
			
		||||
/* Thumbnails */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_THUMBNAIL_PATH "thumbnail:path"         /* bytestring */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_THUMBNAILING_FAILED "thumbnail:failed"         /* bytestring */
 | 
			
		||||
 | 
			
		||||
/* File system info (for g_file_get_filesystem_info) */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_FS_SIZE "fs:size"                       /* uint64 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_FS_FREE "fs:free"                       /* uint64 */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_FS_TYPE "fs:type"                       /* string */
 | 
			
		||||
#define G_FILE_ATTRIBUTE_FS_READONLY "fs:readonly"               /* boolean */
 | 
			
		||||
 | 
			
		||||
#define G_FILE_ATTRIBUTE_GVFS_BACKEND "gvfs:backend"             /* string */
 | 
			
		||||
 | 
			
		||||
GType g_file_info_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GFileInfo *        g_file_info_new                       (void);
 | 
			
		||||
GFileInfo *        g_file_info_dup                       (GFileInfo  *other);
 | 
			
		||||
void               g_file_info_copy_into                 (GFileInfo  *src_info,
 | 
			
		||||
							  GFileInfo  *dest_info);
 | 
			
		||||
gboolean           g_file_info_has_attribute             (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
char **            g_file_info_list_attributes           (GFileInfo  *info,
 | 
			
		||||
							  const char *name_space);
 | 
			
		||||
GFileAttributeType g_file_info_get_attribute_type        (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
void               g_file_info_remove_attribute          (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
GFileAttributeValue * g_file_info_get_attribute          (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
const char *       g_file_info_get_attribute_string      (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
const char *       g_file_info_get_attribute_byte_string (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
gboolean           g_file_info_get_attribute_boolean     (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
guint32            g_file_info_get_attribute_uint32      (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
gint32             g_file_info_get_attribute_int32       (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
guint64            g_file_info_get_attribute_uint64      (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
gint64             g_file_info_get_attribute_int64       (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
GObject *          g_file_info_get_attribute_object      (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute);
 | 
			
		||||
 | 
			
		||||
void               g_file_info_set_attribute             (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute,
 | 
			
		||||
							  const GFileAttributeValue *attr_value);
 | 
			
		||||
void               g_file_info_set_attribute_string      (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute,
 | 
			
		||||
							  const char *attr_value);
 | 
			
		||||
void               g_file_info_set_attribute_byte_string (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute,
 | 
			
		||||
							  const char *attr_value);
 | 
			
		||||
void               g_file_info_set_attribute_boolean     (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute,
 | 
			
		||||
							  gboolean    attr_value);
 | 
			
		||||
void               g_file_info_set_attribute_uint32      (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute,
 | 
			
		||||
							  guint32     attr_value);
 | 
			
		||||
void               g_file_info_set_attribute_int32       (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute,
 | 
			
		||||
							  gint32      attr_value);
 | 
			
		||||
void               g_file_info_set_attribute_uint64      (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute,
 | 
			
		||||
							  guint64     attr_value);
 | 
			
		||||
void               g_file_info_set_attribute_int64       (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute,
 | 
			
		||||
							  gint64      attr_value);
 | 
			
		||||
void               g_file_info_set_attribute_object      (GFileInfo  *info,
 | 
			
		||||
							  const char *attribute,
 | 
			
		||||
							  GObject    *attr_value);
 | 
			
		||||
 | 
			
		||||
void               g_file_info_clear_status              (GFileInfo  *info);
 | 
			
		||||
 | 
			
		||||
/* Helper getters: */
 | 
			
		||||
GFileType         g_file_info_get_file_type          (GFileInfo         *info);
 | 
			
		||||
gboolean          g_file_info_get_is_hidden          (GFileInfo         *info);
 | 
			
		||||
gboolean          g_file_info_get_is_backup          (GFileInfo         *info);
 | 
			
		||||
gboolean          g_file_info_get_is_symlink         (GFileInfo         *info);
 | 
			
		||||
const char *      g_file_info_get_name               (GFileInfo         *info);
 | 
			
		||||
const char *      g_file_info_get_display_name       (GFileInfo         *info);
 | 
			
		||||
const char *      g_file_info_get_edit_name          (GFileInfo         *info);
 | 
			
		||||
GIcon *           g_file_info_get_icon               (GFileInfo         *info);
 | 
			
		||||
const char *      g_file_info_get_content_type       (GFileInfo         *info);
 | 
			
		||||
goffset           g_file_info_get_size               (GFileInfo         *info);
 | 
			
		||||
void              g_file_info_get_modification_time  (GFileInfo         *info,
 | 
			
		||||
						      GTimeVal          *result);
 | 
			
		||||
const char *      g_file_info_get_symlink_target     (GFileInfo         *info);
 | 
			
		||||
const char *      g_file_info_get_etag               (GFileInfo         *info);
 | 
			
		||||
gint32            g_file_info_get_sort_order         (GFileInfo         *info);
 | 
			
		||||
 | 
			
		||||
void              g_file_info_set_attribute_mask     (GFileInfo         *info,
 | 
			
		||||
						      GFileAttributeMatcher *mask);
 | 
			
		||||
void              g_file_info_unset_attribute_mask   (GFileInfo         *info);
 | 
			
		||||
 | 
			
		||||
/* Helper setters: */
 | 
			
		||||
void              g_file_info_set_file_type          (GFileInfo         *info,
 | 
			
		||||
						      GFileType          type);
 | 
			
		||||
void              g_file_info_set_is_hidden          (GFileInfo         *info,
 | 
			
		||||
						      gboolean           is_hidden);
 | 
			
		||||
void              g_file_info_set_is_symlink         (GFileInfo         *info,
 | 
			
		||||
						      gboolean           is_symlink);
 | 
			
		||||
void              g_file_info_set_name               (GFileInfo         *info,
 | 
			
		||||
						      const char        *name);
 | 
			
		||||
void              g_file_info_set_display_name       (GFileInfo         *info,
 | 
			
		||||
						      const char        *display_name);
 | 
			
		||||
void              g_file_info_set_edit_name          (GFileInfo         *info,
 | 
			
		||||
						      const char        *edit_name);
 | 
			
		||||
void              g_file_info_set_icon               (GFileInfo         *info,
 | 
			
		||||
						      GIcon             *icon);
 | 
			
		||||
void              g_file_info_set_content_type       (GFileInfo         *info,
 | 
			
		||||
						      const char        *content_type);
 | 
			
		||||
void              g_file_info_set_size               (GFileInfo         *info,
 | 
			
		||||
						      goffset            size);
 | 
			
		||||
void              g_file_info_set_modification_time  (GFileInfo         *info,
 | 
			
		||||
						      GTimeVal          *mtime);
 | 
			
		||||
void              g_file_info_set_symlink_target     (GFileInfo         *info,
 | 
			
		||||
						      const char        *symlink_target);
 | 
			
		||||
void              g_file_info_set_sort_order         (GFileInfo         *info,
 | 
			
		||||
						      gint32             sort_order);
 | 
			
		||||
 | 
			
		||||
/* Helper functions for attributes: */
 | 
			
		||||
/* TODO: Move this to glib when merging */
 | 
			
		||||
char *g_format_file_size_for_display (goffset size);
 | 
			
		||||
 | 
			
		||||
GFileAttributeMatcher *g_file_attribute_matcher_new            (const char            *attributes);
 | 
			
		||||
GFileAttributeMatcher *g_file_attribute_matcher_ref            (GFileAttributeMatcher *matcher);
 | 
			
		||||
void                   g_file_attribute_matcher_unref          (GFileAttributeMatcher *matcher);
 | 
			
		||||
gboolean               g_file_attribute_matcher_matches        (GFileAttributeMatcher *matcher,
 | 
			
		||||
								const char            *attribute);
 | 
			
		||||
gboolean               g_file_attribute_matcher_matches_only   (GFileAttributeMatcher *matcher,
 | 
			
		||||
								const char            *attribute);
 | 
			
		||||
gboolean               g_file_attribute_matcher_enumerate_namespace (GFileAttributeMatcher *matcher,
 | 
			
		||||
								     const char            *ns);
 | 
			
		||||
const char *           g_file_attribute_matcher_enumerate_next (GFileAttributeMatcher *matcher);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_INFO_H__ */
 | 
			
		||||
							
								
								
									
										481
									
								
								gio/gfileinputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										481
									
								
								gio/gfileinputstream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,481 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <gfileinputstream.h>
 | 
			
		||||
#include <gseekable.h>
 | 
			
		||||
#include "gsimpleasyncresult.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
static void       g_file_input_stream_seekable_iface_init    (GSeekableIface       *iface);
 | 
			
		||||
static goffset    g_file_input_stream_seekable_tell          (GSeekable            *seekable);
 | 
			
		||||
static gboolean   g_file_input_stream_seekable_can_seek      (GSeekable            *seekable);
 | 
			
		||||
static gboolean   g_file_input_stream_seekable_seek          (GSeekable            *seekable,
 | 
			
		||||
							      goffset               offset,
 | 
			
		||||
							      GSeekType             type,
 | 
			
		||||
							      GCancellable         *cancellable,
 | 
			
		||||
							      GError              **error);
 | 
			
		||||
static gboolean   g_file_input_stream_seekable_can_truncate  (GSeekable            *seekable);
 | 
			
		||||
static gboolean   g_file_input_stream_seekable_truncate      (GSeekable            *seekable,
 | 
			
		||||
							      goffset               offset,
 | 
			
		||||
							      GCancellable         *cancellable,
 | 
			
		||||
							      GError              **error);
 | 
			
		||||
static void       g_file_input_stream_real_query_info_async  (GFileInputStream     *stream,
 | 
			
		||||
							      char                 *attributes,
 | 
			
		||||
							      int                   io_priority,
 | 
			
		||||
							      GCancellable         *cancellable,
 | 
			
		||||
							      GAsyncReadyCallback   callback,
 | 
			
		||||
							      gpointer              user_data);
 | 
			
		||||
static GFileInfo *g_file_input_stream_real_query_info_finish (GFileInputStream     *stream,
 | 
			
		||||
							      GAsyncResult         *result,
 | 
			
		||||
							      GError              **error);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (GFileInputStream, g_file_input_stream, G_TYPE_INPUT_STREAM,
 | 
			
		||||
			 G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
 | 
			
		||||
						g_file_input_stream_seekable_iface_init))
 | 
			
		||||
 | 
			
		||||
struct _GFileInputStreamPrivate {
 | 
			
		||||
  GAsyncReadyCallback outstanding_callback;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_input_stream_class_init (GFileInputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GFileInputStreamPrivate));
 | 
			
		||||
 | 
			
		||||
  klass->query_info_async = g_file_input_stream_real_query_info_async;
 | 
			
		||||
  klass->query_info_finish = g_file_input_stream_real_query_info_finish;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_input_stream_seekable_iface_init (GSeekableIface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->tell = g_file_input_stream_seekable_tell;
 | 
			
		||||
  iface->can_seek = g_file_input_stream_seekable_can_seek;
 | 
			
		||||
  iface->seek = g_file_input_stream_seekable_seek;
 | 
			
		||||
  iface->can_truncate = g_file_input_stream_seekable_can_truncate;
 | 
			
		||||
  iface->truncate = g_file_input_stream_seekable_truncate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_input_stream_init (GFileInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
 | 
			
		||||
					      G_TYPE_FILE_INPUT_STREAM,
 | 
			
		||||
					      GFileInputStreamPrivate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_input_stream_query_info:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * @attributes:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
GFileInfo *
 | 
			
		||||
g_file_input_stream_query_info (GFileInputStream     *stream,
 | 
			
		||||
				   char                 *attributes,
 | 
			
		||||
				   GCancellable         *cancellable,
 | 
			
		||||
				   GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStreamClass *class;
 | 
			
		||||
  GInputStream *input_stream;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), NULL);
 | 
			
		||||
  
 | 
			
		||||
  input_stream = G_INPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  if (g_input_stream_is_closed (input_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
		   _("Stream is already closed"));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (g_input_stream_has_pending (input_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
		   _("Stream has outstanding operation"));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
      
 | 
			
		||||
  info = NULL;
 | 
			
		||||
  
 | 
			
		||||
  g_input_stream_set_pending (input_stream, TRUE);
 | 
			
		||||
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_push_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_INPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
  if (class->query_info)
 | 
			
		||||
    info = class->query_info (stream, attributes, cancellable, error);
 | 
			
		||||
  else
 | 
			
		||||
    g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
		 _("Stream doesn't support query_info"));
 | 
			
		||||
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_pop_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  g_input_stream_set_pending (input_stream, FALSE);
 | 
			
		||||
  
 | 
			
		||||
  return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_ready_callback_wrapper (GObject *source_object,
 | 
			
		||||
			      GAsyncResult *res,
 | 
			
		||||
			      gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStream *stream = G_FILE_INPUT_STREAM (source_object);
 | 
			
		||||
 | 
			
		||||
  g_input_stream_set_pending (G_INPUT_STREAM (stream), FALSE);
 | 
			
		||||
  if (stream->priv->outstanding_callback)
 | 
			
		||||
    (*stream->priv->outstanding_callback) (source_object, res, user_data);
 | 
			
		||||
  g_object_unref (stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_input_stream_query_info_async:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * @attributes:
 | 
			
		||||
 * @io_priority: the io priority of the request.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. @callback:
 | 
			
		||||
 * @user_data:
 | 
			
		||||
 *  
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_input_stream_query_info_async (GFileInputStream     *stream,
 | 
			
		||||
					 char                 *attributes,
 | 
			
		||||
					 int                   io_priority,
 | 
			
		||||
					 GCancellable         *cancellable,
 | 
			
		||||
					 GAsyncReadyCallback   callback,
 | 
			
		||||
					 gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStreamClass *klass;
 | 
			
		||||
  GInputStream *input_stream;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_FILE_INPUT_STREAM (stream));
 | 
			
		||||
 | 
			
		||||
  input_stream = G_INPUT_STREAM (stream);
 | 
			
		||||
 
 | 
			
		||||
  if (g_input_stream_is_closed (input_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (stream),
 | 
			
		||||
					   callback,
 | 
			
		||||
					   user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
					   _("Stream is already closed"));
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (g_input_stream_has_pending (input_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (stream),
 | 
			
		||||
					   callback,
 | 
			
		||||
					   user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
					   _("Stream has outstanding operation"));
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  klass = G_FILE_INPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  g_input_stream_set_pending (input_stream, TRUE);
 | 
			
		||||
  stream->priv->outstanding_callback = callback;
 | 
			
		||||
  g_object_ref (stream);
 | 
			
		||||
  klass->query_info_async (stream, attributes, io_priority, cancellable,
 | 
			
		||||
			      async_ready_callback_wrapper, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_input_stream_query_info_finish:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * @result:
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: #GFileInfo. 
 | 
			
		||||
 **/
 | 
			
		||||
GFileInfo *
 | 
			
		||||
g_file_input_stream_query_info_finish (GFileInputStream     *stream,
 | 
			
		||||
					  GAsyncResult         *result,
 | 
			
		||||
					  GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple;
 | 
			
		||||
  GFileInputStreamClass *class;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), NULL);
 | 
			
		||||
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
 | 
			
		||||
 | 
			
		||||
  if (G_IS_SIMPLE_ASYNC_RESULT (result))
 | 
			
		||||
    {
 | 
			
		||||
      simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
      if (g_simple_async_result_propagate_error (simple, error))
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_INPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
  return class->query_info_finish (stream, result, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_input_stream_tell:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
goffset
 | 
			
		||||
g_file_input_stream_tell (GFileInputStream  *stream)
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStreamClass *class;
 | 
			
		||||
  goffset offset;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), 0);
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_INPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  offset = 0;
 | 
			
		||||
  if (class->tell)
 | 
			
		||||
    offset = class->tell (stream);
 | 
			
		||||
 | 
			
		||||
  return offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static goffset
 | 
			
		||||
g_file_input_stream_seekable_tell (GSeekable *seekable)
 | 
			
		||||
{
 | 
			
		||||
  return g_file_input_stream_tell (G_FILE_INPUT_STREAM (seekable));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_input_stream_can_seek:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if stream can be seeked. %FALSE otherwise.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_input_stream_can_seek (GFileInputStream  *stream)
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStreamClass *class;
 | 
			
		||||
  gboolean can_seek;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_INPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  can_seek = FALSE;
 | 
			
		||||
  if (class->seek)
 | 
			
		||||
    {
 | 
			
		||||
      can_seek = TRUE;
 | 
			
		||||
      if (class->can_seek)
 | 
			
		||||
	can_seek = class->can_seek (stream);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return can_seek;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_input_stream_seekable_can_seek (GSeekable *seekable)
 | 
			
		||||
{
 | 
			
		||||
  return g_file_input_stream_can_seek (G_FILE_INPUT_STREAM (seekable));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_input_stream_seek:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * @offset:
 | 
			
		||||
 * @type:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_input_stream_seek (GFileInputStream  *stream,
 | 
			
		||||
			  goffset            offset,
 | 
			
		||||
			  GSeekType          type,
 | 
			
		||||
			  GCancellable      *cancellable,
 | 
			
		||||
			  GError           **error)
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStreamClass *class;
 | 
			
		||||
  GInputStream *input_stream;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_INPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  input_stream = G_INPUT_STREAM (stream);
 | 
			
		||||
  class = G_FILE_INPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  if (g_input_stream_is_closed (input_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
		   _("Stream is already closed"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (g_input_stream_has_pending (input_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
		   _("Stream has outstanding operation"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (!class->seek)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
		   _("Seek not supported on stream"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_input_stream_set_pending (input_stream, TRUE);
 | 
			
		||||
  
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_push_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  res = class->seek (stream, offset, type, cancellable, error);
 | 
			
		||||
  
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_pop_current_cancellable (cancellable);
 | 
			
		||||
 | 
			
		||||
  g_input_stream_set_pending (input_stream, FALSE);
 | 
			
		||||
  
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_input_stream_seekable_seek (GSeekable  *seekable,
 | 
			
		||||
				   goffset     offset,
 | 
			
		||||
				   GSeekType   type,
 | 
			
		||||
				   GCancellable  *cancellable,
 | 
			
		||||
				   GError    **error)
 | 
			
		||||
{
 | 
			
		||||
  return g_file_input_stream_seek (G_FILE_INPUT_STREAM (seekable),
 | 
			
		||||
				   offset, type, cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_input_stream_seekable_can_truncate (GSeekable  *seekable)
 | 
			
		||||
{
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_input_stream_seekable_truncate (GSeekable  *seekable,
 | 
			
		||||
				       goffset     offset,
 | 
			
		||||
				       GCancellable  *cancellable,
 | 
			
		||||
				       GError    **error)
 | 
			
		||||
{
 | 
			
		||||
  g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
	       _("Truncate not allowed on input stream"));
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/********************************************
 | 
			
		||||
 *   Default implementation of async ops    *
 | 
			
		||||
 ********************************************/
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  char *attributes;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
} QueryInfoAsyncData;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
query_info_data_free (QueryInfoAsyncData *data)
 | 
			
		||||
{
 | 
			
		||||
  if (data->info)
 | 
			
		||||
    g_object_unref (data->info);
 | 
			
		||||
  g_free (data->attributes);
 | 
			
		||||
  g_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
query_info_async_thread (GSimpleAsyncResult *res,
 | 
			
		||||
		       GObject *object,
 | 
			
		||||
		       GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStreamClass *class;
 | 
			
		||||
  GError *error = NULL;
 | 
			
		||||
  QueryInfoAsyncData *data;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
  
 | 
			
		||||
  data = g_simple_async_result_get_op_res_gpointer (res);
 | 
			
		||||
 | 
			
		||||
  info = NULL;
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_INPUT_STREAM_GET_CLASS (object);
 | 
			
		||||
  if (class->query_info)
 | 
			
		||||
    info = class->query_info (G_FILE_INPUT_STREAM (object), data->attributes, cancellable, &error);
 | 
			
		||||
  else
 | 
			
		||||
    g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
		 _("Stream doesn't support query_info"));
 | 
			
		||||
 | 
			
		||||
  if (info == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_result_set_from_error (res, error);
 | 
			
		||||
      g_error_free (error);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    data->info = info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_input_stream_real_query_info_async (GFileInputStream     *stream,
 | 
			
		||||
					      char                 *attributes,
 | 
			
		||||
					      int                   io_priority,
 | 
			
		||||
					      GCancellable         *cancellable,
 | 
			
		||||
					      GAsyncReadyCallback   callback,
 | 
			
		||||
					      gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *res;
 | 
			
		||||
  QueryInfoAsyncData *data;
 | 
			
		||||
 | 
			
		||||
  data = g_new0 (QueryInfoAsyncData, 1);
 | 
			
		||||
  data->attributes = g_strdup (attributes);
 | 
			
		||||
  
 | 
			
		||||
  res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_file_input_stream_real_query_info_async);
 | 
			
		||||
  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
 | 
			
		||||
  
 | 
			
		||||
  g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
 | 
			
		||||
  g_object_unref (res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFileInfo *
 | 
			
		||||
g_file_input_stream_real_query_info_finish (GFileInputStream     *stream,
 | 
			
		||||
					       GAsyncResult         *res,
 | 
			
		||||
					       GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
 | 
			
		||||
  QueryInfoAsyncData *data;
 | 
			
		||||
 | 
			
		||||
  g_assert (g_simple_async_result_get_source_tag (simple) == g_file_input_stream_real_query_info_async);
 | 
			
		||||
 | 
			
		||||
  data = g_simple_async_result_get_op_res_gpointer (simple);
 | 
			
		||||
  if (data->info)
 | 
			
		||||
    return g_object_ref (data->info);
 | 
			
		||||
  
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								gio/gfileinputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								gio/gfileinputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,110 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILE_INPUT_STREAM_H__
 | 
			
		||||
#define __G_FILE_INPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/ginputstream.h>
 | 
			
		||||
#include <gio/gfileinfo.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILE_INPUT_STREAM         (g_file_input_stream_get_type ())
 | 
			
		||||
#define G_FILE_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_INPUT_STREAM, GFileInputStream))
 | 
			
		||||
#define G_FILE_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_INPUT_STREAM, GFileInputStreamClass))
 | 
			
		||||
#define G_IS_FILE_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_INPUT_STREAM))
 | 
			
		||||
#define G_IS_FILE_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_INPUT_STREAM))
 | 
			
		||||
#define G_FILE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_INPUT_STREAM, GFileInputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GFileInputStream         GFileInputStream;
 | 
			
		||||
typedef struct _GFileInputStreamClass    GFileInputStreamClass;
 | 
			
		||||
typedef struct _GFileInputStreamPrivate  GFileInputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GFileInputStream
 | 
			
		||||
{
 | 
			
		||||
  GInputStream parent;
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GFileInputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GFileInputStreamClass
 | 
			
		||||
{
 | 
			
		||||
  GInputStreamClass parent_class;
 | 
			
		||||
 | 
			
		||||
  goffset    (*tell)          (GFileInputStream     *stream);
 | 
			
		||||
  gboolean   (*can_seek)      (GFileInputStream     *stream);
 | 
			
		||||
  gboolean   (*seek)	      (GFileInputStream     *stream,
 | 
			
		||||
			       goffset               offset,
 | 
			
		||||
			       GSeekType             type,
 | 
			
		||||
			       GCancellable         *cancellable,
 | 
			
		||||
			       GError              **error);
 | 
			
		||||
  GFileInfo *(*query_info)    (GFileInputStream     *stream,
 | 
			
		||||
			       char                 *attributes,
 | 
			
		||||
			       GCancellable         *cancellable,
 | 
			
		||||
			       GError              **error);
 | 
			
		||||
  void       (*query_info_async)  (GFileInputStream     *stream,
 | 
			
		||||
				   char                 *attributes,
 | 
			
		||||
				   int                   io_priority,
 | 
			
		||||
				   GCancellable         *cancellable,
 | 
			
		||||
				   GAsyncReadyCallback   callback,
 | 
			
		||||
				   gpointer              user_data);
 | 
			
		||||
  GFileInfo *(*query_info_finish) (GFileInputStream     *stream,
 | 
			
		||||
				   GAsyncResult         *res,
 | 
			
		||||
				   GError              **error);
 | 
			
		||||
    
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_file_input_stream_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GFileInfo *g_file_input_stream_query_info        (GFileInputStream     *stream,
 | 
			
		||||
						  char                 *attributes,
 | 
			
		||||
						  GCancellable         *cancellable,
 | 
			
		||||
						  GError              **error);
 | 
			
		||||
void       g_file_input_stream_query_info_async  (GFileInputStream     *stream,
 | 
			
		||||
						  char                 *attributes,
 | 
			
		||||
						  int                   io_priority,
 | 
			
		||||
						  GCancellable         *cancellable,
 | 
			
		||||
						  GAsyncReadyCallback   callback,
 | 
			
		||||
						  gpointer              user_data);
 | 
			
		||||
GFileInfo *g_file_input_stream_query_info_finish (GFileInputStream     *stream,
 | 
			
		||||
						  GAsyncResult         *result,
 | 
			
		||||
						  GError              **error);
 | 
			
		||||
goffset    g_file_input_stream_tell              (GFileInputStream     *stream);
 | 
			
		||||
gboolean   g_file_input_stream_can_seek          (GFileInputStream     *stream);
 | 
			
		||||
gboolean   g_file_input_stream_seek              (GFileInputStream     *stream,
 | 
			
		||||
						  goffset               offset,
 | 
			
		||||
						  GSeekType             type,
 | 
			
		||||
						  GCancellable         *cancellable,
 | 
			
		||||
						  GError              **error);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_FILE_INPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										380
									
								
								gio/gfilemonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										380
									
								
								gio/gfilemonitor.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,380 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "gfilemonitor.h"
 | 
			
		||||
#include "gio-marshal.h"
 | 
			
		||||
#include "gvfs.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  CHANGED,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (GFileMonitor, g_file_monitor, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
struct _GFileMonitorPrivate {
 | 
			
		||||
  gboolean cancelled;
 | 
			
		||||
  int rate_limit_msec;
 | 
			
		||||
 | 
			
		||||
  /* Rate limiting change events */
 | 
			
		||||
  guint32 last_sent_change_time; /* Some monitonic clock in msecs */
 | 
			
		||||
  GFile *last_sent_change_file;
 | 
			
		||||
  
 | 
			
		||||
  guint send_delayed_change_timeout;
 | 
			
		||||
 | 
			
		||||
  /* Virtual CHANGES_DONE_HINT emission */
 | 
			
		||||
  GSource *virtual_changes_done_timeout;
 | 
			
		||||
  GFile *virtual_changes_done_file;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_RATE_LIMIT_MSECS 800
 | 
			
		||||
#define DEFAULT_VIRTUAL_CHANGES_DONE_DELAY_SECS 2
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_monitor_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GFileMonitor *monitor;
 | 
			
		||||
 | 
			
		||||
  monitor = G_FILE_MONITOR (object);
 | 
			
		||||
 | 
			
		||||
  if (monitor->priv->last_sent_change_file)
 | 
			
		||||
    g_object_unref (monitor->priv->last_sent_change_file);
 | 
			
		||||
 | 
			
		||||
  if (monitor->priv->send_delayed_change_timeout != 0)
 | 
			
		||||
    g_source_remove (monitor->priv->send_delayed_change_timeout);
 | 
			
		||||
 | 
			
		||||
  if (monitor->priv->virtual_changes_done_file)
 | 
			
		||||
    g_object_unref (monitor->priv->virtual_changes_done_file);
 | 
			
		||||
 | 
			
		||||
  if (monitor->priv->virtual_changes_done_timeout)
 | 
			
		||||
    g_source_destroy (monitor->priv->virtual_changes_done_timeout);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_file_monitor_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_file_monitor_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_monitor_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GFileMonitor *monitor;
 | 
			
		||||
  
 | 
			
		||||
  monitor = G_FILE_MONITOR (object);
 | 
			
		||||
 | 
			
		||||
  /* Make sure we cancel on last unref */
 | 
			
		||||
  if (!monitor->priv->cancelled)
 | 
			
		||||
    g_file_monitor_cancel (monitor);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_file_monitor_parent_class)->dispose)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_file_monitor_parent_class)->dispose) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_monitor_class_init (GFileMonitorClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GFileMonitorPrivate));
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_file_monitor_finalize;
 | 
			
		||||
  gobject_class->dispose = g_file_monitor_dispose;
 | 
			
		||||
 | 
			
		||||
  signals[CHANGED] =
 | 
			
		||||
    g_signal_new (I_("changed"),
 | 
			
		||||
		  G_TYPE_FILE_MONITOR,
 | 
			
		||||
		  G_SIGNAL_RUN_LAST,
 | 
			
		||||
		  G_STRUCT_OFFSET (GFileMonitorClass, changed),
 | 
			
		||||
		  NULL, NULL,
 | 
			
		||||
		  _gio_marshal_VOID__OBJECT_OBJECT_INT,
 | 
			
		||||
		  G_TYPE_NONE,3,
 | 
			
		||||
		  G_TYPE_FILE,
 | 
			
		||||
		  G_TYPE_FILE,
 | 
			
		||||
		  G_TYPE_INT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_monitor_init (GFileMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
  monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
 | 
			
		||||
					       G_TYPE_FILE_MONITOR,
 | 
			
		||||
					       GFileMonitorPrivate);
 | 
			
		||||
  monitor->priv->rate_limit_msec = DEFAULT_RATE_LIMIT_MSECS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_monitor_is_cancelled:
 | 
			
		||||
 * @monitor:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if monitor is canceled. %FALSE otherwise.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_monitor_is_cancelled (GFileMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_MONITOR (monitor), FALSE);
 | 
			
		||||
 | 
			
		||||
  return monitor->priv->cancelled;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_monitor_cancel:
 | 
			
		||||
 * @monitor:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if monitor was cancelled.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_monitor_cancel (GFileMonitor* monitor)
 | 
			
		||||
{
 | 
			
		||||
  GFileMonitorClass *klass;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_MONITOR (monitor), FALSE);
 | 
			
		||||
  
 | 
			
		||||
  if (monitor->priv->cancelled)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
  
 | 
			
		||||
  monitor->priv->cancelled = TRUE;
 | 
			
		||||
  
 | 
			
		||||
  klass = G_FILE_MONITOR_GET_CLASS (monitor);
 | 
			
		||||
  return (* klass->cancel) (monitor);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_monitor_set_rate_limit:
 | 
			
		||||
 * @monitor: a #GFileMonitor.
 | 
			
		||||
 * @limit_msecs: a integer with the limit in milliseconds to 
 | 
			
		||||
 * poll for changes.
 | 
			
		||||
 *
 | 
			
		||||
 * Sets the rate limit to which the @monitor will poll for changes 
 | 
			
		||||
 * on the device. 
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_monitor_set_rate_limit (GFileMonitor *monitor,
 | 
			
		||||
			       int           limit_msecs)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_FILE_MONITOR (monitor));
 | 
			
		||||
 | 
			
		||||
  monitor->priv->rate_limit_msec = limit_msecs;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static guint32
 | 
			
		||||
get_time_msecs (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_thread_gettime() / (1000 * 1000);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static guint32
 | 
			
		||||
time_difference (guint32 from, guint32 to)
 | 
			
		||||
{
 | 
			
		||||
  if (from > to)
 | 
			
		||||
    return 0;
 | 
			
		||||
  return to - from;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Change event rate limiting support: */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
update_last_sent_change (GFileMonitor *monitor, GFile *file, guint32 time_now)
 | 
			
		||||
{
 | 
			
		||||
  if (monitor->priv->last_sent_change_file != file)
 | 
			
		||||
    {
 | 
			
		||||
      if (monitor->priv->last_sent_change_file)
 | 
			
		||||
	{
 | 
			
		||||
	  g_object_unref (monitor->priv->last_sent_change_file);
 | 
			
		||||
	  monitor->priv->last_sent_change_file = NULL;
 | 
			
		||||
	}
 | 
			
		||||
      if (file)
 | 
			
		||||
	monitor->priv->last_sent_change_file = g_object_ref (file);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  monitor->priv->last_sent_change_time = time_now;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_delayed_change_now (GFileMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
  if (monitor->priv->send_delayed_change_timeout)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_emit (monitor, signals[CHANGED], 0,
 | 
			
		||||
		     monitor->priv->last_sent_change_file, NULL,
 | 
			
		||||
		     G_FILE_MONITOR_EVENT_CHANGED);
 | 
			
		||||
      
 | 
			
		||||
      g_source_remove (monitor->priv->send_delayed_change_timeout);
 | 
			
		||||
      monitor->priv->send_delayed_change_timeout = 0;
 | 
			
		||||
 | 
			
		||||
      /* Same file, new last_sent time */
 | 
			
		||||
      monitor->priv->last_sent_change_time = get_time_msecs ();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
delayed_changed_event_timeout (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  GFileMonitor *monitor = data;
 | 
			
		||||
 | 
			
		||||
  send_delayed_change_now (monitor);
 | 
			
		||||
  
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
schedule_delayed_change (GFileMonitor *monitor, GFile *file, guint32 delay_msec)
 | 
			
		||||
{
 | 
			
		||||
  if (monitor->priv->send_delayed_change_timeout == 0) /* Only set the timeout once */
 | 
			
		||||
    {
 | 
			
		||||
      monitor->priv->send_delayed_change_timeout = 
 | 
			
		||||
	g_timeout_add (delay_msec, delayed_changed_event_timeout, monitor);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cancel_delayed_change (GFileMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
  if (monitor->priv->send_delayed_change_timeout != 0)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_remove (monitor->priv->send_delayed_change_timeout);
 | 
			
		||||
      monitor->priv->send_delayed_change_timeout = 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Virtual changes_done_hint support: */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
send_virtual_changes_done_now (GFileMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
  if (monitor->priv->virtual_changes_done_timeout)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_emit (monitor, signals[CHANGED], 0,
 | 
			
		||||
		     monitor->priv->virtual_changes_done_file, NULL,
 | 
			
		||||
		     G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT);
 | 
			
		||||
      
 | 
			
		||||
      g_source_destroy (monitor->priv->virtual_changes_done_timeout);
 | 
			
		||||
      monitor->priv->virtual_changes_done_timeout = NULL;
 | 
			
		||||
 | 
			
		||||
      g_object_unref (monitor->priv->virtual_changes_done_file);
 | 
			
		||||
      monitor->priv->virtual_changes_done_file = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
virtual_changes_done_timeout (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  GFileMonitor *monitor = data;
 | 
			
		||||
 | 
			
		||||
  send_virtual_changes_done_now (monitor);
 | 
			
		||||
  
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
schedule_virtual_change_done (GFileMonitor *monitor, GFile *file)
 | 
			
		||||
{
 | 
			
		||||
  GSource *source;
 | 
			
		||||
  
 | 
			
		||||
  source = g_timeout_source_new_seconds (DEFAULT_VIRTUAL_CHANGES_DONE_DELAY_SECS);
 | 
			
		||||
  
 | 
			
		||||
  g_source_set_callback (source, virtual_changes_done_timeout, monitor, NULL);
 | 
			
		||||
  g_source_attach (source, NULL);
 | 
			
		||||
  monitor->priv->virtual_changes_done_timeout = source;
 | 
			
		||||
  monitor->priv->virtual_changes_done_file = g_object_ref (file);
 | 
			
		||||
  g_source_unref (source);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cancel_virtual_changes_done (GFileMonitor *monitor)
 | 
			
		||||
{
 | 
			
		||||
  if (monitor->priv->virtual_changes_done_timeout)
 | 
			
		||||
    {
 | 
			
		||||
      g_source_destroy (monitor->priv->virtual_changes_done_timeout);
 | 
			
		||||
      monitor->priv->virtual_changes_done_timeout = NULL;
 | 
			
		||||
      
 | 
			
		||||
      g_object_unref (monitor->priv->virtual_changes_done_file);
 | 
			
		||||
      monitor->priv->virtual_changes_done_file = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_monitor_emit_event:
 | 
			
		||||
 * @monitor:
 | 
			
		||||
 * @file:
 | 
			
		||||
 * @other_file:
 | 
			
		||||
 * @event_type:
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_monitor_emit_event (GFileMonitor *monitor,
 | 
			
		||||
			   GFile *file,
 | 
			
		||||
			   GFile *other_file,
 | 
			
		||||
			   GFileMonitorEvent event_type)
 | 
			
		||||
{
 | 
			
		||||
  guint32 time_now, since_last;
 | 
			
		||||
  gboolean emit_now;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_FILE_MONITOR (monitor));
 | 
			
		||||
  g_return_if_fail (G_IS_FILE (file));
 | 
			
		||||
 | 
			
		||||
  if (event_type != G_FILE_MONITOR_EVENT_CHANGED)
 | 
			
		||||
    {
 | 
			
		||||
      send_delayed_change_now (monitor);
 | 
			
		||||
      update_last_sent_change (monitor, NULL, 0);
 | 
			
		||||
      if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT)
 | 
			
		||||
	cancel_virtual_changes_done (monitor);
 | 
			
		||||
      else
 | 
			
		||||
	send_virtual_changes_done_now (monitor);
 | 
			
		||||
      g_signal_emit (monitor, signals[CHANGED], 0, file, other_file, event_type);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      time_now = get_time_msecs ();
 | 
			
		||||
      emit_now = TRUE;
 | 
			
		||||
      
 | 
			
		||||
      if (monitor->priv->last_sent_change_file)
 | 
			
		||||
	{
 | 
			
		||||
	  since_last = time_difference (monitor->priv->last_sent_change_time, time_now);
 | 
			
		||||
	  if (since_last < monitor->priv->rate_limit_msec)
 | 
			
		||||
	    {
 | 
			
		||||
	      /* We ignore this change, but arm a timer so that we can fire it later if we
 | 
			
		||||
		 don't get any other events (that kill this timeout) */
 | 
			
		||||
	      emit_now = FALSE;
 | 
			
		||||
	      schedule_delayed_change (monitor, file,
 | 
			
		||||
				       monitor->priv->rate_limit_msec - since_last);
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      if (emit_now)
 | 
			
		||||
	{
 | 
			
		||||
	  g_signal_emit (monitor, signals[CHANGED], 0, file, other_file, event_type);
 | 
			
		||||
	  
 | 
			
		||||
	  cancel_delayed_change (monitor);
 | 
			
		||||
	  update_last_sent_change (monitor, file, time_now);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      /* Schedule a virtual change done. This is removed if we get a real one, and
 | 
			
		||||
	 postponed if we get more change events. */
 | 
			
		||||
      cancel_virtual_changes_done (monitor);
 | 
			
		||||
      schedule_virtual_change_done (monitor, file);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										97
									
								
								gio/gfilemonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								gio/gfilemonitor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,97 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILE_MONITOR_H__
 | 
			
		||||
#define __G_FILE_MONITOR_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gfile.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILE_MONITOR         (g_file_monitor_get_type ())
 | 
			
		||||
#define G_FILE_MONITOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_MONITOR, GFileMonitor))
 | 
			
		||||
#define G_FILE_MONITOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_MONITOR, GFileMonitorClass))
 | 
			
		||||
#define G_IS_FILE_MONITOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_MONITOR))
 | 
			
		||||
#define G_IS_FILE_MONITOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_MONITOR))
 | 
			
		||||
#define G_FILE_MONITOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_MONITOR, GFileMonitorClass))
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
  G_FILE_MONITOR_EVENT_CHANGED,
 | 
			
		||||
  G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT,
 | 
			
		||||
  G_FILE_MONITOR_EVENT_DELETED,
 | 
			
		||||
  G_FILE_MONITOR_EVENT_CREATED,
 | 
			
		||||
  G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED,
 | 
			
		||||
  G_FILE_MONITOR_EVENT_PRE_UNMOUNT,
 | 
			
		||||
  G_FILE_MONITOR_EVENT_UNMOUNTED
 | 
			
		||||
} GFileMonitorEvent;
 | 
			
		||||
 | 
			
		||||
typedef struct _GFileMonitorClass	GFileMonitorClass;
 | 
			
		||||
typedef struct _GFileMonitorPrivate	GFileMonitorPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GFileMonitor
 | 
			
		||||
{
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GFileMonitorPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GFileMonitorClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
  
 | 
			
		||||
  /* Signals */
 | 
			
		||||
  void (* changed) (GFileMonitor* monitor,
 | 
			
		||||
		    GFile* file,
 | 
			
		||||
		    GFile* other_file,
 | 
			
		||||
		    GFileMonitorEvent event_type);
 | 
			
		||||
  
 | 
			
		||||
  /* Virtual Table */
 | 
			
		||||
  gboolean	(*cancel)(GFileMonitor* monitor);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_file_monitor_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
gboolean g_file_monitor_cancel         (GFileMonitor *monitor);
 | 
			
		||||
gboolean g_file_monitor_is_cancelled   (GFileMonitor *monitor);
 | 
			
		||||
void     g_file_monitor_set_rate_limit (GFileMonitor *monitor,
 | 
			
		||||
					int           limit_msecs);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* For implementations */
 | 
			
		||||
void g_file_monitor_emit_event (GFileMonitor      *monitor,
 | 
			
		||||
				GFile             *file,
 | 
			
		||||
				GFile             *other_file,
 | 
			
		||||
				GFileMonitorEvent  event_type);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_MONITOR_H__ */
 | 
			
		||||
							
								
								
									
										489
									
								
								gio/gfilenamecompleter.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										489
									
								
								gio/gfilenamecompleter.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,489 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "gfilenamecompleter.h"
 | 
			
		||||
#include "gurifuncs.h"
 | 
			
		||||
#include "gfile.h"
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  GOT_COMPLETION_DATA,
 | 
			
		||||
  LAST_SIGNAL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static guint signals[LAST_SIGNAL] = { 0 };
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  GFilenameCompleter *completer;
 | 
			
		||||
  GFileEnumerator *enumerator;
 | 
			
		||||
  GCancellable *cancellable;
 | 
			
		||||
  gboolean should_escape;
 | 
			
		||||
  GFile *dir;
 | 
			
		||||
  GList *basenames;
 | 
			
		||||
  gboolean dirs_only;
 | 
			
		||||
} LoadBasenamesData;
 | 
			
		||||
 | 
			
		||||
struct _GFilenameCompleter {
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  GFile *basenames_dir;
 | 
			
		||||
  gboolean basenames_are_escaped;
 | 
			
		||||
  GList *basenames;
 | 
			
		||||
  gboolean dirs_only;
 | 
			
		||||
 | 
			
		||||
  LoadBasenamesData *basename_loader;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GFilenameCompleter, g_filename_completer, G_TYPE_OBJECT);
 | 
			
		||||
 | 
			
		||||
static void cancel_load_basenames (GFilenameCompleter *completer);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filename_completer_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GFilenameCompleter *completer;
 | 
			
		||||
 | 
			
		||||
  completer = G_FILENAME_COMPLETER (object);
 | 
			
		||||
 | 
			
		||||
  cancel_load_basenames (completer);
 | 
			
		||||
 | 
			
		||||
  if (completer->basenames_dir)
 | 
			
		||||
    g_object_unref (completer->basenames_dir);
 | 
			
		||||
 | 
			
		||||
  g_list_foreach (completer->basenames, (GFunc)g_free, NULL);
 | 
			
		||||
  g_list_free (completer->basenames);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_filename_completer_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_filename_completer_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filename_completer_class_init (GFilenameCompleterClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_filename_completer_finalize;
 | 
			
		||||
 | 
			
		||||
  signals[GOT_COMPLETION_DATA] = g_signal_new (I_("got_completion_data"),
 | 
			
		||||
					  G_TYPE_FILENAME_COMPLETER,
 | 
			
		||||
					  G_SIGNAL_RUN_LAST,
 | 
			
		||||
					  G_STRUCT_OFFSET (GFilenameCompleterClass, got_completion_data),
 | 
			
		||||
					  NULL, NULL,
 | 
			
		||||
					  g_cclosure_marshal_VOID__VOID,
 | 
			
		||||
					  G_TYPE_NONE, 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filename_completer_init (GFilenameCompleter *completer)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_filename_completer_new:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a new #GFilenameCompleter.
 | 
			
		||||
 **/
 | 
			
		||||
GFilenameCompleter *
 | 
			
		||||
g_filename_completer_new (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_object_new (G_TYPE_FILENAME_COMPLETER, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
longest_common_prefix (char *a, char *b)
 | 
			
		||||
{
 | 
			
		||||
  char *start;
 | 
			
		||||
 | 
			
		||||
  start = a;
 | 
			
		||||
 | 
			
		||||
  while (g_utf8_get_char (a) == g_utf8_get_char (b))
 | 
			
		||||
    {
 | 
			
		||||
      a = g_utf8_next_char (a);
 | 
			
		||||
      b = g_utf8_next_char (b);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return g_strndup (start, a - start);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_basenames_data_free (LoadBasenamesData *data)
 | 
			
		||||
{
 | 
			
		||||
  if (data->enumerator)
 | 
			
		||||
    g_object_unref (data->enumerator);
 | 
			
		||||
  
 | 
			
		||||
  g_object_unref (data->cancellable);
 | 
			
		||||
  g_object_unref (data->dir);
 | 
			
		||||
  
 | 
			
		||||
  g_list_foreach (data->basenames, (GFunc)g_free, NULL);
 | 
			
		||||
  g_list_free (data->basenames);
 | 
			
		||||
  
 | 
			
		||||
  g_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
got_more_files (GObject *source_object,
 | 
			
		||||
		GAsyncResult *res,
 | 
			
		||||
		gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  LoadBasenamesData *data = user_data;
 | 
			
		||||
  GList *infos, *l;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
  const char *name;
 | 
			
		||||
  gboolean append_slash;
 | 
			
		||||
  char *t;
 | 
			
		||||
  char *basename;
 | 
			
		||||
 | 
			
		||||
  if (data->completer == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* Was cancelled */
 | 
			
		||||
      load_basenames_data_free (data);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  infos = g_file_enumerator_next_files_finish (data->enumerator, res, NULL);
 | 
			
		||||
 | 
			
		||||
  for (l = infos; l != NULL; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      info = l->data;
 | 
			
		||||
 | 
			
		||||
      if (data->dirs_only &&
 | 
			
		||||
	  g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY)
 | 
			
		||||
	{
 | 
			
		||||
	  g_object_unref (info);
 | 
			
		||||
	  continue;
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      append_slash = g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY;
 | 
			
		||||
      name = g_file_info_get_name (info);
 | 
			
		||||
      if (name == NULL)
 | 
			
		||||
	{
 | 
			
		||||
	  g_object_unref (info);
 | 
			
		||||
	  continue;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      
 | 
			
		||||
      if (data->should_escape)
 | 
			
		||||
	basename = g_uri_escape_string (name,
 | 
			
		||||
					G_URI_RESERVED_CHARS_ALLOWED_IN_PATH,
 | 
			
		||||
					TRUE);
 | 
			
		||||
      else
 | 
			
		||||
	/* If not should_escape, must be a local filename, convert to utf8 */
 | 
			
		||||
	basename = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
 | 
			
		||||
      
 | 
			
		||||
      if (basename)
 | 
			
		||||
	{
 | 
			
		||||
	  if (append_slash)
 | 
			
		||||
	    {
 | 
			
		||||
	      t = basename;
 | 
			
		||||
	      basename = g_strconcat (basename, "/", NULL);
 | 
			
		||||
	      g_free (t);
 | 
			
		||||
	    }
 | 
			
		||||
	  
 | 
			
		||||
	  data->basenames = g_list_prepend (data->basenames, basename);
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      g_object_unref (info);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  g_list_free (infos);
 | 
			
		||||
  
 | 
			
		||||
  if (infos)
 | 
			
		||||
    {
 | 
			
		||||
      /* Not last, get more files */
 | 
			
		||||
      g_file_enumerator_next_files_async (data->enumerator,
 | 
			
		||||
					  100,
 | 
			
		||||
					  0,
 | 
			
		||||
					  data->cancellable,
 | 
			
		||||
					  got_more_files, data);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      data->completer->basename_loader = NULL;
 | 
			
		||||
      
 | 
			
		||||
      if (data->completer->basenames_dir)
 | 
			
		||||
	g_object_unref (data->completer->basenames_dir);
 | 
			
		||||
      g_list_foreach (data->completer->basenames, (GFunc)g_free, NULL);
 | 
			
		||||
      g_list_free (data->completer->basenames);
 | 
			
		||||
      
 | 
			
		||||
      data->completer->basenames_dir = g_object_ref (data->dir);
 | 
			
		||||
      data->completer->basenames = data->basenames;
 | 
			
		||||
      data->completer->basenames_are_escaped = data->should_escape;
 | 
			
		||||
      data->basenames = NULL;
 | 
			
		||||
      
 | 
			
		||||
      g_file_enumerator_close_async (data->enumerator, 0, NULL, NULL, NULL);
 | 
			
		||||
 | 
			
		||||
      g_signal_emit (data->completer, signals[GOT_COMPLETION_DATA], 0);
 | 
			
		||||
      load_basenames_data_free (data);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
got_enum (GObject *source_object,
 | 
			
		||||
	  GAsyncResult *res,
 | 
			
		||||
	  gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  LoadBasenamesData *data = user_data;
 | 
			
		||||
 | 
			
		||||
  if (data->completer == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* Was cancelled */
 | 
			
		||||
      load_basenames_data_free (data);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  data->enumerator = g_file_enumerate_children_finish (G_FILE (source_object), res, NULL);
 | 
			
		||||
  
 | 
			
		||||
  if (data->enumerator == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      data->completer->basename_loader = NULL;
 | 
			
		||||
 | 
			
		||||
      if (data->completer->basenames_dir)
 | 
			
		||||
	g_object_unref (data->completer->basenames_dir);
 | 
			
		||||
      g_list_foreach (data->completer->basenames, (GFunc)g_free, NULL);
 | 
			
		||||
      g_list_free (data->completer->basenames);
 | 
			
		||||
 | 
			
		||||
      /* Mark uptodate with no basenames */
 | 
			
		||||
      data->completer->basenames_dir = g_object_ref (data->dir);
 | 
			
		||||
      data->completer->basenames = NULL;
 | 
			
		||||
      data->completer->basenames_are_escaped = data->should_escape;
 | 
			
		||||
      
 | 
			
		||||
      load_basenames_data_free (data);
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  g_file_enumerator_next_files_async (data->enumerator,
 | 
			
		||||
				      100,
 | 
			
		||||
				      0,
 | 
			
		||||
				      data->cancellable,
 | 
			
		||||
				      got_more_files, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
schedule_load_basenames (GFilenameCompleter *completer,
 | 
			
		||||
			 GFile *dir,
 | 
			
		||||
			 gboolean should_escape)
 | 
			
		||||
{
 | 
			
		||||
  LoadBasenamesData *data;
 | 
			
		||||
 | 
			
		||||
  cancel_load_basenames (completer);
 | 
			
		||||
 | 
			
		||||
  data = g_new0 (LoadBasenamesData, 1);
 | 
			
		||||
  data->completer = completer;
 | 
			
		||||
  data->cancellable = g_cancellable_new ();
 | 
			
		||||
  data->dir = g_object_ref (dir);
 | 
			
		||||
  data->should_escape = should_escape;
 | 
			
		||||
  data->dirs_only = completer->dirs_only;
 | 
			
		||||
 | 
			
		||||
  completer->basename_loader = data;
 | 
			
		||||
  
 | 
			
		||||
  g_file_enumerate_children_async (dir,
 | 
			
		||||
				   G_FILE_ATTRIBUTE_STD_NAME "," G_FILE_ATTRIBUTE_STD_TYPE,
 | 
			
		||||
				   0, 0,
 | 
			
		||||
				   data->cancellable,
 | 
			
		||||
				   got_enum, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
cancel_load_basenames (GFilenameCompleter *completer)
 | 
			
		||||
{
 | 
			
		||||
  LoadBasenamesData *loader;
 | 
			
		||||
  
 | 
			
		||||
  if (completer->basename_loader)
 | 
			
		||||
    {
 | 
			
		||||
      loader = completer->basename_loader; 
 | 
			
		||||
      loader->completer = NULL;
 | 
			
		||||
      
 | 
			
		||||
      g_cancellable_cancel (loader->cancellable);
 | 
			
		||||
      
 | 
			
		||||
      completer->basename_loader = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Returns a list of possible matches and the basename to use for it */
 | 
			
		||||
static GList *
 | 
			
		||||
init_completion (GFilenameCompleter *completer,
 | 
			
		||||
		 const char *initial_text,
 | 
			
		||||
		 char **basename_out)
 | 
			
		||||
{
 | 
			
		||||
  gboolean should_escape;
 | 
			
		||||
  GFile *file, *parent;
 | 
			
		||||
  char *basename;
 | 
			
		||||
  char *t;
 | 
			
		||||
  int len;
 | 
			
		||||
 | 
			
		||||
  *basename_out = NULL;
 | 
			
		||||
  
 | 
			
		||||
  should_escape = ! (g_path_is_absolute (initial_text) || *initial_text == '~');
 | 
			
		||||
 | 
			
		||||
  len = strlen (initial_text);
 | 
			
		||||
  
 | 
			
		||||
  if (len > 0 &&
 | 
			
		||||
      initial_text[len - 1] == '/')
 | 
			
		||||
    return NULL;
 | 
			
		||||
  
 | 
			
		||||
  file = g_file_parse_name (initial_text);
 | 
			
		||||
  parent = g_file_get_parent (file);
 | 
			
		||||
  if (parent == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (file);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (completer->basenames_dir == NULL ||
 | 
			
		||||
      completer->basenames_are_escaped != should_escape ||
 | 
			
		||||
      !g_file_equal (parent, completer->basenames_dir))
 | 
			
		||||
    {
 | 
			
		||||
      schedule_load_basenames (completer, parent, should_escape);
 | 
			
		||||
      g_object_unref (file);
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  basename = g_file_get_basename (file);
 | 
			
		||||
  if (should_escape)
 | 
			
		||||
    {
 | 
			
		||||
      t = basename;
 | 
			
		||||
      basename = g_uri_escape_string (basename, G_URI_RESERVED_CHARS_ALLOWED_IN_PATH, TRUE);
 | 
			
		||||
      g_free (t);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      t = basename;
 | 
			
		||||
      basename = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);
 | 
			
		||||
      g_free (t);
 | 
			
		||||
      
 | 
			
		||||
      if (basename == NULL)
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  *basename_out = basename;
 | 
			
		||||
 | 
			
		||||
  return completer->basenames;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_filename_completer_get_completion_suffix:
 | 
			
		||||
 * @completer: the filename completer.
 | 
			
		||||
 * @initial_text: text to be completed.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a completed string. This string is not owned by GIO, so
 | 
			
		||||
 * remember to g_free() it when finished.
 | 
			
		||||
 **/
 | 
			
		||||
char *
 | 
			
		||||
g_filename_completer_get_completion_suffix (GFilenameCompleter *completer,
 | 
			
		||||
					    const char *initial_text)
 | 
			
		||||
{
 | 
			
		||||
  GList *possible_matches, *l;
 | 
			
		||||
  char *prefix;
 | 
			
		||||
  char *suffix;
 | 
			
		||||
  char *possible_match;
 | 
			
		||||
  char *lcp;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILENAME_COMPLETER (completer), NULL);
 | 
			
		||||
  g_return_val_if_fail (initial_text != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  possible_matches = init_completion (completer, initial_text, &prefix);
 | 
			
		||||
 | 
			
		||||
  suffix = NULL;
 | 
			
		||||
  
 | 
			
		||||
  for (l = possible_matches; l != NULL; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      possible_match = l->data;
 | 
			
		||||
      
 | 
			
		||||
      if (g_str_has_prefix (possible_match, prefix))
 | 
			
		||||
	{
 | 
			
		||||
	  if (suffix == NULL)
 | 
			
		||||
	    suffix = g_strdup (possible_match + strlen (prefix));
 | 
			
		||||
	  else
 | 
			
		||||
	    {
 | 
			
		||||
	      lcp = longest_common_prefix (suffix,
 | 
			
		||||
					   possible_match + strlen (prefix));
 | 
			
		||||
	      g_free (suffix);
 | 
			
		||||
	      suffix = lcp;
 | 
			
		||||
	      
 | 
			
		||||
	      if (*suffix == 0)
 | 
			
		||||
		break;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (prefix);
 | 
			
		||||
  
 | 
			
		||||
  return suffix;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_filename_completer_get_completions:
 | 
			
		||||
 * @completer: the filename completer.
 | 
			
		||||
 * @initial_text: text to be completed.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: array of strings with possible completions for @initial_text.
 | 
			
		||||
 * This array must be freed by g_strfreev() when finished. 
 | 
			
		||||
 **/
 | 
			
		||||
char **
 | 
			
		||||
g_filename_completer_get_completions (GFilenameCompleter *completer,
 | 
			
		||||
				      const char *initial_text)
 | 
			
		||||
{
 | 
			
		||||
  GList *possible_matches, *l;
 | 
			
		||||
  char *prefix;
 | 
			
		||||
  char *possible_match;
 | 
			
		||||
  GPtrArray *res;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILENAME_COMPLETER (completer), NULL);
 | 
			
		||||
  g_return_val_if_fail (initial_text != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  possible_matches = init_completion (completer, initial_text, &prefix);
 | 
			
		||||
 | 
			
		||||
  res = g_ptr_array_new ();
 | 
			
		||||
  for (l = possible_matches; l != NULL; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      possible_match = l->data;
 | 
			
		||||
      
 | 
			
		||||
      if (g_str_has_prefix (possible_match, prefix))
 | 
			
		||||
	g_ptr_array_add (res,
 | 
			
		||||
			 g_strconcat (initial_text, possible_match + strlen (prefix), NULL));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (prefix);
 | 
			
		||||
  
 | 
			
		||||
  return (char**)g_ptr_array_free (res, FALSE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_filename_completer_set_dirs_only:
 | 
			
		||||
 * @completer: the filename completer.
 | 
			
		||||
 * @dirs_only: 
 | 
			
		||||
 * 
 | 
			
		||||
 * If @dirs_only is %TRUE, @completer will only 
 | 
			
		||||
 * complete directory names, and not file names.
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_filename_completer_set_dirs_only (GFilenameCompleter *completer,
 | 
			
		||||
				    gboolean dirs_only)
 | 
			
		||||
{
 | 
			
		||||
  g_return_if_fail (G_IS_FILENAME_COMPLETER (completer));
 | 
			
		||||
 | 
			
		||||
  completer->dirs_only = dirs_only;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										66
									
								
								gio/gfilenamecompleter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								gio/gfilenamecompleter.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILENAME_COMPLETER_H__
 | 
			
		||||
#define __G_FILENAME_COMPLETER_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILENAME_COMPLETER         (g_filename_completer_get_type ())
 | 
			
		||||
#define G_FILENAME_COMPLETER(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILENAME_COMPLETER, GFilenameCompleter))
 | 
			
		||||
#define G_FILENAME_COMPLETER_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILENAME_COMPLETER, GFilenameCompleterClass))
 | 
			
		||||
#define G_FILENAME_COMPLETER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILENAME_COMPLETER, GFilenameCompleterClass))
 | 
			
		||||
#define G_IS_FILENAME_COMPLETER(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILENAME_COMPLETER))
 | 
			
		||||
#define G_IS_FILENAME_COMPLETER_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILENAME_COMPLETER))
 | 
			
		||||
 | 
			
		||||
typedef struct _GFilenameCompleter GFilenameCompleter;
 | 
			
		||||
typedef struct _GFilenameCompleterClass GFilenameCompleterClass;
 | 
			
		||||
 | 
			
		||||
struct _GFilenameCompleterClass {
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /*< public >*/
 | 
			
		||||
  /* signals */
 | 
			
		||||
  void (* got_completion_data)	(GFilenameCompleter *filename_completer);
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_filename_completer_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GFilenameCompleter *g_filename_completer_new                   (void);
 | 
			
		||||
 | 
			
		||||
char *              g_filename_completer_get_completion_suffix (GFilenameCompleter *completer,
 | 
			
		||||
								const char *initial_text);
 | 
			
		||||
char **             g_filename_completer_get_completions       (GFilenameCompleter *completer,
 | 
			
		||||
								const char *initial_text);
 | 
			
		||||
void                g_filename_completer_set_dirs_only         (GFilenameCompleter *completer,
 | 
			
		||||
								gboolean dirs_only);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILENAME_COMPLETER_H__ */
 | 
			
		||||
							
								
								
									
										613
									
								
								gio/gfileoutputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										613
									
								
								gio/gfileoutputstream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,613 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <gfileoutputstream.h>
 | 
			
		||||
#include <gseekable.h>
 | 
			
		||||
#include "gsimpleasyncresult.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
static void       g_file_output_stream_seekable_iface_init    (GSeekableIface       *iface);
 | 
			
		||||
static goffset    g_file_output_stream_seekable_tell          (GSeekable            *seekable);
 | 
			
		||||
static gboolean   g_file_output_stream_seekable_can_seek      (GSeekable            *seekable);
 | 
			
		||||
static gboolean   g_file_output_stream_seekable_seek          (GSeekable            *seekable,
 | 
			
		||||
							       goffset               offset,
 | 
			
		||||
							       GSeekType             type,
 | 
			
		||||
							       GCancellable         *cancellable,
 | 
			
		||||
							       GError              **error);
 | 
			
		||||
static gboolean   g_file_output_stream_seekable_can_truncate  (GSeekable            *seekable);
 | 
			
		||||
static gboolean   g_file_output_stream_seekable_truncate      (GSeekable            *seekable,
 | 
			
		||||
							       goffset               offset,
 | 
			
		||||
							       GCancellable         *cancellable,
 | 
			
		||||
							       GError              **error);
 | 
			
		||||
static void       g_file_output_stream_real_query_info_async  (GFileOutputStream    *stream,
 | 
			
		||||
							       char                 *attributes,
 | 
			
		||||
							       int                   io_priority,
 | 
			
		||||
							       GCancellable         *cancellable,
 | 
			
		||||
							       GAsyncReadyCallback   callback,
 | 
			
		||||
							       gpointer              user_data);
 | 
			
		||||
static GFileInfo *g_file_output_stream_real_query_info_finish (GFileOutputStream    *stream,
 | 
			
		||||
							       GAsyncResult         *result,
 | 
			
		||||
							       GError              **error);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE_WITH_CODE (GFileOutputStream, g_file_output_stream, G_TYPE_OUTPUT_STREAM,
 | 
			
		||||
			 G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
 | 
			
		||||
						g_file_output_stream_seekable_iface_init));
 | 
			
		||||
 | 
			
		||||
struct _GFileOutputStreamPrivate {
 | 
			
		||||
  GAsyncReadyCallback outstanding_callback;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_output_stream_class_init (GFileOutputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GFileOutputStreamPrivate));
 | 
			
		||||
 | 
			
		||||
  klass->query_info_async = g_file_output_stream_real_query_info_async;
 | 
			
		||||
  klass->query_info_finish = g_file_output_stream_real_query_info_finish;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_output_stream_seekable_iface_init (GSeekableIface *iface)
 | 
			
		||||
{
 | 
			
		||||
  iface->tell = g_file_output_stream_seekable_tell;
 | 
			
		||||
  iface->can_seek = g_file_output_stream_seekable_can_seek;
 | 
			
		||||
  iface->seek = g_file_output_stream_seekable_seek;
 | 
			
		||||
  iface->can_truncate = g_file_output_stream_seekable_can_truncate;
 | 
			
		||||
  iface->truncate = g_file_output_stream_seekable_truncate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_output_stream_init (GFileOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
 | 
			
		||||
					      G_TYPE_FILE_OUTPUT_STREAM,
 | 
			
		||||
					      GFileOutputStreamPrivate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_output_stream_query_info:
 | 
			
		||||
 * @stream: a #GFileOutputStream.
 | 
			
		||||
 * @attributes:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 *
 | 
			
		||||
 *  * Returns: %NULL or a #GFileInfo for the @stream.
 | 
			
		||||
 * 
 | 
			
		||||
 * For the asynchronous version of this function, see 
 | 
			
		||||
 * g_file_output_stream_query_info_async(). 
 | 
			
		||||
 **/
 | 
			
		||||
GFileInfo *
 | 
			
		||||
g_file_output_stream_query_info (GFileOutputStream      *stream,
 | 
			
		||||
				    char                   *attributes,
 | 
			
		||||
				    GCancellable           *cancellable,
 | 
			
		||||
				    GError                **error)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass *class;
 | 
			
		||||
  GOutputStream *output_stream;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), NULL);
 | 
			
		||||
  
 | 
			
		||||
  output_stream = G_OUTPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  if (g_output_stream_is_closed (output_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
		   _("Stream is already closed"));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (g_output_stream_has_pending (output_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
		   _("Stream has outstanding operation"));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
      
 | 
			
		||||
  info = NULL;
 | 
			
		||||
  
 | 
			
		||||
  g_output_stream_set_pending (output_stream, TRUE);
 | 
			
		||||
  
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_push_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
  if (class->query_info)
 | 
			
		||||
    info = class->query_info (stream, attributes, cancellable, error);
 | 
			
		||||
  else
 | 
			
		||||
    g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
		 _("Stream doesn't support query_info"));
 | 
			
		||||
  
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_pop_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  g_output_stream_set_pending (output_stream, FALSE);
 | 
			
		||||
  
 | 
			
		||||
  return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
async_ready_callback_wrapper (GObject *source_object,
 | 
			
		||||
			      GAsyncResult *res,
 | 
			
		||||
			      gpointer      user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStream *stream = G_FILE_OUTPUT_STREAM (source_object);
 | 
			
		||||
 | 
			
		||||
  g_output_stream_set_pending (G_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
  if (stream->priv->outstanding_callback)
 | 
			
		||||
    (*stream->priv->outstanding_callback) (source_object, res, user_data);
 | 
			
		||||
  g_object_unref (stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_output_stream_query_info_async:
 | 
			
		||||
 * @stream: a #GFileOutputStream.
 | 
			
		||||
 * @attributes:
 | 
			
		||||
 * @io_priority: the io priority of the request.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @callback: a #GAsyncReadyCallback.
 | 
			
		||||
 * @user_data: user data for @callback.
 | 
			
		||||
 * 
 | 
			
		||||
 * Asynchronously queries the @stream for a #GFileInfo. When completed,
 | 
			
		||||
 * @callback will be called with a #GAsyncResult which can be used to 
 | 
			
		||||
 * finish the operation with g_file_output_stream_query_info_finish().
 | 
			
		||||
 * 
 | 
			
		||||
 * For the synchronous version of this function, see 
 | 
			
		||||
 * g_file_output_stream_query_info().
 | 
			
		||||
 *
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_file_output_stream_query_info_async (GFileOutputStream     *stream,
 | 
			
		||||
					  char                 *attributes,
 | 
			
		||||
					  int                   io_priority,
 | 
			
		||||
					  GCancellable         *cancellable,
 | 
			
		||||
					  GAsyncReadyCallback   callback,
 | 
			
		||||
					  gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass *klass;
 | 
			
		||||
  GOutputStream *output_stream;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (G_IS_FILE_OUTPUT_STREAM (stream));
 | 
			
		||||
 | 
			
		||||
  output_stream = G_OUTPUT_STREAM (stream);
 | 
			
		||||
 
 | 
			
		||||
  if (g_output_stream_is_closed (output_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (stream),
 | 
			
		||||
					   callback,
 | 
			
		||||
					   user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
					   _("Stream is already closed"));
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (g_output_stream_has_pending (output_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_report_error_in_idle (G_OBJECT (stream),
 | 
			
		||||
					   callback,
 | 
			
		||||
					   user_data,
 | 
			
		||||
					   G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
					   _("Stream has outstanding operation"));
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  klass = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  g_output_stream_set_pending (output_stream, TRUE);
 | 
			
		||||
  stream->priv->outstanding_callback = callback;
 | 
			
		||||
  g_object_ref (stream);
 | 
			
		||||
  klass->query_info_async (stream, attributes, io_priority, cancellable,
 | 
			
		||||
			      async_ready_callback_wrapper, user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_output_stream_query_info_finish:
 | 
			
		||||
 * @stream: a #GFileOutputStream.
 | 
			
		||||
 * @result: a #GAsyncResult.
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * 
 | 
			
		||||
 * Finalizes the asynchronous query started 
 | 
			
		||||
 * by g_file_output_stream_query_info_async().
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: A #GFileInfo for the finished query.
 | 
			
		||||
 **/
 | 
			
		||||
GFileInfo *
 | 
			
		||||
g_file_output_stream_query_info_finish (GFileOutputStream     *stream,
 | 
			
		||||
					   GAsyncResult         *result,
 | 
			
		||||
					   GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple;
 | 
			
		||||
  GFileOutputStreamClass *class;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), NULL);
 | 
			
		||||
  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
 | 
			
		||||
  
 | 
			
		||||
  if (G_IS_SIMPLE_ASYNC_RESULT (result))
 | 
			
		||||
    {
 | 
			
		||||
      simple = G_SIMPLE_ASYNC_RESULT (result);
 | 
			
		||||
      if (g_simple_async_result_propagate_error (simple, error))
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
  return class->query_info_finish (stream, result, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_output_stream_get_etag:
 | 
			
		||||
 * @stream: a #GFileOutputString.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
char *
 | 
			
		||||
g_file_output_stream_get_etag (GFileOutputStream  *stream)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass *class;
 | 
			
		||||
  GOutputStream *output_stream;
 | 
			
		||||
  char *etag;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), NULL);
 | 
			
		||||
  
 | 
			
		||||
  output_stream = G_OUTPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  if (!g_output_stream_is_closed (output_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("stream is not closed yet, can't get etag");
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  etag = NULL;
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
  if (class->get_etag)
 | 
			
		||||
    etag = class->get_etag (stream);
 | 
			
		||||
  
 | 
			
		||||
  return etag;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_output_stream_tell:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
goffset
 | 
			
		||||
g_file_output_stream_tell (GFileOutputStream  *stream)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass *class;
 | 
			
		||||
  goffset offset;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), 0);  
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  offset = 0;
 | 
			
		||||
  if (class->tell)
 | 
			
		||||
    offset = class->tell (stream);
 | 
			
		||||
 | 
			
		||||
  return offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static goffset
 | 
			
		||||
g_file_output_stream_seekable_tell (GSeekable *seekable)
 | 
			
		||||
{
 | 
			
		||||
  return g_file_output_stream_tell (G_FILE_OUTPUT_STREAM (seekable));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_output_stream_can_seek:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_output_stream_can_seek (GFileOutputStream  *stream)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass *class;
 | 
			
		||||
  gboolean can_seek;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  can_seek = FALSE;
 | 
			
		||||
  if (class->seek)
 | 
			
		||||
    {
 | 
			
		||||
      can_seek = TRUE;
 | 
			
		||||
      if (class->can_seek)
 | 
			
		||||
	can_seek = class->can_seek (stream);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return can_seek;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_output_stream_seekable_can_seek (GSeekable *seekable)
 | 
			
		||||
{
 | 
			
		||||
  return g_file_output_stream_can_seek (G_FILE_OUTPUT_STREAM (seekable));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_output_stream_seek:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * @offset:
 | 
			
		||||
 * @type:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_output_stream_seek (GFileOutputStream  *stream,
 | 
			
		||||
			   goffset             offset,
 | 
			
		||||
			   GSeekType           type,
 | 
			
		||||
			   GCancellable       *cancellable,
 | 
			
		||||
			   GError            **error)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass *class;
 | 
			
		||||
  GOutputStream *output_stream;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  output_stream = G_OUTPUT_STREAM (stream);
 | 
			
		||||
  class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  if (g_output_stream_is_closed (output_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
		   _("Stream is already closed"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (g_output_stream_has_pending (output_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
		   _("Stream has outstanding operation"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (!class->seek)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
		   _("Seek not supported on stream"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_output_stream_set_pending (output_stream, TRUE);
 | 
			
		||||
  
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_push_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  res = class->seek (stream, offset, type, cancellable, error);
 | 
			
		||||
  
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_pop_current_cancellable (cancellable);
 | 
			
		||||
 | 
			
		||||
  g_output_stream_set_pending (output_stream, FALSE);
 | 
			
		||||
  
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_output_stream_seekable_seek (GSeekable  *seekable,
 | 
			
		||||
				    goffset     offset,
 | 
			
		||||
				    GSeekType   type,
 | 
			
		||||
				    GCancellable  *cancellable,
 | 
			
		||||
				    GError    **error)
 | 
			
		||||
{
 | 
			
		||||
  return g_file_output_stream_seek (G_FILE_OUTPUT_STREAM (seekable),
 | 
			
		||||
				    offset, type, cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_output_stream_can_truncate:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if stream can be truncated.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_output_stream_can_truncate (GFileOutputStream  *stream)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass *class;
 | 
			
		||||
  gboolean can_truncate;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  can_truncate = FALSE;
 | 
			
		||||
  if (class->truncate)
 | 
			
		||||
    {
 | 
			
		||||
      can_truncate = TRUE;
 | 
			
		||||
      if (class->can_truncate)
 | 
			
		||||
	can_truncate = class->can_truncate (stream);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return can_truncate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_output_stream_seekable_can_truncate (GSeekable  *seekable)
 | 
			
		||||
{
 | 
			
		||||
  return g_file_output_stream_can_truncate (G_FILE_OUTPUT_STREAM (seekable));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_file_output_stream_truncate:
 | 
			
		||||
 * @stream:
 | 
			
		||||
 * @size:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: %TRUE if @stream is truncated.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_file_output_stream_truncate (GFileOutputStream  *stream,
 | 
			
		||||
			       goffset             size,
 | 
			
		||||
			       GCancellable       *cancellable,
 | 
			
		||||
			       GError            **error)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass *class;
 | 
			
		||||
  GOutputStream *output_stream;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILE_OUTPUT_STREAM (stream), FALSE);
 | 
			
		||||
 | 
			
		||||
  output_stream = G_OUTPUT_STREAM (stream);
 | 
			
		||||
  class = G_FILE_OUTPUT_STREAM_GET_CLASS (stream);
 | 
			
		||||
 | 
			
		||||
  if (g_output_stream_is_closed (output_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
 | 
			
		||||
		   _("Stream is already closed"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (g_output_stream_has_pending (output_stream))
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PENDING,
 | 
			
		||||
		   _("Stream has outstanding operation"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (!class->truncate)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
		   _("Truncate not supported on stream"));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_output_stream_set_pending (output_stream, TRUE);
 | 
			
		||||
  
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_push_current_cancellable (cancellable);
 | 
			
		||||
  
 | 
			
		||||
  res = class->truncate (stream, size, cancellable, error);
 | 
			
		||||
  
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    g_pop_current_cancellable (cancellable);
 | 
			
		||||
 | 
			
		||||
  g_output_stream_set_pending (output_stream, FALSE);
 | 
			
		||||
  
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_file_output_stream_seekable_truncate (GSeekable     *seekable,
 | 
			
		||||
					goffset        size,
 | 
			
		||||
					GCancellable  *cancellable,
 | 
			
		||||
					GError       **error)
 | 
			
		||||
{
 | 
			
		||||
  return g_file_output_stream_truncate (G_FILE_OUTPUT_STREAM (seekable),
 | 
			
		||||
					size, cancellable, error);
 | 
			
		||||
}
 | 
			
		||||
/********************************************
 | 
			
		||||
 *   Default implementation of async ops    *
 | 
			
		||||
 ********************************************/
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  char *attributes;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
} QueryInfoAsyncData;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
query_info_data_free (QueryInfoAsyncData *data)
 | 
			
		||||
{
 | 
			
		||||
  if (data->info)
 | 
			
		||||
    g_object_unref (data->info);
 | 
			
		||||
  g_free (data->attributes);
 | 
			
		||||
  g_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
query_info_async_thread (GSimpleAsyncResult *res,
 | 
			
		||||
		       GObject *object,
 | 
			
		||||
		       GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass *class;
 | 
			
		||||
  GError *error = NULL;
 | 
			
		||||
  QueryInfoAsyncData *data;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
  
 | 
			
		||||
  data = g_simple_async_result_get_op_res_gpointer (res);
 | 
			
		||||
 | 
			
		||||
  info = NULL;
 | 
			
		||||
  
 | 
			
		||||
  class = G_FILE_OUTPUT_STREAM_GET_CLASS (object);
 | 
			
		||||
  if (class->query_info)
 | 
			
		||||
    info = class->query_info (G_FILE_OUTPUT_STREAM (object), data->attributes, cancellable, &error);
 | 
			
		||||
  else
 | 
			
		||||
    g_set_error (&error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
		 _("Stream doesn't support query_info"));
 | 
			
		||||
 | 
			
		||||
  if (info == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_result_set_from_error (res, error);
 | 
			
		||||
      g_error_free (error);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    data->info = info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_file_output_stream_real_query_info_async (GFileOutputStream     *stream,
 | 
			
		||||
					       char                 *attributes,
 | 
			
		||||
					       int                   io_priority,
 | 
			
		||||
					       GCancellable         *cancellable,
 | 
			
		||||
					       GAsyncReadyCallback   callback,
 | 
			
		||||
					       gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *res;
 | 
			
		||||
  QueryInfoAsyncData *data;
 | 
			
		||||
 | 
			
		||||
  data = g_new0 (QueryInfoAsyncData, 1);
 | 
			
		||||
  data->attributes = g_strdup (attributes);
 | 
			
		||||
  
 | 
			
		||||
  res = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_file_output_stream_real_query_info_async);
 | 
			
		||||
  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
 | 
			
		||||
  
 | 
			
		||||
  g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
 | 
			
		||||
  g_object_unref (res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFileInfo *
 | 
			
		||||
g_file_output_stream_real_query_info_finish (GFileOutputStream     *stream,
 | 
			
		||||
						GAsyncResult         *res,
 | 
			
		||||
						GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
 | 
			
		||||
  QueryInfoAsyncData *data;
 | 
			
		||||
 | 
			
		||||
  g_assert (g_simple_async_result_get_source_tag (simple) == g_file_output_stream_real_query_info_async);
 | 
			
		||||
 | 
			
		||||
  data = g_simple_async_result_get_op_res_gpointer (simple);
 | 
			
		||||
  if (data->info)
 | 
			
		||||
    return g_object_ref (data->info);
 | 
			
		||||
  
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										121
									
								
								gio/gfileoutputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								gio/gfileoutputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILE_OUTPUT_STREAM_H__
 | 
			
		||||
#define __G_FILE_OUTPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/goutputstream.h>
 | 
			
		||||
#include <gio/gfileinfo.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILE_OUTPUT_STREAM         (g_file_output_stream_get_type ())
 | 
			
		||||
#define G_FILE_OUTPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILE_OUTPUT_STREAM, GFileOutputStream))
 | 
			
		||||
#define G_FILE_OUTPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILE_OUTPUT_STREAM, GFileOutputStreamClass))
 | 
			
		||||
#define G_IS_FILE_OUTPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILE_OUTPUT_STREAM))
 | 
			
		||||
#define G_IS_FILE_OUTPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILE_OUTPUT_STREAM))
 | 
			
		||||
#define G_FILE_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILE_OUTPUT_STREAM, GFileOutputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GFileOutputStream         GFileOutputStream;
 | 
			
		||||
typedef struct _GFileOutputStreamClass    GFileOutputStreamClass;
 | 
			
		||||
typedef struct _GFileOutputStreamPrivate  GFileOutputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GFileOutputStream
 | 
			
		||||
{
 | 
			
		||||
  GOutputStream parent;
 | 
			
		||||
  
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GFileOutputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GFileOutputStreamClass
 | 
			
		||||
{
 | 
			
		||||
  GOutputStreamClass parent_class;
 | 
			
		||||
 | 
			
		||||
  goffset    (*tell)          (GFileOutputStream     *stream);
 | 
			
		||||
  gboolean   (*can_seek)      (GFileOutputStream     *stream);
 | 
			
		||||
  gboolean   (*seek)	      (GFileOutputStream     *stream,
 | 
			
		||||
			       goffset               offset,
 | 
			
		||||
			       GSeekType             type,
 | 
			
		||||
			       GCancellable         *cancellable,
 | 
			
		||||
			       GError              **error);
 | 
			
		||||
  gboolean   (*can_truncate)  (GFileOutputStream    *stream);
 | 
			
		||||
  gboolean   (*truncate)      (GFileOutputStream    *stream,
 | 
			
		||||
			       goffset               size,
 | 
			
		||||
			       GCancellable         *cancellable,
 | 
			
		||||
			       GError              **error);
 | 
			
		||||
  GFileInfo *(*query_info)    (GFileOutputStream    *stream,
 | 
			
		||||
			       char                 *attributes,
 | 
			
		||||
			       GCancellable         *cancellable,
 | 
			
		||||
			       GError              **error);
 | 
			
		||||
  void       (*query_info_async)  (GFileOutputStream     *stream,
 | 
			
		||||
				   char                 *attributes,
 | 
			
		||||
				   int                   io_priority,
 | 
			
		||||
				   GCancellable         *cancellable,
 | 
			
		||||
				   GAsyncReadyCallback   callback,
 | 
			
		||||
				   gpointer              user_data);
 | 
			
		||||
  GFileInfo *(*query_info_finish) (GFileOutputStream     *stream,
 | 
			
		||||
				   GAsyncResult         *res,
 | 
			
		||||
				   GError              **error);
 | 
			
		||||
  char      *(*get_etag)      (GFileOutputStream    *stream);
 | 
			
		||||
    
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_file_output_stream_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GFileInfo *g_file_output_stream_query_info (GFileOutputStream  *stream,
 | 
			
		||||
					    char               *attributes,
 | 
			
		||||
					    GCancellable       *cancellable,
 | 
			
		||||
					    GError            **error);
 | 
			
		||||
void       g_file_output_stream_query_info_async  (GFileOutputStream     *stream,
 | 
			
		||||
						   char                 *attributes,
 | 
			
		||||
						   int                   io_priority,
 | 
			
		||||
						   GCancellable         *cancellable,
 | 
			
		||||
						   GAsyncReadyCallback   callback,
 | 
			
		||||
						   gpointer              user_data);
 | 
			
		||||
GFileInfo *g_file_output_stream_query_info_finish (GFileOutputStream     *stream,
 | 
			
		||||
						   GAsyncResult         *result,
 | 
			
		||||
						   GError              **error);
 | 
			
		||||
char *     g_file_output_stream_get_etag      (GFileOutputStream  *stream);
 | 
			
		||||
goffset    g_file_output_stream_tell          (GFileOutputStream  *stream);
 | 
			
		||||
gboolean   g_file_output_stream_can_seek      (GFileOutputStream  *stream);
 | 
			
		||||
gboolean   g_file_output_stream_seek          (GFileOutputStream  *stream,
 | 
			
		||||
					       goffset             offset,
 | 
			
		||||
					       GSeekType           type,
 | 
			
		||||
					       GCancellable       *cancellable,
 | 
			
		||||
					       GError            **error);
 | 
			
		||||
gboolean   g_file_output_stream_can_truncate  (GFileOutputStream  *stream);
 | 
			
		||||
gboolean   g_file_output_stream_truncate      (GFileOutputStream  *stream,
 | 
			
		||||
					       goffset             size,
 | 
			
		||||
					       GCancellable       *cancellable,
 | 
			
		||||
					       GError            **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_FILE_OUTPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										391
									
								
								gio/gfilterinputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										391
									
								
								gio/gfilterinputstream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,391 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Christian Kellner <gicmo@gnome.org> 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "gfilterinputstream.h"
 | 
			
		||||
#include "ginputstream.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  PROP_0,
 | 
			
		||||
  PROP_BASE_STREAM
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void     g_filter_input_stream_set_property (GObject      *object,
 | 
			
		||||
                                                    guint         prop_id,
 | 
			
		||||
                                                    const GValue *value,
 | 
			
		||||
                                                    GParamSpec   *pspec);
 | 
			
		||||
 | 
			
		||||
static void     g_filter_input_stream_get_property (GObject      *object,
 | 
			
		||||
                                                    guint         prop_id,
 | 
			
		||||
                                                    GValue       *value,
 | 
			
		||||
                                                    GParamSpec   *pspec);
 | 
			
		||||
static void     g_filter_input_stream_finalize     (GObject *object);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static gssize   g_filter_input_stream_read         (GInputStream         *stream,
 | 
			
		||||
                                                    void                 *buffer,
 | 
			
		||||
                                                    gsize                 count,
 | 
			
		||||
                                                    GCancellable         *cancellable,
 | 
			
		||||
                                                    GError              **error);
 | 
			
		||||
static gssize   g_filter_input_stream_skip         (GInputStream         *stream,
 | 
			
		||||
                                                    gsize                 count,
 | 
			
		||||
                                                    GCancellable         *cancellable,
 | 
			
		||||
                                                    GError              **error);
 | 
			
		||||
static gboolean g_filter_input_stream_close        (GInputStream         *stream,
 | 
			
		||||
                                                    GCancellable         *cancellable,
 | 
			
		||||
                                                    GError              **error);
 | 
			
		||||
static void     g_filter_input_stream_read_async   (GInputStream         *stream,
 | 
			
		||||
                                                    void                 *buffer,
 | 
			
		||||
                                                    gsize                 count,
 | 
			
		||||
                                                    int                   io_priority,
 | 
			
		||||
                                                    GCancellable         *cancellable,
 | 
			
		||||
                                                    GAsyncReadyCallback   callback,
 | 
			
		||||
                                                    gpointer              user_data);
 | 
			
		||||
static gssize   g_filter_input_stream_read_finish  (GInputStream         *stream,
 | 
			
		||||
                                                    GAsyncResult         *result,
 | 
			
		||||
                                                    GError              **error);
 | 
			
		||||
static void     g_filter_input_stream_skip_async   (GInputStream         *stream,
 | 
			
		||||
                                                    gsize                 count,
 | 
			
		||||
                                                    int                   io_priority,
 | 
			
		||||
                                                    GCancellable         *cancellabl,
 | 
			
		||||
                                                    GAsyncReadyCallback   callback,
 | 
			
		||||
                                                    gpointer              datae);
 | 
			
		||||
static gssize   g_filter_input_stream_skip_finish  (GInputStream         *stream,
 | 
			
		||||
                                                    GAsyncResult         *result,
 | 
			
		||||
                                                    GError              **error);
 | 
			
		||||
static void     g_filter_input_stream_close_async  (GInputStream         *stream,
 | 
			
		||||
                                                    int                   io_priority,
 | 
			
		||||
                                                    GCancellable         *cancellabl,
 | 
			
		||||
                                                    GAsyncReadyCallback   callback,
 | 
			
		||||
                                                    gpointer              data);
 | 
			
		||||
static gboolean g_filter_input_stream_close_finish (GInputStream         *stream,
 | 
			
		||||
                                                    GAsyncResult         *result,
 | 
			
		||||
                                                    GError              **error);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GFilterInputStream, g_filter_input_stream, G_TYPE_INPUT_STREAM)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_input_stream_class_init (GFilterInputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class;
 | 
			
		||||
  GInputStreamClass *istream_class;
 | 
			
		||||
 | 
			
		||||
  object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  object_class->get_property = g_filter_input_stream_get_property;
 | 
			
		||||
  object_class->set_property = g_filter_input_stream_set_property;
 | 
			
		||||
  object_class->finalize     = g_filter_input_stream_finalize;
 | 
			
		||||
 | 
			
		||||
  istream_class = G_INPUT_STREAM_CLASS (klass);
 | 
			
		||||
  istream_class->read  = g_filter_input_stream_read;
 | 
			
		||||
  istream_class->skip  = g_filter_input_stream_skip;
 | 
			
		||||
  istream_class->close = g_filter_input_stream_close;
 | 
			
		||||
 | 
			
		||||
  istream_class->read_async   = g_filter_input_stream_read_async;
 | 
			
		||||
  istream_class->read_finish  = g_filter_input_stream_read_finish;
 | 
			
		||||
  istream_class->skip_async   = g_filter_input_stream_skip_async;
 | 
			
		||||
  istream_class->skip_finish  = g_filter_input_stream_skip_finish;
 | 
			
		||||
  istream_class->close_async  = g_filter_input_stream_close_async;
 | 
			
		||||
  istream_class->close_finish = g_filter_input_stream_close_finish;
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_BASE_STREAM,
 | 
			
		||||
                                   g_param_spec_object ("base-stream",
 | 
			
		||||
                                                         P_("The Filter Base Stream"),
 | 
			
		||||
                                                         P_("The underlying base stream the io ops will be done on"),
 | 
			
		||||
                                                         G_TYPE_INPUT_STREAM,
 | 
			
		||||
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
 | 
			
		||||
                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_input_stream_set_property (GObject         *object,
 | 
			
		||||
                                    guint            prop_id,
 | 
			
		||||
                                    const GValue    *value,
 | 
			
		||||
                                    GParamSpec      *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GObject *obj;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id) 
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_BASE_STREAM:
 | 
			
		||||
      obj = g_value_dup_object (value);
 | 
			
		||||
      filter_stream->base_stream = G_INPUT_STREAM (obj); 
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_input_stream_get_property (GObject    *object,
 | 
			
		||||
                                    guint       prop_id,
 | 
			
		||||
                                    GValue     *value,
 | 
			
		||||
                                    GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_BASE_STREAM:
 | 
			
		||||
      g_value_set_object (value, filter_stream->base_stream);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_input_stream_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *stream;
 | 
			
		||||
 | 
			
		||||
  stream = G_FILTER_INPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
  g_object_unref (stream->base_stream);
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (g_filter_input_stream_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_filter_input_stream_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_input_stream_init (GFilterInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_filter_input_stream_get_base_stream:
 | 
			
		||||
 * @stream: a #GFilterInputStream.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a #GInputStream.
 | 
			
		||||
 **/
 | 
			
		||||
GInputStream *
 | 
			
		||||
g_filter_input_stream_get_base_stream (GFilterInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILTER_INPUT_STREAM (stream), NULL);
 | 
			
		||||
 | 
			
		||||
  return stream->base_stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_filter_input_stream_read (GInputStream *stream,
 | 
			
		||||
                            void         *buffer,
 | 
			
		||||
                            gsize         count,
 | 
			
		||||
                            GCancellable *cancellable,
 | 
			
		||||
                            GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GInputStream       *base_stream;
 | 
			
		||||
  gssize              nread;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (stream);
 | 
			
		||||
  base_stream = filter_stream->base_stream;
 | 
			
		||||
 | 
			
		||||
  nread = g_input_stream_read (base_stream,
 | 
			
		||||
                               buffer,
 | 
			
		||||
                               count,
 | 
			
		||||
                               cancellable,
 | 
			
		||||
                               error);
 | 
			
		||||
 | 
			
		||||
  return nread;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_filter_input_stream_skip (GInputStream              *stream,
 | 
			
		||||
                            gsize                      count,
 | 
			
		||||
                            GCancellable              *cancellable,
 | 
			
		||||
                            GError                   **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GInputStream       *base_stream;
 | 
			
		||||
  gssize              nskipped;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (stream);
 | 
			
		||||
  base_stream = filter_stream->base_stream;
 | 
			
		||||
 | 
			
		||||
  nskipped = g_input_stream_skip (base_stream,
 | 
			
		||||
                                  count,
 | 
			
		||||
                                  cancellable,
 | 
			
		||||
                                  error);
 | 
			
		||||
  return nskipped;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_filter_input_stream_close (GInputStream  *stream,
 | 
			
		||||
                             GCancellable  *cancellable,
 | 
			
		||||
                             GError       **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GInputStream       *base_stream;
 | 
			
		||||
  gboolean            res;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (stream);
 | 
			
		||||
  base_stream = filter_stream->base_stream;
 | 
			
		||||
 | 
			
		||||
  res = g_input_stream_close (base_stream,
 | 
			
		||||
                              cancellable,
 | 
			
		||||
                              error);
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_input_stream_read_async (GInputStream           *stream,
 | 
			
		||||
                                  void                   *buffer,
 | 
			
		||||
                                  gsize                   count,
 | 
			
		||||
                                  int                     io_priority,
 | 
			
		||||
                                  GCancellable           *cancellable,
 | 
			
		||||
                                  GAsyncReadyCallback     callback,
 | 
			
		||||
                                  gpointer                user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GInputStream       *base_stream;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (stream);
 | 
			
		||||
  base_stream = filter_stream->base_stream;
 | 
			
		||||
 | 
			
		||||
  g_input_stream_read_async (base_stream,
 | 
			
		||||
                             buffer,
 | 
			
		||||
                             count,
 | 
			
		||||
                             io_priority,
 | 
			
		||||
                             cancellable,
 | 
			
		||||
                             callback,
 | 
			
		||||
                             user_data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_filter_input_stream_read_finish (GInputStream  *stream,
 | 
			
		||||
                                   GAsyncResult  *result,
 | 
			
		||||
                                   GError       **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GInputStream       *base_stream;
 | 
			
		||||
  gssize nread;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (stream);
 | 
			
		||||
  base_stream = filter_stream->base_stream;
 | 
			
		||||
 | 
			
		||||
  nread = g_input_stream_read_finish (base_stream,
 | 
			
		||||
                                      result,
 | 
			
		||||
                                      error);
 | 
			
		||||
  
 | 
			
		||||
  return nread;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_input_stream_skip_async (GInputStream        *stream,
 | 
			
		||||
                                  gsize                count,
 | 
			
		||||
                                  int                  io_priority,
 | 
			
		||||
                                  GCancellable        *cancellable,
 | 
			
		||||
                                  GAsyncReadyCallback  callback,
 | 
			
		||||
                                  gpointer             user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GInputStream       *base_stream;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (stream);
 | 
			
		||||
  base_stream = filter_stream->base_stream;
 | 
			
		||||
 | 
			
		||||
  g_input_stream_skip_async (base_stream,
 | 
			
		||||
                             count,
 | 
			
		||||
                             io_priority,
 | 
			
		||||
                             cancellable,
 | 
			
		||||
                             callback,
 | 
			
		||||
                             user_data);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_filter_input_stream_skip_finish (GInputStream  *stream,
 | 
			
		||||
                                   GAsyncResult  *result,
 | 
			
		||||
                                   GError       **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GInputStream       *base_stream;
 | 
			
		||||
  gssize nskipped;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (stream);
 | 
			
		||||
  base_stream = filter_stream->base_stream;
 | 
			
		||||
 | 
			
		||||
  nskipped = g_input_stream_skip_finish (base_stream,
 | 
			
		||||
                                         result,
 | 
			
		||||
                                         error);
 | 
			
		||||
 | 
			
		||||
  return nskipped;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_input_stream_close_async (GInputStream         *stream,
 | 
			
		||||
                                   int                   io_priority,
 | 
			
		||||
                                   GCancellable         *cancellable,
 | 
			
		||||
                                   GAsyncReadyCallback   callback,
 | 
			
		||||
                                   gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GInputStream       *base_stream;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (stream);
 | 
			
		||||
  base_stream = filter_stream->base_stream;
 | 
			
		||||
 | 
			
		||||
  g_input_stream_close_async (base_stream,
 | 
			
		||||
                              io_priority,
 | 
			
		||||
                              cancellable,
 | 
			
		||||
                              callback,
 | 
			
		||||
                              user_data);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_filter_input_stream_close_finish (GInputStream  *stream,
 | 
			
		||||
                                    GAsyncResult  *result,
 | 
			
		||||
                                    GError       **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterInputStream *filter_stream;
 | 
			
		||||
  GInputStream       *base_stream;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_INPUT_STREAM (stream);
 | 
			
		||||
  base_stream = filter_stream->base_stream;
 | 
			
		||||
 | 
			
		||||
  res = g_input_stream_close_finish (stream,
 | 
			
		||||
                                     result,
 | 
			
		||||
                                     error);
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* vim: ts=2 sw=2 et */
 | 
			
		||||
							
								
								
									
										65
									
								
								gio/gfilterinputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								gio/gfilterinputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Christian Kellner <gicmo@gnome.org> 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILTER_INPUT_STREAM_H__
 | 
			
		||||
#define __G_FILTER_INPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/ginputstream.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILTER_INPUT_STREAM         (g_filter_input_stream_get_type ())
 | 
			
		||||
#define G_FILTER_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILTER_INPUT_STREAM, GFilterInputStream))
 | 
			
		||||
#define G_FILTER_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILTER_INPUT_STREAM, GFilterInputStreamClass))
 | 
			
		||||
#define G_IS_FILTER_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILTER_INPUT_STREAM))
 | 
			
		||||
#define G_IS_FILTER_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILTER_INPUT_STREAM))
 | 
			
		||||
#define G_FILTER_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILTER_INPUT_STREAM, GFilterInputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GFilterInputStream         GFilterInputStream;
 | 
			
		||||
typedef struct _GFilterInputStreamClass    GFilterInputStreamClass;
 | 
			
		||||
typedef struct _GFilterInputStreamPrivate  GFilterInputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GFilterInputStream
 | 
			
		||||
{
 | 
			
		||||
  GInputStream parent;
 | 
			
		||||
 | 
			
		||||
  /*<protected >*/
 | 
			
		||||
  GInputStream *base_stream;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GFilterInputStreamClass
 | 
			
		||||
{
 | 
			
		||||
  GInputStreamClass parent_class;
 | 
			
		||||
  
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GType          g_filter_input_stream_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
GInputStream  *g_filter_input_stream_get_base_stream (GFilterInputStream *stream);
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILTER_INPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										366
									
								
								gio/gfilteroutputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								gio/gfilteroutputstream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,366 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Christian Kellner <gicmo@gnome.org> 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "gfilteroutputstream.h"
 | 
			
		||||
#include "goutputstream.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
  PROP_0,
 | 
			
		||||
  PROP_BASE_STREAM
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void     g_filter_output_stream_set_property (GObject      *object,
 | 
			
		||||
                                                     guint         prop_id,
 | 
			
		||||
                                                     const GValue *value,
 | 
			
		||||
                                                     GParamSpec   *pspec);
 | 
			
		||||
 | 
			
		||||
static void     g_filter_output_stream_get_property (GObject    *object,
 | 
			
		||||
                                                     guint       prop_id,
 | 
			
		||||
                                                     GValue     *value,
 | 
			
		||||
                                                     GParamSpec *pspec);
 | 
			
		||||
static void     g_filter_output_stream_dispose      (GObject *object);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static gssize   g_filter_output_stream_write        (GOutputStream *stream,
 | 
			
		||||
                                                     const void    *buffer,
 | 
			
		||||
                                                     gsize          count,
 | 
			
		||||
                                                     GCancellable  *cancellable,
 | 
			
		||||
                                                     GError       **error);
 | 
			
		||||
static gboolean g_filter_output_stream_flush        (GOutputStream    *stream,
 | 
			
		||||
                                                     GCancellable  *cancellable,
 | 
			
		||||
                                                     GError          **error);
 | 
			
		||||
static gboolean g_filter_output_stream_close        (GOutputStream  *stream,
 | 
			
		||||
                                                     GCancellable   *cancellable,
 | 
			
		||||
                                                     GError        **error);
 | 
			
		||||
static void     g_filter_output_stream_write_async  (GOutputStream        *stream,
 | 
			
		||||
                                                     const void           *buffer,
 | 
			
		||||
                                                     gsize                 count,
 | 
			
		||||
                                                     int                   io_priority,
 | 
			
		||||
                                                     GCancellable         *cancellable,
 | 
			
		||||
                                                     GAsyncReadyCallback   callback,
 | 
			
		||||
                                                     gpointer              data);
 | 
			
		||||
static gssize   g_filter_output_stream_write_finish (GOutputStream        *stream,
 | 
			
		||||
                                                     GAsyncResult         *result,
 | 
			
		||||
                                                     GError              **error);
 | 
			
		||||
static void     g_filter_output_stream_flush_async  (GOutputStream        *stream,
 | 
			
		||||
                                                     int                   io_priority,
 | 
			
		||||
                                                     GCancellable         *cancellable,
 | 
			
		||||
                                                     GAsyncReadyCallback   callback,
 | 
			
		||||
                                                     gpointer              data);
 | 
			
		||||
static gboolean g_filter_output_stream_flush_finish (GOutputStream        *stream,
 | 
			
		||||
                                                     GAsyncResult         *result,
 | 
			
		||||
                                                     GError              **error);
 | 
			
		||||
static void     g_filter_output_stream_close_async  (GOutputStream        *stream,
 | 
			
		||||
                                                     int                   io_priority,
 | 
			
		||||
                                                     GCancellable         *cancellable,
 | 
			
		||||
                                                     GAsyncReadyCallback   callback,
 | 
			
		||||
                                                     gpointer              data);
 | 
			
		||||
static gboolean g_filter_output_stream_close_finish (GOutputStream        *stream,
 | 
			
		||||
                                                     GAsyncResult         *result,
 | 
			
		||||
                                                     GError              **error);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GFilterOutputStream, g_filter_output_stream, G_TYPE_OUTPUT_STREAM)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_output_stream_class_init (GFilterOutputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *object_class;
 | 
			
		||||
  GOutputStreamClass *ostream_class;
 | 
			
		||||
 | 
			
		||||
  object_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  object_class->get_property = g_filter_output_stream_get_property;
 | 
			
		||||
  object_class->set_property = g_filter_output_stream_set_property;
 | 
			
		||||
  object_class->dispose      = g_filter_output_stream_dispose;
 | 
			
		||||
    
 | 
			
		||||
  ostream_class = G_OUTPUT_STREAM_CLASS (klass);
 | 
			
		||||
  ostream_class->write = g_filter_output_stream_write;
 | 
			
		||||
  ostream_class->flush = g_filter_output_stream_flush;
 | 
			
		||||
  ostream_class->close = g_filter_output_stream_close;
 | 
			
		||||
  ostream_class->write_async  = g_filter_output_stream_write_async;
 | 
			
		||||
  ostream_class->write_finish = g_filter_output_stream_write_finish;
 | 
			
		||||
  ostream_class->flush_async  = g_filter_output_stream_flush_async;
 | 
			
		||||
  ostream_class->flush_finish = g_filter_output_stream_flush_finish;
 | 
			
		||||
  ostream_class->close_async  = g_filter_output_stream_close_async;
 | 
			
		||||
  ostream_class->close_finish = g_filter_output_stream_close_finish;
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (object_class,
 | 
			
		||||
                                   PROP_BASE_STREAM,
 | 
			
		||||
                                   g_param_spec_object ("base-stream",
 | 
			
		||||
                                                         P_("The Filter Base Stream"),
 | 
			
		||||
                                                         P_("The underlying base stream the io ops will be done on"),
 | 
			
		||||
                                                         G_TYPE_OUTPUT_STREAM,
 | 
			
		||||
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
 | 
			
		||||
                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_output_stream_set_property (GObject         *object,
 | 
			
		||||
                                     guint            prop_id,
 | 
			
		||||
                                     const GValue    *value,
 | 
			
		||||
                                     GParamSpec      *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
  GObject *obj;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id) 
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_BASE_STREAM:
 | 
			
		||||
      obj = g_value_dup_object (value);
 | 
			
		||||
      filter_stream->base_stream = G_OUTPUT_STREAM (obj);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_output_stream_get_property (GObject    *object,
 | 
			
		||||
                                     guint       prop_id,
 | 
			
		||||
                                     GValue     *value,
 | 
			
		||||
                                     GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
  switch (prop_id)
 | 
			
		||||
    {
 | 
			
		||||
    case PROP_BASE_STREAM:
 | 
			
		||||
      g_value_set_object (value, filter_stream->base_stream);
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_output_stream_dispose (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream        *stream;
 | 
			
		||||
 | 
			
		||||
  stream = G_FILTER_OUTPUT_STREAM (object);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (g_filter_output_stream_parent_class)->dispose (object);
 | 
			
		||||
  
 | 
			
		||||
  if (stream->base_stream)
 | 
			
		||||
    {
 | 
			
		||||
      g_object_unref (stream->base_stream);
 | 
			
		||||
      stream->base_stream = NULL;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_output_stream_init (GFilterOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GOutputStream *
 | 
			
		||||
g_filter_output_stream_get_base_stream (GFilterOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), NULL);
 | 
			
		||||
 | 
			
		||||
  return stream->base_stream;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_filter_output_stream_write (GOutputStream *stream,
 | 
			
		||||
                              const void *buffer,
 | 
			
		||||
                              gsize          count,
 | 
			
		||||
                              GCancellable  *cancellable,
 | 
			
		||||
                              GError       **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
  gssize nwritten;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  nwritten = g_output_stream_write (filter_stream->base_stream,
 | 
			
		||||
                                    buffer,
 | 
			
		||||
                                    count,
 | 
			
		||||
                                    cancellable,
 | 
			
		||||
                                    error);
 | 
			
		||||
 | 
			
		||||
  return nwritten;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_filter_output_stream_flush (GOutputStream    *stream,
 | 
			
		||||
                              GCancellable  *cancellable,
 | 
			
		||||
                              GError          **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  res = g_output_stream_flush (filter_stream->base_stream,
 | 
			
		||||
                               cancellable,
 | 
			
		||||
                               error);
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_filter_output_stream_close (GOutputStream  *stream,
 | 
			
		||||
                              GCancellable   *cancellable,
 | 
			
		||||
                              GError        **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  res = g_output_stream_close (filter_stream->base_stream,
 | 
			
		||||
                               cancellable,
 | 
			
		||||
                               error);
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_output_stream_write_async (GOutputStream        *stream,
 | 
			
		||||
                                    const void           *buffer,
 | 
			
		||||
                                    gsize                 count,
 | 
			
		||||
                                    int                   io_priority,
 | 
			
		||||
                                    GCancellable         *cancellable,
 | 
			
		||||
                                    GAsyncReadyCallback   callback,
 | 
			
		||||
                                    gpointer              data)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  g_output_stream_write_async (filter_stream->base_stream,
 | 
			
		||||
                               buffer,
 | 
			
		||||
                               count,
 | 
			
		||||
                               io_priority,
 | 
			
		||||
                               cancellable,
 | 
			
		||||
                               callback,
 | 
			
		||||
                               data);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_filter_output_stream_write_finish (GOutputStream        *stream,
 | 
			
		||||
                                     GAsyncResult         *result,
 | 
			
		||||
                                     GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
  gssize nwritten;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  nwritten = g_output_stream_write_finish (filter_stream->base_stream,
 | 
			
		||||
                                           result,
 | 
			
		||||
                                           error);
 | 
			
		||||
 | 
			
		||||
  return nwritten;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_output_stream_flush_async (GOutputStream        *stream,
 | 
			
		||||
                                    int                   io_priority,
 | 
			
		||||
                                    GCancellable         *cancellable,
 | 
			
		||||
                                    GAsyncReadyCallback   callback,
 | 
			
		||||
                                    gpointer              data)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  g_output_stream_flush_async (filter_stream->base_stream,
 | 
			
		||||
                               io_priority,
 | 
			
		||||
                               cancellable,
 | 
			
		||||
                               callback,
 | 
			
		||||
                               data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_filter_output_stream_flush_finish (GOutputStream        *stream,
 | 
			
		||||
                                     GAsyncResult         *result,
 | 
			
		||||
                                     GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  res = g_output_stream_flush_finish (filter_stream->base_stream,
 | 
			
		||||
                                      result,
 | 
			
		||||
                                      error);
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_filter_output_stream_close_async (GOutputStream        *stream,
 | 
			
		||||
                                    int                   io_priority,
 | 
			
		||||
                                    GCancellable         *cancellable,
 | 
			
		||||
                                    GAsyncReadyCallback   callback,
 | 
			
		||||
                                    gpointer              data)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  g_output_stream_close_async (filter_stream->base_stream,
 | 
			
		||||
                               io_priority,
 | 
			
		||||
                               cancellable,
 | 
			
		||||
                               callback,
 | 
			
		||||
                               data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_filter_output_stream_close_finish (GOutputStream        *stream,
 | 
			
		||||
                                     GAsyncResult         *result,
 | 
			
		||||
                                     GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GFilterOutputStream *filter_stream;
 | 
			
		||||
  gboolean res;
 | 
			
		||||
 | 
			
		||||
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  res = g_output_stream_close_finish (filter_stream->base_stream,
 | 
			
		||||
                                      result,
 | 
			
		||||
                                      error);
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* vim: ts=2 sw=2 et */
 | 
			
		||||
							
								
								
									
										65
									
								
								gio/gfilteroutputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								gio/gfilteroutputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Christian Kellner <gicmo@gnome.org> 
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_FILTER_OUTPUT_STREAM_H__
 | 
			
		||||
#define __G_FILTER_OUTPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/goutputstream.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_FILTER_OUTPUT_STREAM         (g_filter_output_stream_get_type ())
 | 
			
		||||
#define G_FILTER_OUTPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_FILTER_OUTPUT_STREAM, GFilterOutputStream))
 | 
			
		||||
#define G_FILTER_OUTPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_FILTER_OUTPUT_STREAM, GFilterOutputStreamClass))
 | 
			
		||||
#define G_IS_FILTER_OUTPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_FILTER_OUTPUT_STREAM))
 | 
			
		||||
#define G_IS_FILTER_OUTPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_FILTER_OUTPUT_STREAM))
 | 
			
		||||
#define G_FILTER_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_FILTER_OUTPUT_STREAM, GFilterOutputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GFilterOutputStream         GFilterOutputStream;
 | 
			
		||||
typedef struct _GFilterOutputStreamClass    GFilterOutputStreamClass;
 | 
			
		||||
typedef struct _GFilterOutputStreamPrivate  GFilterOutputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GFilterOutputStream
 | 
			
		||||
{
 | 
			
		||||
  GOutputStream parent;
 | 
			
		||||
 | 
			
		||||
  /*< protected >*/
 | 
			
		||||
  GOutputStream *base_stream;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GFilterOutputStreamClass
 | 
			
		||||
{
 | 
			
		||||
 GOutputStreamClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GType           g_filter_output_stream_get_type  (void) G_GNUC_CONST;
 | 
			
		||||
GOutputStream  *g_filter_output_stream_get_base_stream (GFilterOutputStream *stream);
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILTER_OUTPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										118
									
								
								gio/gicon.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								gio/gicon.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,118 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include "gicon.h"
 | 
			
		||||
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
static void g_icon_base_init (gpointer g_class);
 | 
			
		||||
static void g_icon_class_init (gpointer g_class,
 | 
			
		||||
			       gpointer class_data);
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
g_icon_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
  static GType icon_type = 0;
 | 
			
		||||
 | 
			
		||||
  if (! icon_type)
 | 
			
		||||
    {
 | 
			
		||||
      static const GTypeInfo icon_info =
 | 
			
		||||
      {
 | 
			
		||||
        sizeof (GIconIface), /* class_size */
 | 
			
		||||
	g_icon_base_init,   /* base_init */
 | 
			
		||||
	NULL,		/* base_finalize */
 | 
			
		||||
	g_icon_class_init,
 | 
			
		||||
	NULL,		/* class_finalize */
 | 
			
		||||
	NULL,		/* class_data */
 | 
			
		||||
	0,
 | 
			
		||||
	0,              /* n_preallocs */
 | 
			
		||||
	NULL
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      icon_type =
 | 
			
		||||
	g_type_register_static (G_TYPE_INTERFACE, I_("GIcon"),
 | 
			
		||||
				&icon_info, 0);
 | 
			
		||||
 | 
			
		||||
      g_type_interface_add_prerequisite (icon_type, G_TYPE_OBJECT);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return icon_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_icon_class_init (gpointer g_class,
 | 
			
		||||
		   gpointer class_data)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_icon_base_init (gpointer g_class)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_icon_hash:
 | 
			
		||||
 * @icon: #gconstpointer to an icon object.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a #guint containing a hash for the @icon, suitable for 
 | 
			
		||||
 * use in a #GHashTable or similar data structure.
 | 
			
		||||
 **/
 | 
			
		||||
guint
 | 
			
		||||
g_icon_hash (gconstpointer icon)
 | 
			
		||||
{
 | 
			
		||||
  GIconIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_ICON (icon), 0);
 | 
			
		||||
 | 
			
		||||
  iface = G_ICON_GET_IFACE (icon);
 | 
			
		||||
 | 
			
		||||
  return (* iface->hash) ((GIcon *)icon);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_icon_equal:
 | 
			
		||||
 * @icon1: pointer to the first #GIcon.
 | 
			
		||||
 * @icon2: pointer to the second #GIcon.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: %TRUE if @icon1 is equal to @icon2. %FALSE otherwise.
 | 
			
		||||
 **/
 | 
			
		||||
gboolean
 | 
			
		||||
g_icon_equal (GIcon *icon1,
 | 
			
		||||
	      GIcon *icon2)
 | 
			
		||||
{
 | 
			
		||||
  GIconIface *iface;
 | 
			
		||||
 | 
			
		||||
  if (icon1 == NULL && icon2 == NULL)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  if (icon1 == NULL || icon2 == NULL)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  
 | 
			
		||||
  if (G_TYPE_FROM_INSTANCE (icon1) != G_TYPE_FROM_INSTANCE (icon2))
 | 
			
		||||
    return FALSE;
 | 
			
		||||
 | 
			
		||||
  iface = G_ICON_GET_IFACE (icon1);
 | 
			
		||||
  
 | 
			
		||||
  return (* iface->equal) (icon1, icon2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										58
									
								
								gio/gicon.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								gio/gicon.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_ICON_H__
 | 
			
		||||
#define __G_ICON_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_ICON            (g_icon_get_type ())
 | 
			
		||||
#define G_ICON(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_ICON, GIcon))
 | 
			
		||||
#define G_IS_ICON(obj)	       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_ICON))
 | 
			
		||||
#define G_ICON_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_ICON, GIconIface))
 | 
			
		||||
 | 
			
		||||
typedef struct _GIcon         		GIcon; /* Dummy typedef */
 | 
			
		||||
typedef struct _GIconIface    		GIconIface;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _GIconIface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface g_iface;
 | 
			
		||||
 | 
			
		||||
  /* Virtual Table */
 | 
			
		||||
 | 
			
		||||
  guint               (*hash)               (GIcon                *icon);
 | 
			
		||||
  gboolean            (*equal)              (GIcon                *icon1,
 | 
			
		||||
					     GIcon                *icon2);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_icon_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
guint    g_icon_hash  (gconstpointer  icon);
 | 
			
		||||
gboolean g_icon_equal (GIcon         *icon1,
 | 
			
		||||
		       GIcon         *icon2);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_ICON_H__ */
 | 
			
		||||
							
								
								
									
										1184
									
								
								gio/ginputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1184
									
								
								gio/ginputstream.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										165
									
								
								gio/ginputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										165
									
								
								gio/ginputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,165 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_INPUT_STREAM_H__
 | 
			
		||||
#define __G_INPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gioerror.h>
 | 
			
		||||
#include <gio/gcancellable.h>
 | 
			
		||||
#include <gio/gasyncresult.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_INPUT_STREAM         (g_input_stream_get_type ())
 | 
			
		||||
#define G_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_INPUT_STREAM, GInputStream))
 | 
			
		||||
#define G_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_INPUT_STREAM, GInputStreamClass))
 | 
			
		||||
#define G_IS_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_INPUT_STREAM))
 | 
			
		||||
#define G_IS_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_INPUT_STREAM))
 | 
			
		||||
#define G_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_INPUT_STREAM, GInputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GInputStream         GInputStream;
 | 
			
		||||
typedef struct _GInputStreamClass    GInputStreamClass;
 | 
			
		||||
typedef struct _GInputStreamPrivate  GInputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GInputStream
 | 
			
		||||
{
 | 
			
		||||
  GObject parent;
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GInputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GInputStreamClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
 | 
			
		||||
  /* Sync ops: */
 | 
			
		||||
  
 | 
			
		||||
  gssize   (* read)        (GInputStream *stream,
 | 
			
		||||
			    void         *buffer,
 | 
			
		||||
			    gsize         count,
 | 
			
		||||
			    GCancellable *cancellable,
 | 
			
		||||
			    GError      **error);
 | 
			
		||||
  gssize   (* skip)        (GInputStream *stream,
 | 
			
		||||
			    gsize         count,
 | 
			
		||||
			    GCancellable *cancellable,
 | 
			
		||||
			    GError      **error);
 | 
			
		||||
  gboolean (* close)	   (GInputStream *stream,
 | 
			
		||||
			    GCancellable *cancellable,
 | 
			
		||||
			    GError      **error);
 | 
			
		||||
 | 
			
		||||
  /* Async ops: (optional in derived classes) */
 | 
			
		||||
  void     (* read_async)  (GInputStream        *stream,
 | 
			
		||||
			    void               *buffer,
 | 
			
		||||
			    gsize               count,
 | 
			
		||||
			    int                 io_priority,
 | 
			
		||||
			    GCancellable       *cancellable,
 | 
			
		||||
			    GAsyncReadyCallback callback,
 | 
			
		||||
			    gpointer            user_data);
 | 
			
		||||
  gssize   (* read_finish) (GInputStream       *stream,
 | 
			
		||||
			    GAsyncResult       *result,
 | 
			
		||||
			    GError            **error);
 | 
			
		||||
  void     (* skip_async)  (GInputStream       *stream,
 | 
			
		||||
			    gsize               count,
 | 
			
		||||
			    int                 io_priority,
 | 
			
		||||
			    GCancellable       *cancellable,
 | 
			
		||||
			    GAsyncReadyCallback callback,
 | 
			
		||||
			    gpointer            user_data);
 | 
			
		||||
  gssize   (* skip_finish) (GInputStream        *stream,
 | 
			
		||||
			    GAsyncResult       *result,
 | 
			
		||||
			    GError            **error);
 | 
			
		||||
  void     (* close_async) (GInputStream        *stream,
 | 
			
		||||
			    int                  io_priority,
 | 
			
		||||
			    GCancellable       *cancellable,
 | 
			
		||||
			    GAsyncReadyCallback callback,
 | 
			
		||||
			    gpointer            user_data);
 | 
			
		||||
  gboolean (* close_finish)(GInputStream        *stream,
 | 
			
		||||
			    GAsyncResult       *result,
 | 
			
		||||
			    GError            **error);
 | 
			
		||||
 | 
			
		||||
  /* Padding for future expansion */
 | 
			
		||||
  void (*_g_reserved1) (void);
 | 
			
		||||
  void (*_g_reserved2) (void);
 | 
			
		||||
  void (*_g_reserved3) (void);
 | 
			
		||||
  void (*_g_reserved4) (void);
 | 
			
		||||
  void (*_g_reserved5) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_input_stream_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
gssize   g_input_stream_read         (GInputStream          *stream,
 | 
			
		||||
				      void                  *buffer,
 | 
			
		||||
				      gsize                  count,
 | 
			
		||||
				      GCancellable          *cancellable,
 | 
			
		||||
				      GError               **error);
 | 
			
		||||
gboolean g_input_stream_read_all     (GInputStream          *stream,
 | 
			
		||||
				      void                  *buffer,
 | 
			
		||||
				      gsize                  count,
 | 
			
		||||
				      gsize                 *bytes_read,
 | 
			
		||||
				      GCancellable          *cancellable,
 | 
			
		||||
				      GError               **error);
 | 
			
		||||
gssize   g_input_stream_skip         (GInputStream          *stream,
 | 
			
		||||
				      gsize                  count,
 | 
			
		||||
				      GCancellable          *cancellable,
 | 
			
		||||
				      GError               **error);
 | 
			
		||||
gboolean g_input_stream_close        (GInputStream          *stream,
 | 
			
		||||
				      GCancellable          *cancellable,
 | 
			
		||||
				      GError               **error);
 | 
			
		||||
void     g_input_stream_read_async   (GInputStream          *stream,
 | 
			
		||||
				      void                  *buffer,
 | 
			
		||||
				      gsize                  count,
 | 
			
		||||
				      int                    io_priority,
 | 
			
		||||
				      GCancellable          *cancellable,
 | 
			
		||||
				      GAsyncReadyCallback    callback,
 | 
			
		||||
				      gpointer               user_data);
 | 
			
		||||
gssize   g_input_stream_read_finish  (GInputStream          *stream,
 | 
			
		||||
				      GAsyncResult          *result,
 | 
			
		||||
				      GError               **error);
 | 
			
		||||
void     g_input_stream_skip_async   (GInputStream          *stream,
 | 
			
		||||
				      gsize                  count,
 | 
			
		||||
				      int                    io_priority,
 | 
			
		||||
				      GCancellable          *cancellable,
 | 
			
		||||
				      GAsyncReadyCallback    callback,
 | 
			
		||||
				      gpointer               user_data);
 | 
			
		||||
gssize   g_input_stream_skip_finish  (GInputStream          *stream,
 | 
			
		||||
				      GAsyncResult          *result,
 | 
			
		||||
				      GError               **error);
 | 
			
		||||
void     g_input_stream_close_async  (GInputStream          *stream,
 | 
			
		||||
				      int                    io_priority,
 | 
			
		||||
				      GCancellable          *cancellable,
 | 
			
		||||
				      GAsyncReadyCallback    callback,
 | 
			
		||||
				      gpointer               user_data);
 | 
			
		||||
gboolean g_input_stream_close_finish (GInputStream          *stream,
 | 
			
		||||
				      GAsyncResult          *result,
 | 
			
		||||
				      GError               **error);
 | 
			
		||||
 | 
			
		||||
/* For implementations: */
 | 
			
		||||
 | 
			
		||||
gboolean g_input_stream_is_closed    (GInputStream          *stream);
 | 
			
		||||
gboolean g_input_stream_has_pending  (GInputStream          *stream);
 | 
			
		||||
void     g_input_stream_set_pending  (GInputStream          *stream,
 | 
			
		||||
				      gboolean               pending);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_INPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										4
									
								
								gio/gio-marshal.list
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								gio/gio-marshal.list
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
BOOLEAN:STRING,STRING,STRING,INT
 | 
			
		||||
BOOLEAN:STRING,POINTER
 | 
			
		||||
VOID:BOOLEAN,POINTER
 | 
			
		||||
VOID:OBJECT,OBJECT,INT
 | 
			
		||||
							
								
								
									
										155
									
								
								gio/gioerror.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								gio/gioerror.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,155 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include "gioerror.h"
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_io_error_quark:
 | 
			
		||||
 *
 | 
			
		||||
 * Return value: The quark used as %G_IO_ERROR
 | 
			
		||||
 **/
 | 
			
		||||
GQuark
 | 
			
		||||
g_io_error_quark (void)
 | 
			
		||||
{
 | 
			
		||||
  return g_quark_from_static_string ("g-io-error-quark");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GIOErrorEnum
 | 
			
		||||
g_io_error_from_errno (gint err_no)
 | 
			
		||||
{
 | 
			
		||||
  switch (err_no)
 | 
			
		||||
    {
 | 
			
		||||
#ifdef EEXIST
 | 
			
		||||
    case EEXIST:
 | 
			
		||||
      return G_IO_ERROR_EXISTS;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EISDIR
 | 
			
		||||
    case EISDIR:
 | 
			
		||||
      return G_IO_ERROR_IS_DIRECTORY;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EACCES
 | 
			
		||||
    case EACCES:
 | 
			
		||||
      return G_IO_ERROR_PERMISSION_DENIED;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ENAMETOOLONG
 | 
			
		||||
    case ENAMETOOLONG:
 | 
			
		||||
      return G_IO_ERROR_FILENAME_TOO_LONG;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ENOENT
 | 
			
		||||
    case ENOENT:
 | 
			
		||||
      return G_IO_ERROR_NOT_FOUND;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ENOTDIR
 | 
			
		||||
    case ENOTDIR:
 | 
			
		||||
      return G_IO_ERROR_NOT_DIRECTORY;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EROFS
 | 
			
		||||
    case EROFS:
 | 
			
		||||
      return G_IO_ERROR_READ_ONLY;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ELOOP
 | 
			
		||||
    case ELOOP:
 | 
			
		||||
      return G_IO_ERROR_TOO_MANY_LINKS;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ENOSPC
 | 
			
		||||
    case ENOSPC:
 | 
			
		||||
      return G_IO_ERROR_NO_SPACE;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ENOMEM
 | 
			
		||||
    case ENOMEM:
 | 
			
		||||
      return G_IO_ERROR_NO_SPACE;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
      
 | 
			
		||||
#ifdef EINVAL
 | 
			
		||||
    case EINVAL:
 | 
			
		||||
      return G_IO_ERROR_INVALID_ARGUMENT;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EPERM
 | 
			
		||||
    case EPERM:
 | 
			
		||||
      return G_IO_ERROR_PERMISSION_DENIED;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ECANCELED
 | 
			
		||||
    case ECANCELED:
 | 
			
		||||
      return G_IO_ERROR_CANCELLED;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ENOTEMPTY
 | 
			
		||||
    case ENOTEMPTY:
 | 
			
		||||
      return G_IO_ERROR_NOT_EMPTY;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ENOTSUP
 | 
			
		||||
    case ENOTSUP:
 | 
			
		||||
      return G_IO_ERROR_NOT_SUPPORTED;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ETIMEDOUT
 | 
			
		||||
    case ETIMEDOUT:
 | 
			
		||||
      return G_IO_ERROR_TIMED_OUT;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EBUSY
 | 
			
		||||
    case EBUSY:
 | 
			
		||||
      return G_IO_ERROR_BUSY;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef EWOULDBLOCK
 | 
			
		||||
    case EWOULDBLOCK:
 | 
			
		||||
      return G_IO_ERROR_WOULD_BLOCK;
 | 
			
		||||
      break;
 | 
			
		||||
#endif
 | 
			
		||||
      
 | 
			
		||||
    default:
 | 
			
		||||
      return G_IO_ERROR_FAILED;
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								gio/gioerror.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								gio/gioerror.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,78 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_IO_ERROR_H__
 | 
			
		||||
#define __G_IO_ERROR_H__
 | 
			
		||||
 | 
			
		||||
#include <glib/gerror.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
GQuark          g_io_error_quark      (void);
 | 
			
		||||
 | 
			
		||||
#define G_IO_ERROR g_io_error_quark()
 | 
			
		||||
 | 
			
		||||
/* This enumeration conflicts with GIOError in giochannel.h. However,
 | 
			
		||||
 * that is only used as a return value in some deprecated functions.
 | 
			
		||||
 * So, we reuse the same prefix for the enumeration values, but call
 | 
			
		||||
 * the actual enumeration (which is rarely used) GIOErrorEnum.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
  G_IO_ERROR_FAILED,
 | 
			
		||||
  G_IO_ERROR_NOT_FOUND,
 | 
			
		||||
  G_IO_ERROR_EXISTS,
 | 
			
		||||
  G_IO_ERROR_IS_DIRECTORY,
 | 
			
		||||
  G_IO_ERROR_NOT_DIRECTORY,
 | 
			
		||||
  G_IO_ERROR_NOT_EMPTY,
 | 
			
		||||
  G_IO_ERROR_NOT_REGULAR_FILE,
 | 
			
		||||
  G_IO_ERROR_NOT_SYMBOLIC_LINK,
 | 
			
		||||
  G_IO_ERROR_NOT_MOUNTABLE_FILE,
 | 
			
		||||
  G_IO_ERROR_FILENAME_TOO_LONG,
 | 
			
		||||
  G_IO_ERROR_INVALID_FILENAME,
 | 
			
		||||
  G_IO_ERROR_TOO_MANY_LINKS,
 | 
			
		||||
  G_IO_ERROR_NO_SPACE,
 | 
			
		||||
  G_IO_ERROR_INVALID_ARGUMENT,
 | 
			
		||||
  G_IO_ERROR_PERMISSION_DENIED,
 | 
			
		||||
  G_IO_ERROR_NOT_SUPPORTED,
 | 
			
		||||
  G_IO_ERROR_NOT_MOUNTED,
 | 
			
		||||
  G_IO_ERROR_ALREADY_MOUNTED,
 | 
			
		||||
  G_IO_ERROR_CLOSED,
 | 
			
		||||
  G_IO_ERROR_CANCELLED,
 | 
			
		||||
  G_IO_ERROR_PENDING,
 | 
			
		||||
  G_IO_ERROR_READ_ONLY,
 | 
			
		||||
  G_IO_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
  G_IO_ERROR_WRONG_ETAG,
 | 
			
		||||
  G_IO_ERROR_TIMED_OUT,
 | 
			
		||||
  G_IO_ERROR_WOULD_RECURSE,
 | 
			
		||||
  G_IO_ERROR_BUSY,
 | 
			
		||||
  G_IO_ERROR_WOULD_BLOCK,
 | 
			
		||||
  G_IO_ERROR_HOST_NOT_FOUND,
 | 
			
		||||
  G_IO_ERROR_WOULD_MERGE
 | 
			
		||||
} GIOErrorEnum;
 | 
			
		||||
 | 
			
		||||
GIOErrorEnum g_io_error_from_errno (gint err_no);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_IO_ERROR_H__ */
 | 
			
		||||
							
								
								
									
										237
									
								
								gio/giomodule.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								gio/giomodule.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,237 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "giomodule.h"
 | 
			
		||||
 | 
			
		||||
struct _GIOModule {
 | 
			
		||||
  GTypeModule parent_instance;
 | 
			
		||||
  
 | 
			
		||||
  gchar       *filename;
 | 
			
		||||
  GModule     *library;
 | 
			
		||||
  
 | 
			
		||||
  void (* load)   (GIOModule *module);
 | 
			
		||||
  void (* unload) (GIOModule *module);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GIOModuleClass
 | 
			
		||||
{
 | 
			
		||||
  GTypeModuleClass parent_class;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void      g_io_module_finalize      (GObject      *object);
 | 
			
		||||
static gboolean  g_io_module_load_module   (GTypeModule  *gmodule);
 | 
			
		||||
static void      g_io_module_unload_module (GTypeModule  *gmodule);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GIOModule, g_io_module, G_TYPE_TYPE_MODULE);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_io_module_class_init (GIOModuleClass *class)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass     *object_class      = G_OBJECT_CLASS (class);
 | 
			
		||||
  GTypeModuleClass *type_module_class = G_TYPE_MODULE_CLASS (class);
 | 
			
		||||
 | 
			
		||||
  object_class->finalize     = g_io_module_finalize;
 | 
			
		||||
 | 
			
		||||
  type_module_class->load    = g_io_module_load_module;
 | 
			
		||||
  type_module_class->unload  = g_io_module_unload_module;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_io_module_init (GIOModule *module)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_io_module_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GIOModule *module = G_IO_MODULE (object);
 | 
			
		||||
 | 
			
		||||
  g_free (module->filename);
 | 
			
		||||
 | 
			
		||||
  G_OBJECT_CLASS (g_io_module_parent_class)->finalize (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_io_module_load_module (GTypeModule *gmodule)
 | 
			
		||||
{
 | 
			
		||||
  GIOModule *module = G_IO_MODULE (gmodule);
 | 
			
		||||
 | 
			
		||||
  if (!module->filename)
 | 
			
		||||
    {
 | 
			
		||||
      g_warning ("GIOModule path not set");
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  module->library = g_module_open (module->filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
 | 
			
		||||
 | 
			
		||||
  if (!module->library)
 | 
			
		||||
    {
 | 
			
		||||
      g_printerr ("%s\n", g_module_error ());
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Make sure that the loaded library contains the required methods */
 | 
			
		||||
  if (! g_module_symbol (module->library,
 | 
			
		||||
                         "g_io_module_load",
 | 
			
		||||
                         (gpointer *) &module->load) ||
 | 
			
		||||
      ! g_module_symbol (module->library,
 | 
			
		||||
                         "g_io_module_unload",
 | 
			
		||||
                         (gpointer *) &module->unload))
 | 
			
		||||
    {
 | 
			
		||||
      g_printerr ("%s\n", g_module_error ());
 | 
			
		||||
      g_module_close (module->library);
 | 
			
		||||
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Initialize the loaded module */
 | 
			
		||||
  module->load (module);
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_io_module_unload_module (GTypeModule *gmodule)
 | 
			
		||||
{
 | 
			
		||||
  GIOModule *module = G_IO_MODULE (gmodule);
 | 
			
		||||
 | 
			
		||||
  module->unload (module);
 | 
			
		||||
 | 
			
		||||
  g_module_close (module->library);
 | 
			
		||||
  module->library = NULL;
 | 
			
		||||
 | 
			
		||||
  module->load   = NULL;
 | 
			
		||||
  module->unload = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_io_module_new:
 | 
			
		||||
 * @filename: filename of the module to load.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a new #GIOModule from given @filename, 
 | 
			
		||||
 * or %NULL on error.
 | 
			
		||||
 **/
 | 
			
		||||
GIOModule *
 | 
			
		||||
g_io_module_new (const gchar *filename)
 | 
			
		||||
{
 | 
			
		||||
  GIOModule *module;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (filename != NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  module = g_object_new (G_IO_TYPE_MODULE, NULL);
 | 
			
		||||
  module->filename = g_strdup (filename);
 | 
			
		||||
 | 
			
		||||
  return module;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
is_valid_module_name (const gchar *basename)
 | 
			
		||||
{
 | 
			
		||||
#if !defined(G_OS_WIN32) && !defined(G_WITH_CYGWIN)
 | 
			
		||||
  return
 | 
			
		||||
    g_str_has_prefix (basename, "lib") &&
 | 
			
		||||
    g_str_has_suffix (basename, ".so");
 | 
			
		||||
#else
 | 
			
		||||
  return g_str_has_suffix (basename, ".dll");
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GList *
 | 
			
		||||
load_modules (const char *dirname)
 | 
			
		||||
{
 | 
			
		||||
  const gchar *name;
 | 
			
		||||
  GDir        *dir;
 | 
			
		||||
  GList *modules;
 | 
			
		||||
 | 
			
		||||
  if (!g_module_supported ())
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  dir = g_dir_open (dirname, 0, NULL);
 | 
			
		||||
  if (!dir)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  modules = NULL;
 | 
			
		||||
  while ((name = g_dir_read_name (dir)))
 | 
			
		||||
    {
 | 
			
		||||
      if (is_valid_module_name (name))
 | 
			
		||||
        {
 | 
			
		||||
          GIOModule *module;
 | 
			
		||||
          gchar     *path;
 | 
			
		||||
 | 
			
		||||
          path = g_build_filename (dirname, name, NULL);
 | 
			
		||||
          module = g_io_module_new (path);
 | 
			
		||||
 | 
			
		||||
          if (!g_type_module_use (G_TYPE_MODULE (module)))
 | 
			
		||||
            {
 | 
			
		||||
              g_printerr ("Failed to load module: %s\n", path);
 | 
			
		||||
              g_object_unref (module);
 | 
			
		||||
              g_free (path);
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
	  
 | 
			
		||||
          g_free (path);
 | 
			
		||||
 | 
			
		||||
          g_type_module_unuse (G_TYPE_MODULE (module));
 | 
			
		||||
	  
 | 
			
		||||
          modules = g_list_prepend (modules, module);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  g_dir_close (dir);
 | 
			
		||||
 | 
			
		||||
  return modules;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
G_LOCK_DEFINE_STATIC (loaded_dirs);
 | 
			
		||||
static GHashTable *loaded_dirs = NULL;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_io_module_ensure_loaded:
 | 
			
		||||
 * @directory: directory to ensure is loaded.
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_io_modules_ensure_loaded (const char *directory)
 | 
			
		||||
{
 | 
			
		||||
  GList *modules;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (directory != NULL);
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (loaded_dirs);
 | 
			
		||||
 | 
			
		||||
  if (loaded_dirs == NULL)
 | 
			
		||||
    loaded_dirs = g_hash_table_new (g_str_hash, g_str_equal);
 | 
			
		||||
 | 
			
		||||
  if (!g_hash_table_lookup_extended (loaded_dirs, directory,
 | 
			
		||||
				     NULL, NULL))
 | 
			
		||||
    {
 | 
			
		||||
      modules = load_modules (directory);
 | 
			
		||||
      g_hash_table_insert (loaded_dirs,
 | 
			
		||||
			   g_strdup (directory),
 | 
			
		||||
			   modules);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  G_UNLOCK (loaded_dirs);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								gio/giomodule.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								gio/giomodule.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_IO_MODULE_H__
 | 
			
		||||
#define __G_IO_MODULE_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gmodule.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_IO_TYPE_MODULE         (g_io_module_get_type ())
 | 
			
		||||
#define G_IO_MODULE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_IO_TYPE_MODULE, GIOModule))
 | 
			
		||||
#define G_IO_MODULE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_IO_TYPE_MODULE, GIOModuleClass))
 | 
			
		||||
#define G_IO_IS_MODULE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_IO_TYPE_MODULE))
 | 
			
		||||
#define G_IO_IS_MODULE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_IO_TYPE_MODULE))
 | 
			
		||||
#define G_IO_MODULE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_IO_TYPE_MODULE, GIOModuleClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GIOModule GIOModule;
 | 
			
		||||
typedef struct _GIOModuleClass GIOModuleClass;
 | 
			
		||||
 | 
			
		||||
GType      g_io_module_get_type (void) G_GNUC_CONST;
 | 
			
		||||
GIOModule *g_io_module_new      (const gchar *filename);
 | 
			
		||||
 | 
			
		||||
void       g_io_modules_ensure_loaded (const char *directory);
 | 
			
		||||
 | 
			
		||||
/* API for the modules to implement */
 | 
			
		||||
void        g_io_module_load     (GIOModule   *module);
 | 
			
		||||
void        g_io_module_unload   (GIOModule   *module);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_IO_MODULE_H__ */
 | 
			
		||||
							
								
								
									
										372
									
								
								gio/gioscheduler.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										372
									
								
								gio/gioscheduler.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,372 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "gioscheduler.h"
 | 
			
		||||
 | 
			
		||||
struct _GIOJob {
 | 
			
		||||
  GSList *active_link;
 | 
			
		||||
  GIOJobFunc job_func;
 | 
			
		||||
  GIODataFunc cancel_func; /* Runs under job map lock */
 | 
			
		||||
  gpointer data;
 | 
			
		||||
  GDestroyNotify destroy_notify;
 | 
			
		||||
 | 
			
		||||
  gint io_priority;
 | 
			
		||||
  GCancellable *cancellable;
 | 
			
		||||
 | 
			
		||||
  guint idle_tag;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_LOCK_DEFINE_STATIC(active_jobs);
 | 
			
		||||
static GSList *active_jobs = NULL;
 | 
			
		||||
 | 
			
		||||
static GThreadPool *job_thread_pool = NULL;
 | 
			
		||||
 | 
			
		||||
static void io_job_thread (gpointer       data,
 | 
			
		||||
			   gpointer       user_data);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_io_job_free (GIOJob *job)
 | 
			
		||||
{
 | 
			
		||||
  if (job->cancellable)
 | 
			
		||||
    g_object_unref (job->cancellable);
 | 
			
		||||
  g_free (job);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
g_io_job_compare (gconstpointer  a,
 | 
			
		||||
		  gconstpointer  b,
 | 
			
		||||
		  gpointer       user_data)
 | 
			
		||||
{
 | 
			
		||||
  const GIOJob *aa = a;
 | 
			
		||||
  const GIOJob *bb = b;
 | 
			
		||||
 | 
			
		||||
  /* Cancelled jobs are set prio == -1, so that
 | 
			
		||||
     they are executed as quickly as possible */
 | 
			
		||||
  
 | 
			
		||||
  /* Lower value => higher priority */
 | 
			
		||||
  if (aa->io_priority < bb->io_priority)
 | 
			
		||||
    return -1;
 | 
			
		||||
  if (aa->io_priority == bb->io_priority)
 | 
			
		||||
    return 0;
 | 
			
		||||
  return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gpointer
 | 
			
		||||
init_scheduler (gpointer arg)
 | 
			
		||||
{
 | 
			
		||||
  if (job_thread_pool == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* TODO: thread_pool_new can fail */
 | 
			
		||||
      job_thread_pool = g_thread_pool_new (io_job_thread,
 | 
			
		||||
					   NULL,
 | 
			
		||||
					   10,
 | 
			
		||||
					   FALSE,
 | 
			
		||||
					   NULL);
 | 
			
		||||
      if (job_thread_pool != NULL)
 | 
			
		||||
	{
 | 
			
		||||
	  g_thread_pool_set_sort_function (job_thread_pool,
 | 
			
		||||
					   g_io_job_compare,
 | 
			
		||||
					   NULL);
 | 
			
		||||
	  /* Its kinda weird that this is a global setting
 | 
			
		||||
	   * instead of per threadpool. However, we really
 | 
			
		||||
	   * want to cache some threads, but not keep around
 | 
			
		||||
	   * those threads forever. */
 | 
			
		||||
	  g_thread_pool_set_max_idle_time (15 * 1000);
 | 
			
		||||
	  g_thread_pool_set_max_unused_threads (2);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
remove_active_job (GIOJob *job)
 | 
			
		||||
{
 | 
			
		||||
  GIOJob *other_job;
 | 
			
		||||
  GSList *l;
 | 
			
		||||
  gboolean resort_jobs;
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (active_jobs);
 | 
			
		||||
  active_jobs = g_slist_delete_link (active_jobs, job->active_link);
 | 
			
		||||
  
 | 
			
		||||
  resort_jobs = FALSE;
 | 
			
		||||
  for (l = active_jobs; l != NULL; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      other_job = l->data;
 | 
			
		||||
      if (other_job->io_priority >= 0 &&
 | 
			
		||||
	  g_cancellable_is_cancelled (other_job->cancellable))
 | 
			
		||||
	{
 | 
			
		||||
	  other_job->io_priority = -1;
 | 
			
		||||
	  resort_jobs = TRUE;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  G_UNLOCK (active_jobs);
 | 
			
		||||
  
 | 
			
		||||
  if (resort_jobs &&
 | 
			
		||||
      job_thread_pool != NULL)
 | 
			
		||||
    g_thread_pool_set_sort_function (job_thread_pool,
 | 
			
		||||
				     g_io_job_compare,
 | 
			
		||||
				     NULL);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
io_job_thread (gpointer       data,
 | 
			
		||||
	       gpointer       user_data)
 | 
			
		||||
{
 | 
			
		||||
  GIOJob *job = data;
 | 
			
		||||
 | 
			
		||||
  if (job->cancellable)
 | 
			
		||||
    g_push_current_cancellable (job->cancellable);
 | 
			
		||||
  job->job_func (job, job->cancellable, job->data);
 | 
			
		||||
  if (job->cancellable)
 | 
			
		||||
    g_pop_current_cancellable (job->cancellable);
 | 
			
		||||
 | 
			
		||||
  if (job->destroy_notify)
 | 
			
		||||
    job->destroy_notify (job->data);
 | 
			
		||||
 | 
			
		||||
  remove_active_job (job);
 | 
			
		||||
  g_io_job_free (job);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
run_job_at_idle (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  GIOJob *job = data;
 | 
			
		||||
 | 
			
		||||
  if (job->cancellable)
 | 
			
		||||
    g_push_current_cancellable (job->cancellable);
 | 
			
		||||
  
 | 
			
		||||
  job->job_func (job, job->cancellable, job->data);
 | 
			
		||||
  
 | 
			
		||||
  if (job->cancellable)
 | 
			
		||||
    g_pop_current_cancellable (job->cancellable);
 | 
			
		||||
 | 
			
		||||
  if (job->destroy_notify)
 | 
			
		||||
    job->destroy_notify (job->data);
 | 
			
		||||
 | 
			
		||||
  remove_active_job (job);
 | 
			
		||||
  g_io_job_free (job);
 | 
			
		||||
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_schedule_io_job:
 | 
			
		||||
 * @job_func: a #GIOJobFunc.
 | 
			
		||||
 * @user_data: a #gpointer.
 | 
			
		||||
 * @notify: a #GDestroyNotify.
 | 
			
		||||
 * @io_priority: the io priority of the request. a #gint.
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore.
 | 
			
		||||
 *
 | 
			
		||||
 * Schedules the @job_func.
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_schedule_io_job (GIOJobFunc     job_func,
 | 
			
		||||
		   gpointer       user_data,
 | 
			
		||||
		   GDestroyNotify notify,
 | 
			
		||||
		   gint           io_priority,
 | 
			
		||||
		   GCancellable  *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  static GOnce once_init = G_ONCE_INIT;
 | 
			
		||||
  GIOJob *job;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (job_func != NULL);
 | 
			
		||||
 | 
			
		||||
  job = g_new0 (GIOJob, 1);
 | 
			
		||||
  job->job_func = job_func;
 | 
			
		||||
  job->data = user_data;
 | 
			
		||||
  job->destroy_notify = notify;
 | 
			
		||||
  job->io_priority = io_priority;
 | 
			
		||||
    
 | 
			
		||||
  if (cancellable)
 | 
			
		||||
    job->cancellable = g_object_ref (cancellable);
 | 
			
		||||
 | 
			
		||||
  G_LOCK (active_jobs);
 | 
			
		||||
  active_jobs = g_slist_prepend (active_jobs, job);
 | 
			
		||||
  job->active_link = active_jobs;
 | 
			
		||||
  G_UNLOCK (active_jobs);
 | 
			
		||||
 | 
			
		||||
  if (g_thread_supported())
 | 
			
		||||
    {
 | 
			
		||||
      g_once (&once_init, init_scheduler, NULL);
 | 
			
		||||
      g_thread_pool_push (job_thread_pool, job, NULL);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      /* Threads not available, instead do the i/o sync inside a
 | 
			
		||||
       * low prio idle handler
 | 
			
		||||
       */
 | 
			
		||||
      job->idle_tag = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE + 1 + io_priority / 10,
 | 
			
		||||
				       run_job_at_idle,
 | 
			
		||||
				       job, NULL);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_cancel_all_io_jobs:
 | 
			
		||||
 * 
 | 
			
		||||
 * Cancels all cancellable I/O Jobs. 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_cancel_all_io_jobs (void)
 | 
			
		||||
{
 | 
			
		||||
  GSList *cancellable_list, *l;
 | 
			
		||||
  
 | 
			
		||||
  G_LOCK (active_jobs);
 | 
			
		||||
  cancellable_list = NULL;
 | 
			
		||||
  for (l = active_jobs; l != NULL; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      GIOJob *job = l->data;
 | 
			
		||||
      if (job->cancellable)
 | 
			
		||||
	cancellable_list = g_slist_prepend (cancellable_list,
 | 
			
		||||
					    g_object_ref (job->cancellable));
 | 
			
		||||
    }
 | 
			
		||||
  G_UNLOCK (active_jobs);
 | 
			
		||||
 | 
			
		||||
  for (l = cancellable_list; l != NULL; l = l->next)
 | 
			
		||||
    {
 | 
			
		||||
      GCancellable *c = l->data;
 | 
			
		||||
      g_cancellable_cancel (c);
 | 
			
		||||
      g_object_unref (c);
 | 
			
		||||
    }
 | 
			
		||||
  g_slist_free (cancellable_list);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  GIODataFunc func;
 | 
			
		||||
  gpointer    data;
 | 
			
		||||
  GDestroyNotify notify;
 | 
			
		||||
 | 
			
		||||
  GMutex *ack_lock;
 | 
			
		||||
  GCond *ack_condition;
 | 
			
		||||
} MainLoopProxy;
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
mainloop_proxy_func (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  MainLoopProxy *proxy = data;
 | 
			
		||||
 | 
			
		||||
  proxy->func (proxy->data);
 | 
			
		||||
 | 
			
		||||
  if (proxy->ack_lock)
 | 
			
		||||
    {
 | 
			
		||||
      g_mutex_lock (proxy->ack_lock);
 | 
			
		||||
      g_cond_signal (proxy->ack_condition);
 | 
			
		||||
      g_mutex_unlock (proxy->ack_lock);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mainloop_proxy_free (MainLoopProxy *proxy)
 | 
			
		||||
{
 | 
			
		||||
  if (proxy->ack_lock)
 | 
			
		||||
    {
 | 
			
		||||
      g_mutex_free (proxy->ack_lock);
 | 
			
		||||
      g_cond_free (proxy->ack_condition);
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  g_free (proxy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mainloop_proxy_notify (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  MainLoopProxy *proxy = data;
 | 
			
		||||
 | 
			
		||||
  if (proxy->notify)
 | 
			
		||||
    proxy->notify (proxy->data);
 | 
			
		||||
 | 
			
		||||
  /* If nonblocking we free here, otherwise we free in io thread */
 | 
			
		||||
  if (proxy->ack_lock == NULL)
 | 
			
		||||
    mainloop_proxy_free (proxy);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_io_job_send_to_mainloop:
 | 
			
		||||
 * @job: a #GIOJob.
 | 
			
		||||
 * @func: a #GIODataFunc.
 | 
			
		||||
 * @user_data: a #gpointer.
 | 
			
		||||
 * @notify: a #GDestroyNotify.
 | 
			
		||||
 * @block: boolean flag indicating whether or not this job should block.
 | 
			
		||||
 * 
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_io_job_send_to_mainloop (GIOJob        *job,
 | 
			
		||||
			   GIODataFunc    func,
 | 
			
		||||
			   gpointer       user_data,
 | 
			
		||||
			   GDestroyNotify notify,
 | 
			
		||||
			   gboolean       block)
 | 
			
		||||
{
 | 
			
		||||
  GSource *source;
 | 
			
		||||
  MainLoopProxy *proxy;
 | 
			
		||||
  guint id;
 | 
			
		||||
 | 
			
		||||
  g_return_if_fail (job != NULL);
 | 
			
		||||
  g_return_if_fail (func != NULL);
 | 
			
		||||
 | 
			
		||||
  if (job->idle_tag)
 | 
			
		||||
    {
 | 
			
		||||
      /* We just immediately re-enter in the case of idles (non-threads)
 | 
			
		||||
       * Anything else would just deadlock. If you can't handle this, enable threads.
 | 
			
		||||
       */
 | 
			
		||||
      func (user_data); 
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  proxy = g_new0 (MainLoopProxy, 1);
 | 
			
		||||
  proxy->func = func;
 | 
			
		||||
  proxy->data = user_data;
 | 
			
		||||
  proxy->notify = notify;
 | 
			
		||||
  
 | 
			
		||||
  if (block)
 | 
			
		||||
    {
 | 
			
		||||
      proxy->ack_lock = g_mutex_new ();
 | 
			
		||||
      proxy->ack_condition = g_cond_new ();
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  source = g_idle_source_new ();
 | 
			
		||||
  g_source_set_priority (source, G_PRIORITY_DEFAULT);
 | 
			
		||||
 | 
			
		||||
  g_source_set_callback (source, mainloop_proxy_func, proxy, mainloop_proxy_notify);
 | 
			
		||||
 | 
			
		||||
  if (block)
 | 
			
		||||
    g_mutex_lock (proxy->ack_lock);
 | 
			
		||||
		  
 | 
			
		||||
  id = g_source_attach (source, NULL);
 | 
			
		||||
  g_source_unref (source);
 | 
			
		||||
 | 
			
		||||
  if (block)
 | 
			
		||||
    {
 | 
			
		||||
      g_cond_wait (proxy->ack_condition, proxy->ack_lock);
 | 
			
		||||
      g_mutex_unlock (proxy->ack_lock);
 | 
			
		||||
      
 | 
			
		||||
      /* destroy notify didn't free proxy */
 | 
			
		||||
      mainloop_proxy_free (proxy);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								gio/gioscheduler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								gio/gioscheduler.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_IO_SCHEDULER_H__
 | 
			
		||||
#define __G_IO_SCHEDULER_H__
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <gio/gcancellable.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct _GIOJob GIOJob;
 | 
			
		||||
 | 
			
		||||
typedef void (*GIOJobFunc) (GIOJob *job,
 | 
			
		||||
			    GCancellable *cancellable,
 | 
			
		||||
			    gpointer user_data);
 | 
			
		||||
 | 
			
		||||
typedef void (*GIODataFunc) (gpointer user_data);
 | 
			
		||||
 | 
			
		||||
void g_schedule_io_job         (GIOJobFunc      job_func,
 | 
			
		||||
				gpointer        user_data,
 | 
			
		||||
				GDestroyNotify  notify,
 | 
			
		||||
				gint            io_priority,
 | 
			
		||||
				GCancellable   *cancellable);
 | 
			
		||||
void g_cancel_all_io_jobs      (void);
 | 
			
		||||
 | 
			
		||||
void g_io_job_send_to_mainloop (GIOJob         *job,
 | 
			
		||||
				GIODataFunc     func,
 | 
			
		||||
				gpointer        user_data,
 | 
			
		||||
				GDestroyNotify  notify,
 | 
			
		||||
				gboolean        block);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_IO_SCHEDULER_H__ */
 | 
			
		||||
							
								
								
									
										260
									
								
								gio/gloadableicon.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								gio/gloadableicon.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,260 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "gsimpleasyncresult.h"
 | 
			
		||||
#include "gloadableicon.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
static void          g_loadable_icon_real_load_async  (GLoadableIcon        *icon,
 | 
			
		||||
						       int                   size,
 | 
			
		||||
						       GCancellable         *cancellable,
 | 
			
		||||
						       GAsyncReadyCallback   callback,
 | 
			
		||||
						       gpointer              user_data);
 | 
			
		||||
static GInputStream *g_loadable_icon_real_load_finish (GLoadableIcon        *icon,
 | 
			
		||||
						       GAsyncResult         *res,
 | 
			
		||||
						       char                **type,
 | 
			
		||||
						       GError              **error);
 | 
			
		||||
static void          g_loadable_icon_base_init        (gpointer              g_class);
 | 
			
		||||
static void          g_loadable_icon_class_init       (gpointer              g_class,
 | 
			
		||||
						       gpointer              class_data);
 | 
			
		||||
 | 
			
		||||
GType
 | 
			
		||||
g_loadable_icon_get_type (void)
 | 
			
		||||
{
 | 
			
		||||
  static GType loadable_icon_type = 0;
 | 
			
		||||
 | 
			
		||||
  if (! loadable_icon_type)
 | 
			
		||||
    {
 | 
			
		||||
      static const GTypeInfo loadable_icon_info =
 | 
			
		||||
	{
 | 
			
		||||
        sizeof (GLoadableIconIface), /* class_size */
 | 
			
		||||
	g_loadable_icon_base_init,   /* base_init */
 | 
			
		||||
	NULL,		/* base_finalize */
 | 
			
		||||
	g_loadable_icon_class_init,
 | 
			
		||||
	NULL,		/* class_finalize */
 | 
			
		||||
	NULL,		/* class_data */
 | 
			
		||||
	0,
 | 
			
		||||
	0,              /* n_preallocs */
 | 
			
		||||
	NULL
 | 
			
		||||
      };
 | 
			
		||||
 | 
			
		||||
      loadable_icon_type =
 | 
			
		||||
	g_type_register_static (G_TYPE_INTERFACE, I_("GLoadableIcon"),
 | 
			
		||||
				&loadable_icon_info, 0);
 | 
			
		||||
 | 
			
		||||
      g_type_interface_add_prerequisite (loadable_icon_type, G_TYPE_ICON);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return loadable_icon_type;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_loadable_icon_class_init (gpointer g_class,
 | 
			
		||||
			    gpointer class_data)
 | 
			
		||||
{
 | 
			
		||||
  GLoadableIconIface *iface = g_class;
 | 
			
		||||
 | 
			
		||||
  iface->load_async = g_loadable_icon_real_load_async;
 | 
			
		||||
  iface->load_finish = g_loadable_icon_real_load_finish;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_loadable_icon_base_init (gpointer g_class)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_loadable_icon_load:
 | 
			
		||||
 * @icon:
 | 
			
		||||
 * @size:
 | 
			
		||||
 * @type:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
GInputStream *
 | 
			
		||||
g_loadable_icon_load (GLoadableIcon        *icon,
 | 
			
		||||
		      int                   size,
 | 
			
		||||
		      char                **type,
 | 
			
		||||
		      GCancellable         *cancellable,
 | 
			
		||||
		      GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GLoadableIconIface *iface;
 | 
			
		||||
 | 
			
		||||
  g_return_val_if_fail (G_IS_LOADABLE_ICON (icon), NULL);
 | 
			
		||||
 | 
			
		||||
  iface = G_LOADABLE_ICON_GET_IFACE (icon);
 | 
			
		||||
 | 
			
		||||
  return (* iface->load) (icon, size, type, cancellable, error);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_loadable_icon_load_async:
 | 
			
		||||
 * @icon:
 | 
			
		||||
 * @size:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. @callback:
 | 
			
		||||
 * @user_data:
 | 
			
		||||
 * 
 | 
			
		||||
 * Loads an icon asynchronously.
 | 
			
		||||
 * 
 | 
			
		||||
 **/
 | 
			
		||||
void
 | 
			
		||||
g_loadable_icon_load_async (GLoadableIcon        *icon,
 | 
			
		||||
			    int                   size,
 | 
			
		||||
			    GCancellable         *cancellable,
 | 
			
		||||
			    GAsyncReadyCallback   callback,
 | 
			
		||||
			    gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  GLoadableIconIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_if_fail (G_IS_LOADABLE_ICON (icon));
 | 
			
		||||
 | 
			
		||||
  iface = G_LOADABLE_ICON_GET_IFACE (icon);
 | 
			
		||||
 | 
			
		||||
  (* iface->load_async) (icon, size, cancellable, callback, user_data);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_loadable_icon_load_finish:
 | 
			
		||||
 * @icon:
 | 
			
		||||
 * @res:
 | 
			
		||||
 * @type:
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns:
 | 
			
		||||
 **/
 | 
			
		||||
GInputStream *
 | 
			
		||||
g_loadable_icon_load_finish (GLoadableIcon        *icon,
 | 
			
		||||
			     GAsyncResult         *res,
 | 
			
		||||
			     char                **type,
 | 
			
		||||
			     GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GLoadableIconIface *iface;
 | 
			
		||||
  
 | 
			
		||||
  g_return_val_if_fail (G_IS_LOADABLE_ICON (icon), NULL);
 | 
			
		||||
  g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
 | 
			
		||||
 | 
			
		||||
  if (G_IS_SIMPLE_ASYNC_RESULT (res))
 | 
			
		||||
    {
 | 
			
		||||
      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
 | 
			
		||||
      if (g_simple_async_result_propagate_error (simple, error))
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  iface = G_LOADABLE_ICON_GET_IFACE (icon);
 | 
			
		||||
 | 
			
		||||
  return (* iface->load_finish) (icon, res, type, error);
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/********************************************
 | 
			
		||||
 *   Default implementation of async load   *
 | 
			
		||||
 ********************************************/
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  int size;
 | 
			
		||||
  char *type;
 | 
			
		||||
  GInputStream *stream;
 | 
			
		||||
} LoadData;
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_data_free (LoadData *data)
 | 
			
		||||
{
 | 
			
		||||
  if (data->stream)
 | 
			
		||||
    g_object_unref (data->stream);
 | 
			
		||||
  g_free (data->type);
 | 
			
		||||
  g_free (data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
load_async_thread (GSimpleAsyncResult *res,
 | 
			
		||||
		   GObject *object,
 | 
			
		||||
		   GCancellable *cancellable)
 | 
			
		||||
{
 | 
			
		||||
  GLoadableIconIface *iface;
 | 
			
		||||
  GInputStream *stream;
 | 
			
		||||
  LoadData *data;
 | 
			
		||||
  GError *error = NULL;
 | 
			
		||||
  char *type = NULL;
 | 
			
		||||
 | 
			
		||||
  data = g_simple_async_result_get_op_res_gpointer (res);
 | 
			
		||||
  
 | 
			
		||||
  iface = G_LOADABLE_ICON_GET_IFACE (object);
 | 
			
		||||
  stream = iface->load (G_LOADABLE_ICON (object), data->size, &type, cancellable, &error);
 | 
			
		||||
 | 
			
		||||
  if (stream == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      g_simple_async_result_set_from_error (res, error);
 | 
			
		||||
      g_error_free (error);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      data->stream = stream;
 | 
			
		||||
      data->type = type;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_loadable_icon_real_load_async (GLoadableIcon        *icon,
 | 
			
		||||
				 int                   size,
 | 
			
		||||
				 GCancellable         *cancellable,
 | 
			
		||||
				 GAsyncReadyCallback   callback,
 | 
			
		||||
				 gpointer              user_data)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *res;
 | 
			
		||||
  LoadData *data;
 | 
			
		||||
  
 | 
			
		||||
  res = g_simple_async_result_new (G_OBJECT (icon), callback, user_data, g_loadable_icon_real_load_async);
 | 
			
		||||
  data = g_new0 (LoadData, 1);
 | 
			
		||||
  g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify) load_data_free);
 | 
			
		||||
  g_simple_async_result_run_in_thread (res, load_async_thread, 0, cancellable);
 | 
			
		||||
  g_object_unref (res);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GInputStream *
 | 
			
		||||
g_loadable_icon_real_load_finish (GLoadableIcon        *icon,
 | 
			
		||||
				  GAsyncResult         *res,
 | 
			
		||||
				  char                **type,
 | 
			
		||||
				  GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
 | 
			
		||||
  LoadData *data;
 | 
			
		||||
 | 
			
		||||
  g_assert (g_simple_async_result_get_source_tag (simple) == g_loadable_icon_real_load_async);
 | 
			
		||||
 | 
			
		||||
  data = g_simple_async_result_get_op_res_gpointer (simple);
 | 
			
		||||
 | 
			
		||||
  if (type)
 | 
			
		||||
    {
 | 
			
		||||
      *type = data->type;
 | 
			
		||||
      data->type = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return g_object_ref (data->stream);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										83
									
								
								gio/gloadableicon.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								gio/gloadableicon.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_LOADABLE_ICON_H__
 | 
			
		||||
#define __G_LOADABLE_ICON_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gicon.h>
 | 
			
		||||
#include <gio/ginputstream.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_LOADABLE_ICON            (g_loadable_icon_get_type ())
 | 
			
		||||
#define G_LOADABLE_ICON(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), G_TYPE_LOADABLE_ICON, GLoadableIcon))
 | 
			
		||||
#define G_IS_LOADABLE_ICON(obj)	        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), G_TYPE_LOADABLE_ICON))
 | 
			
		||||
#define G_LOADABLE_ICON_GET_IFACE(obj)  (G_TYPE_INSTANCE_GET_INTERFACE ((obj), G_TYPE_LOADABLE_ICON, GLoadableIconIface))
 | 
			
		||||
 | 
			
		||||
typedef struct _GLoadableIcon         		GLoadableIcon; /* Dummy typedef */
 | 
			
		||||
typedef struct _GLoadableIconIface    		GLoadableIconIface;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _GLoadableIconIface
 | 
			
		||||
{
 | 
			
		||||
  GTypeInterface g_iface;
 | 
			
		||||
 | 
			
		||||
  /* Virtual Table */
 | 
			
		||||
 | 
			
		||||
  GInputStream * (*load)        (GLoadableIcon      *icon,
 | 
			
		||||
				 int                 size,
 | 
			
		||||
				 char              **type,
 | 
			
		||||
				 GCancellable       *cancellable,
 | 
			
		||||
				 GError            **error);
 | 
			
		||||
  void           (*load_async)  (GLoadableIcon      *icon,
 | 
			
		||||
				 int                 size,
 | 
			
		||||
				 GCancellable       *cancellable,
 | 
			
		||||
				 GAsyncReadyCallback callback,
 | 
			
		||||
				 gpointer            user_data);
 | 
			
		||||
  GInputStream * (*load_finish) (GLoadableIcon      *icon,
 | 
			
		||||
				  GAsyncResult      *res,
 | 
			
		||||
				  char             **type,
 | 
			
		||||
				  GError           **error);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_loadable_icon_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
GInputStream *g_loadable_icon_load        (GLoadableIcon        *icon,
 | 
			
		||||
					   int                   size,
 | 
			
		||||
					   char                **type,
 | 
			
		||||
					   GCancellable         *cancellable,
 | 
			
		||||
					   GError              **error);
 | 
			
		||||
void          g_loadable_icon_load_async  (GLoadableIcon        *icon,
 | 
			
		||||
					   int                   size,
 | 
			
		||||
					   GCancellable         *cancellable,
 | 
			
		||||
					   GAsyncReadyCallback   callback,
 | 
			
		||||
					   gpointer              user_data);
 | 
			
		||||
GInputStream *g_loadable_icon_load_finish (GLoadableIcon        *icon,
 | 
			
		||||
					   GAsyncResult         *res,
 | 
			
		||||
					   char                **type,
 | 
			
		||||
					   GError              **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_LOADABLE_ICON_H__ */
 | 
			
		||||
							
								
								
									
										290
									
								
								gio/glocaldirectorymonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								gio/glocaldirectorymonitor.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,290 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "glocaldirectorymonitor.h"
 | 
			
		||||
#include "gunixmounts.h"
 | 
			
		||||
#include "gdirectorymonitor.h"
 | 
			
		||||
#include "giomodule.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
  PROP_DIRNAME
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gboolean g_local_directory_monitor_cancel (GDirectoryMonitor* monitor);
 | 
			
		||||
static void mounts_changed (GUnixMountMonitor *mount_monitor, gpointer user_data);
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (GLocalDirectoryMonitor, g_local_directory_monitor, G_TYPE_DIRECTORY_MONITOR)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_directory_monitor_finalize (GObject* object)
 | 
			
		||||
{
 | 
			
		||||
  GLocalDirectoryMonitor* local_monitor;
 | 
			
		||||
  local_monitor = G_LOCAL_DIRECTORY_MONITOR (object);
 | 
			
		||||
 | 
			
		||||
  g_free (local_monitor->dirname);
 | 
			
		||||
 | 
			
		||||
  if (local_monitor->mount_monitor)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_handlers_disconnect_by_func (local_monitor->mount_monitor, mounts_changed, local_monitor);
 | 
			
		||||
      g_object_unref (local_monitor->mount_monitor);
 | 
			
		||||
      local_monitor->mount_monitor = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (g_local_directory_monitor_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_local_directory_monitor_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_directory_monitor_set_property (GObject *object,
 | 
			
		||||
                                   guint property_id,
 | 
			
		||||
                                   const GValue *value,
 | 
			
		||||
                                   GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  switch (property_id)
 | 
			
		||||
  {
 | 
			
		||||
    case PROP_DIRNAME:
 | 
			
		||||
      /* Do nothing */
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GObject *
 | 
			
		||||
g_local_directory_monitor_constructor (GType type,
 | 
			
		||||
                                    guint n_construct_properties,
 | 
			
		||||
                                    GObjectConstructParam *construct_properties)
 | 
			
		||||
{
 | 
			
		||||
  GObject *obj;
 | 
			
		||||
  GLocalDirectoryMonitorClass *klass;
 | 
			
		||||
  GObjectClass *parent_class;
 | 
			
		||||
  GLocalDirectoryMonitor *local_monitor;
 | 
			
		||||
  const gchar *dirname = NULL;
 | 
			
		||||
  gint i;
 | 
			
		||||
  
 | 
			
		||||
  klass = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_type_class_peek (G_TYPE_LOCAL_DIRECTORY_MONITOR));
 | 
			
		||||
  parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
 | 
			
		||||
  obj = parent_class->constructor (type,
 | 
			
		||||
                                   n_construct_properties,
 | 
			
		||||
                                   construct_properties);
 | 
			
		||||
 | 
			
		||||
  local_monitor = G_LOCAL_DIRECTORY_MONITOR (obj);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_construct_properties; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (strcmp ("dirname", g_param_spec_get_name (construct_properties[i].pspec)) == 0)
 | 
			
		||||
        {
 | 
			
		||||
          g_assert (G_VALUE_HOLDS_STRING (construct_properties[i].value));
 | 
			
		||||
          dirname = g_value_get_string (construct_properties[i].value);
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  local_monitor->dirname = g_strdup (dirname);
 | 
			
		||||
 | 
			
		||||
  if (!klass->mount_notify)
 | 
			
		||||
    {
 | 
			
		||||
      GUnixMount *mount;
 | 
			
		||||
      
 | 
			
		||||
      /* Emulate unmount detection */
 | 
			
		||||
      
 | 
			
		||||
      mount = g_get_unix_mount_at (local_monitor->dirname, NULL);
 | 
			
		||||
      
 | 
			
		||||
      local_monitor->was_mounted = mount != NULL;
 | 
			
		||||
      
 | 
			
		||||
      if (mount)
 | 
			
		||||
        g_unix_mount_free (mount);
 | 
			
		||||
 | 
			
		||||
      local_monitor->mount_monitor = g_unix_mount_monitor_new ();
 | 
			
		||||
      g_signal_connect (local_monitor->mount_monitor, "mounts_changed",
 | 
			
		||||
        G_CALLBACK (mounts_changed), local_monitor);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_directory_monitor_class_init (GLocalDirectoryMonitorClass* klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass* gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  GDirectoryMonitorClass *dir_monitor_class = G_DIRECTORY_MONITOR_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_local_directory_monitor_finalize;
 | 
			
		||||
  gobject_class->set_property = g_local_directory_monitor_set_property;
 | 
			
		||||
  gobject_class->constructor = g_local_directory_monitor_constructor;
 | 
			
		||||
 | 
			
		||||
  dir_monitor_class->cancel = g_local_directory_monitor_cancel;
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_DIRNAME,
 | 
			
		||||
    g_param_spec_string ("dirname", "Directory name", "Directory to monitor",
 | 
			
		||||
        NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
 | 
			
		||||
 | 
			
		||||
  klass->mount_notify = FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_directory_monitor_init (GLocalDirectoryMonitor* local_monitor)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
mounts_changed (GUnixMountMonitor *mount_monitor,
 | 
			
		||||
                gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  GLocalDirectoryMonitor *local_monitor = user_data;
 | 
			
		||||
  GUnixMount *mount;
 | 
			
		||||
  gboolean is_mounted;
 | 
			
		||||
  GFile *file;
 | 
			
		||||
  
 | 
			
		||||
  /* Emulate unmount detection */
 | 
			
		||||
  
 | 
			
		||||
  mount = g_get_unix_mount_at (local_monitor->dirname, NULL);
 | 
			
		||||
  
 | 
			
		||||
  is_mounted = mount != NULL;
 | 
			
		||||
  
 | 
			
		||||
  if (mount)
 | 
			
		||||
    g_unix_mount_free (mount);
 | 
			
		||||
 | 
			
		||||
  if (local_monitor->was_mounted != is_mounted)
 | 
			
		||||
    {
 | 
			
		||||
      if (local_monitor->was_mounted && !is_mounted)
 | 
			
		||||
        {
 | 
			
		||||
          file = g_file_new_for_path (local_monitor->dirname);
 | 
			
		||||
          g_directory_monitor_emit_event (G_DIRECTORY_MONITOR (local_monitor),
 | 
			
		||||
                                          file, NULL,
 | 
			
		||||
                                          G_FILE_MONITOR_EVENT_UNMOUNTED);
 | 
			
		||||
          g_object_unref (file);
 | 
			
		||||
        }
 | 
			
		||||
      local_monitor->was_mounted = is_mounted;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
_compare_monitor_class_by_prio (gconstpointer a,
 | 
			
		||||
                                gconstpointer b,
 | 
			
		||||
                                gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  GType *type1 = (GType *) a, *type2 = (GType *) b;
 | 
			
		||||
  GLocalDirectoryMonitorClass *klass1, *klass2;
 | 
			
		||||
  gint ret;
 | 
			
		||||
 | 
			
		||||
  klass1 = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_type_class_ref (*type1));
 | 
			
		||||
  klass2 = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_type_class_ref (*type2));
 | 
			
		||||
 | 
			
		||||
  ret = klass1->prio - klass2->prio;
 | 
			
		||||
 | 
			
		||||
  g_type_class_unref (klass1);
 | 
			
		||||
  g_type_class_unref (klass2);
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern GType g_inotify_directory_monitor_get_type (void);
 | 
			
		||||
 | 
			
		||||
static gpointer
 | 
			
		||||
get_default_local_directory_monitor (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  GType *monitor_impls, chosen_type;
 | 
			
		||||
  guint n_monitor_impls;
 | 
			
		||||
  GType *ret = (GType *) data;
 | 
			
		||||
  gint i;
 | 
			
		||||
 | 
			
		||||
#if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
 | 
			
		||||
  /* Register Inotify monitor */
 | 
			
		||||
  g_inotify_directory_monitor_get_type ();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  g_io_modules_ensure_loaded (GIO_MODULE_DIR);
 | 
			
		||||
  
 | 
			
		||||
  monitor_impls = g_type_children (G_TYPE_LOCAL_DIRECTORY_MONITOR,
 | 
			
		||||
                                   &n_monitor_impls);
 | 
			
		||||
 | 
			
		||||
  chosen_type = G_TYPE_INVALID;
 | 
			
		||||
 | 
			
		||||
  g_qsort_with_data (monitor_impls,
 | 
			
		||||
                     n_monitor_impls,
 | 
			
		||||
                     sizeof (GType),
 | 
			
		||||
                     _compare_monitor_class_by_prio,
 | 
			
		||||
                     NULL);
 | 
			
		||||
 | 
			
		||||
  for (i = n_monitor_impls - 1; i >= 0 && chosen_type == G_TYPE_INVALID; i--)
 | 
			
		||||
    {    
 | 
			
		||||
      GLocalDirectoryMonitorClass *klass;
 | 
			
		||||
 | 
			
		||||
      klass = G_LOCAL_DIRECTORY_MONITOR_CLASS (g_type_class_ref (monitor_impls[i]));
 | 
			
		||||
 | 
			
		||||
      if (klass->is_supported())
 | 
			
		||||
        chosen_type = monitor_impls[i];
 | 
			
		||||
 | 
			
		||||
      g_type_class_unref (klass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (monitor_impls);
 | 
			
		||||
  *ret = chosen_type;
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_local_directory_monitor_new:
 | 
			
		||||
 * @dirname: filename of the directory to monitor.
 | 
			
		||||
 * @flags: #GFileMonitorFlags.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: new #GDirectoryMonitor for the given @dirname.
 | 
			
		||||
 **/
 | 
			
		||||
GDirectoryMonitor*
 | 
			
		||||
g_local_directory_monitor_new (const char* dirname,
 | 
			
		||||
                               GFileMonitorFlags flags)
 | 
			
		||||
{
 | 
			
		||||
  static GOnce once_init = G_ONCE_INIT;
 | 
			
		||||
  static GType monitor_type = G_TYPE_INVALID;
 | 
			
		||||
 | 
			
		||||
  g_once (&once_init, get_default_local_directory_monitor, &monitor_type);
 | 
			
		||||
 | 
			
		||||
  if (monitor_type != G_TYPE_INVALID)
 | 
			
		||||
    return G_DIRECTORY_MONITOR (g_object_new (monitor_type, "dirname", dirname, NULL));
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_directory_monitor_cancel (GDirectoryMonitor* monitor)
 | 
			
		||||
{
 | 
			
		||||
  GLocalDirectoryMonitor *local_monitor = G_LOCAL_DIRECTORY_MONITOR (monitor);
 | 
			
		||||
 | 
			
		||||
  if (local_monitor->mount_monitor)
 | 
			
		||||
    {
 | 
			
		||||
      g_signal_handlers_disconnect_by_func (local_monitor->mount_monitor, mounts_changed, local_monitor);
 | 
			
		||||
      g_object_unref (local_monitor->mount_monitor);
 | 
			
		||||
      local_monitor->mount_monitor = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										65
									
								
								gio/glocaldirectorymonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								gio/glocaldirectorymonitor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_LOCAL_DIRECTORY_MONITOR_H__
 | 
			
		||||
#define __G_LOCAL_DIRECTORY_MONITOR_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gdirectorymonitor.h>
 | 
			
		||||
 | 
			
		||||
#include "gunixmounts.h"
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_LOCAL_DIRECTORY_MONITOR		(g_local_directory_monitor_get_type ())
 | 
			
		||||
#define G_LOCAL_DIRECTORY_MONITOR(o)		(G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_DIRECTORY_MONITOR, GLocalDirectoryMonitor))
 | 
			
		||||
#define G_LOCAL_DIRECTORY_MONITOR_CLASS(k)	(G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_LOCAL_DIRECTORY_MONITOR, GLocalDirectoryMonitorClass))
 | 
			
		||||
#define G_IS_LOCAL_DIRECTORY_MONITOR(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_DIRECTORY_MONITOR))
 | 
			
		||||
#define G_IS_LOCAL_DIRECTORY_MONITOR_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_DIRECTORY_MONITOR))
 | 
			
		||||
 | 
			
		||||
typedef struct _GLocalDirectoryMonitor      GLocalDirectoryMonitor;
 | 
			
		||||
typedef struct _GLocalDirectoryMonitorClass GLocalDirectoryMonitorClass;
 | 
			
		||||
 | 
			
		||||
struct _GLocalDirectoryMonitor
 | 
			
		||||
{
 | 
			
		||||
  GDirectoryMonitor parent_instance;
 | 
			
		||||
  gchar *dirname;
 | 
			
		||||
  /* For mount emulation */
 | 
			
		||||
  GUnixMountMonitor *mount_monitor;
 | 
			
		||||
  gboolean was_mounted;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GLocalDirectoryMonitorClass {
 | 
			
		||||
  GDirectoryMonitorClass parent_class;
 | 
			
		||||
  gint prio;
 | 
			
		||||
  gboolean mount_notify;
 | 
			
		||||
  gboolean (*is_supported) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_local_directory_monitor_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GDirectoryMonitor* g_local_directory_monitor_new (const char* dirname,
 | 
			
		||||
						  GFileMonitorFlags flags);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_LOCAL_DIRECTORY_MONITOR_H__ */
 | 
			
		||||
							
								
								
									
										1826
									
								
								gio/glocalfile.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1826
									
								
								gio/glocalfile.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										51
									
								
								gio/glocalfile.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								gio/glocalfile.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_LOCAL_FILE_H__
 | 
			
		||||
#define __G_LOCAL_FILE_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gfile.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_LOCAL_FILE         (g_local_file_get_type ())
 | 
			
		||||
#define G_LOCAL_FILE(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE, GLocalFile))
 | 
			
		||||
#define G_LOCAL_FILE_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LOCAL_FILE, GLocalFileClass))
 | 
			
		||||
#define G_IS_LOCAL_FILE(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE))
 | 
			
		||||
#define G_IS_LOCAL_FILE_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE))
 | 
			
		||||
#define G_LOCAL_FILE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE, GLocalFileClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GLocalFile        GLocalFile;
 | 
			
		||||
typedef struct _GLocalFileClass   GLocalFileClass;
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileClass
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_local_file_get_type (void) G_GNUC_CONST;
 | 
			
		||||
  
 | 
			
		||||
GFile * g_local_file_new (const char *filename);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_LOCAL_FILE_H__ */
 | 
			
		||||
							
								
								
									
										228
									
								
								gio/glocalfileenumerator.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										228
									
								
								gio/glocalfileenumerator.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,228 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <glocalfileenumerator.h>
 | 
			
		||||
#include <glocalfileinfo.h>
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
  /* TODO:
 | 
			
		||||
   *  It would be nice to use the dirent->d_type to check file type without
 | 
			
		||||
   *  needing to stat each files on linux and other systems that support it.
 | 
			
		||||
   *  (question: does that following symlink or not?)
 | 
			
		||||
   */
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileEnumerator
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumerator parent;
 | 
			
		||||
 | 
			
		||||
  GFileAttributeMatcher *matcher;
 | 
			
		||||
  GDir *dir;
 | 
			
		||||
  char *filename;
 | 
			
		||||
  char *attributes;
 | 
			
		||||
  GFileQueryInfoFlags flags;
 | 
			
		||||
 | 
			
		||||
  gboolean got_parent_info;
 | 
			
		||||
  GLocalParentFileInfo parent_info;
 | 
			
		||||
  
 | 
			
		||||
  gboolean follow_symlinks;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GLocalFileEnumerator, g_local_file_enumerator, G_TYPE_FILE_ENUMERATOR);
 | 
			
		||||
 | 
			
		||||
static GFileInfo *g_local_file_enumerator_next_file (GFileEnumerator  *enumerator,
 | 
			
		||||
						     GCancellable     *cancellable,
 | 
			
		||||
						     GError          **error);
 | 
			
		||||
static gboolean   g_local_file_enumerator_close     (GFileEnumerator  *enumerator,
 | 
			
		||||
						     GCancellable     *cancellable,
 | 
			
		||||
						     GError          **error);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_enumerator_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileEnumerator *local;
 | 
			
		||||
 | 
			
		||||
  local = G_LOCAL_FILE_ENUMERATOR (object);
 | 
			
		||||
 | 
			
		||||
  g_free (local->filename);
 | 
			
		||||
  g_file_attribute_matcher_unref (local->matcher);
 | 
			
		||||
  if (local->dir)
 | 
			
		||||
    {
 | 
			
		||||
      g_dir_close (local->dir);
 | 
			
		||||
      local->dir = NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_local_file_enumerator_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_local_file_enumerator_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_enumerator_class_init (GLocalFileEnumeratorClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  GFileEnumeratorClass *enumerator_class = G_FILE_ENUMERATOR_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_local_file_enumerator_finalize;
 | 
			
		||||
 | 
			
		||||
  enumerator_class->next_file = g_local_file_enumerator_next_file;
 | 
			
		||||
  enumerator_class->close = g_local_file_enumerator_close;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_enumerator_init (GLocalFileEnumerator *local)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
convert_file_to_io_error (GError **error,
 | 
			
		||||
			  GError *file_error)
 | 
			
		||||
{
 | 
			
		||||
  int new_code;
 | 
			
		||||
 | 
			
		||||
  if (file_error == NULL)
 | 
			
		||||
    return;
 | 
			
		||||
  
 | 
			
		||||
  new_code = G_IO_ERROR_FAILED;
 | 
			
		||||
  
 | 
			
		||||
  if (file_error->domain == G_FILE_ERROR) {
 | 
			
		||||
    switch (file_error->code) {
 | 
			
		||||
    case G_FILE_ERROR_NOENT:
 | 
			
		||||
      new_code = G_IO_ERROR_NOT_FOUND;
 | 
			
		||||
      break;
 | 
			
		||||
    case G_FILE_ERROR_ACCES:
 | 
			
		||||
      new_code = G_IO_ERROR_PERMISSION_DENIED;
 | 
			
		||||
      break;
 | 
			
		||||
    case G_FILE_ERROR_NOTDIR:
 | 
			
		||||
      new_code = G_IO_ERROR_NOT_DIRECTORY;
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  g_set_error (error, G_IO_ERROR,
 | 
			
		||||
	       new_code,
 | 
			
		||||
	       "%s", file_error->message);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
GFileEnumerator *
 | 
			
		||||
g_local_file_enumerator_new (const char *filename,
 | 
			
		||||
			     const char *attributes,
 | 
			
		||||
			     GFileQueryInfoFlags flags,
 | 
			
		||||
			     GCancellable *cancellable,
 | 
			
		||||
			     GError **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileEnumerator *local;
 | 
			
		||||
  GDir *dir;
 | 
			
		||||
  GError *dir_error;
 | 
			
		||||
  int new_code;
 | 
			
		||||
 | 
			
		||||
  dir_error = NULL;
 | 
			
		||||
  dir = g_dir_open (filename, 0, error != NULL ? &dir_error : NULL);
 | 
			
		||||
  if (dir == NULL) {
 | 
			
		||||
    convert_file_to_io_error (error, dir_error);
 | 
			
		||||
    g_error_free (dir_error);
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  local = g_object_new (G_TYPE_LOCAL_FILE_ENUMERATOR, NULL);
 | 
			
		||||
 | 
			
		||||
  local->dir = dir;
 | 
			
		||||
  local->filename = g_strdup (filename);
 | 
			
		||||
  local->matcher = g_file_attribute_matcher_new (attributes);
 | 
			
		||||
  local->flags = flags;
 | 
			
		||||
  
 | 
			
		||||
  return G_FILE_ENUMERATOR (local);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFileInfo *
 | 
			
		||||
g_local_file_enumerator_next_file (GFileEnumerator *enumerator,
 | 
			
		||||
				   GCancellable     *cancellable,
 | 
			
		||||
				   GError **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileEnumerator *local = G_LOCAL_FILE_ENUMERATOR (enumerator);
 | 
			
		||||
  const char *filename;
 | 
			
		||||
  char *path;
 | 
			
		||||
  GFileInfo *info;
 | 
			
		||||
  GError *my_error = NULL;
 | 
			
		||||
 | 
			
		||||
  if (!local->got_parent_info)
 | 
			
		||||
    {
 | 
			
		||||
      _g_local_file_info_get_parent_info (local->filename, local->matcher, &local->parent_info);
 | 
			
		||||
      local->got_parent_info = TRUE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
 next_file:
 | 
			
		||||
  
 | 
			
		||||
  filename = g_dir_read_name (local->dir);
 | 
			
		||||
  if (filename == NULL)
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  path = g_build_filename (local->filename, filename, NULL);
 | 
			
		||||
  info = _g_local_file_info_get (filename, path,
 | 
			
		||||
				 local->matcher,
 | 
			
		||||
				 local->flags,
 | 
			
		||||
				 &local->parent_info,
 | 
			
		||||
				 &my_error); 
 | 
			
		||||
  g_free (path);
 | 
			
		||||
  
 | 
			
		||||
  if (info == NULL)
 | 
			
		||||
    {
 | 
			
		||||
      /* Failed to get info */
 | 
			
		||||
      /* If the file does not exist there might have been a race where
 | 
			
		||||
       * the file was removed between the readdir and the stat, so we
 | 
			
		||||
       * ignore the file. */
 | 
			
		||||
      if (my_error->domain == G_IO_ERROR &&
 | 
			
		||||
	  my_error->code == G_IO_ERROR_NOT_FOUND)
 | 
			
		||||
	{
 | 
			
		||||
	  g_error_free (my_error);
 | 
			
		||||
	  goto next_file;
 | 
			
		||||
	}
 | 
			
		||||
      else
 | 
			
		||||
	g_propagate_error (error, my_error);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_file_enumerator_close (GFileEnumerator *enumerator,
 | 
			
		||||
			       GCancellable     *cancellable,
 | 
			
		||||
			       GError          **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileEnumerator *local = G_LOCAL_FILE_ENUMERATOR (enumerator);
 | 
			
		||||
 | 
			
		||||
  if (local->dir)
 | 
			
		||||
    {
 | 
			
		||||
      g_dir_close (local->dir);
 | 
			
		||||
      local->dir = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										60
									
								
								gio/glocalfileenumerator.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								gio/glocalfileenumerator.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_LOCAL_FILE_ENUMERATOR_H__
 | 
			
		||||
#define __G_LOCAL_FILE_ENUMERATOR_H__
 | 
			
		||||
 | 
			
		||||
#include <gfileenumerator.h>
 | 
			
		||||
#include <gfileinfo.h>
 | 
			
		||||
#include <gfile.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_LOCAL_FILE_ENUMERATOR         (g_local_file_enumerator_get_type ())
 | 
			
		||||
#define G_LOCAL_FILE_ENUMERATOR(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE_ENUMERATOR, GLocalFileEnumerator))
 | 
			
		||||
#define G_LOCAL_FILE_ENUMERATOR_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LOCAL_FILE_ENUMERATOR, GLocalFileEnumeratorClass))
 | 
			
		||||
#define G_IS_LOCAL_FILE_ENUMERATOR(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_ENUMERATOR))
 | 
			
		||||
#define G_IS_LOCAL_FILE_ENUMERATOR_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_ENUMERATOR))
 | 
			
		||||
#define G_LOCAL_FILE_ENUMERATOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE_ENUMERATOR, GLocalFileEnumeratorClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GLocalFileEnumerator         GLocalFileEnumerator;
 | 
			
		||||
typedef struct _GLocalFileEnumeratorClass    GLocalFileEnumeratorClass;
 | 
			
		||||
typedef struct _GLocalFileEnumeratorPrivate  GLocalFileEnumeratorPrivate;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileEnumeratorClass
 | 
			
		||||
{
 | 
			
		||||
  GFileEnumeratorClass parent_class;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_local_file_enumerator_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GFileEnumerator *g_local_file_enumerator_new (const char *filename,
 | 
			
		||||
					      const char *attributes,
 | 
			
		||||
					      GFileQueryInfoFlags flags,
 | 
			
		||||
					      GCancellable *cancellable,
 | 
			
		||||
					      GError **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_LOCAL_FILE_ENUMERATOR_H__ */
 | 
			
		||||
							
								
								
									
										2216
									
								
								gio/glocalfileinfo.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2216
									
								
								gio/glocalfileinfo.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										68
									
								
								gio/glocalfileinfo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								gio/glocalfileinfo.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_LOCAL_FILE_INFO_H__
 | 
			
		||||
#define __G_LOCAL_FILE_INFO_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gfileinfo.h>
 | 
			
		||||
#include <gio/gfile.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
  gboolean writable;
 | 
			
		||||
  gboolean is_sticky;
 | 
			
		||||
  int owner;
 | 
			
		||||
  dev_t device;
 | 
			
		||||
} GLocalParentFileInfo;
 | 
			
		||||
 | 
			
		||||
void       _g_local_file_info_get_parent_info (const char                 *dir,
 | 
			
		||||
					       GFileAttributeMatcher      *attribute_matcher,
 | 
			
		||||
					       GLocalParentFileInfo       *parent_info);
 | 
			
		||||
GFileInfo *_g_local_file_info_get             (const char                 *basename,
 | 
			
		||||
					       const char                 *path,
 | 
			
		||||
					       GFileAttributeMatcher      *attribute_matcher,
 | 
			
		||||
					       GFileQueryInfoFlags         flags,
 | 
			
		||||
					       GLocalParentFileInfo       *parent_info,
 | 
			
		||||
					       GError                    **error);
 | 
			
		||||
GFileInfo *_g_local_file_info_get_from_fd     (int                         fd,
 | 
			
		||||
					       char                       *attributes,
 | 
			
		||||
					       GError                    **error);
 | 
			
		||||
char *     _g_local_file_info_create_etag     (struct stat                *statbuf);
 | 
			
		||||
gboolean   _g_local_file_info_set_attribute   (char                       *filename,
 | 
			
		||||
					       const char                 *attribute,
 | 
			
		||||
					       const GFileAttributeValue  *value,
 | 
			
		||||
					       GFileQueryInfoFlags         flags,
 | 
			
		||||
					       GCancellable               *cancellable,
 | 
			
		||||
					       GError                    **error);
 | 
			
		||||
gboolean   _g_local_file_info_set_attributes  (char                       *filename,
 | 
			
		||||
					       GFileInfo                  *info,
 | 
			
		||||
					       GFileQueryInfoFlags         flags,
 | 
			
		||||
					       GCancellable               *cancellable,
 | 
			
		||||
					       GError                    **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_FILE_LOCAL_FILE_INFO_H__ */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										319
									
								
								gio/glocalfileinputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										319
									
								
								gio/glocalfileinputstream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,319 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <glib/gstdio.h>
 | 
			
		||||
#include "gioerror.h"
 | 
			
		||||
#include "glocalfileinputstream.h"
 | 
			
		||||
#include "glocalfileinfo.h"
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GLocalFileInputStream, g_local_file_input_stream, G_TYPE_FILE_INPUT_STREAM);
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileInputStreamPrivate {
 | 
			
		||||
  int fd;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gssize     g_local_file_input_stream_read       (GInputStream      *stream,
 | 
			
		||||
							void              *buffer,
 | 
			
		||||
							gsize              count,
 | 
			
		||||
							GCancellable      *cancellable,
 | 
			
		||||
							GError           **error);
 | 
			
		||||
static gssize     g_local_file_input_stream_skip       (GInputStream      *stream,
 | 
			
		||||
							gsize              count,
 | 
			
		||||
							GCancellable      *cancellable,
 | 
			
		||||
							GError           **error);
 | 
			
		||||
static gboolean   g_local_file_input_stream_close      (GInputStream      *stream,
 | 
			
		||||
							GCancellable      *cancellable,
 | 
			
		||||
							GError           **error);
 | 
			
		||||
static goffset    g_local_file_input_stream_tell       (GFileInputStream  *stream);
 | 
			
		||||
static gboolean   g_local_file_input_stream_can_seek   (GFileInputStream  *stream);
 | 
			
		||||
static gboolean   g_local_file_input_stream_seek       (GFileInputStream  *stream,
 | 
			
		||||
							goffset            offset,
 | 
			
		||||
							GSeekType          type,
 | 
			
		||||
							GCancellable      *cancellable,
 | 
			
		||||
							GError           **error);
 | 
			
		||||
static GFileInfo *g_local_file_input_stream_query_info (GFileInputStream  *stream,
 | 
			
		||||
							char              *attributes,
 | 
			
		||||
							GCancellable      *cancellable,
 | 
			
		||||
							GError           **error);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_input_stream_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileInputStream *file;
 | 
			
		||||
  
 | 
			
		||||
  file = G_LOCAL_FILE_INPUT_STREAM (object);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_local_file_input_stream_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_local_file_input_stream_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_input_stream_class_init (GLocalFileInputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  GInputStreamClass *stream_class = G_INPUT_STREAM_CLASS (klass);
 | 
			
		||||
  GFileInputStreamClass *file_stream_class = G_FILE_INPUT_STREAM_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GLocalFileInputStreamPrivate));
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_local_file_input_stream_finalize;
 | 
			
		||||
 | 
			
		||||
  stream_class->read = g_local_file_input_stream_read;
 | 
			
		||||
  stream_class->skip = g_local_file_input_stream_skip;
 | 
			
		||||
  stream_class->close = g_local_file_input_stream_close;
 | 
			
		||||
  file_stream_class->tell = g_local_file_input_stream_tell;
 | 
			
		||||
  file_stream_class->can_seek = g_local_file_input_stream_can_seek;
 | 
			
		||||
  file_stream_class->seek = g_local_file_input_stream_seek;
 | 
			
		||||
  file_stream_class->query_info = g_local_file_input_stream_query_info;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_input_stream_init (GLocalFileInputStream *info)
 | 
			
		||||
{
 | 
			
		||||
  info->priv = G_TYPE_INSTANCE_GET_PRIVATE (info,
 | 
			
		||||
					    G_TYPE_LOCAL_FILE_INPUT_STREAM,
 | 
			
		||||
					    GLocalFileInputStreamPrivate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_local_file_input_stream_new:
 | 
			
		||||
 * @fd: File Descriptor.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: #GFileInputStream for the given file descriptor.
 | 
			
		||||
 **/
 | 
			
		||||
GFileInputStream *
 | 
			
		||||
g_local_file_input_stream_new (int fd)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileInputStream *stream;
 | 
			
		||||
 | 
			
		||||
  stream = g_object_new (G_TYPE_LOCAL_FILE_INPUT_STREAM, NULL);
 | 
			
		||||
  stream->priv->fd = fd;
 | 
			
		||||
  
 | 
			
		||||
  return G_FILE_INPUT_STREAM (stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_local_file_input_stream_read (GInputStream *stream,
 | 
			
		||||
				void         *buffer,
 | 
			
		||||
				gsize         count,
 | 
			
		||||
				GCancellable *cancellable,
 | 
			
		||||
				GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileInputStream *file;
 | 
			
		||||
  gssize res;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_INPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  res = -1;
 | 
			
		||||
  while (1)
 | 
			
		||||
    {
 | 
			
		||||
      if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
	break;
 | 
			
		||||
      res = read (file->priv->fd, buffer, count);
 | 
			
		||||
      if (res == -1)
 | 
			
		||||
	{
 | 
			
		||||
	  if (errno == EINTR)
 | 
			
		||||
	    continue;
 | 
			
		||||
	  
 | 
			
		||||
	  g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		       g_io_error_from_errno (errno),
 | 
			
		||||
		       _("Error reading from file: %s"),
 | 
			
		||||
		       g_strerror (errno));
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_local_file_input_stream_skip (GInputStream *stream,
 | 
			
		||||
				gsize         count,
 | 
			
		||||
				GCancellable *cancellable,
 | 
			
		||||
				GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  off_t res, start;
 | 
			
		||||
  GLocalFileInputStream *file;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_INPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
    return -1;
 | 
			
		||||
  
 | 
			
		||||
  start = lseek (file->priv->fd, 0, SEEK_CUR);
 | 
			
		||||
  if (start == -1)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		   g_io_error_from_errno (errno),
 | 
			
		||||
		   _("Error seeking in file: %s"),
 | 
			
		||||
		   g_strerror (errno));
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  res = lseek (file->priv->fd, count, SEEK_CUR);
 | 
			
		||||
  if (res == -1)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		   g_io_error_from_errno (errno),
 | 
			
		||||
		   _("Error seeking in file: %s"),
 | 
			
		||||
		   g_strerror (errno));
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return res - start;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_file_input_stream_close (GInputStream *stream,
 | 
			
		||||
				 GCancellable *cancellable,
 | 
			
		||||
				 GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileInputStream *file;
 | 
			
		||||
  int res;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_INPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  if (file->priv->fd == -1)
 | 
			
		||||
    return TRUE;
 | 
			
		||||
 | 
			
		||||
  while (1)
 | 
			
		||||
    {
 | 
			
		||||
      res = close (file->priv->fd);
 | 
			
		||||
      if (res == -1)
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		       g_io_error_from_errno (errno),
 | 
			
		||||
		       _("Error closing file: %s"),
 | 
			
		||||
		       g_strerror (errno));
 | 
			
		||||
	}
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return res != -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static goffset
 | 
			
		||||
g_local_file_input_stream_tell (GFileInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileInputStream *file;
 | 
			
		||||
  off_t pos;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_INPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  pos = lseek (file->priv->fd, 0, SEEK_CUR);
 | 
			
		||||
 | 
			
		||||
  if (pos == (off_t)-1)
 | 
			
		||||
    return 0;
 | 
			
		||||
  
 | 
			
		||||
  return pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_file_input_stream_can_seek (GFileInputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileInputStream *file;
 | 
			
		||||
  off_t pos;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_INPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  pos = lseek (file->priv->fd, 0, SEEK_CUR);
 | 
			
		||||
 | 
			
		||||
  if (pos == (off_t)-1 &&
 | 
			
		||||
      errno == ESPIPE)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
seek_type_to_lseek (GSeekType type)
 | 
			
		||||
{
 | 
			
		||||
  switch (type)
 | 
			
		||||
    {
 | 
			
		||||
    default:
 | 
			
		||||
    case G_SEEK_CUR:
 | 
			
		||||
      return SEEK_CUR;
 | 
			
		||||
      
 | 
			
		||||
    case G_SEEK_SET:
 | 
			
		||||
      return SEEK_SET;
 | 
			
		||||
      
 | 
			
		||||
    case G_SEEK_END:
 | 
			
		||||
      return SEEK_END;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_file_input_stream_seek (GFileInputStream     *stream,
 | 
			
		||||
				goffset               offset,
 | 
			
		||||
				GSeekType             type,
 | 
			
		||||
				GCancellable         *cancellable,
 | 
			
		||||
				GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileInputStream *file;
 | 
			
		||||
  off_t pos;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_INPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  pos = lseek (file->priv->fd, offset, seek_type_to_lseek (type));
 | 
			
		||||
 | 
			
		||||
  if (pos == (off_t)-1)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		   g_io_error_from_errno (errno),
 | 
			
		||||
		   _("Error seeking in file: %s"),
 | 
			
		||||
		   g_strerror (errno));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GFileInfo *
 | 
			
		||||
g_local_file_input_stream_query_info (GFileInputStream     *stream,
 | 
			
		||||
				      char                 *attributes,
 | 
			
		||||
				      GCancellable         *cancellable,
 | 
			
		||||
				      GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileInputStream *file;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_INPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  
 | 
			
		||||
  return _g_local_file_info_get_from_fd (file->priv->fd,
 | 
			
		||||
					 attributes,
 | 
			
		||||
					 error);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										60
									
								
								gio/glocalfileinputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								gio/glocalfileinputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_LOCAL_FILE_INPUT_STREAM_H__
 | 
			
		||||
#define __G_LOCAL_FILE_INPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gfileinputstream.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_LOCAL_FILE_INPUT_STREAM         (g_local_file_input_stream_get_type ())
 | 
			
		||||
#define G_LOCAL_FILE_INPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE_INPUT_STREAM, GLocalFileInputStream))
 | 
			
		||||
#define G_LOCAL_FILE_INPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LOCAL_FILE_INPUT_STREAM, GLocalFileInputStreamClass))
 | 
			
		||||
#define G_IS_LOCAL_FILE_INPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_INPUT_STREAM))
 | 
			
		||||
#define G_IS_LOCAL_FILE_INPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_INPUT_STREAM))
 | 
			
		||||
#define G_LOCAL_FILE_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE_INPUT_STREAM, GLocalFileInputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GLocalFileInputStream         GLocalFileInputStream;
 | 
			
		||||
typedef struct _GLocalFileInputStreamClass    GLocalFileInputStreamClass;
 | 
			
		||||
typedef struct _GLocalFileInputStreamPrivate  GLocalFileInputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileInputStream
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStream parent;
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GLocalFileInputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileInputStreamClass
 | 
			
		||||
{
 | 
			
		||||
  GFileInputStreamClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_local_file_input_stream_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GFileInputStream *g_local_file_input_stream_new (int fd);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_LOCAL_FILE_INPUT_STREAM_H__ */
 | 
			
		||||
							
								
								
									
										211
									
								
								gio/glocalfilemonitor.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								gio/glocalfilemonitor.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,211 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include "glocalfilemonitor.h"
 | 
			
		||||
#include "giomodule.h"
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
  PROP_0,
 | 
			
		||||
  PROP_FILENAME
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
G_DEFINE_ABSTRACT_TYPE (GLocalFileMonitor, g_local_file_monitor, G_TYPE_FILE_MONITOR)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_monitor_init (GLocalFileMonitor* local_monitor)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_monitor_set_property (GObject *object,
 | 
			
		||||
                                   guint property_id,
 | 
			
		||||
                                   const GValue *value,
 | 
			
		||||
                                   GParamSpec *pspec)
 | 
			
		||||
{
 | 
			
		||||
  switch (property_id)
 | 
			
		||||
  {
 | 
			
		||||
    case PROP_FILENAME:
 | 
			
		||||
      /* Do nothing */
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static GObject *
 | 
			
		||||
g_local_file_monitor_constructor (GType type,
 | 
			
		||||
                                  guint n_construct_properties,
 | 
			
		||||
                                  GObjectConstructParam *construct_properties)
 | 
			
		||||
{
 | 
			
		||||
  GObject *obj;
 | 
			
		||||
  GLocalFileMonitorClass *klass;
 | 
			
		||||
  GObjectClass *parent_class;
 | 
			
		||||
  GLocalFileMonitor *local_monitor;
 | 
			
		||||
  const gchar *filename = NULL;
 | 
			
		||||
  gint i;
 | 
			
		||||
  
 | 
			
		||||
  klass = G_LOCAL_FILE_MONITOR_CLASS (g_type_class_peek (G_TYPE_LOCAL_FILE_MONITOR));
 | 
			
		||||
  parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
 | 
			
		||||
  obj = parent_class->constructor (type,
 | 
			
		||||
                                   n_construct_properties,
 | 
			
		||||
                                   construct_properties);
 | 
			
		||||
 | 
			
		||||
  local_monitor = G_LOCAL_FILE_MONITOR (obj);
 | 
			
		||||
 | 
			
		||||
  for (i = 0; i < n_construct_properties; i++)
 | 
			
		||||
    {
 | 
			
		||||
      if (strcmp ("filename", g_param_spec_get_name (construct_properties[i].pspec)) == 0)
 | 
			
		||||
        {
 | 
			
		||||
          g_assert (G_VALUE_HOLDS_STRING (construct_properties[i].value));
 | 
			
		||||
          filename = g_value_get_string (construct_properties[i].value);
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_assert (filename != NULL);
 | 
			
		||||
 | 
			
		||||
  local_monitor->filename = g_strdup (filename);
 | 
			
		||||
  return obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_monitor_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileMonitor *local_monitor = G_LOCAL_FILE_MONITOR (object);
 | 
			
		||||
  if (local_monitor->filename)
 | 
			
		||||
    {
 | 
			
		||||
      g_free (local_monitor->filename);
 | 
			
		||||
      local_monitor->filename = NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (G_OBJECT_CLASS (g_local_file_monitor_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_local_file_monitor_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_monitor_class_init (GLocalFileMonitorClass* klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
 | 
			
		||||
  gobject_class->set_property = g_local_file_monitor_set_property;
 | 
			
		||||
  gobject_class->finalize = g_local_file_monitor_finalize;
 | 
			
		||||
  gobject_class->constructor = g_local_file_monitor_constructor;
 | 
			
		||||
 | 
			
		||||
  g_object_class_install_property (gobject_class, PROP_FILENAME,
 | 
			
		||||
      g_param_spec_string ("filename", "File name", "File name to monitor",
 | 
			
		||||
          NULL, G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gint
 | 
			
		||||
_compare_monitor_class_by_prio (gconstpointer a,
 | 
			
		||||
                                gconstpointer b,
 | 
			
		||||
                                gpointer user_data)
 | 
			
		||||
{
 | 
			
		||||
  GType *type1 = (GType *) a, *type2 = (GType *) b;
 | 
			
		||||
  GLocalFileMonitorClass *klass1, *klass2;
 | 
			
		||||
  gint ret;
 | 
			
		||||
 | 
			
		||||
  klass1 = G_LOCAL_FILE_MONITOR_CLASS (g_type_class_ref (*type1));
 | 
			
		||||
  klass2 = G_LOCAL_FILE_MONITOR_CLASS (g_type_class_ref (*type2));
 | 
			
		||||
 | 
			
		||||
  ret = klass1->prio - klass2->prio;
 | 
			
		||||
 | 
			
		||||
  g_type_class_unref (klass1);
 | 
			
		||||
  g_type_class_unref (klass2);
 | 
			
		||||
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern GType g_inotify_file_monitor_get_type (void);
 | 
			
		||||
 | 
			
		||||
static gpointer
 | 
			
		||||
get_default_local_file_monitor (gpointer data)
 | 
			
		||||
{
 | 
			
		||||
  GType *monitor_impls, chosen_type;
 | 
			
		||||
  guint n_monitor_impls;
 | 
			
		||||
  gint i;
 | 
			
		||||
  GType *ret = (GType *) data;
 | 
			
		||||
 | 
			
		||||
#if defined(HAVE_SYS_INOTIFY_H) || defined(HAVE_LINUX_INOTIFY_H)
 | 
			
		||||
  /* Register Inotify monitor */
 | 
			
		||||
  g_inotify_file_monitor_get_type ();
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  g_io_modules_ensure_loaded (GIO_MODULE_DIR);
 | 
			
		||||
  
 | 
			
		||||
  monitor_impls = g_type_children (G_TYPE_LOCAL_FILE_MONITOR,
 | 
			
		||||
                                   &n_monitor_impls);
 | 
			
		||||
 | 
			
		||||
  chosen_type = G_TYPE_INVALID;
 | 
			
		||||
 | 
			
		||||
  g_qsort_with_data (monitor_impls,
 | 
			
		||||
                     n_monitor_impls,
 | 
			
		||||
                     sizeof (GType),
 | 
			
		||||
                     _compare_monitor_class_by_prio,
 | 
			
		||||
                     NULL);
 | 
			
		||||
 | 
			
		||||
  for (i = n_monitor_impls - 1; i >= 0 && chosen_type == G_TYPE_INVALID; i--)
 | 
			
		||||
    {    
 | 
			
		||||
      GLocalFileMonitorClass *klass;
 | 
			
		||||
 | 
			
		||||
      klass = G_LOCAL_FILE_MONITOR_CLASS (g_type_class_ref (monitor_impls[i]));
 | 
			
		||||
 | 
			
		||||
      if (klass->is_supported())
 | 
			
		||||
        chosen_type = monitor_impls[i];
 | 
			
		||||
 | 
			
		||||
      g_type_class_unref (klass);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  g_free (monitor_impls);
 | 
			
		||||
 | 
			
		||||
  *ret = chosen_type;
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_local_file_monitor_new:
 | 
			
		||||
 * @pathname: path name to monitor.
 | 
			
		||||
 * @flags: #GFileMonitorFlags.
 | 
			
		||||
 * 
 | 
			
		||||
 * Returns: a new #GFileMonitor for the given @pathname. 
 | 
			
		||||
 **/
 | 
			
		||||
GFileMonitor*
 | 
			
		||||
g_local_file_monitor_new (const char* pathname,
 | 
			
		||||
                          GFileMonitorFlags flags)
 | 
			
		||||
{
 | 
			
		||||
  static GOnce once_init = G_ONCE_INIT;
 | 
			
		||||
  static GType monitor_type = G_TYPE_INVALID;
 | 
			
		||||
 | 
			
		||||
  g_once (&once_init, get_default_local_file_monitor, &monitor_type);
 | 
			
		||||
 | 
			
		||||
  if (monitor_type != G_TYPE_INVALID)
 | 
			
		||||
    return G_FILE_MONITOR (g_object_new (monitor_type, "filename", pathname, NULL));
 | 
			
		||||
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								gio/glocalfilemonitor.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								gio/glocalfilemonitor.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_LOCAL_FILE_MONITOR_H__
 | 
			
		||||
#define __G_LOCAL_FILE_MONITOR_H__
 | 
			
		||||
 | 
			
		||||
#include <glib-object.h>
 | 
			
		||||
#include <gio/gfilemonitor.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_LOCAL_FILE_MONITOR		(g_local_file_monitor_get_type ())
 | 
			
		||||
#define G_LOCAL_FILE_MONITOR(o)			(G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE_MONITOR, GLocalFileMonitor))
 | 
			
		||||
#define G_LOCAL_FILE_MONITOR_CLASS(k)		(G_TYPE_CHECK_CLASS_CAST ((k), G_TYPE_LOCAL_FILE_MONITOR, GLocalFileMonitorClass))
 | 
			
		||||
#define G_IS_LOCAL_FILE_MONITOR(o)		(G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_MONITOR))
 | 
			
		||||
#define G_IS_LOCAL_FILE_MONITOR_CLASS(k)	(G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_MONITOR))
 | 
			
		||||
 | 
			
		||||
typedef struct _GLocalFileMonitor      GLocalFileMonitor;
 | 
			
		||||
typedef struct _GLocalFileMonitorClass GLocalFileMonitorClass;
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileMonitor
 | 
			
		||||
{
 | 
			
		||||
  GFileMonitor parent_instance;
 | 
			
		||||
  gchar *filename;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileMonitorClass {
 | 
			
		||||
  GFileMonitorClass parent_class;
 | 
			
		||||
  gint prio;
 | 
			
		||||
  gboolean (*is_supported) (void);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_local_file_monitor_get_type (void) G_GNUC_CONST;
 | 
			
		||||
 | 
			
		||||
GFileMonitor* g_local_file_monitor_new (const char* pathname,
 | 
			
		||||
					GFileMonitorFlags flags);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_LOCAL_FILE_MONITOR_H__ */
 | 
			
		||||
							
								
								
									
										910
									
								
								gio/glocalfileoutputstream.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										910
									
								
								gio/glocalfileoutputstream.c
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,910 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <config.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include <glib.h>
 | 
			
		||||
#include <glib/gstdio.h>
 | 
			
		||||
#include "glibintl.h"
 | 
			
		||||
#include "gioerror.h"
 | 
			
		||||
#include "glocalfileoutputstream.h"
 | 
			
		||||
#include "glocalfileinfo.h"
 | 
			
		||||
 | 
			
		||||
G_DEFINE_TYPE (GLocalFileOutputStream, g_local_file_output_stream, G_TYPE_FILE_OUTPUT_STREAM);
 | 
			
		||||
 | 
			
		||||
/* Some of the file replacement code was based on the code from gedit,
 | 
			
		||||
 * relicenced to LGPL with permissions from the authors.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define BACKUP_EXTENSION "~"
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileOutputStreamPrivate {
 | 
			
		||||
  char *tmp_filename;
 | 
			
		||||
  char *original_filename;
 | 
			
		||||
  char *backup_filename;
 | 
			
		||||
  char *etag;
 | 
			
		||||
  int fd;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static gssize     g_local_file_output_stream_write        (GOutputStream      *stream,
 | 
			
		||||
							   const void         *buffer,
 | 
			
		||||
							   gsize               count,
 | 
			
		||||
							   GCancellable       *cancellable,
 | 
			
		||||
							   GError            **error);
 | 
			
		||||
static gboolean   g_local_file_output_stream_close        (GOutputStream      *stream,
 | 
			
		||||
							   GCancellable       *cancellable,
 | 
			
		||||
							   GError            **error);
 | 
			
		||||
static GFileInfo *g_local_file_output_stream_query_info   (GFileOutputStream  *stream,
 | 
			
		||||
							   char               *attributes,
 | 
			
		||||
							   GCancellable       *cancellable,
 | 
			
		||||
							   GError            **error);
 | 
			
		||||
static char *     g_local_file_output_stream_get_etag     (GFileOutputStream  *stream);
 | 
			
		||||
static goffset    g_local_file_output_stream_tell         (GFileOutputStream  *stream);
 | 
			
		||||
static gboolean   g_local_file_output_stream_can_seek     (GFileOutputStream  *stream);
 | 
			
		||||
static gboolean   g_local_file_output_stream_seek         (GFileOutputStream  *stream,
 | 
			
		||||
							   goffset             offset,
 | 
			
		||||
							   GSeekType           type,
 | 
			
		||||
							   GCancellable       *cancellable,
 | 
			
		||||
							   GError            **error);
 | 
			
		||||
static gboolean   g_local_file_output_stream_can_truncate (GFileOutputStream  *stream);
 | 
			
		||||
static gboolean   g_local_file_output_stream_truncate     (GFileOutputStream  *stream,
 | 
			
		||||
							   goffset             size,
 | 
			
		||||
							   GCancellable       *cancellable,
 | 
			
		||||
							   GError            **error);
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_output_stream_finalize (GObject *object)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *file;
 | 
			
		||||
  
 | 
			
		||||
  file = G_LOCAL_FILE_OUTPUT_STREAM (object);
 | 
			
		||||
  
 | 
			
		||||
  g_free (file->priv->tmp_filename);
 | 
			
		||||
  g_free (file->priv->original_filename);
 | 
			
		||||
  g_free (file->priv->backup_filename);
 | 
			
		||||
  g_free (file->priv->etag);
 | 
			
		||||
  
 | 
			
		||||
  if (G_OBJECT_CLASS (g_local_file_output_stream_parent_class)->finalize)
 | 
			
		||||
    (*G_OBJECT_CLASS (g_local_file_output_stream_parent_class)->finalize) (object);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_output_stream_class_init (GLocalFileOutputStreamClass *klass)
 | 
			
		||||
{
 | 
			
		||||
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 | 
			
		||||
  GOutputStreamClass *stream_class = G_OUTPUT_STREAM_CLASS (klass);
 | 
			
		||||
  GFileOutputStreamClass *file_stream_class = G_FILE_OUTPUT_STREAM_CLASS (klass);
 | 
			
		||||
  
 | 
			
		||||
  g_type_class_add_private (klass, sizeof (GLocalFileOutputStreamPrivate));
 | 
			
		||||
  
 | 
			
		||||
  gobject_class->finalize = g_local_file_output_stream_finalize;
 | 
			
		||||
 | 
			
		||||
  stream_class->write = g_local_file_output_stream_write;
 | 
			
		||||
  stream_class->close = g_local_file_output_stream_close;
 | 
			
		||||
  file_stream_class->query_info = g_local_file_output_stream_query_info;
 | 
			
		||||
  file_stream_class->get_etag = g_local_file_output_stream_get_etag;
 | 
			
		||||
  file_stream_class->tell = g_local_file_output_stream_tell;
 | 
			
		||||
  file_stream_class->can_seek = g_local_file_output_stream_can_seek;
 | 
			
		||||
  file_stream_class->seek = g_local_file_output_stream_seek;
 | 
			
		||||
  file_stream_class->can_truncate = g_local_file_output_stream_can_truncate;
 | 
			
		||||
  file_stream_class->truncate = g_local_file_output_stream_truncate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
g_local_file_output_stream_init (GLocalFileOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
 | 
			
		||||
					      G_TYPE_LOCAL_FILE_OUTPUT_STREAM,
 | 
			
		||||
					      GLocalFileOutputStreamPrivate);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gssize
 | 
			
		||||
g_local_file_output_stream_write (GOutputStream *stream,
 | 
			
		||||
				  const void   *buffer,
 | 
			
		||||
				  gsize         count,
 | 
			
		||||
				  GCancellable *cancellable,
 | 
			
		||||
				  GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *file;
 | 
			
		||||
  gssize res;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  while (1)
 | 
			
		||||
    {
 | 
			
		||||
      if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
	return -1;
 | 
			
		||||
      res = write (file->priv->fd, buffer, count);
 | 
			
		||||
      if (res == -1)
 | 
			
		||||
	{
 | 
			
		||||
	  if (errno == EINTR)
 | 
			
		||||
	    continue;
 | 
			
		||||
	  
 | 
			
		||||
	  g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		       g_io_error_from_errno (errno),
 | 
			
		||||
		       _("Error writing to file: %s"),
 | 
			
		||||
		       g_strerror (errno));
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_file_output_stream_close (GOutputStream *stream,
 | 
			
		||||
				  GCancellable *cancellable,
 | 
			
		||||
				  GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *file;
 | 
			
		||||
  struct stat final_stat;
 | 
			
		||||
  int res;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  if (file->priv->tmp_filename)
 | 
			
		||||
    {
 | 
			
		||||
      /* We need to move the temp file to its final place,
 | 
			
		||||
       * and possibly create the backup file
 | 
			
		||||
       */
 | 
			
		||||
 | 
			
		||||
      if (file->priv->backup_filename)
 | 
			
		||||
	{
 | 
			
		||||
	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
	    goto err_out;
 | 
			
		||||
	  
 | 
			
		||||
#ifdef HAVE_LINK
 | 
			
		||||
	  /* create original -> backup link, the original is then renamed over */
 | 
			
		||||
	  if (unlink (file->priv->backup_filename) != 0 &&
 | 
			
		||||
	      errno != ENOENT)
 | 
			
		||||
	    {
 | 
			
		||||
	      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
			   G_IO_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
			   _("Error removing old backup link: %s"),
 | 
			
		||||
			   g_strerror (errno));
 | 
			
		||||
	      goto err_out;
 | 
			
		||||
	    }
 | 
			
		||||
 | 
			
		||||
	  if (link (file->priv->original_filename, file->priv->backup_filename) != 0)
 | 
			
		||||
	    {
 | 
			
		||||
	      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
			   G_IO_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
			   _("Error creating backup link: %s"),
 | 
			
		||||
			   g_strerror (errno));
 | 
			
		||||
	      goto err_out;
 | 
			
		||||
	    }
 | 
			
		||||
#else
 | 
			
		||||
	    /* If link not supported, just rename... */
 | 
			
		||||
	  if (!rename (file->priv->original_filename, file->priv->backup_filename) != 0)
 | 
			
		||||
	    {
 | 
			
		||||
	      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
			   G_IO_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
			   _("Error creating backup copy: %s"),
 | 
			
		||||
			   g_strerror (errno));
 | 
			
		||||
	      goto err_out;
 | 
			
		||||
	    }
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
 | 
			
		||||
      if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
	goto err_out;
 | 
			
		||||
 | 
			
		||||
      /* tmp -> original */
 | 
			
		||||
      if (rename (file->priv->tmp_filename, file->priv->original_filename) != 0)
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		       g_io_error_from_errno (errno),
 | 
			
		||||
		       _("Error renamining temporary file: %s"),
 | 
			
		||||
		       g_strerror (errno));
 | 
			
		||||
	  goto err_out;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
    goto err_out;
 | 
			
		||||
      
 | 
			
		||||
  if (fstat (file->priv->fd, &final_stat) == 0)
 | 
			
		||||
    file->priv->etag = _g_local_file_info_create_etag (&final_stat);
 | 
			
		||||
 | 
			
		||||
  while (1)
 | 
			
		||||
    {
 | 
			
		||||
      res = close (file->priv->fd);
 | 
			
		||||
      if (res == -1)
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		       g_io_error_from_errno (errno),
 | 
			
		||||
		       _("Error closing file: %s"),
 | 
			
		||||
		       g_strerror (errno));
 | 
			
		||||
	}
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return res != -1;
 | 
			
		||||
 | 
			
		||||
 err_out:
 | 
			
		||||
  /* A simple try to close the fd in case we fail before the actual close */
 | 
			
		||||
  close (file->priv->fd);
 | 
			
		||||
  return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
g_local_file_output_stream_get_etag (GFileOutputStream      *stream)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *file;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  return g_strdup (file->priv->etag);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static goffset
 | 
			
		||||
g_local_file_output_stream_tell (GFileOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *file;
 | 
			
		||||
  off_t pos;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  pos = lseek (file->priv->fd, 0, SEEK_CUR);
 | 
			
		||||
 | 
			
		||||
  if (pos == (off_t)-1)
 | 
			
		||||
    return 0;
 | 
			
		||||
  
 | 
			
		||||
  return pos;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_file_output_stream_can_seek (GFileOutputStream *stream)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *file;
 | 
			
		||||
  off_t pos;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
  
 | 
			
		||||
  pos = lseek (file->priv->fd, 0, SEEK_CUR);
 | 
			
		||||
 | 
			
		||||
  if (pos == (off_t)-1 &&
 | 
			
		||||
      errno == ESPIPE)
 | 
			
		||||
    return FALSE;
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
seek_type_to_lseek (GSeekType type)
 | 
			
		||||
{
 | 
			
		||||
  switch (type)
 | 
			
		||||
    {
 | 
			
		||||
    default:
 | 
			
		||||
    case G_SEEK_CUR:
 | 
			
		||||
      return SEEK_CUR;
 | 
			
		||||
      
 | 
			
		||||
    case G_SEEK_SET:
 | 
			
		||||
      return SEEK_SET;
 | 
			
		||||
      
 | 
			
		||||
    case G_SEEK_END:
 | 
			
		||||
      return SEEK_END;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_file_output_stream_seek (GFileOutputStream     *stream,
 | 
			
		||||
				 goffset               offset,
 | 
			
		||||
				 GSeekType             type,
 | 
			
		||||
				 GCancellable         *cancellable,
 | 
			
		||||
				 GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *file;
 | 
			
		||||
  off_t pos;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  pos = lseek (file->priv->fd, offset, seek_type_to_lseek (type));
 | 
			
		||||
 | 
			
		||||
  if (pos == (off_t)-1)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		   g_io_error_from_errno (errno),
 | 
			
		||||
		   _("Error seeking in file: %s"),
 | 
			
		||||
		   g_strerror (errno));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_file_output_stream_can_truncate (GFileOutputStream    *stream)
 | 
			
		||||
{
 | 
			
		||||
  /* We can't truncate pipes and stuff where we can't seek */
 | 
			
		||||
  return g_local_file_output_stream_can_seek (stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
g_local_file_output_stream_truncate (GFileOutputStream    *stream,
 | 
			
		||||
				     goffset               size,
 | 
			
		||||
				     GCancellable         *cancellable,
 | 
			
		||||
				     GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *file;
 | 
			
		||||
  int res;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
 restart:
 | 
			
		||||
  res = ftruncate(file->priv->fd, size);
 | 
			
		||||
  
 | 
			
		||||
  if (res == -1)
 | 
			
		||||
    {
 | 
			
		||||
      if (errno == EINTR)
 | 
			
		||||
	{
 | 
			
		||||
	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
	    return FALSE;
 | 
			
		||||
	  goto restart;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		   g_io_error_from_errno (errno),
 | 
			
		||||
		   _("Error truncating file: %s"),
 | 
			
		||||
		   g_strerror (errno));
 | 
			
		||||
      return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static GFileInfo *
 | 
			
		||||
g_local_file_output_stream_query_info (GFileOutputStream     *stream,
 | 
			
		||||
				       char                 *attributes,
 | 
			
		||||
				       GCancellable         *cancellable,
 | 
			
		||||
				       GError              **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *file;
 | 
			
		||||
 | 
			
		||||
  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
 | 
			
		||||
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
    return NULL;
 | 
			
		||||
  
 | 
			
		||||
  return _g_local_file_info_get_from_fd (file->priv->fd,
 | 
			
		||||
					 attributes,
 | 
			
		||||
					 error);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_local_file_output_stream_create:
 | 
			
		||||
 * @filename:
 | 
			
		||||
 * @flags:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: #GFileOutputStream.
 | 
			
		||||
 **/
 | 
			
		||||
GFileOutputStream *
 | 
			
		||||
g_local_file_output_stream_create  (const char       *filename,
 | 
			
		||||
				    GFileCreateFlags  flags,
 | 
			
		||||
				    GCancellable     *cancellable,
 | 
			
		||||
				    GError          **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *stream;
 | 
			
		||||
  int mode;
 | 
			
		||||
  int fd;
 | 
			
		||||
 | 
			
		||||
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (flags & G_FILE_CREATE_FLAGS_PRIVATE)
 | 
			
		||||
    mode = 0600;
 | 
			
		||||
  else
 | 
			
		||||
    mode = 0666;
 | 
			
		||||
  
 | 
			
		||||
  fd = g_open (filename,
 | 
			
		||||
	       O_CREAT | O_EXCL | O_WRONLY,
 | 
			
		||||
	       0666);
 | 
			
		||||
  if (fd == -1)
 | 
			
		||||
    {
 | 
			
		||||
      int errsv = errno;
 | 
			
		||||
 | 
			
		||||
      if (errsv == EINVAL)
 | 
			
		||||
	/* This must be an invalid filename, on e.g. FAT */
 | 
			
		||||
	g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		     G_IO_ERROR_INVALID_FILENAME,
 | 
			
		||||
		     _("Invalid filename"));
 | 
			
		||||
      else
 | 
			
		||||
	g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		     g_io_error_from_errno (errsv),
 | 
			
		||||
		     _("Error opening file '%s': %s"),
 | 
			
		||||
		     filename, g_strerror (errsv));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
 | 
			
		||||
  stream->priv->fd = fd;
 | 
			
		||||
  return G_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_local_file_output_stream_append:
 | 
			
		||||
 * @filename:
 | 
			
		||||
 * @flags:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: 
 | 
			
		||||
 **/
 | 
			
		||||
GFileOutputStream *
 | 
			
		||||
g_local_file_output_stream_append  (const char       *filename,
 | 
			
		||||
				    GFileCreateFlags  flags,
 | 
			
		||||
				    GCancellable     *cancellable,
 | 
			
		||||
				    GError          **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *stream;
 | 
			
		||||
  int mode;
 | 
			
		||||
  int fd;
 | 
			
		||||
 | 
			
		||||
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  if (flags & G_FILE_CREATE_FLAGS_PRIVATE)
 | 
			
		||||
    mode = 0600;
 | 
			
		||||
  else
 | 
			
		||||
    mode = 0666;
 | 
			
		||||
 | 
			
		||||
  fd = g_open (filename,
 | 
			
		||||
	       O_CREAT | O_APPEND | O_WRONLY,
 | 
			
		||||
	       mode);
 | 
			
		||||
  if (fd == -1)
 | 
			
		||||
    {
 | 
			
		||||
      int errsv = errno;
 | 
			
		||||
 | 
			
		||||
      if (errsv == EINVAL)
 | 
			
		||||
	/* This must be an invalid filename, on e.g. FAT */
 | 
			
		||||
	g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		     G_IO_ERROR_INVALID_FILENAME,
 | 
			
		||||
		     _("Invalid filename"));
 | 
			
		||||
      else
 | 
			
		||||
	g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		     g_io_error_from_errno (errsv),
 | 
			
		||||
		     _("Error opening file '%s': %s"),
 | 
			
		||||
		     filename, g_strerror (errsv));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
 | 
			
		||||
  stream->priv->fd = fd;
 | 
			
		||||
  
 | 
			
		||||
  return G_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static char *
 | 
			
		||||
create_backup_filename (const char *filename)
 | 
			
		||||
{
 | 
			
		||||
  return g_strconcat (filename, BACKUP_EXTENSION, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define BUFSIZE	8192 /* size of normal write buffer */
 | 
			
		||||
 | 
			
		||||
static gboolean
 | 
			
		||||
copy_file_data (gint     sfd,
 | 
			
		||||
		gint     dfd,
 | 
			
		||||
		GError **error)
 | 
			
		||||
{
 | 
			
		||||
  gboolean ret = TRUE;
 | 
			
		||||
  gpointer buffer;
 | 
			
		||||
  const gchar *write_buffer;
 | 
			
		||||
  ssize_t bytes_read;
 | 
			
		||||
  ssize_t bytes_to_write;
 | 
			
		||||
  ssize_t bytes_written;
 | 
			
		||||
  
 | 
			
		||||
  buffer = g_malloc (BUFSIZE);
 | 
			
		||||
  
 | 
			
		||||
  do
 | 
			
		||||
    {
 | 
			
		||||
      bytes_read = read (sfd, buffer, BUFSIZE);
 | 
			
		||||
      if (bytes_read == -1)
 | 
			
		||||
	{
 | 
			
		||||
	  if (errno == EINTR)
 | 
			
		||||
	    continue;
 | 
			
		||||
	  
 | 
			
		||||
	  g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		       g_io_error_from_errno (errno),
 | 
			
		||||
		       _("Error reading from file: %s"),
 | 
			
		||||
		       g_strerror (errno));
 | 
			
		||||
	  ret = FALSE;
 | 
			
		||||
	  break;
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      bytes_to_write = bytes_read;
 | 
			
		||||
      write_buffer = buffer;
 | 
			
		||||
      
 | 
			
		||||
      do
 | 
			
		||||
	{
 | 
			
		||||
	  bytes_written = write (dfd, write_buffer, bytes_to_write);
 | 
			
		||||
	  if (bytes_written == -1)
 | 
			
		||||
	    {
 | 
			
		||||
	      if (errno == EINTR)
 | 
			
		||||
		continue;
 | 
			
		||||
	      
 | 
			
		||||
	      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
			   g_io_error_from_errno (errno),
 | 
			
		||||
			   _("Error writing to file: %s"),
 | 
			
		||||
			   g_strerror (errno));
 | 
			
		||||
	      ret = FALSE;
 | 
			
		||||
	      break;
 | 
			
		||||
	    }
 | 
			
		||||
	  
 | 
			
		||||
	  bytes_to_write -= bytes_written;
 | 
			
		||||
	  write_buffer += bytes_written;
 | 
			
		||||
	}
 | 
			
		||||
      while (bytes_to_write > 0);
 | 
			
		||||
      
 | 
			
		||||
    } while ((bytes_read != 0) && (ret == TRUE));
 | 
			
		||||
 | 
			
		||||
  g_free (buffer);
 | 
			
		||||
  
 | 
			
		||||
  return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int
 | 
			
		||||
handle_overwrite_open (const char *filename,
 | 
			
		||||
		       const char *etag,
 | 
			
		||||
		       gboolean create_backup,
 | 
			
		||||
		       char **temp_filename,
 | 
			
		||||
		       GCancellable *cancellable,
 | 
			
		||||
		       GError      **error)
 | 
			
		||||
{
 | 
			
		||||
  int fd = -1;
 | 
			
		||||
  struct stat original_stat;
 | 
			
		||||
  char *current_etag;
 | 
			
		||||
  gboolean is_symlink;
 | 
			
		||||
  int open_flags;
 | 
			
		||||
 | 
			
		||||
  /* We only need read access to the original file if we are creating a backup.
 | 
			
		||||
   * We also add O_CREATE to avoid a race if the file was just removed */
 | 
			
		||||
  if (create_backup)
 | 
			
		||||
    open_flags = O_RDWR | O_CREAT;
 | 
			
		||||
  else
 | 
			
		||||
    open_flags = O_WRONLY | O_CREAT;
 | 
			
		||||
  
 | 
			
		||||
  /* Some systems have O_NOFOLLOW, which lets us avoid some races
 | 
			
		||||
   * when finding out if the file we opened was a symlink */
 | 
			
		||||
#ifdef O_NOFOLLOW
 | 
			
		||||
  is_symlink = FALSE;
 | 
			
		||||
  fd = g_open (filename, open_flags | O_NOFOLLOW, 0666);
 | 
			
		||||
  if (fd == -1 && errno == ELOOP)
 | 
			
		||||
    {
 | 
			
		||||
      /* Could be a symlink, or it could be a regular ELOOP error,
 | 
			
		||||
       * but then the next open will fail too. */
 | 
			
		||||
      is_symlink = TRUE;
 | 
			
		||||
      fd = g_open (filename, open_flags, 0666);
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
  fd = g_open (filename, open_flags, 0666);
 | 
			
		||||
  /* This is racy, but we do it as soon as possible to minimize the race */
 | 
			
		||||
  is_symlink = g_file_test (filename, G_FILE_TEST_IS_SYMLINK);
 | 
			
		||||
#endif
 | 
			
		||||
    
 | 
			
		||||
  if (fd == -1)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		   g_io_error_from_errno (errno),
 | 
			
		||||
		   _("Error opening file '%s': %s"),
 | 
			
		||||
		   filename, g_strerror (errno));
 | 
			
		||||
      return -1;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (fstat (fd, &original_stat) != 0) 
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		   g_io_error_from_errno (errno),
 | 
			
		||||
		   _("Error stating file '%s': %s"),
 | 
			
		||||
		   filename, g_strerror (errno));
 | 
			
		||||
      goto err_out;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  /* not a regular file */
 | 
			
		||||
  if (!S_ISREG (original_stat.st_mode))
 | 
			
		||||
    {
 | 
			
		||||
      if (S_ISDIR (original_stat.st_mode))
 | 
			
		||||
	g_set_error (error,
 | 
			
		||||
		     G_IO_ERROR,
 | 
			
		||||
		     G_IO_ERROR_IS_DIRECTORY,
 | 
			
		||||
		     _("Target file is a directory"));
 | 
			
		||||
      else
 | 
			
		||||
	g_set_error (error,
 | 
			
		||||
		     G_IO_ERROR,
 | 
			
		||||
		     G_IO_ERROR_NOT_REGULAR_FILE,
 | 
			
		||||
		     _("Target file is not a regular file"));
 | 
			
		||||
      goto err_out;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
  if (etag != NULL)
 | 
			
		||||
    {
 | 
			
		||||
      current_etag = _g_local_file_info_create_etag (&original_stat);
 | 
			
		||||
      if (strcmp (etag, current_etag) != 0)
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error,
 | 
			
		||||
		       G_IO_ERROR,
 | 
			
		||||
		       G_IO_ERROR_WRONG_ETAG,
 | 
			
		||||
		       _("The file was externally modified"));
 | 
			
		||||
	  g_free (current_etag);
 | 
			
		||||
	  goto err_out;
 | 
			
		||||
	}
 | 
			
		||||
      g_free (current_etag);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* We use two backup strategies.
 | 
			
		||||
   * The first one (which is faster) consist in saving to a
 | 
			
		||||
   * tmp file then rename the original file to the backup and the
 | 
			
		||||
   * tmp file to the original name. This is fast but doesn't work
 | 
			
		||||
   * when the file is a link (hard or symbolic) or when we can't
 | 
			
		||||
   * write to the current dir or can't set the permissions on the
 | 
			
		||||
   * new file. 
 | 
			
		||||
   * The second strategy consist simply in copying the old file
 | 
			
		||||
   * to a backup file and rewrite the contents of the file.
 | 
			
		||||
   */
 | 
			
		||||
  
 | 
			
		||||
  if (!(original_stat.st_nlink > 1) && !is_symlink)
 | 
			
		||||
    {
 | 
			
		||||
      char *dirname, *tmp_filename;
 | 
			
		||||
      int tmpfd;
 | 
			
		||||
      
 | 
			
		||||
      dirname = g_path_get_dirname (filename);
 | 
			
		||||
      tmp_filename = g_build_filename (dirname, ".goutputstream-XXXXXX", NULL);
 | 
			
		||||
      g_free (dirname);
 | 
			
		||||
 | 
			
		||||
      tmpfd = g_mkstemp (tmp_filename);
 | 
			
		||||
      if (tmpfd == -1)
 | 
			
		||||
	{
 | 
			
		||||
	  g_free (tmp_filename);
 | 
			
		||||
	  goto fallback_strategy;
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      /* try to keep permissions */
 | 
			
		||||
 | 
			
		||||
      if (
 | 
			
		||||
#ifdef F_CHOWN
 | 
			
		||||
	  fchown (tmpfd, original_stat.st_uid, original_stat.st_gid) == -1 ||
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef F_CHMOD
 | 
			
		||||
	  fchmod (tmpfd, original_stat.st_mode) == -1 ||
 | 
			
		||||
#endif
 | 
			
		||||
	  0
 | 
			
		||||
	  )
 | 
			
		||||
	{
 | 
			
		||||
	  struct stat tmp_statbuf;
 | 
			
		||||
	  
 | 
			
		||||
	  /* Check that we really needed to change something */
 | 
			
		||||
	  if (fstat (tmpfd, &tmp_statbuf) != 0 ||
 | 
			
		||||
	      original_stat.st_uid != tmp_statbuf.st_uid ||
 | 
			
		||||
	      original_stat.st_gid != tmp_statbuf.st_gid ||
 | 
			
		||||
	      original_stat.st_mode != tmp_statbuf.st_mode)
 | 
			
		||||
	    {
 | 
			
		||||
	      close (tmpfd);
 | 
			
		||||
	      unlink (tmp_filename);
 | 
			
		||||
	      g_free (tmp_filename);
 | 
			
		||||
	      goto fallback_strategy;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      close (fd);
 | 
			
		||||
      *temp_filename = tmp_filename;
 | 
			
		||||
      return tmpfd;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 fallback_strategy:
 | 
			
		||||
 | 
			
		||||
  if (create_backup)
 | 
			
		||||
    {
 | 
			
		||||
      struct stat tmp_statbuf;      
 | 
			
		||||
      char *backup_filename;
 | 
			
		||||
      int bfd;
 | 
			
		||||
      
 | 
			
		||||
      backup_filename = create_backup_filename (filename);
 | 
			
		||||
 | 
			
		||||
      if (unlink (backup_filename) == -1 && errno != ENOENT)
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error,
 | 
			
		||||
		       G_IO_ERROR,
 | 
			
		||||
		       G_IO_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
		       _("Backup file creation failed"));
 | 
			
		||||
	  g_free (backup_filename);
 | 
			
		||||
	  goto err_out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      bfd = g_open (backup_filename,
 | 
			
		||||
		    O_WRONLY | O_CREAT | O_EXCL,
 | 
			
		||||
		    original_stat.st_mode & 0777);
 | 
			
		||||
 | 
			
		||||
      if (bfd == -1)
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error,
 | 
			
		||||
		       G_IO_ERROR,
 | 
			
		||||
		       G_IO_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
		       _("Backup file creation failed"));
 | 
			
		||||
	  g_free (backup_filename);
 | 
			
		||||
	  goto err_out;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
      /* If needed, Try to set the group of the backup same as the
 | 
			
		||||
       * original file. If this fails, set the protection
 | 
			
		||||
       * bits for the group same as the protection bits for
 | 
			
		||||
       * others. */
 | 
			
		||||
#ifdef HAVE_FCHOWN
 | 
			
		||||
      if (fstat (bfd, &tmp_statbuf) != 0)
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error,
 | 
			
		||||
		       G_IO_ERROR,
 | 
			
		||||
		       G_IO_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
		       _("Backup file creation failed"));
 | 
			
		||||
	  unlink (backup_filename);
 | 
			
		||||
	  g_free (backup_filename);
 | 
			
		||||
	  goto err_out;
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      if ((original_stat.st_gid != tmp_statbuf.st_gid)  &&
 | 
			
		||||
	  fchown (bfd, (uid_t) -1, original_stat.st_gid) != 0)
 | 
			
		||||
	{
 | 
			
		||||
	  if (fchmod (bfd,
 | 
			
		||||
		      (original_stat.st_mode & 0707) |
 | 
			
		||||
		      ((original_stat.st_mode & 07) << 3)) != 0)
 | 
			
		||||
	    {
 | 
			
		||||
	      g_set_error (error,
 | 
			
		||||
			   G_IO_ERROR,
 | 
			
		||||
			   G_IO_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
			   _("Backup file creation failed"));
 | 
			
		||||
	      unlink (backup_filename);
 | 
			
		||||
	      close (bfd);
 | 
			
		||||
	      g_free (backup_filename);
 | 
			
		||||
	      goto err_out;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
      if (!copy_file_data (fd, bfd, NULL))
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error,
 | 
			
		||||
		       G_IO_ERROR,
 | 
			
		||||
		       G_IO_ERROR_CANT_CREATE_BACKUP,
 | 
			
		||||
		       _("Backup file creation failed"));
 | 
			
		||||
	  unlink (backup_filename);
 | 
			
		||||
	  close (bfd);
 | 
			
		||||
	  g_free (backup_filename);
 | 
			
		||||
	  
 | 
			
		||||
	  goto err_out;
 | 
			
		||||
	}
 | 
			
		||||
      
 | 
			
		||||
      close (bfd);
 | 
			
		||||
      g_free (backup_filename);
 | 
			
		||||
 | 
			
		||||
      /* Seek back to the start of the file after the backup copy */
 | 
			
		||||
      if (lseek (fd, 0, SEEK_SET) == -1)
 | 
			
		||||
	{
 | 
			
		||||
	  g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		       g_io_error_from_errno (errno),
 | 
			
		||||
		       _("Error seeking in file: %s"),
 | 
			
		||||
		       g_strerror (errno));
 | 
			
		||||
	  goto err_out;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  /* Truncate the file at the start */
 | 
			
		||||
  if (ftruncate (fd, 0) == -1)
 | 
			
		||||
    {
 | 
			
		||||
      g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		   g_io_error_from_errno (errno),
 | 
			
		||||
		   _("Error truncating file: %s"),
 | 
			
		||||
		   g_strerror (errno));
 | 
			
		||||
      goto err_out;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
  return fd;
 | 
			
		||||
 | 
			
		||||
 err_out:
 | 
			
		||||
  close (fd);
 | 
			
		||||
  return -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_local_file_output_stream_replace:
 | 
			
		||||
 * @filename: the file name.
 | 
			
		||||
 * @etag:
 | 
			
		||||
 * @create_backup: if set, create a backup of the file.
 | 
			
		||||
 * @flags:
 | 
			
		||||
 * @cancellable: optional #GCancellable object, %NULL to ignore. 
 | 
			
		||||
 * @error: a #GError location to store the error occuring, or %NULL to 
 | 
			
		||||
 * ignore.
 | 
			
		||||
 * Returns: #GFileOutputStream
 | 
			
		||||
 **/
 | 
			
		||||
GFileOutputStream *
 | 
			
		||||
g_local_file_output_stream_replace (const char        *filename,
 | 
			
		||||
				    const char        *etag,
 | 
			
		||||
				    gboolean           create_backup,
 | 
			
		||||
				    GFileCreateFlags   flags,
 | 
			
		||||
				    GCancellable      *cancellable,
 | 
			
		||||
				    GError           **error)
 | 
			
		||||
{
 | 
			
		||||
  GLocalFileOutputStream *stream;
 | 
			
		||||
  int mode;
 | 
			
		||||
  int fd;
 | 
			
		||||
  char *temp_file;
 | 
			
		||||
 | 
			
		||||
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
 | 
			
		||||
    return NULL;
 | 
			
		||||
 | 
			
		||||
  temp_file = NULL;
 | 
			
		||||
 | 
			
		||||
  if (flags & G_FILE_CREATE_FLAGS_PRIVATE)
 | 
			
		||||
    mode = 0600;
 | 
			
		||||
  else
 | 
			
		||||
    mode = 0666;
 | 
			
		||||
 | 
			
		||||
  /* If the file doesn't exist, create it */
 | 
			
		||||
  fd = g_open (filename,
 | 
			
		||||
	       O_CREAT | O_EXCL | O_WRONLY,
 | 
			
		||||
	       mode);
 | 
			
		||||
 | 
			
		||||
  if (fd == -1 && errno == EEXIST)
 | 
			
		||||
    {
 | 
			
		||||
      /* The file already exists */
 | 
			
		||||
      fd = handle_overwrite_open (filename, etag, create_backup, &temp_file,
 | 
			
		||||
				  cancellable, error);
 | 
			
		||||
      if (fd == -1)
 | 
			
		||||
	return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  else if (fd == -1)
 | 
			
		||||
    {
 | 
			
		||||
      int errsv = errno;
 | 
			
		||||
 | 
			
		||||
      if (errsv == EINVAL)
 | 
			
		||||
	/* This must be an invalid filename, on e.g. FAT */
 | 
			
		||||
	g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		     G_IO_ERROR_INVALID_FILENAME,
 | 
			
		||||
		     _("Invalid filename"));
 | 
			
		||||
      else
 | 
			
		||||
	g_set_error (error, G_IO_ERROR,
 | 
			
		||||
		     g_io_error_from_errno (errsv),
 | 
			
		||||
		     _("Error opening file '%s': %s"),
 | 
			
		||||
		     filename, g_strerror (errsv));
 | 
			
		||||
      return NULL;
 | 
			
		||||
    }
 | 
			
		||||
  
 | 
			
		||||
 
 | 
			
		||||
  stream = g_object_new (G_TYPE_LOCAL_FILE_OUTPUT_STREAM, NULL);
 | 
			
		||||
  stream->priv->fd = fd;
 | 
			
		||||
  stream->priv->tmp_filename = temp_file;
 | 
			
		||||
  if (create_backup)
 | 
			
		||||
    stream->priv->backup_filename = create_backup_filename (filename);
 | 
			
		||||
  stream->priv->original_filename =  g_strdup (filename);
 | 
			
		||||
  
 | 
			
		||||
  return G_FILE_OUTPUT_STREAM (stream);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										73
									
								
								gio/glocalfileoutputstream.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								gio/glocalfileoutputstream.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
			
		||||
/* GIO - GLib Input, Output and Streaming Library
 | 
			
		||||
 * 
 | 
			
		||||
 * Copyright (C) 2006-2007 Red Hat, Inc.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is free software; you can redistribute it and/or
 | 
			
		||||
 * modify it under the terms of the GNU Lesser General Public
 | 
			
		||||
 * License as published by the Free Software Foundation; either
 | 
			
		||||
 * version 2 of the License, or (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This library is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
			
		||||
 * Lesser General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU Lesser General
 | 
			
		||||
 * Public License along with this library; if not, write to the
 | 
			
		||||
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 | 
			
		||||
 * Boston, MA 02111-1307, USA.
 | 
			
		||||
 *
 | 
			
		||||
 * Author: Alexander Larsson <alexl@redhat.com>
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __G_LOCAL_FILE_OUTPUT_STREAM_H__
 | 
			
		||||
#define __G_LOCAL_FILE_OUTPUT_STREAM_H__
 | 
			
		||||
 | 
			
		||||
#include <gio/gfileoutputstream.h>
 | 
			
		||||
#include <gio/gfile.h>
 | 
			
		||||
 | 
			
		||||
G_BEGIN_DECLS
 | 
			
		||||
 | 
			
		||||
#define G_TYPE_LOCAL_FILE_OUTPUT_STREAM         (g_local_file_output_stream_get_type ())
 | 
			
		||||
#define G_LOCAL_FILE_OUTPUT_STREAM(o)           (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LOCAL_FILE_OUTPUT_STREAM, GLocalFileOutputStream))
 | 
			
		||||
#define G_LOCAL_FILE_OUTPUT_STREAM_CLASS(k)     (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LOCAL_FILE_OUTPUT_STREAM, GLocalFileOutputStreamClass))
 | 
			
		||||
#define G_IS_LOCAL_FILE_OUTPUT_STREAM(o)        (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LOCAL_FILE_OUTPUT_STREAM))
 | 
			
		||||
#define G_IS_LOCAL_FILE_OUTPUT_STREAM_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LOCAL_FILE_OUTPUT_STREAM))
 | 
			
		||||
#define G_LOCAL_FILE_OUTPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LOCAL_FILE_OUTPUT_STREAM, GLocalFileOutputStreamClass))
 | 
			
		||||
 | 
			
		||||
typedef struct _GLocalFileOutputStream         GLocalFileOutputStream;
 | 
			
		||||
typedef struct _GLocalFileOutputStreamClass    GLocalFileOutputStreamClass;
 | 
			
		||||
typedef struct _GLocalFileOutputStreamPrivate  GLocalFileOutputStreamPrivate;
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileOutputStream
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStream parent;
 | 
			
		||||
 | 
			
		||||
  /*< private >*/
 | 
			
		||||
  GLocalFileOutputStreamPrivate *priv;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct _GLocalFileOutputStreamClass
 | 
			
		||||
{
 | 
			
		||||
  GFileOutputStreamClass parent_class;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
GType g_local_file_output_stream_get_type (void) G_GNUC_CONST;
 | 
			
		||||
GFileOutputStream *g_local_file_output_stream_create  (const char       *filename,
 | 
			
		||||
						       GFileCreateFlags  flags,
 | 
			
		||||
						       GCancellable     *cancellable,
 | 
			
		||||
						       GError          **error);
 | 
			
		||||
GFileOutputStream *g_local_file_output_stream_append  (const char       *filename,
 | 
			
		||||
						       GFileCreateFlags  flags,
 | 
			
		||||
						       GCancellable     *cancellable,
 | 
			
		||||
						       GError          **error);
 | 
			
		||||
GFileOutputStream *g_local_file_output_stream_replace (const char       *filename,
 | 
			
		||||
						       const char       *etag,
 | 
			
		||||
						       gboolean          create_backup,
 | 
			
		||||
						       GFileCreateFlags  flags,
 | 
			
		||||
						       GCancellable     *cancellable,
 | 
			
		||||
						       GError          **error);
 | 
			
		||||
 | 
			
		||||
G_END_DECLS
 | 
			
		||||
 | 
			
		||||
#endif /* __G_LOCAL_FILE_OUTPUT_STREAM_H__ */
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user