[Groonga-commit] groonga/groonga at f1da757 [master] windows grn_text_vprintf: support auto buffer expansion on Windows

Back to archive index

Kouhei Sutou null+****@clear*****
Fri Apr 17 13:13:50 JST 2015


Kouhei Sutou	2015-04-17 13:13:50 +0900 (Fri, 17 Apr 2015)

  New Revision: f1da757fbe7126a9b68178191b48d190f2d06a1a
  https://github.com/groonga/groonga/commit/f1da757fbe7126a9b68178191b48d190f2d06a1a

  Message:
    windows grn_text_vprintf: support auto buffer expansion on Windows
    
    vsnprintf() on Windows doesn't return "will be written size" when buffer
    size is shorter. We need to guess enough size when buffer is shorter on
    Windows.

  Modified files:
    lib/str.c

  Modified: lib/str.c (+39 -2)
===================================================================
--- lib/str.c    2015-04-17 12:26:18 +0900 (5aaa058)
+++ lib/str.c    2015-04-17 13:13:50 +0900 (71b6df5)
@@ -2512,9 +2512,11 @@ grn_text_printf(grn_ctx *ctx, grn_obj *bulk, const char *format, ...)
 grn_rc
 grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args)
 {
-  int rest_size, written_size;
+  grn_bool is_written = GRN_FALSE;
+  int written_size;
 
   {
+    int rest_size;
     va_list copied_args;
 
     rest_size = GRN_BULK_REST(bulk);
@@ -2522,9 +2524,43 @@ grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args)
     written_size = vsnprintf(GRN_BULK_CURR(bulk), rest_size,
                              format, copied_args);
     va_end(copied_args);
+
+    if (written_size < rest_size) {
+      is_written = GRN_TRUE;
+    }
   }
 
-  if (written_size >= rest_size) {
+#ifdef WIN32
+  if (written_size == -1 && errno == ERANGE) {
+# define N_NEW_SIZES 3
+    int i;
+    int new_sizes[N_NEW_SIZES];
+
+    new_sizes[0] = GRN_BULK_REST(bulk) + strlen(format) * 2;
+    new_sizes[1] = new_sizes[0] + 4096;
+    new_sizes[2] = new_sizes[0] + 65536;
+
+    for (i = 0; i < N_NEW_SIZES; i++) {
+      grn_rc rc;
+      int new_size = new_sizes[i];
+      va_list copied_args;
+
+      rc = grn_bulk_reserve(ctx, bulk, GRN_BULK_VSIZE(bulk) + new_size);
+      if (rc) {
+        return rc;
+      }
+      va_copy(copied_args, args);
+      written_size = vsnprintf(GRN_BULK_CURR(bulk), new_size,
+                               format, copied_args);
+      va_end(copied_args);
+      if (written_size != -1) {
+        break;
+      }
+    }
+# undef N_NEW_SIZES
+  }
+#else /* WIN32 */
+  if (!is_written) {
     grn_rc rc;
     int required_size = written_size + 1; /* "+ 1" for terminate '\0'. */
 
@@ -2535,6 +2571,7 @@ grn_text_vprintf(grn_ctx *ctx, grn_obj *bulk, const char *format, va_list args)
     written_size = vsnprintf(GRN_BULK_CURR(bulk), required_size,
                              format, args);
   }
+#endif /* WIN32 */
 
   if (written_size < 0) {
     return GRN_INVALID_ARGUMENT;
-------------- next part --------------
HTML����������������������������...
下載 



More information about the Groonga-commit mailing list
Back to archive index