summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2014-06-14 16:19:42 -0600
committerGregory Nutt <gnutt@nuttx.org>2014-06-14 16:19:42 -0600
commit8313fee0c65f94ba27a4c8e0f8289dd53865104c (patch)
tree04a25aaff9ea95add124f2dafd9bab2c98f83a25
parentd5e4bf8a63f61d4fcc678cd6ea0b6adf5a6808a3 (diff)
downloadnuttx-8313fee0c65f94ba27a4c8e0f8289dd53865104c.tar.gz
nuttx-8313fee0c65f94ba27a4c8e0f8289dd53865104c.tar.bz2
nuttx-8313fee0c65f94ba27a4c8e0f8289dd53865104c.zip
Add seekable standard streams
-rw-r--r--nuttx/include/nuttx/streams.h61
-rw-r--r--nuttx/libc/stdio/Make.defs4
-rw-r--r--nuttx/libc/stdio/lib_stdinstream.c20
-rw-r--r--nuttx/libc/stdio/lib_stdoutstream.c26
-rw-r--r--nuttx/libc/stdio/lib_stdsistream.c111
-rw-r--r--nuttx/libc/stdio/lib_stdsostream.c162
6 files changed, 330 insertions, 54 deletions
diff --git a/nuttx/include/nuttx/streams.h b/nuttx/include/nuttx/streams.h
index c74b430ea..848fb85f4 100644
--- a/nuttx/include/nuttx/streams.h
+++ b/nuttx/include/nuttx/streams.h
@@ -246,57 +246,64 @@ void lib_memsostream(FAR struct lib_memsostream_s *outstream,
*
* Description:
* Initializes a stream for use with a FILE instance.
- * Defined in lib/lib_stdinstream.c and lib/lib_stdoutstream.c
+ * Defined in lib/stdio/lib_stdinstream.c and lib/stdio/lib_stdoutstream.c
*
* Input parameters:
- * stdinstream - User allocated, uninitialized instance of struct
- * lib_stdinstream_s to be initialized.
- * stdoutstream - User allocated, uninitialized instance of struct
- * lib_stdoutstream_s to be initialized.
- * stream - User provided stream instance (must have been opened for
- * the correct access).
+ * instream - User allocated, uninitialized instance of struct
+ * lib_stdinstream_s to be initialized.
+ * outstream - User allocated, uninitialized instance of struct
+ * lib_stdoutstream_s to be initialized.
+ * stream - User provided stream instance (must have been opened for
+ * the correct access).
*
* Returned Value:
* None (User allocated instance initialized).
*
****************************************************************************/
-void lib_stdinstream(FAR struct lib_stdinstream_s *stdinstream,
- FAR FILE *stream);
-void lib_stdoutstream(FAR struct lib_stdoutstream_s *stdoutstream,
- FAR FILE *stream);
+void lib_stdinstream(FAR struct lib_stdinstream_s *instream,
+ FAR FILE *stream);
+void lib_stdoutstream(FAR struct lib_stdoutstream_s *outstream,
+ FAR FILE *stream);
+void lib_stdsistream(FAR struct lib_stdsistream_s *instream,
+ FAR FILE *stream);
+void lib_stdsostream(FAR struct lib_stdsostream_s *outstream,
+ FAR FILE *stream);
/****************************************************************************
- * Name: lib_rawinstream, lib_rawoutstream
+ * Name: lib_rawinstream, lib_rawoutstream, lib_rawsistream, and
+ * lib_rawsostream,
*
* Description:
* Initializes a stream for use with a file descriptor.
- * Defined in lib/lib_rawinstream.c and lib/lib_rawoutstream.c
+ * Defined in lib/stdio/lib_rawinstream.c and lib/stdio/lib_rawoutstream.c.
+ * Seekable versions are defined in lib/stdio/lib_rawsistream.c and
+ * lib/stdio/lib_rawsostream.c
*
* Input parameters:
- * rawinstream - User allocated, uninitialized instance of struct
- * lib_rawinstream_s to be initialized.
- * rawoutstream - User allocated, uninitialized instance of struct
- * lib_rawoutstream_s to be initialized.
- * fd - User provided file/socket descriptor (must have been opened
- * for the correct access).
+ * instream - User allocated, uninitialized instance of struct
+ * lib_rawinstream_s to be initialized.
+ * outstream - User allocated, uninitialized instance of struct
+ * lib_rawoutstream_s to be initialized.
+ * fd - User provided file/socket descriptor (must have been opened
+ * for the correct access).
*
* Returned Value:
* None (User allocated instance initialized).
*
****************************************************************************/
-void lib_rawinstream(FAR struct lib_rawinstream_s *rawinstream,
- int fd);
-void lib_rawoutstream(FAR struct lib_rawoutstream_s *rawoutstream,
- int fd);
+void lib_rawinstream(FAR struct lib_rawinstream_s *instream, int fd);
+void lib_rawoutstream(FAR struct lib_rawoutstream_s *outstream, int fd);
+void lib_rawsistream(FAR struct lib_rawsistream_s *instream, int fd);
+void lib_rawsostream(FAR struct lib_rawsostream_s *outstream, int fd);
/****************************************************************************
* Name: lib_lowinstream, lib_lowoutstream
*
* Description:
* Initializes a stream for use with low-level, architecture-specific I/O.
- * Defined in lib/lib_lowinstream.c and lib/lib_lowoutstream.c
+ * Defined in lib/stdio/lib_lowinstream.c and lib/stdio/lib_lowoutstream.c
*
* Input parameters:
* lowinstream - User allocated, uninitialized instance of struct
@@ -323,11 +330,11 @@ void lib_lowoutstream(FAR struct lib_outstream_s *lowoutstream);
* Initializes NULL streams:
*
* o The stream created by lib_zeroinstream will return an infinitely long
- * stream of zeroes. Defined in lib/lib_zeroinstream.c
+ * stream of zeroes. Defined in lib/stdio/lib_zeroinstream.c
* o The stream created by lib_nullinstream will return only EOF.
- * Defined in lib/lib_nullinstream.c
+ * Defined in lib/stdio/lib_nullinstream.c
* o The stream created by lib_nulloutstream will write all data to the
- * bit-bucket. Defined in lib/lib_nulloutstream.c
+ * bit-bucket. Defined in lib/stdio/lib_nulloutstream.c
*
* Input parameters:
* zeroinstream - User allocated, uninitialized instance of struct
diff --git a/nuttx/libc/stdio/Make.defs b/nuttx/libc/stdio/Make.defs
index 9a741581f..484b969ce 100644
--- a/nuttx/libc/stdio/Make.defs
+++ b/nuttx/libc/stdio/Make.defs
@@ -63,8 +63,8 @@ CSRCS += lib_gets_s.c lib_gets.c lib_libfgets.c lib_fwrite.c lib_libfwrite.c
CSRCS += lib_fflush.c lib_libflushall.c lib_libfflush.c lib_rdflush.c
CSRCS += lib_wrflush.c lib_fputc.c lib_puts.c lib_fputs.c lib_ungetc.c
CSRCS += lib_vprintf.c lib_fprintf.c lib_vfprintf.c lib_stdinstream.c
-CSRCS += lib_stdoutstream.c lib_perror.c lib_feof.c lib_ferror.c
-CSRCS += lib_clearerr.c
+CSRCS += lib_stdoutstream.c lib_stdsistream.c lib_stdsostream.c lib_perror.c
+CSRCS += lib_feof.c lib_ferror.c lib_clearerr.c
endif
endif
diff --git a/nuttx/libc/stdio/lib_stdinstream.c b/nuttx/libc/stdio/lib_stdinstream.c
index cf9654465..4b0088878 100644
--- a/nuttx/libc/stdio/lib_stdinstream.c
+++ b/nuttx/libc/stdio/lib_stdinstream.c
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/stdio/lib_stdinstream.c
*
- * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2011-2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -78,22 +78,20 @@ static int stdinstream_getc(FAR struct lib_instream_s *this)
* Initializes a stream for use with a FILE instance.
*
* Input parameters:
- * stdinstream - User allocated, uninitialized instance of struct
- * lib_stdinstream_s to be initialized.
- * stream - User provided stream instance (must have been opened for
- * read access).
+ * instream - User allocated, uninitialized instance of struct
+ * lib_stdinstream_s to be initialized.
+ * stream - User provided stream instance (must have been opened for
+ * read access).
*
* Returned Value:
* None (User allocated instance initialized).
*
****************************************************************************/
-void lib_stdinstream(FAR struct lib_stdinstream_s *stdinstream,
+void lib_stdinstream(FAR struct lib_stdinstream_s *instream,
FAR FILE *stream)
{
- stdinstream->public.get = stdinstream_getc;
- stdinstream->public.nget = 0;
- stdinstream->stream = stream;
+ instream->public.get = stdinstream_getc;
+ instream->public.nget = 0;
+ instream->stream = stream;
}
-
-
diff --git a/nuttx/libc/stdio/lib_stdoutstream.c b/nuttx/libc/stdio/lib_stdoutstream.c
index 74a744772..73321c7fd 100644
--- a/nuttx/libc/stdio/lib_stdoutstream.c
+++ b/nuttx/libc/stdio/lib_stdoutstream.c
@@ -1,7 +1,7 @@
/****************************************************************************
* libc/stdio/lib_stdoutstream.c
*
- * Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
+ * Copyright (C) 2007-2009, 2011-2012, 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@@ -101,22 +101,22 @@ static int stdoutstream_flush(FAR struct lib_outstream_s *this)
* Initializes a stream for use with a FILE instance.
*
* Input parameters:
- * stdoutstream - User allocated, uninitialized instance of struct
- * lib_stdoutstream_s to be initialized.
- * stream - User provided stream instance (must have been opened for
- * write access).
+ * outstream - User allocated, uninitialized instance of struct
+ * lib_stdoutstream_s to be initialized.
+ * stream - User provided stream instance (must have been opened for
+ * write access).
*
* Returned Value:
* None (User allocated instance initialized).
*
****************************************************************************/
-void lib_stdoutstream(FAR struct lib_stdoutstream_s *stdoutstream,
- FAR FILE *stream)
+void lib_stdoutstream(FAR struct lib_stdoutstream_s *outstream,
+ FAR FILE *stream)
{
/* Select the put operation */
- stdoutstream->public.put = stdoutstream_putc;
+ outstream->public.put = stdoutstream_putc;
/* Select the correct flush operation. This flush is only called when
* a newline is encountered in the output stream. However, we do not
@@ -129,19 +129,17 @@ void lib_stdoutstream(FAR struct lib_stdoutstream_s *stdoutstream,
#if CONFIG_STDIO_BUFFER_SIZE > 0
if ((stream->fs_oflags & O_BINARY) == 0)
{
- stdoutstream->public.flush = stdoutstream_flush;
+ outstream->public.flush = stdoutstream_flush;
}
else
#endif
{
- stdoutstream->public.flush = lib_noflush;
+ outstream->public.flush = lib_noflush;
}
#endif
/* Set the number of bytes put to zero and remember the stream */
- stdoutstream->public.nput = 0;
- stdoutstream->stream = stream;
+ outstream->public.nput = 0;
+ outstream->stream = stream;
}
-
-
diff --git a/nuttx/libc/stdio/lib_stdsistream.c b/nuttx/libc/stdio/lib_stdsistream.c
new file mode 100644
index 000000000..85eaf0fe7
--- /dev/null
+++ b/nuttx/libc/stdio/lib_stdsistream.c
@@ -0,0 +1,111 @@
+/****************************************************************************
+ * libc/stdio/lib_stdsistream.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <assert.h>
+
+#include "lib_internal.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stdsistream_getc
+ ****************************************************************************/
+
+static int stdsistream_getc(FAR struct lib_sistream_s *this)
+{
+ FAR struct lib_stdsistream_s *sthis = (FAR struct lib_stdsistream_s *)this;
+ int ret;
+
+ DEBUGASSERT(this);
+
+ /* Get the next character from the incoming stream */
+
+ ret = getc(sthis->stream);
+ if (ret != EOF)
+ {
+ this->nget++;
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stdsistream_seek
+ ****************************************************************************/
+
+static off_t stdsistream_seek(FAR struct lib_sistream_s *this, off_t offset,
+ int whence)
+{
+ FAR struct lib_stdsistream_s *mthis = (FAR struct lib_stdsistream_s *)this;
+
+ DEBUGASSERT(this);
+ return fseek(mthis->stream, offset, whence);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lib_stdsistream
+ *
+ * Description:
+ * Initializes a stream for use with a FILE instance.
+ *
+ * Input parameters:
+ * instream - User allocated, uninitialized instance of struct
+ * lib_stdsistream_s to be initialized.
+ * stream - User provided stream instance (must have been opened for
+ * read access).
+ *
+ * Returned Value:
+ * None (User allocated instance initialized).
+ *
+ ****************************************************************************/
+
+void lib_stdsistream(FAR struct lib_stdsistream_s *instream,
+ FAR FILE *stream)
+{
+ instream->public.get = stdsistream_getc;
+ instream->public.seek = stdsistream_seek;
+ instream->public.nget = 0;
+ instream->stream = stream;
+}
diff --git a/nuttx/libc/stdio/lib_stdsostream.c b/nuttx/libc/stdio/lib_stdsostream.c
new file mode 100644
index 000000000..ade6369c5
--- /dev/null
+++ b/nuttx/libc/stdio/lib_stdsostream.c
@@ -0,0 +1,162 @@
+/****************************************************************************
+ * libc/stdio/lib_stdsostream.c
+ *
+ * Copyright (C) 2014 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <fcntl.h>
+#include <assert.h>
+#include <errno.h>
+
+#include "lib_internal.h"
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stdsostream_putc
+ ****************************************************************************/
+
+static void stdsostream_putc(FAR struct lib_sostream_s *this, int ch)
+{
+ 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 = fputc(ch, sthis->stream);
+ if (result != EOF)
+ {
+ this->nput++;
+ return;
+ }
+
+ /* EINTR (meaning that fputc was interrupted by a signal) is the only
+ * recoverable error.
+ */
+ }
+ while (get_errno() == EINTR);
+}
+
+/****************************************************************************
+ * Name: stdsostream_flush
+ ****************************************************************************/
+
+#if defined(CONFIG_STDIO_LINEBUFFER) && CONFIG_STDIO_BUFFER_SIZE > 0
+static int stdsostream_flush(FAR struct lib_sostream_s *this)
+{
+ FAR struct lib_stdsostream_s *sthis = (FAR struct lib_stdsostream_s *)this;
+ return lib_fflush(sthis->stream, true);
+}
+#endif
+
+/****************************************************************************
+ * Name: stdsostream_seek
+ ****************************************************************************/
+
+static off_t stdsostream_seek(FAR struct lib_sostream_s *this, off_t offset,
+ int whence)
+{
+ FAR struct lib_stdsostream_s *mthis = (FAR struct lib_stdsostream_s *)this;
+
+ DEBUGASSERT(this);
+ return fseek(mthis->stream, offset, whence);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: lib_stdsostream
+ *
+ * Description:
+ * Initializes a stream for use with a FILE instance.
+ *
+ * Input parameters:
+ * outstream - User allocated, uninitialized instance of struct
+ * lib_stdsostream_s to be initialized.
+ * stream - User provided stream instance (must have been opened for
+ * write access).
+ *
+ * Returned Value:
+ * None (User allocated instance initialized).
+ *
+ ****************************************************************************/
+
+void lib_stdsostream(FAR struct lib_stdsostream_s *outstream,
+ FAR FILE *stream)
+{
+ /* Select the put operation */
+
+ outstream->public.put = stdsostream_putc;
+
+ /* Select the correct flush operation. This flush is only called when
+ * a newline is encountered in the output stream. However, we do not
+ * want to support this line buffering behavior if the stream was
+ * opened in binary mode. In binary mode, the newline has no special
+ * meaning.
+ */
+
+#ifdef CONFIG_STDIO_LINEBUFFER
+#if CONFIG_STDIO_BUFFER_SIZE > 0
+ if ((stream->fs_oflags & O_BINARY) == 0)
+ {
+ outstream->public.flush = stdsostream_flush;
+ }
+ else
+#endif
+ {
+ outstream->public.flush = lib_snoflush;
+ }
+#endif
+
+ /* Select the seek operation */
+
+ outstream->public.seek = stdsostream_seek;
+
+ /* Set the number of bytes put to zero and remember the stream */
+
+ outstream->public.nput = 0;
+ outstream->stream = stream;
+}