[PATCH 4/6] [Msvcrt]: for the internal msvcrt use, added ability to grow automatically the size of the buffer in printf core engine

Eric Pouech eric.pouech at orange.fr
Sun Nov 7 12:11:32 CST 2010




A+
---

 dlls/msvcrt/msvcrt.h |   18 +++++++++++++
 dlls/msvcrt/wcs.c    |   71 +++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 70 insertions(+), 19 deletions(-)


diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 2e8263e..b14a326 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -861,4 +861,22 @@ void __cdecl MSVCRT__invalid_parameter(const MSVCRT_wchar_t *expr, const MSVCRT_
 #define MSVCRT_CHECK_PMT(x)   ((x) || (MSVCRT_INVALID_PMT(0),FALSE))
 #endif
 
+typedef struct pf_output_t
+{
+    int used;
+    int len;
+    BOOL unicode;
+    union {
+        LPWSTR W;
+        LPSTR  A;
+    } buf;
+    union {
+        LPWSTR W;
+        LPSTR  A;
+    } grow;
+} pf_output;
+
+int pf_vsnprintf( pf_output *out, const WCHAR *format,
+                  MSVCRT__locale_t locale, BOOL valid, __ms_va_list valist );
+
 #endif /* __WINE_MSVCRT_H */
diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c
index de2c88b..484679f 100644
--- a/dlls/msvcrt/wcs.c
+++ b/dlls/msvcrt/wcs.c
@@ -361,17 +361,6 @@ double CDECL MSVCRT__wtof_l(const MSVCRT_wchar_t *str, MSVCRT__locale_t locale)
     return MSVCRT__wcstod_l(str, NULL, locale);
 }
 
-typedef struct pf_output_t
-{
-    int used;
-    int len;
-    BOOL unicode;
-    union {
-        LPWSTR W;
-        LPSTR  A;
-    } buf;
-} pf_output;
-
 typedef struct pf_flags_t
 {
     char Sign, LeftAlign, Alternate, PadZero;
@@ -381,6 +370,36 @@ typedef struct pf_flags_t
     char Format;
 } pf_flags;
 
+static inline BOOL pf_is_auto_grow(pf_output *out)
+{
+    return (out->unicode) ? !!out->grow.W : !!out->grow.A;
+}
+
+static inline int pf_check_auto_grow(pf_output *out, unsigned delta)
+{
+    if (pf_is_auto_grow(out) && out->used + delta > out->len)
+    {
+        out->len = max(out->len * 2, out->used + delta);
+        if (out->unicode)
+        {
+            if (out->buf.W != out->grow.W)
+                out->buf.W = MSVCRT_realloc(out->buf.W, out->len * sizeof(WCHAR));
+            else
+                out->buf.W = MSVCRT_malloc(out->len * sizeof(WCHAR));
+            if (!out->buf.W) return -1;
+        }
+        else
+        {
+            if (out->buf.A != out->grow.A)
+                out->buf.A = MSVCRT_realloc(out->buf.A, out->len * sizeof(char));
+            else
+                out->buf.A = MSVCRT_malloc(out->len * sizeof(char));
+            if (!out->buf.A) return -1;
+        }
+    }
+    return 0;
+}
+
 /*
  * writes a string of characters to the output
  * returns -1 if the string doesn't fit in the output buffer
@@ -388,14 +407,17 @@ typedef struct pf_flags_t
  */
 static inline int pf_output_stringW( pf_output *out, LPCWSTR str, int len )
 {
-    int space = out->len - out->used;
+    int space;
 
     if( len < 0 )
         len = strlenW( str );
     if( out->unicode )
     {
-        LPWSTR p = out->buf.W + out->used;
+        LPWSTR p;
 
+        if(pf_check_auto_grow(out, len) == -1) return -1;
+        space = out->len - out->used;
+        p = out->buf.W + out->used;
         if( space >= len )
         {
             if (out->buf.W) memcpy( p, str, len*sizeof(WCHAR) );
@@ -409,8 +431,11 @@ static inline int pf_output_stringW( pf_output *out, LPCWSTR str, int len )
     else
     {
         int n = WideCharToMultiByte( CP_ACP, 0, str, len, NULL, 0, NULL, NULL );
-        LPSTR p = out->buf.A + out->used;
+        LPSTR p;
 
+        if(pf_check_auto_grow(out, n) == -1) return -1;
+        space = out->len - out->used;
+        p = out->buf.A + out->used;
         if( space >= n )
         {
             if (out->buf.A) WideCharToMultiByte( CP_ACP, 0, str, len, p, n, NULL, NULL );
@@ -426,14 +451,17 @@ static inline int pf_output_stringW( pf_output *out, LPCWSTR str, int len )
 
 static inline int pf_output_stringA( pf_output *out, LPCSTR str, int len )
 {
-    int space = out->len - out->used;
+    int space;
 
     if( len < 0 )
         len = strlen( str );
     if( !out->unicode )
     {
-        LPSTR p = out->buf.A + out->used;
+        LPSTR p;
 
+        if (pf_check_auto_grow(out, len) == -1) return -1;
+        p = out->buf.A + out->used;
+        space = out->len - out->used;
         if( space >= len )
         {
             if (out->buf.A) memcpy( p, str, len );
@@ -447,8 +475,11 @@ static inline int pf_output_stringA( pf_output *out, LPCSTR str, int len )
     else
     {
         int n = MultiByteToWideChar( CP_ACP, 0, str, len, NULL, 0 );
-        LPWSTR p = out->buf.W + out->used;
+        LPWSTR p;
 
+        if (pf_check_auto_grow(out, n) == -1) return -1;
+        p = out->buf.W + out->used;
+        space = out->len - out->used;
         if( space >= n )
         {
             if (out->buf.W) MultiByteToWideChar( CP_ACP, 0, str, len, p, n );
@@ -723,8 +754,8 @@ static void pf_fixup_exponent( char *buf )
  *
  *  implements both A and W vsnprintf functions
  */
-static int pf_vsnprintf( pf_output *out, const WCHAR *format,
-        MSVCRT__locale_t locale, BOOL valid, __ms_va_list valist )
+int pf_vsnprintf( pf_output *out, const WCHAR *format,
+                  MSVCRT__locale_t locale, BOOL valid, __ms_va_list valist )
 {
     int r;
     LPCWSTR q, p = format;
@@ -1000,6 +1031,7 @@ static inline int vsnprintf_internal( char *str, MSVCRT_size_t len, const char *
 
     out.unicode = FALSE;
     out.buf.A = str;
+    out.grow.A = NULL;
     out.used = 0;
     out.len = len;
 
@@ -1146,6 +1178,7 @@ static inline int vsnwprintf_internal(MSVCRT_wchar_t *str, MSVCRT_size_t len,
 
     out.unicode = TRUE;
     out.buf.W = str;
+    out.grow.W = NULL;
     out.used = 0;
     out.len = len;
 






More information about the wine-patches mailing list