2 * anjuta-document-loader.c
3 * This file is part of anjuta
5 * Copyright (C) 2005 - Paolo Maggi
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301, USA.
24 * Modified by the anjuta Team, 2005. See the AUTHORS file for a
25 * list of people on the anjuta Team.
26 * See the ChangeLog files for a list of changes.
35 #include <sys/types.h>
42 #include <glib/gi18n.h>
43 #include <glib/gstdio.h>
44 #include <libgnomevfs/gnome-vfs.h>
46 #include <libanjuta/anjuta-encodings.h>
47 #include <libanjuta/anjuta-convert.h>
49 #include "anjuta-document-loader.h"
50 #include "anjuta-marshal.h"
53 #define READ_CHUNK_SIZE 8192
55 #define ANJUTA_DOCUMENT_LOADER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
56 ANJUTA_TYPE_DOCUMENT_LOADER, \
57 AnjutaDocumentLoaderPrivate))
59 static void async_close_cb (GnomeVFSAsyncHandle
*handle
,
60 GnomeVFSResult result
,
64 struct _AnjutaDocumentLoaderPrivate
66 AnjutaDocument
*document
;
70 /* Info on the current file */
72 const AnjutaEncoding
*encoding
;
76 GnomeVFSFileInfo
*info
;
77 GnomeVFSFileSize bytes_read
;
79 /* Handle for local files */
81 gchar
*local_file_name
;
83 /* Handle for remote files */
84 GnomeVFSAsyncHandle
*handle
;
85 GnomeVFSAsyncHandle
*info_handle
;
89 const AnjutaEncoding
*auto_detected_encoding
;
94 G_DEFINE_TYPE(AnjutaDocumentLoader
, anjuta_document_loader
, G_TYPE_OBJECT
)
103 static guint signals
[LAST_SIGNAL
] = { 0 };
114 anjuta_document_loader_set_property (GObject
*object
,
119 AnjutaDocumentLoader
*dl
= ANJUTA_DOCUMENT_LOADER (object
);
124 g_return_if_fail (dl
->priv
->document
== NULL
);
125 dl
->priv
->document
= g_value_get_object (value
);
128 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
134 anjuta_document_loader_get_property (GObject
*object
,
139 AnjutaDocumentLoader
*dl
= ANJUTA_DOCUMENT_LOADER (object
);
144 g_value_set_object (value
,
148 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
154 anjuta_document_loader_finalize (GObject
*object
)
156 AnjutaDocumentLoaderPrivate
*priv
= ANJUTA_DOCUMENT_LOADER (object
)->priv
;
158 if (priv
->handle
!= NULL
)
160 if (priv
->info_handle
!= NULL
)
162 gnome_vfs_async_cancel (priv
->info_handle
);
163 gnome_vfs_async_close (priv
->info_handle
,
168 gnome_vfs_async_cancel (priv
->handle
);
169 gnome_vfs_async_close (priv
->handle
,
177 gnome_vfs_file_info_unref (priv
->info
);
180 g_free (priv
->local_file_name
);
181 g_free (priv
->buffer
);
184 gnome_vfs_uri_unref (priv
->vfs_uri
);
187 g_error_free (priv
->error
);
189 G_OBJECT_CLASS (anjuta_document_loader_parent_class
)->finalize (object
);
193 anjuta_document_loader_class_init (AnjutaDocumentLoaderClass
*klass
)
195 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
197 object_class
->finalize
= anjuta_document_loader_finalize
;
198 object_class
->get_property
= anjuta_document_loader_get_property
;
199 object_class
->set_property
= anjuta_document_loader_set_property
;
201 g_object_class_install_property (object_class
,
203 g_param_spec_object ("document",
205 "The AnjutaDocument this AnjutaDocumentLoader is associated with",
206 ANJUTA_TYPE_DOCUMENT
,
208 G_PARAM_CONSTRUCT_ONLY
));
211 g_signal_new ("loading",
212 G_OBJECT_CLASS_TYPE (object_class
),
214 G_STRUCT_OFFSET (AnjutaDocumentLoaderClass
, loading
),
216 anjuta_marshal_VOID__BOOLEAN_POINTER
,
222 g_type_class_add_private (object_class
, sizeof(AnjutaDocumentLoaderPrivate
));
226 anjuta_document_loader_init (AnjutaDocumentLoader
*loader
)
228 loader
->priv
= ANJUTA_DOCUMENT_LOADER_GET_PRIVATE (loader
);
230 loader
->priv
->used
= FALSE
;
232 loader
->priv
->fd
= -1;
234 loader
->priv
->error
= NULL
;
237 AnjutaDocumentLoader
*
238 anjuta_document_loader_new (AnjutaDocument
*doc
)
240 AnjutaDocumentLoader
*dl
;
242 g_return_val_if_fail (ANJUTA_IS_DOCUMENT (doc
), NULL
);
244 dl
= ANJUTA_DOCUMENT_LOADER (g_object_new (ANJUTA_TYPE_DOCUMENT_LOADER
,
252 insert_text_in_document (AnjutaDocumentLoader
*loader
,
256 gtk_source_buffer_begin_not_undoable_action (
257 GTK_SOURCE_BUFFER (loader
->priv
->document
));
259 /* Insert text in the buffer */
260 gtk_text_buffer_set_text (GTK_TEXT_BUFFER (loader
->priv
->document
),
264 gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (loader
->priv
->document
),
267 gtk_source_buffer_end_not_undoable_action (
268 GTK_SOURCE_BUFFER (loader
->priv
->document
));
272 update_document_contents (AnjutaDocumentLoader
*loader
,
273 const gchar
*file_contents
,
277 g_return_val_if_fail (file_size
> 0, FALSE
);
278 g_return_val_if_fail (file_contents
!= NULL
, FALSE
);
280 if (loader
->priv
->encoding
== anjuta_encoding_get_utf8 ())
282 if (g_utf8_validate (file_contents
, file_size
, NULL
))
284 insert_text_in_document (loader
,
294 G_CONVERT_ERROR_ILLEGAL_SEQUENCE
,
295 "The file you are trying to open contains an invalid byte sequence.");
302 GError
*conv_error
= NULL
;
303 gchar
*converted_text
= NULL
;
304 gsize new_len
= file_size
;
306 if (converted_text
== NULL
)
308 loader
->priv
->auto_detected_encoding
= loader
->priv
->encoding
;
310 converted_text
= anjuta_convert_to_utf8 (
313 &loader
->priv
->auto_detected_encoding
,
317 if (converted_text
== NULL
)
319 /* Last change, let's try 8859-15 */
320 loader
->priv
->auto_detected_encoding
=
321 anjuta_encoding_get_from_charset( "ISO-8859-15");
323 converted_text
= anjuta_convert_to_utf8 (
326 &loader
->priv
->auto_detected_encoding
,
331 if (converted_text
== NULL
)
333 g_return_val_if_fail (conv_error
!= NULL
, FALSE
);
335 g_propagate_error (error
, conv_error
);
341 insert_text_in_document (loader
,
345 g_free (converted_text
);
351 g_return_val_if_reached (FALSE
);
354 /* The following function has been copied from gnome-vfs
355 (modules/file-method.c) file */
357 get_access_info (GnomeVFSFileInfo
*file_info
,
358 const gchar
*full_name
)
360 /* FIXME: should check errno after calling access because we don't
361 * want to set valid_fields if something bad happened during one
362 * of the access calls
364 if (g_access (full_name
, W_OK
) == 0)
365 file_info
->permissions
|= GNOME_VFS_PERM_ACCESS_WRITABLE
;
368 * We don't need to know if a local file is readable or
369 * executable so I have commented the followig code to avoid
370 * multiple g_access calls - Paolo (Oct. 18, 2005)
374 * if (g_access (full_name, R_OK) == 0)
375 * file_info->permissions |= GNOME_VFS_PERM_ACCESS_READABLE;
378 * if (g_file_test (full_name, G_FILE_TEST_IS_EXECUTABLE))
379 * file_info->permissions |= GNOME_VFS_PERM_ACCESS_EXECUTABLE;
381 * if (g_access (full_name, X_OK) == 0)
382 * file_info->permissions |= GNOME_VFS_PERM_ACCESS_EXECUTABLE;
386 file_info
->valid_fields
|= GNOME_VFS_FILE_INFO_FIELDS_ACCESS
;
389 /* The following function has been copied from gnome-vfs
390 (gnome-vfs-module-shared.c) file */
392 stat_to_file_info (GnomeVFSFileInfo
*file_info
,
393 const struct stat
*statptr
)
395 if (S_ISDIR (statptr
->st_mode
))
396 file_info
->type
= GNOME_VFS_FILE_TYPE_DIRECTORY
;
397 else if (S_ISCHR (statptr
->st_mode
))
398 file_info
->type
= GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE
;
399 else if (S_ISBLK (statptr
->st_mode
))
400 file_info
->type
= GNOME_VFS_FILE_TYPE_BLOCK_DEVICE
;
401 else if (S_ISFIFO (statptr
->st_mode
))
402 file_info
->type
= GNOME_VFS_FILE_TYPE_FIFO
;
403 else if (S_ISSOCK (statptr
->st_mode
))
404 file_info
->type
= GNOME_VFS_FILE_TYPE_SOCKET
;
405 else if (S_ISREG (statptr
->st_mode
))
406 file_info
->type
= GNOME_VFS_FILE_TYPE_REGULAR
;
407 else if (S_ISLNK (statptr
->st_mode
))
408 file_info
->type
= GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK
;
410 file_info
->type
= GNOME_VFS_FILE_TYPE_UNKNOWN
;
412 file_info
->permissions
413 = statptr
->st_mode
& (GNOME_VFS_PERM_USER_ALL
414 | GNOME_VFS_PERM_GROUP_ALL
415 | GNOME_VFS_PERM_OTHER_ALL
416 | GNOME_VFS_PERM_SUID
417 | GNOME_VFS_PERM_SGID
418 | GNOME_VFS_PERM_STICKY
);
420 file_info
->device
= statptr
->st_dev
;
421 file_info
->inode
= statptr
->st_ino
;
423 file_info
->link_count
= statptr
->st_nlink
;
425 file_info
->uid
= statptr
->st_uid
;
426 file_info
->gid
= statptr
->st_gid
;
428 file_info
->size
= statptr
->st_size
;
429 file_info
->block_count
= statptr
->st_blocks
;
430 file_info
->io_block_size
= statptr
->st_blksize
;
431 if (file_info
->io_block_size
> 0 &&
432 file_info
->io_block_size
< 4096) {
433 /* Never use smaller block than 4k,
434 should probably be pagesize.. */
435 file_info
->io_block_size
= 4096;
438 file_info
->atime
= statptr
->st_atime
;
439 file_info
->ctime
= statptr
->st_ctime
;
440 file_info
->mtime
= statptr
->st_mtime
;
442 file_info
->valid_fields
|= GNOME_VFS_FILE_INFO_FIELDS_TYPE
|
443 GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS
| GNOME_VFS_FILE_INFO_FIELDS_FLAGS
|
444 GNOME_VFS_FILE_INFO_FIELDS_DEVICE
| GNOME_VFS_FILE_INFO_FIELDS_INODE
|
445 GNOME_VFS_FILE_INFO_FIELDS_LINK_COUNT
| GNOME_VFS_FILE_INFO_FIELDS_SIZE
|
446 GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT
| GNOME_VFS_FILE_INFO_FIELDS_IO_BLOCK_SIZE
|
447 GNOME_VFS_FILE_INFO_FIELDS_ATIME
| GNOME_VFS_FILE_INFO_FIELDS_MTIME
|
448 GNOME_VFS_FILE_INFO_FIELDS_CTIME
;
452 load_completed_or_failed (AnjutaDocumentLoader
*loader
)
455 /* the object will be unrefed in the callback of the loading
456 * signal, so we need to prevent finalization.
458 g_object_ref (loader
);
460 g_signal_emit (loader
,
463 TRUE
, /* completed */
464 loader
->priv
->error
);
466 g_object_unref (loader
);
469 /* ----------- local files ----------- */
471 #define MAX_MIME_SNIFF_SIZE 4096
474 load_local_file_real (AnjutaDocumentLoader
*loader
)
477 GnomeVFSResult result
;
480 g_return_val_if_fail (loader
->priv
->fd
!= -1, FALSE
);
482 if (fstat (loader
->priv
->fd
, &statbuf
) != 0)
484 result
= gnome_vfs_result_from_errno ();
486 g_set_error (&loader
->priv
->error
,
487 ANJUTA_DOCUMENT_ERROR
,
489 gnome_vfs_result_to_string (result
));
494 loader
->priv
->info
= gnome_vfs_file_info_new ();
495 stat_to_file_info (loader
->priv
->info
, &statbuf
);
496 GNOME_VFS_FILE_INFO_SET_LOCAL (loader
->priv
->info
, TRUE
);
497 get_access_info (loader
->priv
->info
, loader
->priv
->local_file_name
);
499 if (loader
->priv
->info
->size
== 0)
501 if (loader
->priv
->encoding
== NULL
)
502 loader
->priv
->auto_detected_encoding
= anjuta_encoding_get_current ();
504 /* guessing the mime from the filename is up to the caller */
509 const gchar
*mime_type
;
511 /* CHECK: should we lock the file */
512 mapped_file
= mmap (0, /* start */
513 loader
->priv
->info
->size
,
515 MAP_PRIVATE
, /* flags */
519 if (mapped_file
== MAP_FAILED
)
521 result
= gnome_vfs_result_from_errno ();
523 g_set_error (&loader
->priv
->error
,
524 ANJUTA_DOCUMENT_ERROR
,
526 gnome_vfs_result_to_string (result
));
531 loader
->priv
->bytes_read
= loader
->priv
->info
->size
;
533 if (!update_document_contents (loader
,
535 loader
->priv
->info
->size
,
536 &loader
->priv
->error
))
538 ret
= munmap (mapped_file
, loader
->priv
->info
->size
);
540 g_warning ("File '%s' has not been correctly unmapped: %s",
547 mime_type
= gnome_vfs_get_mime_type_for_name(loader
->priv
->local_file_name
);
548 if (mime_type
== NULL
)
549 mime_type
= gnome_vfs_get_mime_type_for_data(mapped_file
,
550 MIN (loader
->priv
->bytes_read
, MAX_MIME_SNIFF_SIZE
));
552 if ((mime_type
!= NULL
) &&
553 strcmp (mime_type
, GNOME_VFS_MIME_TYPE_UNKNOWN
) != 0)
555 loader
->priv
->info
->mime_type
= g_strdup (mime_type
);
556 loader
->priv
->info
->valid_fields
|= GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
;
559 ret
= munmap (mapped_file
, loader
->priv
->info
->size
);
562 g_warning ("File '%s' has not been correctly unmapped: %s",
567 ret
= close (loader
->priv
->fd
);
570 g_warning ("File '%s' has not been correctly closed: %s",
574 loader
->priv
->fd
= -1;
577 load_completed_or_failed (loader
);
583 open_local_failed (AnjutaDocumentLoader
*loader
)
585 load_completed_or_failed (loader
);
587 /* stop the timeout */
592 load_local_file (AnjutaDocumentLoader
*loader
,
595 g_signal_emit (loader
,
601 loader
->priv
->fd
= open (fname
, O_RDONLY
);
602 if (loader
->priv
->fd
== -1)
604 GnomeVFSResult result
= gnome_vfs_result_from_errno ();
606 g_set_error (&loader
->priv
->error
,
607 ANJUTA_DOCUMENT_ERROR
,
609 gnome_vfs_result_to_string (result
));
611 g_timeout_add_full (G_PRIORITY_HIGH
,
613 (GSourceFunc
) open_local_failed
,
620 g_free (loader
->priv
->local_file_name
);
621 loader
->priv
->local_file_name
= g_strdup (fname
);
623 g_timeout_add_full (G_PRIORITY_HIGH
,
625 (GSourceFunc
) load_local_file_real
,
630 /* ----------- remote files ----------- */
633 async_close_cb (GnomeVFSAsyncHandle
*handle
,
634 GnomeVFSResult result
,
637 /* nothing to do... no point in reporting an error */
641 remote_load_completed_or_failed (AnjutaDocumentLoader
*loader
)
644 /* free the buffer and close the handle */
645 gnome_vfs_async_close (loader
->priv
->handle
,
649 loader
->priv
->handle
= NULL
;
651 g_free (loader
->priv
->buffer
);
652 loader
->priv
->buffer
= NULL
;
654 load_completed_or_failed (loader
);
657 /* prototype, because they call each other... isn't C lovely */
658 static void read_file_chunk (AnjutaDocumentLoader
*loader
);
661 async_read_cb (GnomeVFSAsyncHandle
*handle
,
662 GnomeVFSResult result
,
664 GnomeVFSFileSize bytes_requested
,
665 GnomeVFSFileSize bytes_read
,
668 AnjutaDocumentLoader
*loader
= ANJUTA_DOCUMENT_LOADER (data
);
670 /* reality checks. */
671 g_return_if_fail (bytes_requested
== READ_CHUNK_SIZE
);
672 g_return_if_fail (loader
->priv
->handle
== handle
);
673 g_return_if_fail (loader
->priv
->buffer
+ loader
->priv
->bytes_read
== buffer
);
674 g_return_if_fail (bytes_read
<= bytes_requested
);
677 if (result
!= GNOME_VFS_OK
&& result
!= GNOME_VFS_ERROR_EOF
)
679 g_set_error (&loader
->priv
->error
,
680 ANJUTA_DOCUMENT_ERROR
,
682 gnome_vfs_result_to_string (result
));
684 remote_load_completed_or_failed (loader
);
689 /* Check for the extremely unlikely case where the file size overflows. */
690 if (loader
->priv
->bytes_read
+ bytes_read
< loader
->priv
->bytes_read
)
692 g_set_error (&loader
->priv
->error
,
693 ANJUTA_DOCUMENT_ERROR
,
694 GNOME_VFS_ERROR_TOO_BIG
,
695 gnome_vfs_result_to_string (GNOME_VFS_ERROR_TOO_BIG
));
697 remote_load_completed_or_failed (loader
);
703 loader
->priv
->bytes_read
+= bytes_read
;
705 /* end of the file, we are done! */
706 if (bytes_read
== 0 || result
!= GNOME_VFS_OK
)
708 update_document_contents (loader
,
709 loader
->priv
->buffer
,
710 loader
->priv
->bytes_read
,
711 &loader
->priv
->error
);
713 remote_load_completed_or_failed (loader
);
718 /* otherwise emit progress and read some more */
720 /* note that this signal blocks the read... check if it isn't
721 * a performance problem
723 g_signal_emit (loader
,
729 read_file_chunk (loader
);
733 read_file_chunk (AnjutaDocumentLoader
*loader
)
735 loader
->priv
->buffer
= g_realloc (loader
->priv
->buffer
,
736 loader
->priv
->bytes_read
+ READ_CHUNK_SIZE
);
738 gnome_vfs_async_read (loader
->priv
->handle
,
739 loader
->priv
->buffer
+ loader
->priv
->bytes_read
,
746 remote_get_info_cb (GnomeVFSAsyncHandle
*handle
,
750 AnjutaDocumentLoader
*loader
= ANJUTA_DOCUMENT_LOADER (data
);
751 GnomeVFSGetFileInfoResult
*info_result
;
753 /* assert that the list has one and only one item */
754 g_return_if_fail (results
!= NULL
&& results
->next
== NULL
);
756 loader
->priv
->info_handle
= NULL
;
758 info_result
= (GnomeVFSGetFileInfoResult
*) results
->data
;
759 g_return_if_fail (info_result
!= NULL
);
761 if (info_result
->result
!= GNOME_VFS_OK
)
763 g_set_error (&loader
->priv
->error
,
764 ANJUTA_DOCUMENT_ERROR
,
766 gnome_vfs_result_to_string (info_result
->result
));
768 remote_load_completed_or_failed (loader
);
773 /* CHECK: ref is necessary, right? or the info will go away... */
774 loader
->priv
->info
= info_result
->file_info
;
775 gnome_vfs_file_info_ref (loader
->priv
->info
);
777 /* if it's not a regular file, error out... */
778 if (info_result
->file_info
->type
!= GNOME_VFS_FILE_TYPE_REGULAR
)
780 g_set_error (&loader
->priv
->error
,
781 ANJUTA_DOCUMENT_ERROR
,
782 GNOME_VFS_ERROR_GENERIC
, // FIXME
783 gnome_vfs_result_to_string (GNOME_VFS_ERROR_GENERIC
));
785 remote_load_completed_or_failed (loader
);
791 read_file_chunk (loader
);
795 async_open_callback (GnomeVFSAsyncHandle
*handle
,
796 GnomeVFSResult result
,
797 AnjutaDocumentLoader
*loader
)
799 GList
*uri_list
= NULL
;
801 g_return_if_fail (loader
->priv
->handle
== handle
);
803 if (result
!= GNOME_VFS_OK
)
805 g_set_error (&loader
->priv
->error
,
806 ANJUTA_DOCUMENT_ERROR
,
808 gnome_vfs_result_to_string (result
));
810 /* in this case we don't need to close the handle */
811 load_completed_or_failed (loader
);
816 /* get the file info after open to avoid races... this really
817 * should be async_get_file_info_from_handle (fstat equivalent)
818 * but gnome-vfs lacks that.
821 uri_list
= g_list_prepend (uri_list
, loader
->priv
->vfs_uri
);
823 gnome_vfs_async_get_file_info (&loader
->priv
->info_handle
,
825 GNOME_VFS_FILE_INFO_DEFAULT
|
826 GNOME_VFS_FILE_INFO_GET_MIME_TYPE
|
827 GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE
|
828 GNOME_VFS_FILE_INFO_FOLLOW_LINKS
,
829 GNOME_VFS_PRIORITY_MAX
,
833 g_list_free (uri_list
);
837 load_remote_file (AnjutaDocumentLoader
*loader
)
839 g_return_if_fail (loader
->priv
->handle
== NULL
);
842 g_signal_emit (loader
,
848 gnome_vfs_async_open_uri (&loader
->priv
->handle
,
849 loader
->priv
->vfs_uri
,
851 GNOME_VFS_PRIORITY_MAX
,
852 (GnomeVFSAsyncOpenCallback
) async_open_callback
,
856 /* ---------- public api ---------- */
859 vfs_uri_new_failed (AnjutaDocumentLoader
*loader
)
861 load_completed_or_failed (loader
);
863 /* stop the timeout */
867 /* If enconding == NULL, the encoding will be autodetected */
869 anjuta_document_loader_load (AnjutaDocumentLoader
*loader
,
871 const AnjutaEncoding
*encoding
)
875 g_return_if_fail (ANJUTA_IS_DOCUMENT_LOADER (loader
));
876 g_return_if_fail (uri
!= NULL
);
878 /* the loader can be used just once, then it must be thrown away */
879 g_return_if_fail (loader
->priv
->used
== FALSE
);
880 loader
->priv
->used
= TRUE
;
882 /* vfs_uri may be NULL for some valid but unsupported uris */
883 loader
->priv
->vfs_uri
= gnome_vfs_uri_new (uri
);
884 if (loader
->priv
->vfs_uri
== NULL
)
886 g_set_error (&loader
->priv
->error
,
887 ANJUTA_DOCUMENT_ERROR
,
888 GNOME_VFS_ERROR_NOT_SUPPORTED
,
889 gnome_vfs_result_to_string (GNOME_VFS_ERROR_NOT_SUPPORTED
));
891 g_timeout_add_full (G_PRIORITY_HIGH
,
893 (GSourceFunc
) vfs_uri_new_failed
,
900 loader
->priv
->encoding
= encoding
;
902 loader
->priv
->uri
= g_strdup (uri
);
904 local_path
= gnome_vfs_get_local_path_from_uri (uri
);
905 if (local_path
!= NULL
)
907 load_local_file (loader
, local_path
);
912 load_remote_file (loader
);
916 /* Returns STDIN_URI if loading from stdin */
918 anjuta_document_loader_get_uri (AnjutaDocumentLoader
*loader
)
920 g_return_val_if_fail (ANJUTA_IS_DOCUMENT_LOADER (loader
), NULL
);
922 return loader
->priv
->uri
;
925 /* it may return NULL, it's up to anjuta-document handle it */
927 anjuta_document_loader_get_mime_type (AnjutaDocumentLoader
*loader
)
929 g_return_val_if_fail (ANJUTA_IS_DOCUMENT_LOADER (loader
), NULL
);
931 if (loader
->priv
->info
&&
932 (loader
->priv
->info
->valid_fields
& GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE
))
933 return loader
->priv
->info
->mime_type
;
939 anjuta_document_loader_get_mtime (AnjutaDocumentLoader
*loader
)
941 g_return_val_if_fail (ANJUTA_IS_DOCUMENT_LOADER (loader
), 0);
943 if (loader
->priv
->info
&&
944 (loader
->priv
->info
->valid_fields
& GNOME_VFS_FILE_INFO_FIELDS_MTIME
))
945 return loader
->priv
->info
->mtime
;
950 /* Returns 0 if file size is unknown */
952 anjuta_document_loader_get_file_size (AnjutaDocumentLoader
*loader
)
954 g_return_val_if_fail (ANJUTA_IS_DOCUMENT_LOADER (loader
), 0);
956 if (loader
->priv
->info
== NULL
)
959 return loader
->priv
->info
->size
;
963 anjuta_document_loader_get_bytes_read (AnjutaDocumentLoader
*loader
)
965 g_return_val_if_fail (ANJUTA_IS_DOCUMENT_LOADER (loader
), 0);
967 return loader
->priv
->bytes_read
;
971 anjuta_document_loader_cancel (AnjutaDocumentLoader
*loader
)
974 g_return_val_if_fail (ANJUTA_IS_DOCUMENT_LOADER (loader
), FALSE
);
976 if (loader
->priv
->handle
== NULL
)
979 if (loader
->priv
->info_handle
!= NULL
)
981 gnome_vfs_async_cancel (loader
->priv
->info_handle
);
982 gnome_vfs_async_close (loader
->priv
->info_handle
,
987 gnome_vfs_async_cancel (loader
->priv
->handle
);
989 g_set_error (&loader
->priv
->error
,
990 ANJUTA_DOCUMENT_ERROR
,
991 GNOME_VFS_ERROR_CANCELLED
,
992 gnome_vfs_result_to_string (GNOME_VFS_ERROR_CANCELLED
));
994 remote_load_completed_or_failed (loader
);
999 /* In the case the loader does not know if the file is readonly, for example
1000 for most remote files, the function returns FALSE, so that we can try writing
1001 and if needed handle the error. */
1003 anjuta_document_loader_get_readonly (AnjutaDocumentLoader
*loader
)
1005 g_return_val_if_fail (ANJUTA_IS_DOCUMENT_LOADER (loader
), FALSE
);
1007 if (loader
->priv
->info
&&
1008 (loader
->priv
->info
->valid_fields
& GNOME_VFS_FILE_INFO_FIELDS_ACCESS
))
1009 return (loader
->priv
->info
->permissions
& GNOME_VFS_PERM_ACCESS_WRITABLE
) ? FALSE
: TRUE
;
1014 const AnjutaEncoding
*
1015 anjuta_document_loader_get_encoding (AnjutaDocumentLoader
*loader
)
1017 g_return_val_if_fail (ANJUTA_IS_DOCUMENT_LOADER (loader
), NULL
);
1019 if (loader
->priv
->encoding
!= NULL
)
1020 return loader
->priv
->encoding
;
1022 if (loader
->priv
->auto_detected_encoding
== NULL
)
1024 return anjuta_encoding_get_current ();
1027 return loader
->priv
->auto_detected_encoding
;