1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 1999-2025 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#include "mu_scm.h"
#include <mailutils/io.h>
struct mu_port
{
mu_stream_t stream; /* Associated stream */
};
#define MU_PORT(x) ((struct mu_port *) SCM_STREAM (x))
static scm_t_port_type *scm_mu_port_type;
SCM
mu_port_make_from_stream (mu_stream_t stream, long mode)
{
struct mu_port *mp;
mp = scm_gc_typed_calloc (struct mu_port);
mp->stream = stream;
return scm_c_make_port (scm_mu_port_type, mode | SCM_BUF0, (scm_t_bits) mp);
}
static void
mu_port_close (SCM port)
{
struct mu_port *mp = MU_PORT (port);
mu_stream_destroy (&mp->stream);
}
static size_t
mu_port_read (SCM port, SCM dst, size_t start, size_t count)
{
struct mu_port *mp = MU_PORT (port);
int status;
size_t nread;
status = mu_stream_read (mp->stream,
SCM_BYTEVECTOR_CONTENTS (dst) + start,
count,
&nread);
if (status)
mu_scm_error ("mu_port_read", status,
"Error reading from stream", SCM_BOOL_F);
return nread;
}
static size_t
mu_port_write (SCM port, SCM src, size_t start, size_t count)
{
struct mu_port *mp = MU_PORT (port);
int status;
size_t nwrite;
status = mu_stream_write (mp->stream,
SCM_BYTEVECTOR_CONTENTS (src) + start, count,
&nwrite);
if (status)
mu_scm_error ("mu_port_read", status,
"Error reading from stream", SCM_BOOL_F);
return nwrite;
}
static scm_t_off
mu_port_seek (SCM port, scm_t_off offset, int whence)
{
struct mu_port *mp = MU_PORT (port);
mu_off_t pos;
int status;
status = mu_stream_seek (mp->stream, offset, whence, &pos);
if (status)
pos = -1;
return (scm_t_off) pos;
}
static void
mu_port_truncate (SCM port, mu_off_t length)
{
struct mu_port *mp = MU_PORT (port);
int status;
status = mu_stream_truncate (mp->stream, length);
if (status)
mu_scm_error ("mu_port_truncate", status,
"Error truncating stream", SCM_BOOL_F);
}
static int
mu_port_print (SCM exp, SCM port, scm_print_state *pstate)
{
struct mu_port *mp = MU_PORT (exp);
mu_off_t size = 0;
scm_puts ("#<", port);
scm_print_port_mode (exp, port);
scm_puts ("mu-port", port);
if (mu_stream_size (mp->stream, &size) == 0)
{
scm_intprint (size, 10, port);
scm_puts (" octets", port);
}
scm_putc ('>', port);
return 1;
}
void
mu_scm_port_init (void)
{
scm_mu_port_type = scm_make_port_type ("mu-port",
mu_port_read, mu_port_write);
scm_set_port_print (scm_mu_port_type, mu_port_print);
scm_set_port_close (scm_mu_port_type, mu_port_close);
scm_set_port_needs_close_on_gc (scm_mu_port_type, 1);
scm_set_port_seek (scm_mu_port_type, mu_port_seek);
scm_set_port_truncate (scm_mu_port_type, mu_port_truncate);
}
|