File: mu_port.c

package info (click to toggle)
mailutils 1%3A3.20-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 38,912 kB
  • sloc: ansic: 187,772; sh: 111,430; yacc: 7,463; cpp: 3,834; makefile: 3,166; lex: 1,972; python: 1,617; exp: 1,563; awk: 152; lisp: 132; sed: 31
file content (132 lines) | stat: -rw-r--r-- 3,475 bytes parent folder | download | duplicates (2)
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);
}