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: