source: trunk/third/gnome-vfs/libgnomevfs/gnome-vfs-mime-sniff-buffer.c @ 17128

Revision 17128, 4.8 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r17127, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3/*
4 * gnome-vfs-mime-sniff-buffer.c
5 * Utility for implementing gnome_vfs_mime_type_from_magic, and other
6 * mime-type sniffing calls.
7 *
8 * Copyright (C) 2000 Eazel, Inc.
9 * All rights reserved.
10 *
11 * This file is part of the Gnome Library.
12 *
13 * The Gnome Library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Library General Public License as
15 * published by the Free Software Foundation; either version 2 of the
16 * License, or (at your option) any later version.
17 *
18 * The Gnome Library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 * Library General Public License for more details.
22 *
23 * You should have received a copy of the GNU Library General Public
24 * License along with the Gnome Library; see the file COPYING.LIB.  If not,
25 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26 * Boston, MA 02111-1307, USA.
27 */
28
29#include <config.h>
30#include "gnome-vfs-mime-sniff-buffer.h"
31
32#include "gnome-vfs-handle.h"
33#include "gnome-vfs-mime-sniff-buffer-private.h"
34#include "gnome-vfs-ops.h"
35#include <string.h>
36
37static GnomeVFSResult
38handle_seek_glue (gpointer context, GnomeVFSSeekPosition whence,
39        GnomeVFSFileOffset offset)
40{
41        GnomeVFSHandle *handle = (GnomeVFSHandle *)context;
42        return gnome_vfs_seek (handle, whence, offset);
43}
44
45static GnomeVFSResult
46handle_read_glue (gpointer context, gpointer buffer,
47        GnomeVFSFileSize bytes, GnomeVFSFileSize *bytes_read)
48{
49        GnomeVFSHandle *handle = (GnomeVFSHandle *)context;
50        return gnome_vfs_read (handle, buffer, bytes, bytes_read);
51}
52
53GnomeVFSMimeSniffBuffer *
54gnome_vfs_mime_sniff_buffer_new_from_handle (GnomeVFSHandle *file)
55{
56        GnomeVFSMimeSniffBuffer *result;
57
58        result = g_new0 (GnomeVFSMimeSniffBuffer, 1);
59        result->owning = TRUE;
60        result->context = file;
61        result->seek = handle_seek_glue;
62        result->read = handle_read_glue;
63
64        return result;
65}
66
67GnomeVFSMimeSniffBuffer *
68gnome_vfs_mime_sniff_buffer_new_generic (GnomeVFSSniffBufferSeekCall seek_callback,
69                                         GnomeVFSSniffBufferReadCall read_callback,
70                                         gpointer context)
71{
72        GnomeVFSMimeSniffBuffer * result;
73       
74        result = g_new0 (GnomeVFSMimeSniffBuffer, 1);
75
76        result->owning = TRUE;
77        result->seek = seek_callback;
78        result->read = read_callback;
79        result->context = context;
80
81        return result;
82}
83
84GnomeVFSMimeSniffBuffer *
85gnome_vfs_mime_sniff_buffer_new_from_memory (const guchar *buffer,
86                                             gssize buffer_length)
87{
88        GnomeVFSMimeSniffBuffer *result;
89
90        result = g_new0 (GnomeVFSMimeSniffBuffer, 1);
91        result->owning = TRUE;
92        result->buffer = g_malloc (buffer_length);
93        result->buffer_length = buffer_length;
94        memcpy (result->buffer, buffer, buffer_length);
95        result->read_whole_file = TRUE;
96
97        return result;
98}
99
100GnomeVFSMimeSniffBuffer *
101gnome_vfs_mime_sniff_buffer_new_from_existing_data (const guchar *buffer,
102                                                    gssize buffer_length)
103{
104        GnomeVFSMimeSniffBuffer *result;
105
106        result = g_new0 (GnomeVFSMimeSniffBuffer, 1);
107        result->owning = FALSE;
108        result->buffer = (guchar *)buffer;
109        result->buffer_length = buffer_length;
110        result->read_whole_file = TRUE;
111
112        return result;
113}
114
115void
116gnome_vfs_mime_sniff_buffer_free (GnomeVFSMimeSniffBuffer *buffer)
117{
118        if (buffer->owning)
119                g_free (buffer->buffer);
120        g_free (buffer);
121}
122
123enum {
124        GNOME_VFS_SNIFF_BUFFER_INITIAL_CHUNK = 256,
125        GNOME_VFS_SNIFF_BUFFER_MIN_CHUNK = 128
126};
127
128GnomeVFSResult
129gnome_vfs_mime_sniff_buffer_get (GnomeVFSMimeSniffBuffer *buffer,
130                                 gssize size)
131{
132        GnomeVFSResult result;
133        GnomeVFSFileSize bytes_to_read, bytes_read;
134
135        /* check to see if we already have enough data */
136        if (buffer->buffer_length >= size) {
137                return GNOME_VFS_OK;
138        }
139
140        /* if we've read the whole file, don't try to read any more */
141        if (buffer->read_whole_file) {
142                return GNOME_VFS_ERROR_EOF;
143        }
144
145        /* figure out how much to read */
146        bytes_to_read = size - buffer->buffer_length;
147
148        /* don't bother to read less than this */
149        if (bytes_to_read < GNOME_VFS_SNIFF_BUFFER_MIN_CHUNK) {
150                bytes_to_read = GNOME_VFS_SNIFF_BUFFER_MIN_CHUNK;
151        }
152
153        /* make room in buffer for new data */
154        buffer->buffer = g_realloc (buffer->buffer,
155                                    buffer->buffer_length + bytes_to_read);
156
157        /* read in more data */
158        result = (* buffer->read) (buffer->context,
159                                   buffer->buffer + buffer->buffer_length,
160                                   bytes_to_read,
161                                   &bytes_read);
162        if (result == GNOME_VFS_ERROR_EOF) {
163                /* only happens with 0-byte files, due to other logic */
164                buffer->read_whole_file = TRUE;
165        }
166        if (result != GNOME_VFS_OK) {
167                return result;
168        }
169        if (bytes_read < bytes_to_read) {
170                buffer->read_whole_file = TRUE;
171        }
172        buffer->buffer_length += bytes_read;
173
174        /* check to see if we have enough data */
175        if (buffer->buffer_length >= size) {
176                return GNOME_VFS_OK;
177        }
178
179        /* not enough data */
180        return GNOME_VFS_ERROR_EOF;
181}
Note: See TracBrowser for help on using the repository browser.