You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/11/24 03:00:50 UTC

[incubator-nuttx] branch master updated: libs/libc: add interface to support output stream as buffer style

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new e228434  libs/libc: add interface to support output stream as buffer style
e228434 is described below

commit e228434ceaabe60e7131368b3f5af9d5fa9106d9
Author: chao.an <an...@xiaomi.com>
AuthorDate: Mon Nov 22 23:51:00 2021 +0800

    libs/libc: add interface to support output stream as buffer style
    
    Signed-off-by: chao.an <an...@xiaomi.com>
---
 include/nuttx/streams.h            |  3 +++
 libs/libc/stdio/lib_memoutstream.c | 27 +++++++++++++++----
 libs/libc/stdio/lib_rawsostream.c  | 54 +++++++++++++++++++++-----------------
 libs/libc/stdio/lib_stdoutstream.c | 48 +++++++++++++++++++++------------
 4 files changed, 86 insertions(+), 46 deletions(-)

diff --git a/include/nuttx/streams.h b/include/nuttx/streams.h
index 8b63e8c..d10ad46 100644
--- a/include/nuttx/streams.h
+++ b/include/nuttx/streams.h
@@ -39,6 +39,8 @@ typedef CODE int  (*lib_getc_t)(FAR struct lib_instream_s *this);
 
 struct lib_outstream_s;
 typedef CODE void (*lib_putc_t)(FAR struct lib_outstream_s *this, int ch);
+typedef CODE int  (*lib_puts_t)(FAR struct lib_outstream_s *this,
+                                FAR const void *buf, int len);
 typedef CODE int  (*lib_flush_t)(FAR struct lib_outstream_s *this);
 
 struct lib_instream_s
@@ -51,6 +53,7 @@ struct lib_instream_s
 struct lib_outstream_s
 {
   lib_putc_t             put;     /* Put one character to the outstream */
+  lib_puts_t             puts;    /* Writes the string to the outstream */
   lib_flush_t            flush;   /* Flush any buffered characters in the outstream */
   int                    nput;    /* Total number of characters put.  Written
                                    * by put method, readable by user */
diff --git a/libs/libc/stdio/lib_memoutstream.c b/libs/libc/stdio/lib_memoutstream.c
index 2fba9b0..d035eb2 100644
--- a/libs/libc/stdio/lib_memoutstream.c
+++ b/libs/libc/stdio/lib_memoutstream.c
@@ -31,13 +31,15 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: memoutstream_putc
+ * Name: memoutstream_puts
  ****************************************************************************/
 
-static void memoutstream_putc(FAR struct lib_outstream_s *this, int ch)
+static int memoutstream_puts(FAR struct lib_outstream_s *this,
+                             FAR const void *buf, int len)
 {
   FAR struct lib_memoutstream_s *mthis =
                                 (FAR struct lib_memoutstream_s *)this;
+  int ncopy;
 
   DEBUGASSERT(this);
 
@@ -46,12 +48,26 @@ static void memoutstream_putc(FAR struct lib_outstream_s *this, int ch)
    * created so it is okay to write past the end of the buflen by one.
    */
 
-  if (this->nput < mthis->buflen)
+  ncopy = mthis->buflen - this->nput >= len ?
+          len : mthis->buflen - this->nput;
+  if (ncopy > 0)
     {
-      mthis->buffer[this->nput] = ch;
-      this->nput++;
+      memcpy(mthis->buffer + this->nput, buf, ncopy);
+      this->nput += ncopy;
       mthis->buffer[this->nput] = '\0';
     }
+
+  return ncopy;
+}
+
+/****************************************************************************
+ * Name: memoutstream_putc
+ ****************************************************************************/
+
+static void memoutstream_putc(FAR struct lib_outstream_s *this, int ch)
+{
+  char tmp = ch;
+  (void)memoutstream_puts(this, &tmp, 1);
 }
 
 /****************************************************************************
@@ -79,6 +95,7 @@ void lib_memoutstream(FAR struct lib_memoutstream_s *outstream,
                       FAR char *bufstart, int buflen)
 {
   outstream->public.put   = memoutstream_putc;
+  outstream->public.puts  = memoutstream_puts;
   outstream->public.flush = lib_noflush;
   outstream->public.nput  = 0;          /* Will be buffer index */
   outstream->buffer       = bufstart;   /* Start of buffer */
diff --git a/libs/libc/stdio/lib_rawsostream.c b/libs/libc/stdio/lib_rawsostream.c
index e584900..9af34ad 100644
--- a/libs/libc/stdio/lib_rawsostream.c
+++ b/libs/libc/stdio/lib_rawsostream.c
@@ -37,41 +37,46 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: rawoutstream_putc
+ * Name: rawoutstream_puts
  ****************************************************************************/
 
-static void rawoutstream_putc(FAR struct lib_outstream_s *this, int ch)
+static int rawoutstream_puts(FAR struct lib_outstream_s *this,
+                             FAR const void *buf, int len)
 {
   FAR struct lib_rawoutstream_s *rthis =
                                 (FAR struct lib_rawoutstream_s *)this;
-  char buffer = ch;
-  int nwritten;
-  int errcode;
-
-  DEBUGASSERT(this && rthis->fd >= 0);
-
-  /* Loop until the character is successfully transferred or until an
-   * irrecoverable error occurs.
-   */
+  int nwritten = 0;
+  int ret;
 
-  do
+  while (1)
     {
-      nwritten = _NX_WRITE(rthis->fd, &buffer, 1);
-      if (nwritten == 1)
+      ret = _NX_WRITE(rthis->fd, (FAR const char *)buf + nwritten,
+                      len - nwritten);
+      if (ret <= 0)
         {
-          this->nput++;
-          return;
-        }
+          if (_NX_GETERRNO(ret) == EINTR)
+            {
+              continue;
+            }
 
-      /* The only expected error is EINTR, meaning that the write operation
-       * was awakened by a signal.  Zero or values > 1 would not be valid
-       * return values from _NX_WRITE().
-       */
+          break;
+        }
 
-      errcode = _NX_GETERRNO(nwritten);
-      DEBUGASSERT(nwritten < 0);
+      this->nput += ret;
+      nwritten   += ret;
     }
-  while (errcode == EINTR);
+
+  return nwritten > 0 ? nwritten : ret;
+}
+
+/****************************************************************************
+ * Name: rawoutstream_putc
+ ****************************************************************************/
+
+static void rawoutstream_putc(FAR struct lib_outstream_s *this, int ch)
+{
+  char tmp = ch;
+  (void)rawoutstream_puts(this, &tmp, 1);
 }
 
 /****************************************************************************
@@ -98,6 +103,7 @@ static void rawoutstream_putc(FAR struct lib_outstream_s *this, int ch)
 void lib_rawoutstream(FAR struct lib_rawoutstream_s *outstream, int fd)
 {
   outstream->public.put   = rawoutstream_putc;
+  outstream->public.puts  = rawoutstream_puts;
   outstream->public.flush = lib_noflush;
   outstream->public.nput  = 0;
   outstream->fd           = fd;
diff --git a/libs/libc/stdio/lib_stdoutstream.c b/libs/libc/stdio/lib_stdoutstream.c
index beb4157..903acb2 100644
--- a/libs/libc/stdio/lib_stdoutstream.c
+++ b/libs/libc/stdio/lib_stdoutstream.c
@@ -33,35 +33,48 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: stdoutstream_putc
+ * Name: stdoutstream_puts
  ****************************************************************************/
 
