<h3>Comment combiner GnomeVFS et libxml pour lire et écrire des fichiers XML sur des serveurs distants.</h3>
<p class="spip"><strong class="spip">Première étape, permettre l’authentification de l’utilisateur si nécessaire :</strong></p>

<p class="spip">Il faut en tout premier initaliser GnomeVFS, puis le gestionnaire d’authentification.</p>

<div style='text-align: left;' class='spip_code' dir='ltr'><code><br />
gnome_vfs_init ();<br />
gnome_authentication_manager_init ();<br />
</code></div>
<p class="spip">Cet appel n’est nécessaire que si le serveur distant nécessite une authentification. Dans le doute, il l’est. La fonction est implémentée dans libgnomeui et donc cette bibliothèque est nécessaire.
Remarque : si le premier accès se fait à travers la boite de dialogue GtkFileChooserDialog, cet appel n’est pas nécessaire, et si on veut éviter l’utilisation de libgnomeui, on peut toujours écire une fonction équivalente.</p>

<p class="spip"><strong class="spip">Deuxième étape, lire le fichier pour obtenir une structure xmlDoc :</strong></p>

<div style='text-align: left;' class='spip_code' dir='ltr'><code><br />
GnomeVFSHandle *handle;<br />
xmlDocPtr xml;<br />
GnomeVFSResult result = gnome_vfs_open (&handle, filename, GNOME_VFS_OPEN_READ);<br />
if (result != GNOME_VFS_OK) {<br />
        /* traiter l'erreur, par exemple en émettant un message et en retournant un code d'erreur */<br />
}<br />
if (!(xml = xmlReadIO ((xmlInputReadCallback) cb_vfs_to_xml, <br />
                                 (xmlInputCloseCallback) gnome_vfs_close, handle, filename, NULL, 0))) {<br />
        /* traiter l'erreur de lecture */<br />
}<br />
</code></div>
<p class="spip">La fonction cb_vfs_to_xml est nécessaire car gnome_vfs_write n’a pas les mêmes arguments que xmlInputCloseCallback. Son code source est :</p>

<div style='text-align: left;' class='spip_code' dir='ltr'><code><br />
static int        cb_vfs_to_xml (GnomeVFSHandle *handle, char* buf, int nb)<br />
{<br />
        GnomeVFSFileSize ndone;<br />
        return  (gnome_vfs_read (handle, buf, nb, &ndone) == GNOME_VFS_OK)? (int) ndone: -1;<br />
}<br />
</code></div>
<p class="spip"><strong class="spip">De même, pour écrire un fichier :</strong></p>

<div style='text-align: left;' class='spip_code' dir='ltr'><code><br />
xmlDocPtr xml;<br />
/* Ici, construire l'arbre ... */<br />
<br />
xmlOutputBufferPtr buf = xmlAllocOutputBuffer (NULL);<br />
GnomeVFSHandle *handle;<br />
int n;<br />
GnomeVFSResult result = gnome_vfs_open (&handle, filename, GNOME_VFS_OPEN_WRITE);<br />
if (result == GNOME_VFS_ERROR_NOT_FOUND)<br />
        result = gnome_vfs_create (&handle, filename, GNOME_VFS_OPEN_WRITE, true, 0644); /* on peut utiliser un autre droit d'accès, mais ils ne sont utilisés que si le serveur l'autorise */<br />
if (result != GNOME_VFS_OK) {<br />
        /* traiter l'erreur, par exemple en émettant un message et en retournant un code d'erreur */<br />
}<br />
buf->context = handle;<br />
buf->closecallback = (xmlOutputCloseCallback) gnome_vfs_close;<br />
buf->writecallback = (xmlOutputWriteCallback) cb_xml_to_vfs;<br />
int n = xmlSaveFormatFileTo (buf, xml, NULL, true);<br />
</code></div>
<p class="spip">De la même façon que pour la lecture, on a besoin d’une fonction utilitaire, appelée ici cb_xml_to_vfs. Son code est :</p>

<div style='text-align: left;' class='spip_code' dir='ltr'><code><br />
static int        cb_xml_to_vfs (GnomeVFSHandle *handle, const char* buf, int nb)<br />
{<br />
        GnomeVFSFileSize ndone;<br />
        return (int) gnome_vfs_write (handle, buf, nb, &ndone);<br />
}<br />
</code></div>