Annotation of win32/gnome/gmime-x.x.x/gmime-stream-fs.c, revision 1.1

1.1     ! paf         1: /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
        !             2: /*
        !             3:  *  Authors: Jeffrey Stedfast <fejj@ximian.com>
        !             4:  *
        !             5:  *  Copyright 2001 Ximian, Inc. (www.ximian.com)
        !             6:  *
        !             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.
        !            11:  *
        !            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.
        !            16:  *
        !            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., 59 Temple Street #330, Boston, MA 02111-1307, USA.
        !            20:  *
        !            21:  */
        !            22: 
        !            23: 
        !            24: #ifdef HAVE_CONFIG_H
        !            25: #include <config.h>
        !            26: #endif
        !            27: 
        !            28: #ifdef HAVE_IO_H
        !            29: #include <io.h>
        !            30: #endif
        !            31: #include <sys/types.h>
        !            32: #include <sys/stat.h>
        !            33: #include <fcntl.h>
        !            34: #include <errno.h>
        !            35: 
        !            36: #include "gmime-stream-fs.h"
        !            37: 
        !            38: 
        !            39: static void stream_destroy (GMimeStream *stream);
        !            40: static ssize_t stream_read (GMimeStream *stream, char *buf, size_t len);
        !            41: static ssize_t stream_write (GMimeStream *stream, char *buf, size_t len);
        !            42: static int stream_flush (GMimeStream *stream);
        !            43: static int stream_close (GMimeStream *stream);
        !            44: static gboolean stream_eos (GMimeStream *stream);
        !            45: static int stream_reset (GMimeStream *stream);
        !            46: static off_t stream_seek (GMimeStream *stream, off_t offset, GMimeSeekWhence whence);
        !            47: static off_t stream_tell (GMimeStream *stream);
        !            48: static ssize_t stream_length (GMimeStream *stream);
        !            49: static GMimeStream *stream_substream (GMimeStream *stream, off_t start, off_t end);
        !            50: 
        !            51: static GMimeStream stream_template = {
        !            52:        NULL, 0,
        !            53:        1, 0, 0, 0, stream_destroy,
        !            54:        stream_read, stream_write,
        !            55:        stream_flush, stream_close,
        !            56:        stream_eos, stream_reset,
        !            57:        stream_seek, stream_tell,
        !            58:        stream_length, stream_substream,
        !            59: };
        !            60: 
        !            61: 
        !            62: static void
        !            63: stream_destroy (GMimeStream *stream)
        !            64: {
        !            65:        GMimeStreamFs *fstream = (GMimeStreamFs *) stream;
        !            66:        
        !            67:        if (fstream->owner && fstream->fd != -1)
        !            68:                close (fstream->fd);
        !            69:        
        !            70:        g_free (fstream);
        !            71: }
        !            72: 
        !            73: static ssize_t
        !            74: stream_read (GMimeStream *stream, char *buf, size_t len)
        !            75: {
        !            76:        GMimeStreamFs *fstream = (GMimeStreamFs *) stream;
        !            77:        ssize_t nread;
        !            78:        
        !            79:        if (stream->bound_end != -1 && stream->position >= stream->bound_end)
        !            80:                return -1;
        !            81:        
        !            82:        if (stream->bound_end != -1)
        !            83:                len = MIN (stream->bound_end - stream->position, len);
        !            84:        
        !            85:        /* make sure we are at the right position */
        !            86:        lseek (fstream->fd, stream->position, SEEK_SET);
        !            87:        
        !            88:        do {
        !            89:                nread = read (fstream->fd, buf, len);
        !            90:        } while (nread == -1 && errno == EINTR);
        !            91:        
        !            92:        if (nread > 0)
        !            93:                stream->position += nread;
        !            94:        else if (nread == 0)
        !            95:                fstream->eos = TRUE;
        !            96:        
        !            97:        return nread;
        !            98: }
        !            99: 
        !           100: static ssize_t
        !           101: stream_write (GMimeStream *stream, char *buf, size_t len)
        !           102: {
        !           103:        GMimeStreamFs *fstream = (GMimeStreamFs *) stream;
        !           104:        ssize_t nwritten = 0, n;
        !           105:        
        !           106:        if (stream->bound_end != -1 && stream->position >= stream->bound_end)
        !           107:                return -1;
        !           108:        
        !           109:        if (stream->bound_end != -1)
        !           110:                len = MIN (stream->bound_end - stream->position, len);
        !           111:        
        !           112:        /* make sure we are at the right position */
        !           113:        lseek (fstream->fd, stream->position, SEEK_SET);
        !           114:        
        !           115:        do {
        !           116:                do {
        !           117:                        n = write (fstream->fd, buf + nwritten, len - nwritten);
        !           118:                } while (n == -1 && (errno == EINTR || errno == EAGAIN));
        !           119:                
        !           120:                if (n > 0)
        !           121:                        nwritten += n;
        !           122:        } while (n != -1 && nwritten < len);
        !           123:        
        !           124:        if (nwritten > 0)
        !           125:                stream->position += nwritten;
        !           126:        else if (n == -1)
        !           127:                return -1;
        !           128:        
        !           129:        return nwritten;
        !           130: }
        !           131: 
        !           132: static int
        !           133: stream_flush (GMimeStream *stream)
        !           134: {
        !           135: #ifdef DONT_HAVE_FSYNC
        !           136:        return -1;
        !           137: #else
        !           138:        GMimeStreamFs *fstream = (GMimeStreamFs *) stream;
        !           139:        
        !           140:        g_return_val_if_fail (fstream->fd != -1, -1);
        !           141:        
        !           142:        return fsync (fstream->fd);
        !           143: #endif
        !           144: }
        !           145: 
        !           146: static int
        !           147: stream_close (GMimeStream *stream)
        !           148: {
        !           149:        GMimeStreamFs *fstream = (GMimeStreamFs *) stream;
        !           150:        int ret;
        !           151:        
        !           152:        g_return_val_if_fail (fstream->fd != -1, -1);
        !           153:        
        !           154:        ret = close (fstream->fd);
        !           155:        if (ret != -1)
        !           156:                fstream->fd = -1;
        !           157:        
        !           158:        return ret;
        !           159: }
        !           160: 
        !           161: static gboolean
        !           162: stream_eos (GMimeStream *stream)
        !           163: {
        !           164:        GMimeStreamFs *fstream = (GMimeStreamFs *) stream;
        !           165:        
        !           166:        g_return_val_if_fail (fstream->fd != -1, TRUE);
        !           167:        
        !           168:        return fstream->eos;
        !           169: }
        !           170: 
        !           171: static int
        !           172: stream_reset (GMimeStream *stream)
        !           173: {
        !           174:        GMimeStreamFs *fstream = (GMimeStreamFs *) stream;
        !           175:        off_t ret;
        !           176:        
        !           177:        g_return_val_if_fail (fstream->fd != -1, -1);
        !           178:        
        !           179:        ret = lseek (fstream->fd, stream->bound_start, SEEK_SET);
        !           180:        if (ret != -1) {
        !           181:                fstream->eos = FALSE;
        !           182:                stream->position = stream->bound_start;
        !           183:        }
        !           184:        
        !           185:        return ret;
        !           186: }
        !           187: 
        !           188: static off_t
        !           189: stream_seek (GMimeStream *stream, off_t offset, GMimeSeekWhence whence)
        !           190: {
        !           191:        GMimeStreamFs *fstream = (GMimeStreamFs *) stream;
        !           192:        off_t real = stream->position;
        !           193:        
        !           194:        g_return_val_if_fail (fstream->fd != -1, -1);
        !           195:        
        !           196:        switch (whence) {
        !           197:        case GMIME_STREAM_SEEK_SET:
        !           198:                real = offset;
        !           199:                break;
        !           200:        case GMIME_STREAM_SEEK_CUR:
        !           201:                real = stream->position + offset;
        !           202:                break;
        !           203:        case GMIME_STREAM_SEEK_END:
        !           204:                if (stream->bound_end == -1) {
        !           205:                        real = lseek (fstream->fd, offset, SEEK_END);
        !           206:                        if (real != -1) {
        !           207:                                if (real < stream->bound_start)
        !           208:                                        real = stream->bound_start;
        !           209:                                stream->position = real;
        !           210:                        }
        !           211:                        return real;
        !           212:                }
        !           213:                real = stream->bound_end + offset;
        !           214:                break;
        !           215:        }
        !           216:        
        !           217:        if (stream->bound_end != -1)
        !           218:                real = MIN (real, stream->bound_end);
        !           219:        real = MAX (real, stream->bound_start);
        !           220:        
        !           221:        real = lseek (fstream->fd, real, SEEK_SET);
        !           222:        if (real == -1)
        !           223:                return -1;
        !           224:        
        !           225:        if (real != stream->position && fstream->eos)
        !           226:                fstream->eos = FALSE;
        !           227:        
        !           228:        stream->position = real;
        !           229:        
        !           230:        return real;
        !           231: }
        !           232: 
        !           233: static off_t
        !           234: stream_tell (GMimeStream *stream)
        !           235: {
        !           236:        return stream->position;
        !           237: }
        !           238: 
        !           239: static ssize_t
        !           240: stream_length (GMimeStream *stream)
        !           241: {
        !           242:        GMimeStreamFs *fstream = (GMimeStreamFs *) stream;
        !           243:        off_t bound_end;
        !           244:        
        !           245:        if (stream->bound_start != -1 && stream->bound_end != -1)
        !           246:                return stream->bound_end - stream->bound_start;
        !           247:        
        !           248:        bound_end = lseek (fstream->fd, 0, SEEK_END);
        !           249:        lseek (fstream->fd, stream->position, SEEK_SET);
        !           250:        
        !           251:        return bound_end - stream->bound_start;
        !           252: }
        !           253: 
        !           254: static GMimeStream *
        !           255: stream_substream (GMimeStream *stream, off_t start, off_t end)
        !           256: {
        !           257:        GMimeStreamFs *fstream;
        !           258:        
        !           259:        fstream = g_new (GMimeStreamFs, 1);
        !           260:        fstream->owner = FALSE;
        !           261:        fstream->fd = GMIME_STREAM_FS (stream)->fd;
        !           262:        
        !           263:        g_mime_stream_construct (GMIME_STREAM (fstream), &stream_template, GMIME_STREAM_FS_TYPE, start, end);
        !           264:        
        !           265:        return GMIME_STREAM (fstream);
        !           266: }
        !           267: 
        !           268: 
        !           269: /**
        !           270:  * g_mime_stream_fs_new:
        !           271:  * @fd: file descriptor
        !           272:  *
        !           273:  * Creates a new GMimeStreamFs object around @fd.
        !           274:  *
        !           275:  * Returns a stream using @fd.
        !           276:  **/
        !           277: GMimeStream *
        !           278: g_mime_stream_fs_new (int fd)
        !           279: {
        !           280:        GMimeStreamFs *fstream;
        !           281:        off_t start;
        !           282:        
        !           283:        fstream = g_new (GMimeStreamFs, 1);
        !           284:        fstream->owner = TRUE;
        !           285:        fstream->eos = FALSE;
        !           286:        fstream->fd = fd;
        !           287:        
        !           288:        start = lseek (fd, 0, SEEK_CUR);
        !           289:        
        !           290:        g_mime_stream_construct (GMIME_STREAM (fstream), &stream_template, GMIME_STREAM_FS_TYPE, start, -1);
        !           291:        
        !           292:        return GMIME_STREAM (fstream);
        !           293: }
        !           294: 
        !           295: 
        !           296: /**
        !           297:  * g_mime_stream_fs_new_with_bounds:
        !           298:  * @fd: file descriptor
        !           299:  * @start: start boundary
        !           300:  * @end: end boundary
        !           301:  *
        !           302:  * Creates a new GMimeStreamFs object around @fd with bounds @start
        !           303:  * and @end.
        !           304:  *
        !           305:  * Returns a stream using @fd with bounds @start and @end.
        !           306:  **/
        !           307: GMimeStream *
        !           308: g_mime_stream_fs_new_with_bounds (int fd, off_t start, off_t end)
        !           309: {
        !           310:        GMimeStreamFs *fstream;
        !           311:        
        !           312:        fstream = g_new (GMimeStreamFs, 1);
        !           313:        fstream->owner = TRUE;
        !           314:        fstream->eos = FALSE;
        !           315:        fstream->fd = fd;
        !           316:        
        !           317:        g_mime_stream_construct (GMIME_STREAM (fstream), &stream_template, GMIME_STREAM_FS_TYPE, start, end);
        !           318:        
        !           319:        return GMIME_STREAM (fstream);
        !           320: }

E-mail: