[Groonga-commit] groonga/groonga at 6da856f [master] Add convenient functions for MessagePack

Back to archive index

Kouhei Sutou null+****@clear*****
Tue Apr 3 18:23:07 JST 2018


Kouhei Sutou	2018-04-03 18:23:07 +0900 (Tue, 03 Apr 2018)

  New Revision: 6da856f2942ca8cca860b8ea5b00ec85bbc60fd9
  https://github.com/groonga/groonga/commit/6da856f2942ca8cca860b8ea5b00ec85bbc60fd9

  Message:
    Add convenient functions for MessagePack

  Added files:
    include/groonga/msgpack.h
    lib/msgpack.c
  Modified files:
    include/groonga/Makefile.am
    lib/c_sources.am
    lib/grn_msgpack.h

  Modified: include/groonga/Makefile.am (+1 -0)
===================================================================
--- include/groonga/Makefile.am    2018-04-03 18:15:03 +0900 (3c5018fd8)
+++ include/groonga/Makefile.am    2018-04-03 18:23:07 +0900 (d8e115a2a)
@@ -19,6 +19,7 @@ groonga_include_HEADERS =			\
 	groonga.h				\
 	id.h					\
 	ii.h					\
+	msgpack.h				\
 	obj.h					\
 	operator.h				\
 	option.h				\

  Added: include/groonga/msgpack.h (+48 -0) 100644
===================================================================
--- /dev/null
+++ include/groonga/msgpack.h    2018-04-03 18:23:07 +0900 (16484ecf8)
@@ -0,0 +1,48 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+  Copyright(C) 2018 Brazil
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License version 2.1 as published by the Free Software Foundation.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#pragma once
+
+#include <groonga.h>
+#include <msgpack.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GRN_MSGPACK_OBJECT_EXT_TIME 0
+
+grn_rc grn_msgpack_pack_raw(grn_ctx *ctx,
+                            msgpack_packer *packer,
+                            const char *value,
+                            unsigned int value_size,
+                            grn_id value_domain);
+
+grn_rc grn_msgpack_pack(grn_ctx *ctx,
+                        msgpack_packer *packer,
+                        grn_obj *value);
+
+grn_rc grn_msgpack_unpack_array(grn_ctx *ctx,
+                                msgpack_object_array *array,
+                                grn_obj *vector);
+int64_t grn_msgpack_unpack_ext_time(grn_ctx *ctx,
+                                    msgpack_object_ext *ext);
+
+#ifdef __cplusplus
+}
+#endif

  Modified: lib/c_sources.am (+1 -0)
===================================================================
--- lib/c_sources.am    2018-04-03 18:15:03 +0900 (090e174f7)
+++ lib/c_sources.am    2018-04-03 18:23:07 +0900 (4b0c67447)
@@ -50,6 +50,7 @@ libgroonga_c_sources =				\
 	grn_logger.h				\
 	mrb.c					\
 	grn_mrb.h				\
+	msgpack.c				\
 	grn_msgpack.h				\
 	nfkc.c					\
 	grn_nfkc.h				\

  Modified: lib/grn_msgpack.h (+24 -0)
===================================================================
--- lib/grn_msgpack.h    2018-04-03 18:15:03 +0900 (c153d83bb)
+++ lib/grn_msgpack.h    2018-04-03 18:23:07 +0900 (256ce09f7)
@@ -18,6 +18,8 @@
 
 #pragma once
 
+#include "grn.h"
+
 #ifdef GRN_WITH_MESSAGE_PACK
 # include <msgpack.h>
 
@@ -35,6 +37,9 @@ typedef unsigned int msgpack_size_t;
 #  define MSGPACK_OBJECT_STR_SIZE(object) (object)->via.raw.size
 
 #  define MSGPACK_OBJECT_FLOAT_VALUE(object) (object)->via.dec
+
+#  define MSGPACK_UNPACKER_NEXT(unpacker, unpacked)     \
+  msgpack_unpacker_next((unpacker), (unpacked))
 # else /* MSGPACK_VERSION_MAJOR < 1 */
 typedef size_t msgpack_size_t;
 
@@ -42,5 +47,24 @@ typedef size_t msgpack_size_t;
 #  define MSGPACK_OBJECT_STR_SIZE(object) (object)->via.str.size
 
 #  define MSGPACK_OBJECT_FLOAT_VALUE(object) (object)->via.f64
+
+#  define MSGPACK_UNPACKER_NEXT(unpacker, unpacked)                     \
+  msgpack_unpacker_next((unpacker), (unpacked)) == MSGPACK_UNPACK_SUCCESS
 # endif /* MSGPACK_VERSION_MAJOR < 1 */
