Changeset 3454

Show
Ignore:
Timestamp:
03/04/08 12:53:34
Author:
pvanhoof
Message:

2008-03-04 Philip Van Hoof <pvanhoof@gnome.org>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ChangeLog

    r3453 r3454  
     12008-03-04  Philip Van Hoof <pvanhoof@gnome.org> 
     2 
     3        * Introduction of TnySeekable 
     4 
    152008-03-03  Philip Van Hoof <pvanhoof@gnome.org> 
    26 
  • trunk/libtinymail-camel/tny-camel-stream.c

    r3304 r3454  
    129129} 
    130130 
     131static off_t  
     132tny_camel_stream_seek (TnySeekable *self, off_t offset, int policy) 
     133{ 
     134        TnyCamelStreamPriv *priv = TNY_CAMEL_STREAM_GET_PRIVATE (self); 
     135        if (CAMEL_IS_SEEKABLE_STREAM (priv->stream)) 
     136                return camel_seekable_stream_seek ((CamelSeekableStream *) priv->stream, offset, (CamelStreamSeekPolicy) policy); 
     137        return -1; 
     138} 
     139 
     140 
     141static off_t 
     142tny_camel_stream_tell (TnySeekable *self) 
     143{ 
     144        TnyCamelStreamPriv *priv = TNY_CAMEL_STREAM_GET_PRIVATE (self); 
     145        if (CAMEL_IS_SEEKABLE_STREAM (priv->stream)) 
     146                return camel_seekable_stream_tell ((CamelSeekableStream *) priv->stream); 
     147        return -1; 
     148} 
     149 
     150static gint  
     151tny_camel_stream_set_bounds (TnySeekable *self, off_t start, off_t end) 
     152{ 
     153        TnyCamelStreamPriv *priv = TNY_CAMEL_STREAM_GET_PRIVATE (self); 
     154        if (CAMEL_IS_SEEKABLE_STREAM (priv->stream)) 
     155                return camel_seekable_stream_set_bounds ((CamelSeekableStream *) priv->stream, start, end); 
     156        return -1; 
     157} 
     158 
    131159 
    132160/** 
     
    144172 
    145173        if (priv->stream) 
    146                 camel_object_ref (CAMEL_OBJECT (priv->stream)); 
     174                camel_object_ref (priv->stream); 
    147175 
    148176        return priv->stream; 
     
    186214tny_camel_stream_finalize (GObject *object) 
    187215{ 
    188         TnyCamelStream *self = (TnyCamelStream *)object;        
    189         TnyCamelStreamPriv *priv = TNY_CAMEL_STREAM_GET_PRIVATE (self); 
    190  
    191         if (G_LIKELY (priv->stream)
    192                 camel_object_unref (CAMEL_OBJECT (priv->stream)); 
     216        TnyCamelStream *self = (TnyCamelStream *)object; 
     217        TnyCamelStreamPriv *priv = TNY_CAMEL_STREAM_GET_PRIVATE (self); 
     218 
     219        if (priv->stream
     220                camel_object_unref (priv->stream); 
    193221 
    194222        (*parent_class->finalize) (object); 
     
    209237        klass->reset= tny_camel_stream_reset; 
    210238        klass->write_to_stream= tny_camel_stream_write_to_stream; 
     239 
     240        return; 
     241} 
     242 
     243 
     244 
     245static void 
     246tny_seekable_init (gpointer g, gpointer iface_data) 
     247{ 
     248        TnySeekableIface *klass = (TnySeekableIface *)g; 
     249 
     250        klass->seek= tny_camel_stream_seek; 
     251        klass->tell= tny_camel_stream_tell; 
     252        klass->set_bounds= tny_camel_stream_set_bounds; 
    211253 
    212254        return; 
     
    271313                }; 
    272314 
     315                static const GInterfaceInfo tny_seekable_info =  
     316                { 
     317                  (GInterfaceInitFunc) tny_seekable_init, /* interface_init */ 
     318                  NULL,         /* interface_finalize */ 
     319                  NULL          /* interface_data */ 
     320                }; 
     321 
    273322                type = g_type_register_static (G_TYPE_OBJECT, 
    274323                        "TnyCamelStream", 
     
    277326                g_type_add_interface_static (type, TNY_TYPE_STREAM,  
    278327                        &tny_stream_info); 
     328 
     329                g_type_add_interface_static (type, TNY_TYPE_SEEKABLE,  
     330                        &tny_seekable_info); 
     331 
    279332        } 
    280333 
  • trunk/libtinymail-camel/tny-camel-stream.h

    r2825 r3454  
    2424#include <glib-object.h> 
    2525#include <tny-stream.h> 
     26#include <tny-seekable.h> 
    2627 
    2728#include <camel/camel-stream.h> 
  • trunk/libtinymail-camel/tny-stream-camel.c

    r2825 r3454  
    2121 
    2222#include <tny-stream-camel.h> 
     23#include <tny-camel-stream.h> 
    2324#include <tny-camel-shared.h> 
    2425 
     
    113114} 
    114115 
     116 
     117static off_t  
     118tny_stream_camel_seek (CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy) 
     119{ 
     120        TnyStreamCamel *self = (TnyStreamCamel *)stream; 
     121        off_t retval = -1; 
     122 
     123        if (TNY_IS_SEEKABLE (self->stream)) 
     124                retval = tny_seekable_seek ((TnySeekable *) self->stream, offset, (int) policy); 
     125 
     126        return retval; 
     127} 
     128 
     129static off_t  
     130tny_stream_camel_tell (CamelSeekableStream *stream) 
     131{ 
     132        TnyStreamCamel *self = (TnyStreamCamel *)stream; 
     133        off_t retval = -1; 
     134 
     135        if (TNY_IS_SEEKABLE (self->stream)) 
     136                retval = tny_seekable_tell ((TnySeekable *) self->stream); 
     137 
     138        return retval; 
     139} 
     140 
     141int  
     142tny_stream_camel_set_bouds (CamelSeekableStream *stream, off_t start, off_t end) 
     143{ 
     144        TnyStreamCamel *self = (TnyStreamCamel *)stream; 
     145        int retval = -1; 
     146 
     147        if (TNY_IS_SEEKABLE (self->stream)) 
     148                retval = tny_seekable_set_bounds ((TnySeekable *) self->stream, start, end); 
     149 
     150        return retval; 
     151} 
     152 
    115153static void 
    116154tny_stream_camel_init (CamelObject *object) 
     
    127165        TnyStreamCamel *self = (TnyStreamCamel *)object; 
    128166 
    129         if (G_LIKELY (self->stream)) 
    130                 g_object_unref (G_OBJECT (self->stream)); 
    131  
    132         /* CamelObject types don't need parent finalization (build-in camel) 
    133         (*((CamelObjectClass*)parent_class)->finalise) (object); */ 
    134  
    135         return; 
    136 
     167        if (self->stream) 
     168                g_object_unref (self->stream); 
     169 
     170        return; 
     171
     172 
    137173 
    138174static void 
     
    145181        ((CamelStreamClass *)klass)->reset = tny_stream_camel_reset; 
    146182        ((CamelStreamClass *)klass)->flush = tny_stream_camel_flush; 
     183 
     184 
     185        ((CamelSeekableStreamClass *)klass)->seek = tny_stream_camel_seek; 
     186        ((CamelSeekableStreamClass *)klass)->tell = tny_stream_camel_tell; 
     187        ((CamelSeekableStreamClass *)klass)->set_bounds = tny_stream_camel_set_bouds; 
    147188 
    148189        return; 
  • trunk/libtinymail-camel/tny-stream-camel.h

    r2825 r3454  
    2424#include <glib-object.h> 
    2525#include <tny-stream.h> 
     26#include <tny-seekable.h> 
    2627 
    2728#include <camel/camel-seekable-stream.h> 
     29#include <camel/camel-seekable-substream.h> 
    2830 
    2931G_BEGIN_DECLS 
     
    4143struct _TnyStreamCamel 
    4244{ 
    43         CamelStream parent; 
     45        CamelSeekableSubstream parent; 
    4446 
    4547        TnyStream *stream; 
     
    4850struct _TnyStreamCamelClass  
    4951{ 
    50         CamelStreamClass parent; 
     52        CamelSeekableSubstreamClass parent; 
    5153}; 
    5254 
  • trunk/libtinymail-gnomevfs/tny-vfs-stream.c

    r3399 r3454  
    2424#include <errno.h> 
    2525 
    26 #include <tny-stream.h> 
    2726#include <tny-vfs-stream.h> 
    2827 
     
    3534        GnomeVFSHandle *handle; 
    3635        gboolean eos; 
     36        off_t position;         /* current postion in the stream */ 
     37        off_t bound_start;      /* first valid position */ 
     38        off_t bound_end;        /* first invalid position */ 
    3739}; 
    3840 
     
    166168{ 
    167169        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
    168         GnomeVFSFileSize count; 
     170        GnomeVFSFileSize nread = 0; 
     171        GnomeVFSResult result; 
     172 
     173        if (priv->bound_end != (~0)) 
     174                n = MIN (priv->bound_end - priv->position, n); 
     175 
     176        result = gnome_vfs_read (priv->handle, buffer, n, &nread); 
     177 
     178        if (nread > 0 && result == GNOME_VFS_OK) 
     179                priv->position += nread; 
     180        else {  
     181                if (nread == 0) 
     182                        priv->eos = TRUE; 
     183                tny_vfs_stream_set_errno (result); 
     184        } 
     185 
     186        return nread; 
     187
     188 
     189static gssize 
     190tny_vfs_stream_write (TnyStream *self, const char *buffer, gsize n) 
     191
     192        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     193        GnomeVFSFileSize nwritten = 0; 
     194        GnomeVFSResult result; 
     195 
     196        if (priv->bound_end != (~0)) 
     197                n = MIN (priv->bound_end - priv->position, n); 
     198 
     199        result = gnome_vfs_write (priv->handle, buffer, n, &nwritten); 
     200 
     201        if (nwritten > 0 && result == GNOME_VFS_OK) 
     202                priv->position += nwritten; 
     203        else  
     204                tny_vfs_stream_set_errno (result); 
     205 
     206        return nwritten; 
     207
     208 
     209static gint 
     210tny_vfs_stream_close (TnyStream *self) 
     211
     212        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
    169213        GnomeVFSResult res; 
    170214 
    171         if (G_UNLIKELY (priv->handle == NULL)) 
    172         { 
     215        if (priv->handle == NULL)  { 
    173216                errno = EINVAL; 
    174217                return -1; 
    175218        } 
    176219 
    177         res = gnome_vfs_read (priv->handle, buffer, n, &count); 
    178  
    179         if (G_LIKELY (res == GNOME_VFS_OK)) 
    180         { 
    181                 gchar buf[1]; GnomeVFSResult res2; 
    182                 GnomeVFSFileSize curpos, cnt; 
    183                 gnome_vfs_tell (priv->handle, &curpos); 
    184                 res2 = gnome_vfs_read (priv->handle, buf, 1, &cnt); 
    185                 if (res2 == GNOME_VFS_ERROR_EOF) 
    186                         priv->eos = TRUE; 
    187                 else priv->eos = FALSE; 
    188                 gnome_vfs_seek (priv->handle, GNOME_VFS_SEEK_START, curpos); 
    189              
    190                 return (ssize_t)count; 
    191  
    192         } else if (G_LIKELY (res == GNOME_VFS_ERROR_EOF)) 
    193         { 
    194                 priv->eos = TRUE; 
    195                 return (ssize_t)count; 
    196         } 
     220        res = gnome_vfs_close (priv->handle); 
     221 
     222        priv->handle = NULL; 
     223        priv->eos = TRUE; 
     224 
     225        if (res == GNOME_VFS_OK) 
     226                return 0; 
    197227 
    198228        tny_vfs_stream_set_errno (res); 
     
    201231} 
    202232 
    203 static gssize 
    204 tny_vfs_stream_write (TnyStream *self, const char *buffer, gsize n) 
    205 
    206         TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
    207         GnomeVFSFileSize count; 
    208         GnomeVFSResult res; 
    209  
    210         if (G_UNLIKELY (priv->handle == NULL)) 
    211         { 
    212                 errno = EINVAL; 
    213                 return -1; 
    214         } 
    215  
    216         res = gnome_vfs_write (priv->handle, buffer, n, &count); 
    217         priv->eos = FALSE; 
    218         if (G_LIKELY (res == GNOME_VFS_OK)) 
    219                 return (ssize_t)count; 
    220  
    221         tny_vfs_stream_set_errno (res); 
    222  
    223         return -1; 
    224  
    225 
    226  
    227 static gint 
    228 tny_vfs_stream_close (TnyStream *self) 
    229 
    230         TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     233 
     234/** 
     235 * tny_vfs_stream_set_handle: 
     236 * @self: A #TnyVfsStream instance 
     237 * @handle: The #GnomeVFSHandle to write to or read from 
     238 * 
     239 * Set the #GnomeVFSHandle to play adaptor for 
     240 * 
     241 **/ 
     242void 
     243tny_vfs_stream_set_handle (TnyVfsStream *self, GnomeVFSHandle *handle) 
     244
     245        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     246 
     247        if (priv->handle) 
     248                gnome_vfs_close (priv->handle); 
     249 
     250        if (!handle) 
     251                return; 
     252 
     253        priv->handle = handle; 
     254        priv->eos = FALSE; 
     255        priv->position = 0; 
     256        gnome_vfs_seek (handle, GNOME_VFS_SEEK_CURRENT, priv->position); 
     257 
     258        return; 
     259
     260 
     261/** 
     262 * tny_vfs_stream_new: 
     263 * @handle: The #GnomeVFSHandle to write to or read from 
     264 * 
     265 * Create an adaptor instance between #TnyStream and #GnomeVFSHandle 
     266 * 
     267 * Return value: a new #TnyStream instance 
     268 **/ 
     269TnyStream* 
     270tny_vfs_stream_new (GnomeVFSHandle *handle) 
     271
     272        TnyVfsStream *self = g_object_new (TNY_TYPE_VFS_STREAM, NULL); 
     273 
     274        tny_vfs_stream_set_handle (self, handle); 
     275 
     276        return TNY_STREAM (self); 
     277
     278 
     279static void 
     280tny_vfs_stream_instance_init (GTypeInstance *instance, gpointer g_class) 
     281
     282        TnyVfsStream *self = (TnyVfsStream *)instance; 
     283        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     284 
     285        priv->eos = FALSE; 
     286        priv->handle = NULL; 
     287 
     288        return; 
     289
     290 
     291static void 
     292tny_vfs_stream_finalize (GObject *object) 
     293
     294        TnyVfsStream *self = (TnyVfsStream *)object;     
     295        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     296 
     297        if (G_LIKELY (priv->handle)) 
     298                gnome_vfs_close (priv->handle); 
     299 
     300        (*parent_class->finalize) (object); 
     301 
     302        return; 
     303
     304 
     305static gint  
     306tny_vfs_flush (TnyStream *self) 
     307
     308        return 0; 
     309
     310 
     311static gboolean  
     312tny_vfs_is_eos (TnyStream *self) 
     313
     314        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     315 
     316        return priv->eos; 
     317
     318 
     319static gint  
     320tny_vfs_reset (TnyStream *self) 
     321
     322        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     323        gint retval = 0; 
    231324        GnomeVFSResult res; 
    232325 
     
    237330        } 
    238331 
    239         res = gnome_vfs_close (priv->handle); 
    240  
    241         priv->handle = NULL; 
    242         priv->eos = TRUE; 
    243      
    244         if (res == GNOME_VFS_OK) 
    245                 return 0; 
    246  
    247         tny_vfs_stream_set_errno (res); 
    248  
    249         return -1; 
    250 } 
    251  
    252  
    253 /** 
    254  * tny_vfs_stream_set_handle: 
    255  * @self: A #TnyVfsStream instance 
    256  * @handle: The #GnomeVFSHandle to write to or read from 
    257  * 
    258  * Set the #GnomeVFSHandle to play adaptor for 
    259  * 
    260  **/ 
    261 void 
    262 tny_vfs_stream_set_handle (TnyVfsStream *self, GnomeVFSHandle *handle) 
    263 { 
    264         TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
    265  
    266         if (priv->handle) 
    267                 gnome_vfs_close (priv->handle); 
    268  
    269         priv->handle = handle; 
    270         priv->eos = FALSE; 
    271      
    272         return; 
    273 } 
    274  
    275 /** 
    276  * tny_vfs_stream_new: 
    277  * @handle: The #GnomeVFSHandle to write to or read from 
    278  * 
    279  * Create an adaptor instance between #TnyStream and #GnomeVFSHandle 
    280  * 
    281  * Return value: a new #TnyStream instance 
    282  **/ 
    283 TnyStream* 
    284 tny_vfs_stream_new (GnomeVFSHandle *handle) 
    285 { 
    286         TnyVfsStream *self = g_object_new (TNY_TYPE_VFS_STREAM, NULL); 
    287  
    288         tny_vfs_stream_set_handle (self, handle); 
    289  
    290         return TNY_STREAM (self); 
    291 } 
    292  
    293 static void 
    294 tny_vfs_stream_instance_init (GTypeInstance *instance, gpointer g_class) 
    295 { 
    296         TnyVfsStream *self = (TnyVfsStream *)instance; 
    297         TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
    298  
    299         priv->eos = FALSE; 
    300         priv->handle = NULL; 
    301  
    302         return; 
    303 } 
    304  
    305 static void 
    306 tny_vfs_stream_finalize (GObject *object) 
    307 { 
    308         TnyVfsStream *self = (TnyVfsStream *)object;     
    309         TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
    310  
    311         if (G_LIKELY (priv->handle)) 
    312                 gnome_vfs_close (priv->handle); 
    313  
    314         (*parent_class->finalize) (object); 
    315  
    316         return; 
    317 } 
    318  
    319 static gint  
    320 tny_vfs_flush (TnyStream *self) 
    321 { 
    322         return 0; 
    323 } 
    324  
    325 static gboolean  
    326 tny_vfs_is_eos (TnyStream *self) 
    327 { 
    328         TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
    329  
    330         return priv->eos; 
    331 } 
    332  
    333 static gint  
    334 tny_vfs_reset (TnyStream *self) 
    335 { 
    336         TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
    337         gint retval = 0; 
    338         GnomeVFSResult res; 
    339  
    340         if (priv->handle == NULL)  
    341         { 
    342                 errno = EINVAL; 
    343                 return -1; 
    344         } 
    345  
    346332        res = gnome_vfs_seek (priv->handle, GNOME_VFS_SEEK_START, 0); 
    347333 
     
    352338        } 
    353339        priv->eos = FALSE; 
    354      
     340 
    355341        return retval; 
     342} 
     343 
     344 
     345 
     346static off_t  
     347tny_vfs_seek (TnySeekable *self, off_t offset, int policy) 
     348{ 
     349        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     350        GnomeVFSFileSize real = 0; 
     351        GnomeVFSResult result; 
     352        GnomeVFSHandle *handle = priv->handle; 
     353 
     354        switch (policy) { 
     355        case SEEK_SET: 
     356                real = offset; 
     357                break; 
     358        case SEEK_CUR: 
     359                real = priv->position + offset; 
     360                break; 
     361        case SEEK_END: 
     362                if (priv->bound_end == (~0)) { 
     363                        result = gnome_vfs_seek (handle, GNOME_VFS_SEEK_END, offset); 
     364                        if (result != GNOME_VFS_OK) 
     365                                return -1; 
     366                        gnome_vfs_tell (handle, &real); 
     367                        if (real != -1) { 
     368                                if (real<priv->bound_start) 
     369                                        real = priv->bound_start; 
     370                                priv->position = real; 
     371                        } 
     372                        return real; 
     373                } 
     374                real = priv->bound_end + offset; 
     375                break; 
     376        } 
     377 
     378        if (priv->bound_end != (~0)) 
     379                real = MIN (real, priv->bound_end); 
     380        real = MAX (real, priv->bound_start); 
     381 
     382        result = gnome_vfs_seek (handle, GNOME_VFS_SEEK_START, real); 
     383        if (result != GNOME_VFS_OK) 
     384                return -1; 
     385 
     386        if (real != priv->position && priv->eos) 
     387                priv->eos = FALSE; 
     388 
     389        priv->position = real; 
     390 
     391        return real; 
     392} 
     393 
     394static off_t 
     395tny_vfs_tell (TnySeekable *self) 
     396{ 
     397        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     398        return priv->position; 
     399} 
     400 
     401static gint  
     402tny_vfs_set_bounds (TnySeekable *self, off_t start, off_t end) 
     403{ 
     404        TnyVfsStreamPriv *priv = TNY_VFS_STREAM_GET_PRIVATE (self); 
     405        priv->bound_end = end; 
     406        priv->bound_start = start; 
     407        return; 
    356408} 
    357409 
     
    364416        klass->flush= tny_vfs_flush; 
    365417        klass->is_eos= tny_vfs_is_eos; 
    366  
    367418        klass->read= tny_vfs_stream_read; 
    368419        klass->write= tny_vfs_stream_write; 
    369420        klass->close= tny_vfs_stream_close; 
    370421        klass->write_to_stream= tny_vfs_stream_write_to_stream; 
     422 
     423        return; 
     424} 
     425 
     426 
     427static void 
     428tny_seekable_init (gpointer g, gpointer iface_data) 
     429{ 
     430        TnySeekableIface *klass = (TnySeekableIface *)g; 
     431 
     432        klass->seek= tny_vfs_seek; 
     433        klass->tell= tny_vfs_tell; 
     434        klass->set_bounds= tny_vfs_set_bounds; 
    371435 
    372436        return; 
     
    416480                }; 
    417481 
     482                static const GInterfaceInfo tny_seekable_info =  
     483                { 
     484                  (GInterfaceInitFunc) tny_seekable_init, /* interface_init */ 
     485                  NULL,         /* interface_finalize */ 
     486                  NULL          /* interface_data */ 
     487                }; 
     488 
    418489                type = g_type_register_static (G_TYPE_OBJECT, 
    419490                        "TnyVfsStream", 
     
    422493                g_type_add_interface_static (type, TNY_TYPE_STREAM,  
    423494                        &tny_stream_info); 
     495 
     496                g_type_add_interface_static (type, TNY_TYPE_SEEKABLE,  
     497                        &tny_seekable_info); 
     498 
    424499        } 
    425500 
  • trunk/libtinymail-gnomevfs/tny-vfs-stream.h

    r2825 r3454  
    2626 
    2727#include <tny-stream.h> 
     28#include <tny-seekable.h> 
    2829 
    2930G_BEGIN_DECLS 
  • trunk/libtinymail/Makefile.am

    r3295 r3454  
    4040        tny-account-store.h \ 
    4141        tny-stream.h \ 
     42        tny-seekable.h \ 
    4243        tny-fs-stream.h \ 
    4344        tny-simple-list.h \ 
     
    7980        tny-account-store.c \ 
    8081        tny-stream.c \ 
     82        tny-seekable.c \ 
    8183        tny-fs-stream.c \ 
    8284        tny-simple-list-priv.h \ 
  • trunk/libtinymail/tny-fs-stream.c

    r3304 r3454  
    5757#include <errno.h> 
    5858 
    59 #include <tny-stream.h> 
    6059#include <tny-fs-stream.h> 
    6160 
     
    6766{ 
    6867        int fd; 
    69         gint offset; 
     68        off_t position;         /* current postion in the stream */ 
     69        off_t bound_start;      /* first valid position */ 
     70        off_t bound_end;        /* first invalid position */ 
    7071        gboolean eos; 
    7172}; 
     
    104105} 
    105106 
     107 
    106108static gssize 
    107 tny_fs_stream_read (TnyStream *self, char *buffer, gsize n) 
     109tny_fs_stream_read (TnyStream *self, char *buffer, gsize n) 
    108110{ 
    109111        TnyFsStreamPriv *priv = TNY_FS_STREAM_GET_PRIVATE (self); 
    110112        gssize nread; 
    111         char b[1]; 
    112          
     113 
     114        if (priv->bound_end != (~0)) 
     115                n = MIN (priv->bound_end - priv->position, n); 
     116 
    113117        if ((nread = read (priv->fd, buffer, n)) > 0) 
    114                 priv->offset += nread; 
    115         if (nread != n
     118                priv->position += nread; 
     119        else if (nread == 0
    116120                priv->eos = TRUE; 
    117         if (read (priv->fd, b, 1) != 1) 
    118                 priv->eos = TRUE; 
    119  
    120         priv->offset = lseek (priv->fd, priv->offset, SEEK_SET); 
     121 
    121122        return nread; 
    122  
    123123} 
    124124 
     
    128128        TnyFsStreamPriv *priv = TNY_FS_STREAM_GET_PRIVATE (self); 
    129129        gssize nwritten; 
     130 
     131        if (priv->bound_end != (~0)) 
     132                n = MIN (priv->bound_end - priv->position, n); 
     133 
    130134        if ((nwritten = write (priv->fd, buffer, n)) > 0) 
    131                 priv->offset += nwritten; 
    132         priv->eos = FALSE; 
     135                priv->position += nwritten; 
     136 
    133137        return nwritten; 
    134138} 
     139 
    135140 
    136141static gint 
     
    164169                close (priv->fd); 
    165170        priv->fd = fd; 
    166         priv->offset = lseek (priv->fd, 0, SEEK_SET); 
    167         if (priv->offset == -1) 
    168                 priv->offset = 0; 
    169         priv->eos = FALSE; 
     171        priv->position = lseek (priv->fd, 0, SEEK_CUR); 
     172        if (priv->position == -1) 
     173                priv->position = 0; 
    170174        return; 
    171175} 
     
    205209        TnyFsStream *self = (TnyFsStream *)instance; 
    206210        TnyFsStreamPriv *priv = TNY_FS_STREAM_GET_PRIVATE (self); 
    207         priv->eos = TRUE; 
     211 
    208212        priv->fd = -1; 
    209         priv->offset = 0; 
     213        priv->position = 0; 
     214        priv->bound_start = 0; 
     215        priv->bound_end = (~0); 
     216 
    210217        return; 
    211218} 
     
    214221tny_fs_stream_finalize (GObject *object) 
    215222{ 
    216         TnyFsStream *self = (TnyFsStream *)object;      
     223        TnyFsStream *self = (TnyFsStream *)object; 
    217224        TnyFsStreamPriv *priv = TNY_FS_STREAM_GET_PRIVATE (self); 
    218225        if (priv->fd != -1) { 
     
    244251{ 
    245252        TnyFsStreamPriv *priv = TNY_FS_STREAM_GET_PRIVATE (self); 
    246         priv->offset = lseek (priv->fd, 0, SEEK_SET); 
     253        priv->position = lseek (priv->fd, 0, SEEK_SET); 
    247254        priv->eos = FALSE; 
    248255        return 0; 
    249256} 
     257 
     258static off_t  
     259tny_fs_seek (TnySeekable *self, off_t offset, int policy) 
     260{ 
     261        TnyFsStreamPriv *priv = TNY_FS_STREAM_GET_PRIVATE (self); 
     262        off_t real = 0; 
     263 
     264        switch (policy) { 
     265        case SEEK_SET: 
     266                real = offset; 
     267                break; 
     268        case SEEK_CUR: 
     269                real = priv->position + offset; 
     270                break; 
     271        case SEEK_END: 
     272                if (priv->bound_end == (~0)) { 
     273                        real = lseek(priv->fd, offset, SEEK_END); 
     274                        if (real != -1) { 
     275                                if (real<priv->bound_start) 
     276                                        real = priv->bound_start; 
     277                                priv->position = real; 
     278                        } 
     279                        return real; 
     280                } 
     281                real = priv->bound_end + offset; 
     282                break; 
     283        } 
     284 
     285        if (priv->bound_end != (~0)) 
     286                real = MIN (real, priv->bound_end); 
     287        real = MAX (real, priv->bound_start); 
     288 
     289        real = lseek(priv->fd, real, SEEK_SET); 
     290        if (real == -1) 
     291                return -1; 
     292 
     293        if (real != priv->position && priv->eos) 
     294                priv->eos = FALSE; 
     295 
     296        priv->position = real; 
     297 
     298        return real; 
     299} 
     300 
     301static off_t 
     302tny_fs_tell (TnySeekable *self) 
     303{ 
     304        TnyFsStreamPriv *priv = TNY_FS_STREAM_GET_PRIVATE (self); 
     305        return priv->position; 
     306} 
     307 
     308static gint  
     309tny_fs_set_bounds (TnySeekable *self, off_t start, off_t end) 
     310{ 
     311        TnyFsStreamPriv *priv = TNY_FS_STREAM_GET_PRIVATE (self); 
     312        priv->bound_end = end; 
     313        priv->bound_start = start; 
     314        return; 
     315} 
     316 
    250317 
    251318static void 
     
    261328        klass->close= tny_fs_stream_close; 
    262329        klass->write_to_stream= tny_fs_stream_write_to_stream; 
     330 
     331        return; 
     332} 
     333 
     334static void 
     335tny_seekable_init (gpointer g, gpointer iface_data) 
     336{ 
     337        TnySeekableIface *klass = (TnySeekableIface *)g; 
     338 
     339        klass->seek= tny_fs_seek; 
     340        klass->tell= tny_fs_tell; 
     341        klass->set_bounds= tny_fs_set_bounds; 
    263342 
    264343        return; 
     
    306385                }; 
    307386 
     387                static const GInterfaceInfo tny_seekable_info =  
     388                { 
     389                  (GInterfaceInitFunc) tny_seekable_init, /* interface_init */ 
     390                  NULL,         /* interface_finalize */ 
     391                  NULL          /* interface_data */ 
     392                }; 
     393 
    308394                type = g_type_register_static (G_TYPE_OBJECT, 
    309395                        "TnyFsStream", 
     
    312398                g_type_add_interface_static (type, TNY_TYPE_STREAM,  
    313399                        &tny_stream_info); 
     400 
     401                g_type_add_interface_static (type, TNY_TYPE_SEEKABLE,  
     402                        &tny_seekable_info); 
     403 
    314404        } 
    315405 
  • trunk/libtinymail/tny-fs-stream.h

    r2825 r3454  
    2929 
    3030#include <tny-stream.h> 
     31#include <tny-seekable.h> 
    3132 
    3233G_BEGIN_DECLS 
  • trunk/libtinymail/tny-shared.h

    r3436 r3454  
    103103typedef struct _TnyConnectionPolicy TnyConnectionPolicy; 
    104104typedef struct _TnyConnectionPolicyIface TnyConnectionPolicyIface; 
     105typedef struct _TnySeekable TnySeekable; 
     106typedef struct _TnySeekableIface TnySeekableIface; 
     107 
    105108 
    106109typedef void (*TnyStatusCallback) (GObject *self, TnyStatus *status, gpointer user_data); 
  • trunk/libtinymailui-gtk/tny-gtk-text-buffer-stream.c

    r3400 r3454  
    309309tny_gtk_text_buffer_stream_finalize (GObject *object) 
    310310{ 
    311         TnyGtkTextBufferStream *self = (TnyGtkTextBufferStream *)object;        
     311        TnyGtkTextBufferStream *self = (TnyGtkTextBufferStream *)object; 
    312312        TnyGtkTextBufferStreamPriv *priv = TNY_GTK_TEXT_BUFFER_STREAM_GET_PRIVATE (self); 
    313313 
    314314        if (priv->buffer && priv->pending_bytes) 
    315                 tny_gtk_text_buffer_stream_flush (self); 
     315                tny_gtk_text_buffer_stream_flush ((TnyStream *) self); 
    316316 
    317317        if (priv->buffer) 
    318                 g_object_unref (G_OBJECT (priv->buffer)); 
     318                g_object_unref (priv->buffer); 
    319319        if (priv->pending_bytes) 
    320320                g_byte_array_free (priv->pending_bytes, TRUE);