libc/streams: Implement gets/puts for all streams
Signed-off-by: yinshengkai <yinshengkai@xiaomi.com>
This commit is contained in:
parent
6e35a51feb
commit
205ca26556
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user