+
+grn_rc grn_msgpack_pack_raw_internal(grn_ctx *ctx,
+                                     msgpack_packer *packer,
+                                     const char *value,
+                                     unsigned int value_size,
+                                     grn_id value_domain);
+grn_rc grn_msgpack_pack_internal(grn_ctx *ctx,
+                                 msgpack_packer *packer,
+                                 grn_obj *value);
+grn_rc grn_msgpack_unpack_array_internal(grn_ctx *ctx,
+                                         msgpack_object_array *array,
+                                         grn_obj *vector);
+int64_t grn_msgpack_unpack_ext_time_internal(grn_ctx *ctx,
+                                             msgpack_object_ext *ext);
+
+
 #endif /* GRN_WITH_MESSAGE_PACK */

  Added: lib/msgpack.c (+266 -0) 100644
===================================================================
--- /dev/null
+++ lib/msgpack.c    2018-04-03 18:23:07 +0900 (70fb27276)
@@ -0,0 +1,266 @@
+/* -*- c-basic-offset: 2 -*- */
+/*
+  Copyright(C) 2018 Brazil
+
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License version 2.1 as published by the Free Software Foundation.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include "grn_ctx.h"
+#include "grn_db.h"
+#include "grn_msgpack.h"
+
+#ifdef GRN_WITH_MESSAGE_PACK
+
+# include <groonga/msgpack.h>
+
+grn_rc
+grn_msgpack_pack_raw_internal(grn_ctx *ctx,
+                              msgpack_packer *packer,
+                              const char *value,
+                              unsigned int value_size,
+                              grn_id value_domain)
+{
+  if (value_size == 0) {
+    msgpack_pack_nil(packer);
+    return ctx->rc;
+  }
+
+  switch (value_domain) {
+  case GRN_DB_VOID :
+    msgpack_pack_nil(packer);
+    break;
+  case GRN_DB_BOOL :
+    if (*((grn_bool *)value)) {
+      msgpack_pack_true(packer);
+    } else {
+      msgpack_pack_false(packer);
+    }
+    break;
+  case GRN_DB_INT8 :
+    msgpack_pack_int8(packer, *((int8_t *)(value)));
+    break;
+  case GRN_DB_UINT8 :
+    msgpack_pack_uint8(packer, *((uint8_t *)(value)));
+    break;
+  case GRN_DB_INT16 :
+    msgpack_pack_int16(packer, *((int16_t *)(value)));
+    break;
+  case GRN_DB_UINT16 :
+    msgpack_pack_uint16(packer, *((uint16_t *)(value)));
+    break;
+  case GRN_DB_INT32 :
+    msgpack_pack_int32(packer, *((int32_t *)(value)));
+    break;
+  case GRN_DB_UINT32 :
+    msgpack_pack_uint32(packer, *((uint32_t *)(value)));
+    break;
+  case GRN_DB_INT64 :
+    msgpack_pack_int64(packer, *((int64_t *)(value)));
+    break;
+  case GRN_DB_UINT64 :
+    msgpack_pack_uint64(packer, *((uint64_t *)(value)));
+    break;
+  case GRN_DB_FLOAT :
+    msgpack_pack_double(packer, *((double *)(value)));
+    break;
+  case GRN_DB_TIME :
+    /* TODO: Use timestamp time in spec. */
+    msgpack_pack_ext(packer, sizeof(int64_t), GRN_MSGPACK_OBJECT_EXT_TIME);
+    msgpack_pack_ext_body(packer, value, sizeof(int64_t));
+    break;
+  case GRN_DB_SHORT_TEXT :
+  case GRN_DB_TEXT :
+  case GRN_DB_LONG_TEXT :
+    msgpack_pack_str(packer, value_size);
+    msgpack_pack_str_body(packer, value, value_size);
+    break;
+  default :
+    {
+      char domain_name[GRN_TABLE_MAX_KEY_SIZE];
+      int domain_name_size;
+
+      domain_name_size = grn_table_get_key(ctx,
+                                           grn_ctx_db(ctx),
+                                           value_domain,
+                                           domain_name,
+                                           sizeof(domain_name));
+      ERR(GRN_FUNCTION_NOT_IMPLEMENTED,
+          "[msgpack][pack] unsupported type: <%.*s>",
+          domain_name_size, domain_name);
+    }
+    break;
+  }
+
+  return ctx->rc;
+}
+
+grn_rc
+grn_msgpack_pack_internal(grn_ctx *ctx,
+                          msgpack_packer *packer,
+                          grn_obj *value)
+{
+  if (value) {
+    return grn_msgpack_pack_raw_internal(ctx,
+                                         packer,
+                                         GRN_BULK_HEAD(value),
+                                         GRN_BULK_VSIZE(value),
+                                         value->header.domain);
+  } else {
+    return grn_msgpack_pack_raw_internal(ctx,
+                                         packer,
+                                         NULL,
+                                         0,
+                                         GRN_DB_VOID);
+  }
+}
+
+grn_rc
+grn_msgpack_unpack_array_internal(grn_ctx *ctx,
+                                  msgpack_object_array *array,
+                                  grn_obj *vector)
+{
+  int32_t i;
+
+  grn_obj_ensure_vector(ctx, vector);
+
+  for (i = 0; i < array->size && ctx->rc == GRN_SUCCESS; i++) {
+    msgpack_object *element;
+
+    element = &(array->ptr[i]);
+    switch (element->type) {
+    case MSGPACK_OBJECT_BOOLEAN :
+      {
+        grn_bool value = element->via.boolean;
+        grn_vector_add_element(ctx,
+                               vector,
+                               (const char *)&value,
+                               sizeof(grn_bool),
+                               0,
+                               GRN_DB_BOOL);
+      }
+      break;
+    case MSGPACK_OBJECT_POSITIVE_INTEGER :
+      grn_vector_add_element(ctx,
+                             vector,
+                             (const char *)&(element->via.i64),
+                             sizeof(int64_t),
+                             0,
+                             GRN_DB_INT64);
+      break;
+    case MSGPACK_OBJECT_NEGATIVE_INTEGER :
+      grn_vector_add_element(ctx,
+                             vector,
+                             (const char *)&(element->via.u64),
+                             sizeof(uint64_t),
+                             0,
+                             GRN_DB_UINT64);
+      break;
+    case MSGPACK_OBJECT_FLOAT :
+      grn_vector_add_element(ctx,
+                             vector,
+                             (const char *)&(MSGPACK_OBJECT_FLOAT_VALUE(element)),
+                             sizeof(double),
+                             0,
+                             GRN_DB_FLOAT);
+      break;
+    case MSGPACK_OBJECT_STR :
+      grn_vector_add_element(ctx,
+                             vector,
+                             MSGPACK_OBJECT_STR_PTR(element),
+                             MSGPACK_OBJECT_STR_SIZE(element),
+                             0,
+                             GRN_DB_TEXT);
+      break;
+    case MSGPACK_OBJECT_EXT :
+      if (element->via.ext.type == GRN_MSGPACK_OBJECT_EXT_TIME) {
+        grn_vector_add_element(ctx,
+                               vector,
+                               element->via.ext.ptr,
+                               sizeof(int64_t),
+                               0,
+                               GRN_DB_TIME);
+      } else {
+        ERR(GRN_INVALID_ARGUMENT,
+            "[msgpack] unknown extension type: <%u>",
+            element->via.ext.type);
+      }
+      break;
+    default :
+      ERR(GRN_INVALID_ARGUMENT,
+          "[msgpack] unexpected element type: <%#x>",
+          element->type);
+      break;
+    }
+  }
+
+  return ctx->rc;
+}
+
+int64_t
+grn_msgpack_unpack_ext_time_internal(grn_ctx *ctx,
+                                     msgpack_object_ext *ext)
+{
+  if (ext->type == GRN_MSGPACK_OBJECT_EXT_TIME) {
+    return *(int64_t *)(ext->ptr);
+  } else {
+    ERR(GRN_INVALID_ARGUMENT,
+        "[msgpack] time extension type must be <%u>: <%u>",
+        GRN_MSGPACK_OBJECT_EXT_TIME,
+        ext->type);
+    return 0;
+  }
+}
+
+grn_rc
+grn_msgpack_pack_raw(grn_ctx *ctx,
+                     msgpack_packer *packer,
+                     const char *value,
+                     unsigned int value_size,
+                     grn_id value_domain)
+{
+  GRN_API_ENTER;
+  grn_msgpack_pack_raw_internal(ctx, packer, value, value_size, value_domain);
+  GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_msgpack_pack(grn_ctx *ctx,
+                 msgpack_packer *packer,
+                 grn_obj *value)
+{
+  GRN_API_ENTER;
+  grn_msgpack_pack_internal(ctx, packer, value);
+  GRN_API_RETURN(ctx->rc);
+}
+
+grn_rc
+grn_msgpack_unpack_array(grn_ctx *ctx,
+                         msgpack_object_array *array,
+                         grn_obj *vector)
+{
+  GRN_API_ENTER;
+  grn_msgpack_unpack_array_internal(ctx, array, vector);
+  GRN_API_RETURN(ctx->rc);
+}
+
+int64_t
+grn_msgpack_unpack_ext_time(grn_ctx *ctx,
+                            msgpack_object_ext *ext)
+{
+  int64_t time;
+  GRN_API_ENTER;
+  time = grn_msgpack_unpack_ext_time_internal(ctx, ext);
+  GRN_API_RETURN(time);
+}
+#endif /* GRN_WITH_MESSAGE_PACK */
-------------- next part --------------
HTML����������������������������...
URL: https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20180403/566e2ec0/attachment-0001.htm 



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