0 on success, -1 on error.
int Lstream_getc (Lstream *stream)
- Read one byte from the stream. This is a macro and so it
- is very efficient. The STREAM argument is evaluated more
- than once. Return value is -1 for EOF or error.
+ Read one byte from the stream and returns it as an unsigned
+ char cast to an int, or EOF on end of file or error.
+ This is a macro and so it is very efficient. The STREAM
+ argument is evaluated more than once.
void Lstream_ungetc (Lstream *stream, int c)
- Push one byte back onto the input queue. This will be the
- next byte read from the stream. Any number of bytes can be
- pushed back and will be read in the reverse order they were
- pushed back -- most recent first. (This is necessary for
- consistency -- if there are a number of bytes that have been
- unread and I read and unread a byte, it needs to be the first
- to be read again.) This is a macro and so it is very
- efficient. The C argument is only evaluated once but the
- STREAM argument is evaluated more than once.
+ Push one byte back onto the input queue, cast to unsigned char.
+ This will be the next byte read from the stream. Any number
+ of bytes can be pushed back and will be read in the reverse
+ order they were pushed back -- most recent first. (This is
+ necessary for consistency -- if there are a number of bytes
+ that have been unread and I read and unread a byte, it needs
+ to be the first to be read again.) This is a macro and so it
+ is very efficient. The C argument is only evaluated once but
+ the STREAM argument is evaluated more than once.
int Lstream_fputc (Lstream *stream, int c)
int Lstream_fgetc (Lstream *stream)
}
}
+inline static size_t
+aligned_sizeof_lstream (size_t lstream_type_specific_size)
+{
+ return ALIGN_SIZE (offsetof (Lstream, data) + lstream_type_specific_size,
+ ALIGNOF (max_align_t));
+}
+
static size_t
sizeof_lstream (const void *header)
{
- const Lstream *lstr = (const Lstream *) header;
- return sizeof (*lstr) + lstr->imp->size - 1;
+ return aligned_sizeof_lstream (((const Lstream *) header)->imp->size);
}
DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("stream", lstream,
assert (lstream_type_count < countof (lstream_types));
lstream_types[lstream_type_count] = imp;
Vlstream_free_list[lstream_type_count] =
- make_lcrecord_list (sizeof (*p) + imp->size - 1,
+ make_lcrecord_list (aligned_sizeof_lstream (imp->size),
&lrecord_lstream);
lstream_type_count++;
}
p = XLSTREAM (allocate_managed_lcrecord (Vlstream_free_list[i]));
/* Zero it out, except the header. */
- memset ((char *) p + sizeof (p->header), 0,
- sizeof (*p) - sizeof (p->header) + imp->size - 1);
+ memset ((char *) p + sizeof (p->header), '\0',
+ aligned_sizeof_lstream (imp->size) - sizeof (p->header));
p->imp = imp;
Lstream_set_buffering (p, LSTREAM_BLOCK_BUFFERED, 0);
p->flags = LSTREAM_FL_IS_OPEN;
return lstr->imp->was_blocked_p ? lstr->imp->was_blocked_p (lstr) : 0;
}
-static int
+static ssize_t
Lstream_raw_read (Lstream *lstr, unsigned char *buffer, size_t size)
{
if (! (lstr->flags & LSTREAM_FL_IS_OPEN))