libc/streams: Implement gets/puts for all streams

Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
This commit is contained in:
yinshengkai 2023-03-01 21:03:07 +08:00 committed by Xiang Xiao
parent 6e35a51feb
commit 205ca26556
13 changed files with 340 additions and 0 deletions

View File

@ -23,6 +23,7 @@
****************************************************************************/
#include <assert.h>
#include <string.h>
#include "libc.h"
@ -56,6 +57,35 @@ static int meminstream_getc(FAR struct lib_instream_s *this)
return ret;
}
/****************************************************************************
* Name: meminstream_gets
****************************************************************************/
static int meminstream_gets(FAR struct lib_instream_s *this,
FAR void *buffer, int len)
{
FAR struct lib_meminstream_s *mthis = (FAR struct lib_meminstream_s *)this;
int ret;
DEBUGASSERT(this);
/* Get the buffer (if any) from the stream */
if (this->nget < mthis->buflen)
{
ret = mthis->buflen - this->nget < len ?
mthis->buflen - this->nget : len;
this->nget += ret;
memcpy(buffer, mthis->buffer, ret);
}
else
{
ret = EOF;
}
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -81,6 +111,7 @@ void lib_meminstream(FAR struct lib_meminstream_s *instream,
FAR const char *bufstart, int buflen)
{
instream->public.getc = meminstream_getc;
instream->public.gets = meminstream_gets;
instream->public.nget = 0; /* Will be buffer index */
instream->buffer = bufstart; /* Start of buffer */
instream->buflen = buflen; /* Length of the buffer */

View File

@ -57,6 +57,35 @@ static int memsistream_getc(FAR struct lib_sistream_s *this)
return ret;
}
/****************************************************************************
* Name: meminstream_gets
****************************************************************************/
static int memsistream_gets(FAR struct lib_instream_s *this,
FAR void *buffer, int len)
{
FAR struct lib_memsistream_s *mthis = (FAR struct lib_memsistream_s *)this;
int ret;
DEBUGASSERT(this);
/* Get the buffer (if any) from the stream */
if (this->nget < mthis->buflen)
{
ret = mthis->buflen - this->nget;
ret = ret < len ? ret : len;
this->nget += ret;
memcpy(buffer, mthis->buffer, ret);
}
else
{
ret = EOF;
}
return ret;
}
/****************************************************************************
* Name: memsistream_seek
****************************************************************************/
@ -125,6 +154,7 @@ void lib_memsistream(FAR struct lib_memsistream_s *instream,
FAR const char *bufstart, int buflen)
{
instream->public.getc = memsistream_getc;
instream->public.gets = memsistream_gets;
instream->public.seek = memsistream_seek;
instream->public.nget = 0; /* Total number of characters read */
instream->buffer = bufstart; /* Start of buffer */

View File

@ -54,6 +54,31 @@ static void memsostream_putc(FAR struct lib_sostream_s *this, int ch)
}
}
/****************************************************************************
* Name: memoutstream_puts
****************************************************************************/
static int memsostream_puts(FAR struct lib_sostream_s *this,
FAR const void *buf, int len)
{
int ncopy;
FAR struct lib_memsostream_s *mthis = (FAR struct lib_memsostream_s *)this;
DEBUGASSERT(this);
ncopy = mthis->offset + len + 1 < mthis->buflen ? len :
mthis->buflen - mthis->offset - 1;
if (ncopy > 0)
{
memcpy(mthis->buffer + mthis->offset, buf, ncopy);
mthis->public.nput += ncopy;
mthis->offset += ncopy;
mthis->buffer[mthis->offset] = '\0';
}
return ncopy;
}
/****************************************************************************
* Name: memsostream_seek
****************************************************************************/
@ -122,6 +147,7 @@ void lib_memsostream(FAR struct lib_memsostream_s *outstream,
FAR char *bufstart, int buflen)
{
outstream->public.putc = memsostream_putc;
outstream->public.puts = memsostream_puts;
outstream->public.flush = lib_snoflush;
outstream->public.seek = memsostream_seek;
outstream->public.nput = 0; /* Total number of characters written */

View File

@ -37,6 +37,14 @@ static int nullinstream_getc(FAR struct lib_instream_s *this)
return EOF;
}
static int nullinstream_gets(FAR struct lib_instream_s *this,
FAR void *buffer, int len)
{
UNUSED(buffer);
UNUSED(len);
return EOF;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -60,5 +68,6 @@ static int nullinstream_getc(FAR struct lib_instream_s *this)
void lib_nullinstream(FAR struct lib_instream_s *nullinstream)
{
nullinstream->getc = nullinstream_getc;
nullinstream->gets = nullinstream_gets;
nullinstream->nget = 0;
}

View File

@ -39,6 +39,16 @@ static void nulloutstream_putc(FAR struct lib_outstream_s *this, int ch)
this->nput++;
}
static int nulloutstream_puts(FAR struct lib_outstream_s *this,
FAR const void *buffer, int len)
{
UNUSED(buffer);
UNUSED(len);
DEBUGASSERT(this);
this->nput += len;
return len;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -62,6 +72,7 @@ static void nulloutstream_putc(FAR struct lib_outstream_s *this, int ch)
void lib_nulloutstream(FAR struct lib_outstream_s *nulloutstream)
{
nulloutstream->putc = nulloutstream_putc;
nulloutstream->puts = nulloutstream_puts;
nulloutstream->flush = lib_noflush;
nulloutstream->nput = 0;
}

View File

@ -66,6 +66,33 @@ static int rawinstream_getc(FAR struct lib_instream_s *this)
return EOF;
}
/****************************************************************************
* Name: rawinstream_getc
****************************************************************************/
static int rawinstream_gets(FAR struct lib_instream_s *this,
FAR void *buffer, int len)
{
FAR struct lib_rawinstream_s *rthis = (FAR struct lib_rawinstream_s *)this;
int nread;
DEBUGASSERT(this && rthis->fd >= 0);
/* Attempt to read one character */
nread = _NX_READ(rthis->fd, buffer, len);
if (nread >= 0)
{
this->nget += nread;
}
else
{
nread = _NX_GETERRVAL(nread);
}
return nread;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -90,6 +117,7 @@ static int rawinstream_getc(FAR struct lib_instream_s *this)
void lib_rawinstream(FAR struct lib_rawinstream_s *instream, int fd)
{
instream->public.getc = rawinstream_getc;
instream->public.gets = rawinstream_gets;
instream->public.nget = 0;
instream->fd = fd;
}

View File

@ -66,6 +66,33 @@ static int rawsistream_getc(FAR struct lib_sistream_s *this)
return EOF;
}
/****************************************************************************
* Name: rawsistream_gets
****************************************************************************/
static int rawsistream_gets(FAR struct lib_instream_s *this,
FAR void *buffer, int len)
{
FAR struct lib_rawsistream_s *rthis = (FAR struct lib_rawsistream_s *)this;
int nread;
DEBUGASSERT(this && rthis->fd >= 0);
/* Attempt to read a buffer */
nread = _NX_READ(rthis->fd, buffer, len);
if (nread >= 0)
{
this->nget += nread;
}
else
{
nread = _NX_GETERRVAL(nread);
}
return nread;
}
/****************************************************************************
* Name: rawsistream_seek
****************************************************************************/
@ -103,6 +130,7 @@ static off_t rawsistream_seek(FAR struct lib_sistream_s *this, off_t offset,
void lib_rawsistream(FAR struct lib_rawsistream_s *instream, int fd)
{
instream->public.getc = rawsistream_getc;
instream->public.gets = rawsistream_gets;
instream->public.seek = rawsistream_seek;
instream->public.nget = 0;
instream->fd = fd;

View File

@ -73,6 +73,44 @@ static void rawsostream_putc(FAR struct lib_sostream_s *this, int ch)
while (errcode == EINTR);
}
/****************************************************************************
* Name: rawsostream_puts
****************************************************************************/
static int rawsostream_puts(FAR struct lib_sostream_s *this,
FAR const void *buffer, int len)
{
FAR struct lib_rawsostream_s *rthis = (FAR struct lib_rawsostream_s *)this;
int nwritten;
DEBUGASSERT(this && rthis->fd >= 0);
/* Loop until the buffer is successfully transferred or until an
* irrecoverable error occurs.
*/
do
{
nwritten = _NX_WRITE(rthis->fd, buffer, len);
if (nwritten >= 0)
{
this->nput += nwritten;
return nwritten;
}
/* The only expected error is EINTR, meaning that the write operation
* was awakened by a signal. Zero would not be a valid return value
* from _NX_WRITE().
*/
nwritten = _NX_GETERRVAL(nwritten);
DEBUGASSERT(nwritten < 0);
}
while (nwritten == -EINTR);
return nwritten;
}
/****************************************************************************
* Name: rawsostream_seek
****************************************************************************/
@ -110,6 +148,7 @@ static off_t rawsostream_seek(FAR struct lib_sostream_s *this, off_t offset,
void lib_rawsostream(FAR struct lib_rawsostream_s *outstream, int fd)
{
outstream->public.putc = rawsostream_putc;
outstream->public.puts = rawsostream_puts;
outstream->public.flush = lib_snoflush;
outstream->public.seek = rawsostream_seek;
outstream->public.nput = 0;

View File

@ -23,6 +23,7 @@
****************************************************************************/
#include <assert.h>
#include <stdio.h>
#include "libc.h"
@ -52,6 +53,33 @@ static int stdinstream_getc(FAR struct lib_instream_s *this)
return ret;
}
/****************************************************************************
* Name: stdinstream_gets
****************************************************************************/
static int stdinstream_gets(FAR struct lib_instream_s *this,
FAR void *buffer, int len)
{
FAR struct lib_stdinstream_s *sthis = (FAR struct lib_stdinstream_s *)this;
int nread = 0;
DEBUGASSERT(this);
/* Get the buffer from the incoming stream */
nread = fread(buffer, len, 1, sthis->stream);
if (nread >= 0)
{
this->nget += nread;
}
else
{
nread = _NX_GETERRVAL(nread);
}
return nread;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -77,6 +105,7 @@ void lib_stdinstream(FAR struct lib_stdinstream_s *instream,
FAR FILE *stream)
{
instream->public.getc = stdinstream_getc;
instream->public.gets = stdinstream_gets;
instream->public.nget = 0;
instream->stream = stream;
}

View File

@ -25,6 +25,7 @@
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include "libc.h"
@ -64,6 +65,43 @@ static void stdoutstream_putc(FAR struct lib_outstream_s *this, int ch)
while (get_errno() == EINTR);
}
/****************************************************************************
* Name: stdoutstream_puts
****************************************************************************/
static int stdoutstream_puts(FAR struct lib_outstream_s *this,
FAR const void *buffer, int len)
{
FAR struct lib_stdoutstream_s *sthis =
(FAR struct lib_stdoutstream_s *)this;
int result;
DEBUGASSERT(this && sthis->stream);
/* Loop until the buffer is successfully transferred or an irrecoverable
* error occurs.
*/
do
{
result = fwrite(buffer, len, 1, sthis->stream);
if (result >= 0)
{
this->nput += result;
return result;
}
result = _NX_GETERRVAL(result);
/* EINTR (meaning that fputc was interrupted by a signal) is the only
* recoverable error.
*/
}
while (result == -EINTR);
return result;
}
/****************************************************************************
* Name: stdoutstream_flush
****************************************************************************/
@ -106,6 +144,7 @@ void lib_stdoutstream(FAR struct lib_stdoutstream_s *outstream,
/* Select the putc operation */
outstream->public.putc = stdoutstream_putc;
outstream->public.puts = stdoutstream_puts;
/* Select the correct flush operation. This flush is only called when
* a newline is encountered in the output stream. However, we do not

View File

@ -52,6 +52,29 @@ static int stdsistream_getc(FAR struct lib_sistream_s *this)
return ret;
}
/****************************************************************************
* Name: stdsistream_gets
****************************************************************************/
static int stdsistream_gets(FAR struct lib_instream_s *this,
FAR void *buffer, int len)
{
FAR struct lib_stdsistream_s *sthis = (FAR struct lib_stdsistream_s *)this;
int nread = 0;
DEBUGASSERT(this);
/* Get the buffer from the incoming stream */
nread = fread(buffer, len, 1, sthis->stream);
if (nread >= 0)
{
this->nget += nread;
}
return nread;
}
/****************************************************************************
* Name: stdsistream_seek
****************************************************************************/
@ -90,6 +113,7 @@ void lib_stdsistream(FAR struct lib_stdsistream_s *instream,
FAR FILE *stream)
{
instream->public.getc = stdsistream_getc;
instream->public.gets = stdsistream_gets;
instream->public.seek = stdsistream_seek;
instream->public.nget = 0;
instream->stream = stream;

View File

@ -63,6 +63,42 @@ static void stdsostream_putc(FAR struct lib_sostream_s *this, int ch)
while (get_errno() == EINTR);
}
/****************************************************************************
* Name: stdsostream_puts
****************************************************************************/
static int stdsostream_puts(FAR struct lib_sostream_s *this,
FAR const void *buffer, int len)
{
FAR struct lib_stdsostream_s *sthis = (FAR struct lib_stdsostream_s *)this;
int result;
DEBUGASSERT(this && sthis->stream);
/* Loop until the character is successfully transferred or an irrecoverable
* error occurs.
*/
do
{
result = lib_fwrite(buffer, len, sthis->stream);
if (result >= 0)
{
this->nput += result;
return result;
}
result = _NX_GETERRVAL(result);
/* EINTR (meaning that fputc was interrupted by a signal) is the only
* recoverable error.
*/
}
while (result == -EINTR);
return result;
}
/****************************************************************************
* Name: stdsostream_flush
****************************************************************************/
@ -117,6 +153,7 @@ void lib_stdsostream(FAR struct lib_stdsostream_s *outstream,
/* Select the putc operation */
outstream->public.putc = stdsostream_putc;
outstream->public.puts = stdsostream_puts;
/* Select the correct flush operation. This flush is only called when
* a newline is encountered in the output stream. However, we do not

View File

@ -36,6 +36,14 @@ static int zeroinstream_getc(FAR struct lib_instream_s *this)
return 0;
}
static int zeroinstream_gets(FAR struct lib_instream_s *this,
FAR void *buffer, int len)
{
this->nget += len;
memset(buffer, 0, len);
return len;
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -59,5 +67,6 @@ static int zeroinstream_getc(FAR struct lib_instream_s *this)
void lib_zeroinstream(FAR struct lib_instream_s *zeroinstream)
{
zeroinstream->getc = zeroinstream_getc;
zeroinstream->gets = zeroinstream_gets;
zeroinstream->nget = 0;
}