-static void stdoutstream_putc(FAR struct lib_outstream_s *this, int ch)
+static int stdoutstream_puts(FAR struct lib_outstream_s *this,
+                             FAR const void *buf, int len)
 {
   FAR struct lib_stdoutstream_s *sthis =
                                (FAR struct lib_stdoutstream_s *)this;
-  int result;
+  int nwritten = 0;
+  int ret;
 
   DEBUGASSERT(this && sthis->stream);
 
-  /* Loop until the character is successfully transferred or an irrecoverable
-   * error occurs.
-   */
-
-  do
+  while (1)
     {
-      result = fputc(ch, sthis->stream);
-      if (result != EOF)
+      ret = fwrite((FAR char *)buf + nwritten,
+                    len - nwritten, 1, sthis->stream);
+      if (ret <= 0)
         {
-          this->nput++;
-          return;
+          if (_NX_GETERRNO(ret) == EINTR)
+            {
+              continue;
+            }
+
+          break;
         }
 
-      /* EINTR (meaning that fputc was interrupted by a signal) is the only
-       * recoverable error.
-       */
+      this->nput += ret;
+      nwritten   += ret;
     }
-  while (get_errno() == EINTR);
+
+  return nwritten > 0 ? nwritten : ret;
+}
+
+/****************************************************************************
+ * Name: stdoutstream_putc
+ ****************************************************************************/
+
+static void stdoutstream_putc(FAR struct lib_outstream_s *this, int ch)
+{
+  char tmp = ch;
+  (void)stdoutstream_puts(this, &tmp, 1);
 }
 
 /****************************************************************************
@@ -105,7 +118,8 @@ void lib_stdoutstream(FAR struct lib_stdoutstream_s *outstream,
 {
   /* Select the put operation */
 
-  outstream->public.put = stdoutstream_putc;
+  outstream->public.put  = 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