]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - packages/language/c/libc/stdio/v2_0/src/common/vsnprintf.cxx
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / language / c / libc / stdio / v2_0 / src / common / vsnprintf.cxx
index 988e1160a5f6f07ccb64a46baa2e1106101932d0..17b7c0c06f610106e5e23f991b29285527dc760b 100644 (file)
 #include <stddef.h>                 // NULL and size_t from compiler
 #include <stdio.h>                  // header for this file
 #include <errno.h>                  // error codes
-#include <cyg/io/devtab.h>          // Device table
 #include <cyg/libc/stdio/stream.hxx>// Cyg_StdioStream
 
 #include <cyg/libc/stdio/io.inl>     // I/O system inlines
 
-#ifndef CYGPKG_LIBC_STDIO_FILEIO
-
 // FUNCTIONS
 
-static Cyg_ErrNo
-str_write(cyg_stdio_handle_t handle, const void *buf, cyg_uint32 *len)
+class Cyg_VsnprintfStream: public Cyg_OutputStream
 {
-    cyg_devtab_entry_t *dev = (cyg_devtab_entry_t *)handle;
-    cyg_uint8 **str_p = (cyg_uint8 **)dev->priv;
-    cyg_ucount32 i;
-
-    // I suspect most strings passed to vsnprintf will be relatively short,
-    // so we just take the simple approach rather than have the overhead
-    // of calling memcpy etc.
+public:
+    Cyg_VsnprintfStream(char* s): s_(s) {}
 
-    // simply copy string until we run out of user space
+    virtual ~Cyg_VsnprintfStream() { *s_ = '\0'; }
 
-    for (i = 0; i < *len; i++, (*str_p)++ )
-    {
-        **str_p = *((cyg_uint8 *)buf + i);
-    } // for
+    virtual Cyg_ErrNo write( const cyg_uint8 *buffer,
+        cyg_ucount32 buffer_length, cyg_ucount32 *bytes_written );
 
-    *len = i;
+    virtual Cyg_ErrNo get_error( void ) { return ENOERR; }
 
-    return ENOERR;
-    
-} // str_write()
+private:
+    char* s_;
+};
 
-static DEVIO_TABLE(devio_table,
-                   str_write,       // write
-                   NULL,            // read
-                   NULL,            // select
-                   NULL,            // get_config
-                   NULL);           // set_config
-
-externC int
-vsnprintf( char *s, size_t size, const char *format, va_list arg ) __THROW
+Cyg_ErrNo
+Cyg_VsnprintfStream::write(
+    const cyg_uint8 *buffer,
+    cyg_ucount32 buffer_length,
+    cyg_ucount32 *bytes_written )
 {
-    int rc;
-    // construct a fake device with the address of the string we've
-    // been passed as its private data. This way we can use the data
-    // directly
-    DEVTAB_ENTRY_NO_INIT(strdev,
-                         "strdev",       // Name
-                         NULL,           // Dependent name (layered device)
-                         &devio_table,   // I/O function table
-                         NULL,           // Init
-                         NULL,           // Lookup
-                         &s);            // private
-    Cyg_StdioStream my_stream( &strdev, Cyg_StdioStream::CYG_STREAM_WRITE,
-                               false, false, _IONBF, 0, NULL );
-    
-    rc = vfnprintf( (FILE *)&my_stream, size, format, arg );
-
-    // Null-terminate it, but note that s has been changed by str_write(), so
-    // that it now points to the end of the string
-    s[0] = '\0';
-
-    return rc;
-
-} // vsnprintf()
-
-#else
+    char *dest = s_;
+    char const *src = (char const *)buffer;
+    char const *end = src + buffer_length;
+    while(src < end)
+        *dest++ = *src++;
+    s_ = dest;
+    *bytes_written = buffer_length;
+    return ENOERR;
+}
 
 externC int
 vsnprintf( char *s, size_t size, const char *format, va_list arg ) __THROW
 {
-    int rc;
-
-    Cyg_StdioStream my_stream( Cyg_StdioStream::CYG_STREAM_WRITE,
-                               size, (cyg_uint8 *)s );
-    
-    rc = vfnprintf( (FILE *)&my_stream, size, format, arg );
-
-    if( rc > 0 )
-        s[rc] = '\0';
-
-    return rc;
-
+    Cyg_VsnprintfStream stream(s);
+    return vfnprintf( (FILE *)(void *)&stream, size, format, arg );
 } // vsnprintf()
 
-#endif
-
 // EOF vsnprintf.cxx