1/* Copyright (C) 2009-2020 Free Software Foundation, Inc.
2   Contributed by Janne Blomqvist
3
4This file is part of the GNU Fortran runtime library (libgfortran).
5
6Libgfortran is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 3, or (at your option)
9any later version.
10
11Libgfortran is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23<http://www.gnu.org/licenses/>.  */
24
25#ifndef GFOR_FBUF_H
26#define GFOR_FBUF_H
27
28#include "io.h"
29
30
31/* Formatting buffer. This is a temporary scratch buffer used by
32   formatted read and writes.  After every formatted I/O statement,
33   this buffer is flushed. This buffer is needed since not all devices
34   are seekable, and T or TL edit descriptors require moving backwards
35   in the record.  However, advance='no' complicates the situation, so
36   the buffer must only be partially flushed from the end of the last
37   flush until the current position in the record. */
38
39struct fbuf
40{
41  char *buf;			/* Start of buffer.  */
42  size_t len;			/* Length of buffer.  */
43  size_t act;			/* Active bytes in buffer.  */
44  size_t pos;			/* Current position in buffer.  */
45};
46
47extern void fbuf_init (gfc_unit *, size_t);
48internal_proto(fbuf_init);
49
50extern void fbuf_destroy (gfc_unit *);
51internal_proto(fbuf_destroy);
52
53extern ptrdiff_t fbuf_reset (gfc_unit *);
54internal_proto(fbuf_reset);
55
56extern char *fbuf_alloc (gfc_unit *, size_t);
57internal_proto(fbuf_alloc);
58
59extern int fbuf_flush (gfc_unit *, unit_mode);
60internal_proto(fbuf_flush);
61
62extern int fbuf_flush_list (gfc_unit *, unit_mode);
63internal_proto(fbuf_flush_list);
64
65extern ptrdiff_t fbuf_seek (gfc_unit *, ptrdiff_t, int);
66internal_proto(fbuf_seek);
67
68extern char *fbuf_read (gfc_unit *, size_t *);
69internal_proto(fbuf_read);
70
71/* Never call this function, only use fbuf_getc().  */
72extern int fbuf_getc_refill (gfc_unit *);
73internal_proto(fbuf_getc_refill);
74
75static inline int
76fbuf_getc (gfc_unit *u)
77{
78  if (u->fbuf->pos < u->fbuf->act)
79    return (unsigned char) u->fbuf->buf[u->fbuf->pos++];
80  return fbuf_getc_refill (u);
81}
82
83static inline char *
84fbuf_getptr (gfc_unit *u)
85{
86  return (char*) (u->fbuf->buf + u->fbuf->pos);
87}
88
89#endif
90