32-way branching in intmap.scm, not 16-way
[bpt/guile.git] / libguile / ports.h
CommitLineData
0f2d19dd
JB
1/* classes: h_files */
2
22a52da1
DH
3#ifndef SCM_PORTS_H
4#define SCM_PORTS_H
8c494e99 5
a9178715 6/* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004,
e140d85d 7 * 2006, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
8c494e99 8 *
73be1d9e 9 * This library is free software; you can redistribute it and/or
53befeb7
NJ
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
8c494e99 13 *
53befeb7
NJ
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
8c494e99 18 *
73be1d9e
MV
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
53befeb7
NJ
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301 USA
73be1d9e 23 */
d3a6bc94 24
0f2d19dd 25\f
8c494e99 26
b4309c3c 27#include "libguile/__scm.h"
0f2d19dd 28
fca14149
AW
29#include <stdio.h>
30#include <string.h>
0c247c33 31#include <unistd.h>
fca14149
AW
32#include "libguile/gc.h"
33#include "libguile/tags.h"
34#include "libguile/error.h"
e0d86ad2 35#include "libguile/print.h"
78446828 36#include "libguile/struct.h"
b9ad392e 37#include "libguile/threads.h"
889975e5 38#include "libguile/strings.h"
acdb12da 39
0f2d19dd
JB
40\f
41
6c951427 42#define SCM_INITIAL_PUTBACK_BUF_SIZE 4
0855ef71 43
61e452ba 44/* values for the rw_active flag. */
92c2555f 45typedef enum scm_t_port_rw_active {
61e452ba
JB
46 SCM_PORT_NEITHER = 0,
47 SCM_PORT_READ = 1,
48 SCM_PORT_WRITE = 2
92c2555f 49} scm_t_port_rw_active;
61e452ba 50
f6f4feb0
MW
51/* An internal-only structure defined in ports-internal.h. */
52struct scm_port_internal;
6c98257f 53
840ae05d
JB
54/* C representation of a Scheme port. */
55
56typedef struct
0f2d19dd 57{
ee149d03 58 SCM port; /* Link back to the port object. */
92c0ebac 59 scm_i_pthread_mutex_t *lock; /* A recursive lock for this port. */
30b126d2 60
f6f4feb0
MW
61 /* pointer to internal-only port structure */
62 struct scm_port_internal *internal;
63
74a16888 64 /* data for the underlying port implementation as a raw C value. */
92c2555f 65 scm_t_bits stream;
0f2d19dd 66
0855ef71 67 SCM file_name; /* debugging support. */
1be6b49c 68 long line_number; /* debugging support. */
ebf7394e 69 int column_number; /* debugging support. */
0855ef71 70
ee149d03
JB
71 /* port buffers. the buffer(s) are set up for all ports.
72 in the case of string ports, the buffer is the string itself.
73 in the case of unbuffered file ports, the buffer is a
74 single char: shortbuf. */
75
76 /* this buffer is filled from read_buf to read_end using the ptob
77 buffer_fill. then input requests are taken from read_pos until
78 it reaches read_end. */
79
80 unsigned char *read_buf; /* buffer start. */
840ae05d 81 const unsigned char *read_pos;/* the next unread char. */
ee149d03 82 unsigned char *read_end; /* pointer to last buffered char + 1. */
f1ce9199 83 scm_t_off read_buf_size; /* size of the buffer. */
ee149d03 84
6c951427
GH
85 /* when chars are put back into the buffer, e.g., using peek-char or
86 unread-string, the read-buffer pointers are switched to cbuf.
87 the original pointers are saved here and restored when the put-back
88 chars have been consumed. */
89 unsigned char *saved_read_buf;
90 const unsigned char *saved_read_pos;
91 unsigned char *saved_read_end;
f1ce9199 92 scm_t_off saved_read_buf_size;
6c951427 93
ee149d03
JB
94 /* write requests are saved into this buffer at write_pos until it
95 reaches write_buf + write_buf_size, then the ptob flush is
96 called. */
97
6c951427 98 unsigned char *write_buf; /* buffer start. */
ee149d03
JB
99 unsigned char *write_pos; /* pointer to last buffered char + 1. */
100 unsigned char *write_end; /* pointer to end of buffer + 1. */
f1ce9199 101 scm_t_off write_buf_size; /* size of the buffer. */
ee149d03
JB
102
103 unsigned char shortbuf; /* buffer for "unbuffered" streams. */
104
0de97b83
GH
105 int rw_random; /* true if the port is random access.
106 implies that the buffers must be
107 flushed before switching between
108 reading and writing, seeking, etc. */
109
92c2555f 110 scm_t_port_rw_active rw_active; /* for random access ports,
1be6b49c
ML
111 indicates which of the buffers
112 is currently in use. can be
113 SCM_PORT_WRITE, SCM_PORT_READ,
114 or SCM_PORT_NEITHER. */
ee149d03 115
61e452ba 116
6c951427
GH
117 /* a buffer for un-read chars and strings. */
118 unsigned char *putback_buf;
1be6b49c 119 size_t putback_buf_size; /* allocated size of putback_buf. */
f4bc4e59 120
6c98257f
AW
121 /* Character encoding support */
122 char *encoding;
6c98257f 123 scm_t_string_failed_conversion_handler ilseq_handler;
92c2555f 124} scm_t_port;
840ae05d 125
5dbc6c06 126
2721f918 127SCM_INTERNAL SCM scm_i_port_weak_set;
5dbc6c06 128
0f2d19dd 129
6fe692e9 130#define SCM_READ_BUFFER_EMPTY_P(c_port) (c_port->read_pos >= c_port->read_end)
0f2d19dd
JB
131
132\f
133
bc36d050 134#define SCM_EOF_OBJECT_P(x) (scm_is_eq ((x), SCM_EOF_VAL))
0c32d76c 135
0f2d19dd 136/* PORT FLAGS
dbece3a2 137 * A set of flags characterizes a port.
571031dc
JB
138 * Note that we reserve the bits 1 << 24 and above for use by the
139 * routines in the port's scm_ptobfuns structure.
0f2d19dd
JB
140 */
141#define SCM_OPN (1L<<16) /* Is the port open? */
142#define SCM_RDNG (2L<<16) /* Is it a readable port? */
143#define SCM_WRTNG (4L<<16) /* Is it writable? */
ee149d03 144#define SCM_BUF0 (8L<<16) /* Is it unbuffered? */
ee149d03 145#define SCM_BUFLINE (64L<<16) /* Is it line-buffered? */
0f2d19dd 146
dc7da0be
AW
147#define SCM_PORTP(x) (SCM_HAS_TYP7 (x, scm_tc7_port))
148#define SCM_OPPORTP(x) (SCM_PORTP (x) && (SCM_CELL_WORD_0 (x) & SCM_OPN))
149#define SCM_INPUT_PORT_P(x) (SCM_PORTP (x) && (SCM_CELL_WORD_0 (x) & SCM_RDNG))
150#define SCM_OUTPUT_PORT_P(x) (SCM_PORTP (x) && (SCM_CELL_WORD_0 (x) & SCM_WRTNG))
151#define SCM_OPINPORTP(x) (SCM_OPPORTP (x) && SCM_INPUT_PORT_P (x))
152#define SCM_OPOUTPORTP(x) (SCM_OPPORTP (x) && SCM_OUTPUT_PORT_P (x))
153#define SCM_OPENP(x) (SCM_OPPORTP (x))
154#define SCM_CLOSEDP(x) (!SCM_OPENP (x))
22a52da1
DH
155#define SCM_CLR_PORT_OPEN_FLAG(p) \
156 SCM_SET_CELL_WORD_0 ((p), SCM_CELL_WORD_0 (p) & ~SCM_OPN)
843524cc 157
92c2555f 158#define SCM_PTAB_ENTRY(x) ((scm_t_port *) SCM_CELL_WORD_1 (x))
62bd5d66 159#define SCM_PORT_DESCRIPTOR(port) ((scm_t_ptob_descriptor *) SCM_CELL_WORD_2 (port))
34d19ef6 160#define SCM_SETPTAB_ENTRY(x, ent) (SCM_SET_CELL_WORD_1 ((x), (scm_t_bits) (ent)))
843524cc 161#define SCM_STREAM(x) (SCM_PTAB_ENTRY(x)->stream)
34d19ef6 162#define SCM_SETSTREAM(x, s) (SCM_PTAB_ENTRY(x)->stream = (scm_t_bits) (s))
843524cc 163#define SCM_FILENAME(x) (SCM_PTAB_ENTRY(x)->file_name)
b24b5e13 164#define SCM_SET_FILENAME(x, n) (SCM_PTAB_ENTRY(x)->file_name = (n))
843524cc
DH
165#define SCM_LINUM(x) (SCM_PTAB_ENTRY(x)->line_number)
166#define SCM_COL(x) (SCM_PTAB_ENTRY(x)->column_number)
0f2d19dd 167
b0799290
MG
168#define SCM_INCLINE(port) do {SCM_LINUM (port) += 1; SCM_COL (port) = 0;} while (0)
169#define SCM_ZEROCOL(port) do {SCM_COL (port) = 0;} while (0)
170#define SCM_INCCOL(port) do {SCM_COL (port) += 1;} while (0)
171#define SCM_DECCOL(port) do {if (SCM_COL (port) > 0) SCM_COL (port) -= 1;} while (0)
172#define SCM_TABCOL(port) do {SCM_COL (port) += 8 - SCM_COL (port) % 8;} while (0)
0f2d19dd 173
0953b549
LC
174/* Maximum number of port types. */
175#define SCM_I_MAX_PORT_TYPE_COUNT 256
176
0f2d19dd
JB
177\f
178
03a2eeb0
AW
179typedef enum scm_t_port_type_flags {
180 SCM_PORT_TYPE_HAS_FLUSH = 1 << 0
181} scm_t_port_type_flags;
182
affc96b5 183/* port-type description. */
92c2555f 184typedef struct scm_t_ptob_descriptor
0f82baf6 185{
f12733c9 186 char *name;
0c0669cc 187 SCM (*mark) (SCM);
1be6b49c 188 size_t (*free) (SCM);
0c0669cc
JB
189 int (*print) (SCM exp, SCM port, scm_print_state *pstate);
190 SCM (*equalp) (SCM, SCM);
affc96b5
GH
191 int (*close) (SCM port);
192
8aa011a1 193 void (*write) (SCM port, const void *data, size_t size);
affc96b5
GH
194 void (*flush) (SCM port);
195
196 void (*end_input) (SCM port, int offset);
197 int (*fill_input) (SCM port);
198 int (*input_waiting) (SCM port);
199
f1ce9199
LC
200 scm_t_off (*seek) (SCM port, scm_t_off OFFSET, int WHENCE);
201 void (*truncate) (SCM port, scm_t_off length);
affc96b5 202
e140d85d
AW
203 /* When non-NULL, this is the method called by 'setvbuf' for this port.
204 It must create read and write buffers for PORT with the specified
205 sizes (a size of 0 is for unbuffered ports, which should use the
206 'shortbuf' field.) Size -1 means to use the port's preferred buffer
207 size. */
208 void (*setvbuf) (SCM port, long read_size, long write_size);
209
03a2eeb0 210 unsigned flags;
92c2555f 211} scm_t_ptob_descriptor;
1be6b49c 212
12a8b769
DH
213#define SCM_TC2PTOBNUM(x) (0x0ff & ((x) >> 8))
214#define SCM_PTOBNUM(x) (SCM_TC2PTOBNUM (SCM_CELL_TYPE (x)))
f12733c9 215/* SCM_PTOBNAME can be 0 if name is missing */
62bd5d66 216#define SCM_PTOBNAME(ptobnum) (scm_c_port_type_ref (ptobnum)->name)
0f2d19dd 217
a535e9f5 218/* Port types, and their vtables. */
62bd5d66
AW
219SCM_INTERNAL long scm_c_num_port_types (void);
220SCM_API scm_t_ptob_descriptor* scm_c_port_type_ref (long ptobnum);
221SCM_API long scm_c_port_type_add_x (scm_t_ptob_descriptor *desc);
33b001fd
MV
222SCM_API scm_t_bits scm_make_port_type (char *name,
223 int (*fill_input) (SCM port),
224 void (*write) (SCM port,
225 const void *data,
226 size_t size));
23f2b9a3
KR
227SCM_API void scm_set_port_mark (scm_t_bits tc, SCM (*mark) (SCM));
228SCM_API void scm_set_port_free (scm_t_bits tc, size_t (*free) (SCM));
229SCM_API void scm_set_port_print (scm_t_bits tc,
33b001fd
MV
230 int (*print) (SCM exp,
231 SCM port,
232 scm_print_state *pstate));
23f2b9a3
KR
233SCM_API void scm_set_port_equalp (scm_t_bits tc, SCM (*equalp) (SCM, SCM));
234SCM_API void scm_set_port_close (scm_t_bits tc, int (*close) (SCM));
33b001fd 235
62bd5d66 236SCM_API void scm_set_port_flush (scm_t_bits tc, void (*flush) (SCM port));
23f2b9a3 237SCM_API void scm_set_port_end_input (scm_t_bits tc,
62bd5d66
AW
238 void (*end_input) (SCM port,
239 int offset));
23f2b9a3 240SCM_API void scm_set_port_seek (scm_t_bits tc,
f1ce9199
LC
241 scm_t_off (*seek) (SCM port,
242 scm_t_off OFFSET,
243 int WHENCE));
23f2b9a3 244SCM_API void scm_set_port_truncate (scm_t_bits tc,
33b001fd 245 void (*truncate) (SCM port,
f1ce9199 246 scm_t_off length));
23f2b9a3 247SCM_API void scm_set_port_input_waiting (scm_t_bits tc, int (*input_waiting) (SCM));
e140d85d
AW
248SCM_API void scm_set_port_setvbuf (scm_t_bits tc,
249 void (*setvbuf) (SCM, long, long));
a535e9f5
AW
250
251/* The input, output, error, and load ports. */
33b001fd
MV
252SCM_API SCM scm_current_input_port (void);
253SCM_API SCM scm_current_output_port (void);
254SCM_API SCM scm_current_error_port (void);
3972de76 255SCM_API SCM scm_current_warning_port (void);
33b001fd
MV
256SCM_API SCM scm_current_load_port (void);
257SCM_API SCM scm_set_current_input_port (SCM port);
258SCM_API SCM scm_set_current_output_port (SCM port);
259SCM_API SCM scm_set_current_error_port (SCM port);
3972de76 260SCM_API SCM scm_set_current_warning_port (SCM port);
661ae7ab
MV
261SCM_API void scm_dynwind_current_input_port (SCM port);
262SCM_API void scm_dynwind_current_output_port (SCM port);
263SCM_API void scm_dynwind_current_error_port (SCM port);
a535e9f5
AW
264SCM_INTERNAL void scm_i_dynwind_current_load_port (SCM port);
265
266/* Mode bits. */
267SCM_INTERNAL long scm_i_mode_bits (SCM modes);
268SCM_API long scm_mode_bits (char *modes);
269SCM_API SCM scm_port_mode (SCM port);
2721f918 270
a535e9f5 271/* Low-level constructors. */
2721f918
AW
272SCM_API SCM
273scm_c_make_port_with_encoding (scm_t_bits tag,
274 unsigned long mode_bits,
275 const char *encoding,
276 scm_t_string_failed_conversion_handler handler,
277 scm_t_bits stream);
278SCM_API SCM scm_c_make_port (scm_t_bits tag, unsigned long mode_bits,
279 scm_t_bits stream);
891702ea 280SCM_API SCM scm_new_port_table_entry (scm_t_bits tag);
2721f918 281
a535e9f5
AW
282/* Predicates. */
283SCM_API SCM scm_port_p (SCM x);
284SCM_API SCM scm_input_port_p (SCM x);
285SCM_API SCM scm_output_port_p (SCM x);
286SCM_API SCM scm_port_closed_p (SCM port);
287SCM_API SCM scm_eof_object_p (SCM x);
288
289/* Closing ports. */
290SCM_API SCM scm_close_port (SCM port);
291SCM_API SCM scm_close_input_port (SCM port);
292SCM_API SCM scm_close_output_port (SCM port);
293
294/* Encoding characters to byte streams, and decoding byte streams to
295 characters. */
296SCM_INTERNAL const char *scm_i_default_port_encoding (void);
297SCM_INTERNAL void scm_i_set_default_port_encoding (const char *);
0dd7c540
AW
298SCM_INTERNAL scm_t_string_failed_conversion_handler
299scm_i_default_port_conversion_handler (void);
300SCM_INTERNAL void
301scm_i_set_default_port_conversion_handler (scm_t_string_failed_conversion_handler);
a535e9f5
AW
302SCM_INTERNAL void scm_i_set_port_encoding_x (SCM port, const char *str);
303SCM_API SCM scm_port_encoding (SCM port);
304SCM_API SCM scm_set_port_encoding_x (SCM port, SCM encoding);
a535e9f5
AW
305SCM_API SCM scm_port_conversion_strategy (SCM port);
306SCM_API SCM scm_set_port_conversion_strategy_x (SCM port, SCM behavior);
307
308/* Acquiring and releasing the port lock. */
14dcb5cc 309SCM_API void scm_dynwind_lock_port (SCM port);
92c0ebac
AW
310SCM_INLINE int scm_c_lock_port (SCM port, scm_i_pthread_mutex_t **lock);
311SCM_INLINE int scm_c_try_lock_port (SCM port, scm_i_pthread_mutex_t **lock);
30b126d2 312
a535e9f5 313/* Input. */
0d959103 314SCM_API int scm_get_byte_or_eof (SCM port);
0d959103 315SCM_INLINE int scm_get_byte_or_eof_unlocked (SCM port);
f6f4feb0 316SCM_API int scm_slow_get_byte_or_eof_unlocked (SCM port);
c932ce0b 317SCM_API int scm_peek_byte_or_eof (SCM port);
0d959103 318SCM_INLINE int scm_peek_byte_or_eof_unlocked (SCM port);
f6f4feb0 319SCM_API int scm_slow_peek_byte_or_eof_unlocked (SCM port);
33b001fd 320SCM_API size_t scm_c_read (SCM port, void *buffer, size_t size);
be632904 321SCM_API size_t scm_c_read_unlocked (SCM port, void *buffer, size_t size);
a535e9f5 322SCM_API scm_t_wchar scm_getc (SCM port);
be632904 323SCM_API scm_t_wchar scm_getc_unlocked (SCM port);
a535e9f5
AW
324SCM_API SCM scm_read_char (SCM port);
325
326/* Pushback. */
7f6c3f8f 327SCM_API void scm_unget_bytes (const unsigned char *buf, size_t len, SCM port);
f6f4feb0 328SCM_API void scm_unget_bytes_unlocked (const unsigned char *buf, size_t len, SCM port);
5bbd632f 329SCM_API void scm_unget_byte (int c, SCM port);
a3ded465 330SCM_API void scm_unget_byte_unlocked (int c, SCM port);
a535e9f5 331SCM_API void scm_ungetc (scm_t_wchar c, SCM port);
c932ce0b 332SCM_API void scm_ungetc_unlocked (scm_t_wchar c, SCM port);
a535e9f5 333SCM_API void scm_ungets (const char *s, int n, SCM port);
c932ce0b 334SCM_API void scm_ungets_unlocked (const char *s, int n, SCM port);
19b8d12b 335SCM_API SCM scm_peek_char (SCM port);
a535e9f5
AW
336SCM_API SCM scm_unread_char (SCM cobj, SCM port);
337SCM_API SCM scm_unread_string (SCM str, SCM port);
338
339/* Manipulating the buffers. */
340SCM_API void scm_port_non_buffer (scm_t_port *pt);
341SCM_API int scm_fill_input (SCM port);
4251ae2e 342SCM_API int scm_fill_input_unlocked (SCM port);
a535e9f5
AW
343SCM_INTERNAL size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len);
344SCM_API SCM scm_drain_input (SCM port);
345SCM_API void scm_end_input (SCM port);
4251ae2e 346SCM_API void scm_end_input_unlocked (SCM port);
a535e9f5
AW
347SCM_API SCM scm_force_output (SCM port);
348SCM_API void scm_flush (SCM port);
4251ae2e 349SCM_API void scm_flush_unlocked (SCM port);
a535e9f5
AW
350
351/* Output. */
0607ebbf
AW
352SCM_API void scm_putc (char c, SCM port);
353SCM_INLINE void scm_putc_unlocked (char c, SCM port);
354SCM_API void scm_puts (const char *str_data, SCM port);
355SCM_INLINE void scm_puts_unlocked (const char *str_data, SCM port);
33b001fd 356SCM_API void scm_c_write (SCM port, const void *buffer, size_t size);
f209aeee 357SCM_API void scm_c_write_unlocked (SCM port, const void *buffer, size_t size);
33b001fd 358SCM_API void scm_lfwrite (const char *ptr, size_t size, SCM port);
f209aeee 359SCM_API void scm_lfwrite_unlocked (const char *ptr, size_t size, SCM port);
9c44cd45
MG
360SCM_INTERNAL void scm_lfwrite_substr (SCM str, size_t start, size_t end,
361 SCM port);
a535e9f5
AW
362
363/* Querying and setting positions, and character availability. */
364SCM_API SCM scm_char_ready_p (SCM port);
33b001fd
MV
365SCM_API SCM scm_seek (SCM object, SCM offset, SCM whence);
366SCM_API SCM scm_truncate_file (SCM object, SCM length);
367SCM_API SCM scm_port_line (SCM port);
368SCM_API SCM scm_set_port_line_x (SCM port, SCM line);
369SCM_API SCM scm_port_column (SCM port);
370SCM_API SCM scm_set_port_column_x (SCM port, SCM line);
371SCM_API SCM scm_port_filename (SCM port);
372SCM_API SCM scm_set_port_filename_x (SCM port, SCM filename);
a535e9f5 373
9b95f3ce 374/* Port properties. */
a38024ba
MW
375SCM_INTERNAL SCM scm_i_port_property (SCM port, SCM key);
376SCM_INTERNAL SCM scm_i_set_port_property_x (SCM port, SCM key, SCM value);
b22e94db 377
a535e9f5 378/* Implementation helpers for port printing functions. */
33b001fd
MV
379SCM_API int scm_port_print (SCM exp, SCM port, scm_print_state *);
380SCM_API void scm_print_port_mode (SCM exp, SCM port);
a535e9f5
AW
381
382/* Iterating over all ports. */
383SCM_API SCM scm_port_for_each (SCM proc);
384SCM_API void scm_c_port_for_each (void (*proc)(void *data, SCM p), void *data);
385SCM_API SCM scm_flush_all_ports (void);
386
387/* Void ports. */
33b001fd
MV
388SCM_API SCM scm_void_port (char * mode_str);
389SCM_API SCM scm_sys_make_void_port (SCM mode);
d617ee18 390
a535e9f5
AW
391/* Initialization. */
392SCM_INTERNAL void scm_init_ports (void);
d617ee18
MV
393
394
fca14149
AW
395/* Inline function implementations. */
396
397#if SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES
398SCM_INLINE_IMPLEMENTATION int
92c0ebac 399scm_c_lock_port (SCM port, scm_i_pthread_mutex_t **lock)
fca14149 400{
92c0ebac 401 *lock = SCM_PTAB_ENTRY (port)->lock;
fca14149 402
92c0ebac
AW
403 if (*lock)
404 return scm_i_pthread_mutex_lock (*lock);
405 else
406 return 0;
fca14149
AW
407}
408
409SCM_INLINE_IMPLEMENTATION int
92c0ebac 410scm_c_try_lock_port (SCM port, scm_i_pthread_mutex_t **lock)
fca14149 411{
92c0ebac
AW
412 *lock = SCM_PTAB_ENTRY (port)->lock;
413 if (*lock)
414 {
415 int ret = scm_i_pthread_mutex_trylock (*lock);
416 if (ret != 0)
417 *lock = NULL;
418 return ret;
419 }
420 else
421 return 0;
fca14149
AW
422}
423
424SCM_INLINE_IMPLEMENTATION int
0d959103 425scm_get_byte_or_eof_unlocked (SCM port)
fca14149 426{
fca14149
AW
427 scm_t_port *pt = SCM_PTAB_ENTRY (port);
428
f6f4feb0
MW
429 if (SCM_LIKELY ((pt->rw_active == SCM_PORT_READ || !pt->rw_random)
430 && pt->read_pos < pt->read_end))
431 return *pt->read_pos++;
432 else
433 return scm_slow_get_byte_or_eof_unlocked (port);
fca14149
AW
434}
435
436/* Like `scm_get_byte_or_eof' but does not change PORT's `read_pos'. */
437SCM_INLINE_IMPLEMENTATION int
0d959103 438scm_peek_byte_or_eof_unlocked (SCM port)
fca14149 439{
fca14149
AW
440 scm_t_port *pt = SCM_PTAB_ENTRY (port);
441
f6f4feb0
MW
442 if (SCM_LIKELY ((pt->rw_active == SCM_PORT_READ || !pt->rw_random)
443 && pt->read_pos < pt->read_end))
444 return *pt->read_pos;
445 else
446 return scm_slow_peek_byte_or_eof_unlocked (port);
fca14149
AW
447}
448
449SCM_INLINE_IMPLEMENTATION void
0607ebbf 450scm_putc_unlocked (char c, SCM port)
fca14149
AW
451{
452 SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
f209aeee 453 scm_lfwrite_unlocked (&c, 1, port);
fca14149
AW
454}
455
456SCM_INLINE_IMPLEMENTATION void
0607ebbf 457scm_puts_unlocked (const char *s, SCM port)
fca14149
AW
458{
459 SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
f209aeee 460 scm_lfwrite_unlocked (s, strlen (s), port);
fca14149
AW
461}
462#endif /* SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES */
463
22a52da1 464#endif /* SCM_PORTS_H */
89e00824
ML
465
466/*
467 Local Variables:
468 c-file-style: "gnu"
469 End:
470*/