[Groonga-commit] groonga/groonga [master] [http] put return_code into MessagePack response

Back to archive index

null+****@clear***** null+****@clear*****
2011年 12月 15日 (木) 15:33:03 JST


Yoji SHIDARA	2011-12-15 06:33:03 +0000 (Thu, 15 Dec 2011)

  New Revision: 86900e73236b13830bafcdb2a6494e3c7b484355

  Log:
    [http] put return_code into MessagePack response
    
    refs. commit ef2b0c4b4446724e290c639a6ad2db1f2a7af50f

  Modified files:
    src/groonga.c

  Modified: src/groonga.c (+81 -1)
===================================================================
--- src/groonga.c    2011-12-15 04:12:34 +0000 (19da18e)
+++ src/groonga.c    2011-12-15 06:33:03 +0000 (b87f7be)
@@ -499,9 +499,28 @@ transform_xml(grn_ctx *ctx, grn_obj *output, grn_obj *transformed)
   GRN_OBJ_FIN(ctx, &columns);
 }
 
+#ifdef HAVE_MESSAGE_PACK
+typedef struct {
+  grn_ctx *ctx;
+  grn_obj *buffer;
+} msgpack_writer_ctx;
+
+static inline int
+msgpack_buffer_writer(void* data, const char* buf, unsigned int len)
+{
+  msgpack_writer_ctx *writer_ctx = (msgpack_writer_ctx *)data;
+  return grn_bulk_write(writer_ctx->ctx, writer_ctx->buffer, buf, len);
+}
+#endif
+
 static void
 print_return_code(grn_ctx *ctx, grn_rc rc, grn_obj *head, grn_obj *body, grn_obj *foot)
 {
+#ifdef HAVE_MESSAGE_PACK
+  msgpack_writer_ctx head_writer_ctx;
+  msgpack_packer header_packer;
+#endif
+
   switch (ctx->impl->output_type) {
   case GRN_CONTENT_JSON:
     GRN_TEXT_PUTS(ctx, head, "[[");
@@ -636,7 +655,68 @@ print_return_code(grn_ctx *ctx, grn_rc rc, grn_obj *head, grn_obj *body, grn_obj
     }
     break;
   case GRN_CONTENT_MSGPACK:
-    // todo
+#ifdef HAVE_MESSAGE_PACK
+    head_writer_ctx.ctx = ctx;
+    head_writer_ctx.buffer = head;
+    msgpack_packer_init(&header_packer, &head_writer_ctx, msgpack_buffer_writer);
+
+    msgpack_pack_array(&header_packer, (rc == GRN_SUCCESS) ? 2 : 1); /* [HEAD, (BODY)] */
+
+    int header_size = 3; /* HEAD := [rc, uptime, elapsed, (error, (ERROR DETAIL))] */
+    if (rc != GRN_SUCCESS) {
+      header_size ++;
+      if (ctx->errfunc && ctx->errfile) {
+        header_size ++;
+      }
+    }
+    msgpack_pack_array(&header_packer, header_size);
+    msgpack_pack_int(&header_packer, rc);
+    double dv;
+    grn_timeval tv;
+    grn_timeval_now(ctx, &tv);
+    dv = ctx->impl->tv.tv_sec;
+    dv += ctx->impl->tv.tv_nsec / GRN_TIME_NSEC_PER_SEC_F;
+    msgpack_pack_double(&header_packer, dv);
+
+    dv = (tv.tv_sec - ctx->impl->tv.tv_sec);
+    dv += (tv.tv_nsec - ctx->impl->tv.tv_nsec) / GRN_TIME_NSEC_PER_SEC_F;
+    msgpack_pack_double(&header_packer, dv);
+
+    if (rc != GRN_SUCCESS) {
+      msgpack_pack_raw(&header_packer, strlen(ctx->errbuf));
+      msgpack_pack_raw_body(&header_packer, ctx->errbuf, strlen(ctx->errbuf));
+      if (ctx->errfunc && ctx->errfile) {
+        grn_obj *command = GRN_CTX_USER_DATA(ctx)->ptr;
+
+        /* TODO: output backtrace */
+        msgpack_pack_array(&header_packer, 1);
+        msgpack_pack_array(&header_packer, command ? 6 : 3); /* ERROR DETAIL := [[errfunc, errfile, errline, (input_path, number_of_lines, command)]] */
+
+        msgpack_pack_raw(&header_packer, strlen(ctx->errfunc));
+        msgpack_pack_raw_body(&header_packer, ctx->errfunc, strlen(ctx->errfunc));
+
+        msgpack_pack_raw(&header_packer, strlen(ctx->errfile));
+        msgpack_pack_raw_body(&header_packer, ctx->errfile, strlen(ctx->errfile));
+
+        msgpack_pack_int(&header_packer, ctx->errline);
+
+        if (command) {
+          if (input_path) {
+            msgpack_pack_raw(&header_packer, strlen(input_path));
+            msgpack_pack_raw_body(&header_packer, input_path, strlen(input_path));
+          } else {
+            msgpack_pack_raw(&header_packer, 7);
+            msgpack_pack_raw_body(&header_packer, "(stdin)", 7);
+          }
+
+          msgpack_pack_int(&header_packer, number_of_lines);
+
+          msgpack_pack_raw(&header_packer, GRN_TEXT_LEN(command));
+          msgpack_pack_raw_body(&header_packer, GRN_TEXT_VALUE(command), GRN_TEXT_LEN(command));
+        }
+      }
+    }
+#endif
     break;
   case GRN_CONTENT_NONE:
     break;




Groonga-commit メーリングリストの案内
Back to archive index