static VALUE test_num2short(VALUE obj, VALUE num) { char buf[128]; sprintf(buf, "%d", NUM2SHORT(num)); return rb_str_new_cstr(buf); }
grn_obj * rb_grn_bulk_from_ruby_object_with_type (VALUE object, grn_ctx *context, grn_obj *bulk, grn_id type_id, grn_obj *type) { const char *string; unsigned int size; union { int8_t int8_value; uint8_t uint8_value; int16_t int16_value; uint16_t uint16_value; int32_t int32_value; uint32_t uint32_value; int64_t int64_value; uint64_t uint64_value; int64_t time_value; double double_value; grn_geo_point geo_point_value; grn_id record_id; } value; grn_id range; VALUE rb_type_object; grn_obj_flags flags = 0; grn_bool string_p, table_type_p; string_p = rb_type(object) == T_STRING; table_type_p = (GRN_TABLE_HASH_KEY <= type->header.type && type->header.type <= GRN_TABLE_NO_KEY); switch (type_id) { case GRN_DB_INT8: value.int8_value = NUM2SHORT(object); string = (const char *)&(value.int8_value); size = sizeof(value.int8_value); break; case GRN_DB_UINT8: value.uint8_value = NUM2USHORT(object); string = (const char *)&(value.uint8_value); size = sizeof(value.uint8_value); break; case GRN_DB_INT16: value.int16_value = NUM2SHORT(object); string = (const char *)&(value.int16_value); size = sizeof(value.int16_value); break; case GRN_DB_UINT16: value.uint16_value = NUM2USHORT(object); string = (const char *)&(value.uint16_value); size = sizeof(value.uint16_value); break; case GRN_DB_INT32: value.int32_value = NUM2INT(object); string = (const char *)&(value.int32_value); size = sizeof(value.int32_value); break; case GRN_DB_UINT32: value.uint32_value = NUM2UINT(object); string = (const char *)&(value.uint32_value); size = sizeof(value.uint32_value); break; case GRN_DB_INT64: value.int64_value = NUM2LL(object); string = (const char *)&(value.int64_value); size = sizeof(value.int64_value); break; case GRN_DB_UINT64: value.uint64_value = NUM2ULL(object); string = (const char *)&(value.uint64_value); size = sizeof(value.uint64_value); break; case GRN_DB_FLOAT: value.double_value = NUM2DBL(object); string = (const char *)&(value.double_value); size = sizeof(value.double_value); break; case GRN_DB_TIME: { VALUE rb_sec, rb_usec; int64_t sec; int32_t usec; if (string_p) { ID id_parse; CONST_ID(id_parse, "parse"); object = rb_funcall(rb_cTime, id_parse, 1, object); } switch (TYPE(object)) { case T_FIXNUM: case T_BIGNUM: sec = NUM2LL(object); usec = 0; break; case T_FLOAT: rb_sec = rb_funcall(object, rb_intern("to_i"), 0); rb_usec = rb_funcall(object, rb_intern("remainder"), 1, INT2NUM(1)); sec = NUM2LL(rb_sec); usec = (int32_t)(NUM2DBL(rb_usec) * 1000000); break; case T_NIL: sec = 0; usec = 0; break; default: sec = NUM2LL(rb_funcall(object, rb_intern("to_i"), 0)); usec = NUM2INT(rb_funcall(object, rb_intern("usec"), 0)); break; } value.time_value = GRN_TIME_PACK(sec, usec); string = (const char *)&(value.time_value); size = sizeof(value.time_value); break; } case GRN_DB_SHORT_TEXT: case GRN_DB_TEXT: case GRN_DB_LONG_TEXT: string = StringValuePtr(object); size = RSTRING_LEN(object); range = grn_obj_get_range(context, type); if (size > range) rb_raise(rb_eArgError, "string is too large: expected: %u <= %u", size, range); flags |= GRN_OBJ_DO_SHALLOW_COPY; break; case GRN_DB_TOKYO_GEO_POINT: case GRN_DB_WGS84_GEO_POINT: { VALUE rb_geo_point; VALUE rb_latitude, rb_longitude; if (type_id == GRN_DB_TOKYO_GEO_POINT) { rb_geo_point = rb_funcall(rb_cGrnTokyoGeoPoint, rb_intern("new"), 1, object); } else { rb_geo_point = rb_funcall(rb_cGrnWGS84GeoPoint, rb_intern("new"), 1, object); } rb_geo_point = rb_funcall(rb_geo_point, rb_intern("to_msec"), 0); rb_latitude = rb_funcall(rb_geo_point, rb_intern("latitude"), 0); rb_longitude = rb_funcall(rb_geo_point, rb_intern("longitude"), 0); value.geo_point_value.latitude = NUM2INT(rb_latitude); value.geo_point_value.longitude = NUM2INT(rb_longitude); string = (const char *)&(value.geo_point_value); size = sizeof(value.geo_point_value); break; } case GRN_DB_VOID: case GRN_DB_DELIMIT: case GRN_DB_UNIGRAM: case GRN_DB_BIGRAM: case GRN_DB_TRIGRAM: case GRN_DB_MECAB: rb_type_object = GRNOBJECT2RVAL(Qnil, context, type, GRN_FALSE); rb_raise(rb_eArgError, "unbulkable type: %s", rb_grn_inspect(rb_type_object)); break; default: if (table_type_p && (NIL_P(object) || (string_p && RSTRING_LEN(object) == 0))) { value.record_id = GRN_ID_NIL; string = (const char *)&(value.record_id); size = sizeof(value.record_id); if (bulk && bulk->header.domain != type_id) { grn_obj_reinit(context, bulk, type_id, 0); } } else { return RVAL2GRNBULK(object, context, bulk); } break; } if (!bulk) { bulk = grn_obj_open(context, GRN_BULK, flags, GRN_ID_NIL); rb_grn_context_check(context, object); } GRN_TEXT_SET(context, bulk, string, size); return bulk; }