示例#1
0
static void put_ruby_value(VALUE value,
                           const upb_fielddef *f,
                           VALUE type_class,
                           int depth,
                           upb_sink *sink) {
  upb_selector_t sel = 0;
  if (upb_fielddef_isprimitive(f)) {
    sel = getsel(f, upb_handlers_getprimitivehandlertype(f));
  }

  switch (upb_fielddef_type(f)) {
    case UPB_TYPE_INT32:
      upb_sink_putint32(sink, sel, NUM2INT(value));
      break;
    case UPB_TYPE_INT64:
      upb_sink_putint64(sink, sel, NUM2LL(value));
      break;
    case UPB_TYPE_UINT32:
      upb_sink_putuint32(sink, sel, NUM2UINT(value));
      break;
    case UPB_TYPE_UINT64:
      upb_sink_putuint64(sink, sel, NUM2ULL(value));
      break;
    case UPB_TYPE_FLOAT:
      upb_sink_putfloat(sink, sel, NUM2DBL(value));
      break;
    case UPB_TYPE_DOUBLE:
      upb_sink_putdouble(sink, sel, NUM2DBL(value));
      break;
    case UPB_TYPE_ENUM: {
      if (TYPE(value) == T_SYMBOL) {
        value = rb_funcall(type_class, rb_intern("resolve"), 1, value);
      }
      upb_sink_putint32(sink, sel, NUM2INT(value));
      break;
    }
    case UPB_TYPE_BOOL:
      upb_sink_putbool(sink, sel, value == Qtrue);
      break;
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES:
      putstr(value, f, sink);
      break;
    case UPB_TYPE_MESSAGE:
      putsubmsg(value, f, sink, depth);
  }
}
示例#2
0
static double
measure_gc_time()
{
#if defined(HAVE_RB_GC_TIME)
#define MEASURE_GC_TIME_ENABLED Qtrue
    const double conversion = 1000000.0;
#if HAVE_LONG_LONG
    return NUM2LL(rb_gc_time()) / conversion;
#else
    return NUM2LONG(rb_gc_time()) / conversion;
#endif

#else
#define MEASURE_GC_TIME_ENABLED Qfalse
    return 0.0;
#endif
}
示例#3
0
文件: rdwarf.c 项目: kubo/rdwarf
static VALUE rdwarf_die_at(VALUE self, VALUE offset)
{
    rdwarf_t *rd = GetRDwarf(self);
    Dwarf_Die die;
    Dwarf_Off cu_off;
    Dwarf_Error err;
    VALUE cu;

    chkerr1(dwarf_offdie(rd->shared_data->dbg, NUM2LL(offset), &die, &err), &err, self);
    chkerr1(dwarf_CU_dieoffset_given_die(die, &cu_off, &err), &err, self);

    rdwarf_compile_units(self);
    cu = rb_hash_aref(rd->shared_data->off2die, LL2NUM(cu_off));
    if (NIL_P(cu)) {
        rb_raise(rd_eError, "Cannot find CU");
    }
    return rd_die_new(rd->shared_data, self, cu, die);
}
示例#4
0
static void rb_add_value_to_cf_dictionary(CFMutableDictionaryRef dict, CFStringRef key, VALUE value){
  switch(TYPE(value)){
    case T_STRING:
      {
        if(!CFStringCompare(key, kSecValueData,0) || !CFStringCompare(key, kSecAttrGeneric,0)){
          CFDataRef dataValue = rb_create_cf_data(value);
          CFDictionarySetValue(dict,key,dataValue);
          CFRelease(dataValue);
        }
        else{
          CFStringRef stringValue = rb_create_cf_string(value);
          CFDictionarySetValue(dict,key,stringValue);
          CFRelease(stringValue);
        }
      }
      break;
    case T_BIGNUM:
    case T_FIXNUM:
      {
        long long longLongValue = NUM2LL(value);
        CFNumberRef numberValue = CFNumberCreate(NULL,kCFNumberLongLongType,&longLongValue);
        CFDictionarySetValue(dict,key,numberValue);
        CFRelease(numberValue);
        break;
      }
    case T_DATA:
      {
        if(rb_obj_is_kind_of(value, rb_cTime)){
          VALUE floatTime = rb_funcall(value, rb_intern("to_f"),0);
          CFAbsoluteTime abstime = RFLOAT_VALUE(floatTime) - kCFAbsoluteTimeIntervalSince1970;
          CFDateRef cfdate = CFDateCreate(NULL, abstime);
          CFDictionarySetValue(dict, key, cfdate);
          CFRelease(cfdate);
          break;
        }
      }
    default:
      rb_raise(rb_eTypeError, "Can't convert value to cftype: %s", rb_obj_classname(value));
  }
}
示例#5
0
文件: watchman.c 项目: jiayong/myvim
/**
 * Encodes and appends the serialized Ruby object `serializable` to `w`
 *
 * Examples of serializable objects include arrays, hashes, strings, numbers
 * (integers, floats), booleans, and nil.
 */
void watchman_dump(watchman_t *w, VALUE serializable) {
    switch (TYPE(serializable)) {
    case T_ARRAY:
        return watchman_dump_array(w, serializable);
    case T_HASH:
        return watchman_dump_hash(w, serializable);
    case T_STRING:
        return watchman_dump_string(w, serializable);
    case T_FIXNUM: // up to 63 bits
        return watchman_dump_int(w, FIX2LONG(serializable));
    case T_BIGNUM:
        return watchman_dump_int(w, NUM2LL(serializable));
    case T_FLOAT:
        return watchman_dump_double(w, NUM2DBL(serializable));
    case T_TRUE:
        return watchman_append(w, &watchman_true, sizeof(watchman_true));
    case T_FALSE:
        return watchman_append(w, &watchman_false, sizeof(watchman_false));
    case T_NIL:
        return watchman_append(w, &watchman_nil, sizeof(watchman_nil));
    default:
        rb_raise(rb_eTypeError, "unsupported type");
    }
}
示例#6
0
static void
callback_invoke(ffi_cif* cif, void* retval, void** parameters, void* user_data)
{
    Closure* closure = (Closure *) user_data;
    Function* fn = (Function *) closure->info;
    FunctionType *cbInfo = fn->info;
    VALUE* rbParams;
    VALUE rbReturnValue;
    int i;

    rbParams = ALLOCA_N(VALUE, cbInfo->parameterCount);
    for (i = 0; i < cbInfo->parameterCount; ++i) {
        VALUE param;
        switch (cbInfo->parameterTypes[i]->nativeType) {
            case NATIVE_INT8:
                param = INT2NUM(*(int8_t *) parameters[i]);
                break;
            case NATIVE_UINT8:
                param = UINT2NUM(*(uint8_t *) parameters[i]);
                break;
            case NATIVE_INT16:
                param = INT2NUM(*(int16_t *) parameters[i]);
                break;
            case NATIVE_UINT16:
                param = UINT2NUM(*(uint16_t *) parameters[i]);
                break;
            case NATIVE_INT32:
                param = INT2NUM(*(int32_t *) parameters[i]);
                break;
            case NATIVE_UINT32:
                param = UINT2NUM(*(uint32_t *) parameters[i]);
                break;
            case NATIVE_INT64:
                param = LL2NUM(*(int64_t *) parameters[i]);
                break;
            case NATIVE_UINT64:
                param = ULL2NUM(*(uint64_t *) parameters[i]);
                break;
            case NATIVE_LONG:
                param = LONG2NUM(*(long *) parameters[i]);
                break;
            case NATIVE_ULONG:
                param = ULONG2NUM(*(unsigned long *) parameters[i]);
                break;
            case NATIVE_FLOAT32:
                param = rb_float_new(*(float *) parameters[i]);
                break;
            case NATIVE_FLOAT64:
                param = rb_float_new(*(double *) parameters[i]);
                break;
            case NATIVE_STRING:
                param = (*(void **) parameters[i] != NULL) ? rb_tainted_str_new2(*(char **) parameters[i]) : Qnil;
                break;
            case NATIVE_POINTER:
                param = rbffi_Pointer_NewInstance(*(void **) parameters[i]);
                break;
            case NATIVE_BOOL:
                param = (*(uint8_t *) parameters[i]) ? Qtrue : Qfalse;
                break;

            case NATIVE_FUNCTION:
            case NATIVE_CALLBACK:
                param = rbffi_NativeValue_ToRuby(cbInfo->parameterTypes[i],
                     rb_ary_entry(cbInfo->rbParameterTypes, i), parameters[i], Qnil);
                break;
            default:
                param = Qnil;
                break;
        }
        rbParams[i] = param;
    }
    rbReturnValue = rb_funcall2(fn->rbProc, id_call, cbInfo->parameterCount, rbParams);
    if (rbReturnValue == Qnil || TYPE(rbReturnValue) == T_NIL) {
        memset(retval, 0, cbInfo->ffiReturnType->size);
    } else switch (cbInfo->returnType->nativeType) {
        case NATIVE_INT8:
        case NATIVE_INT16:
        case NATIVE_INT32:
            *((ffi_sarg *) retval) = NUM2INT(rbReturnValue);
            break;
        case NATIVE_UINT8:
        case NATIVE_UINT16:
        case NATIVE_UINT32:
            *((ffi_arg *) retval) = NUM2UINT(rbReturnValue);
            break;
        case NATIVE_INT64:
            *((int64_t *) retval) = NUM2LL(rbReturnValue);
            break;
        case NATIVE_UINT64:
            *((uint64_t *) retval) = NUM2ULL(rbReturnValue);
            break;
        case NATIVE_LONG:
            *((ffi_sarg *) retval) = NUM2LONG(rbReturnValue);
            break;
        case NATIVE_ULONG:
            *((ffi_arg *) retval) = NUM2ULONG(rbReturnValue);
            break;
        case NATIVE_FLOAT32:
            *((float *) retval) = (float) NUM2DBL(rbReturnValue);
            break;
        case NATIVE_FLOAT64:
            *((double *) retval) = NUM2DBL(rbReturnValue);
            break;
        case NATIVE_POINTER:
            if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {
                *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;
            } else {
                // Default to returning NULL if not a value pointer object.  handles nil case as well
                *((void **) retval) = NULL;
            }
            break;

        case NATIVE_BOOL:
            *((ffi_arg *) retval) = rbReturnValue == Qtrue;
            break;

        case NATIVE_FUNCTION:
        case NATIVE_CALLBACK:
            if (TYPE(rbReturnValue) == T_DATA && rb_obj_is_kind_of(rbReturnValue, rbffi_PointerClass)) {

                *((void **) retval) = ((AbstractMemory *) DATA_PTR(rbReturnValue))->address;

            } else if (rb_obj_is_kind_of(rbReturnValue, rb_cProc) || rb_respond_to(rbReturnValue, id_call)) {
                VALUE function;

                function = rbffi_Function_ForProc(cbInfo->rbReturnType, rbReturnValue);

                *((void **) retval) = ((AbstractMemory *) DATA_PTR(function))->address;
            } else {
                *((void **) retval) = NULL;
            }
            break;

        default:
            *((ffi_arg *) retval) = 0;
            break;
    }
}
示例#7
0
文件: Call.c 项目: albanpeignier/ffi
static long
rbffi_GetLongValue(int idx, VALUE* argv, FunctionType* fnInfo)
{
    VALUE value = argv[idx];
    NativeType nativeType = fnInfo->nativeParameterTypes[idx];
    int type = TYPE(value);

    switch (nativeType) {
    case NATIVE_INT8:
        return getSignedInt(value, type, -128, 127, "char", fnInfo->rbEnums);

    case NATIVE_INT16:
        return getSignedInt(value, type, -0x8000, 0x7fff, "short", fnInfo->rbEnums);

    case NATIVE_INT32:
    case NATIVE_ENUM:
        return getSignedInt(value, type, -0x80000000, 0x7fffffff, "int", fnInfo->rbEnums);

    case NATIVE_BOOL:
        if (type != T_TRUE && type != T_FALSE) {
            rb_raise(rb_eTypeError, "Expected a Boolean parameter");
        }
        return RTEST(value) ? 1 : 0;

    case NATIVE_UINT8:
        return getUnsignedInt(value, type, 0xff, "unsigned char");

    case NATIVE_UINT16:
        return getUnsignedInt(value, type, 0xffff, "unsigned short");

    case NATIVE_UINT32:
        /* Special handling/checking for unsigned 32 bit integers */
        return getUnsignedInt32(value, type);

    case NATIVE_LONG:
        return NUM2LONG(value);

    case NATIVE_ULONG:
        return NUM2ULONG(value);

#ifdef __x86_64__
    case NATIVE_INT64:
        if (type != T_FIXNUM && type != T_BIGNUM) {
            rb_raise(rb_eTypeError, "Expected an Integer parameter");
        }
        return NUM2LL(value);

    case NATIVE_UINT64:
        if (type != T_FIXNUM && type != T_BIGNUM) {
            rb_raise(rb_eTypeError, "Expected an Integer parameter");
        }
        return NUM2ULL(value);
#endif
    case NATIVE_STRING:
        return (intptr_t) getString(value, type);

    case NATIVE_POINTER:
    case NATIVE_BUFFER_IN:
    case NATIVE_BUFFER_OUT:
    case NATIVE_BUFFER_INOUT:
        return (intptr_t) getPointer(value, type);

    default:
        rb_raise(rb_eTypeError, "unsupported integer type %d", nativeType);
        return 0;
    }
}
示例#8
0
static int write_element(VALUE key, VALUE value, VALUE extra, int allow_id) {
    buffer_t buffer = (buffer_t)NUM2LL(rb_ary_entry(extra, 0));
    VALUE check_keys = rb_ary_entry(extra, 1);

    if (TYPE(key) == T_SYMBOL) {
        // TODO better way to do this... ?
        key = rb_str_new2(rb_id2name(SYM2ID(key)));
    }

    if (TYPE(key) != T_STRING) {
        bson_buffer_free(buffer);
        rb_raise(rb_eTypeError, "keys must be strings or symbols");
    }

    if (allow_id == 0 && strcmp("_id", RSTRING_PTR(key)) == 0) {
        return ST_CONTINUE;
    }

    if (check_keys == Qtrue) {
        int i;
        if (RSTRING_LEN(key) > 0 && RSTRING_PTR(key)[0] == '$') {
            bson_buffer_free(buffer);
            rb_raise(InvalidKeyName, "%s - key must not start with '$'", RSTRING_PTR(key));
        }
        for (i = 0; i < RSTRING_LEN(key); i++) {
            if (RSTRING_PTR(key)[i] == '.') {
                bson_buffer_free(buffer);
                rb_raise(InvalidKeyName, "%s - key must not contain '.'", RSTRING_PTR(key));
            }
        }
    }

    switch(TYPE(value)) {
    case T_BIGNUM:
        {
            if (rb_funcall(value, gt_operator, 1, LL2NUM(9223372036854775807LL)) == Qtrue ||
                rb_funcall(value, lt_operator, 1, LL2NUM(-9223372036854775808ULL)) == Qtrue) {
                bson_buffer_free(buffer);
                rb_raise(rb_eRangeError, "MongoDB can only handle 8-byte ints");
            }
        }
        // NOTE: falls through to T_FIXNUM code
    case T_FIXNUM:
        {
            long long ll_value;
            ll_value = NUM2LL(value);

            if (ll_value > 2147483647LL ||
                ll_value < -2147483648LL) {
                write_name_and_type(buffer, key, 0x12);
                SAFE_WRITE(buffer, (char*)&ll_value, 8);
            } else {
                int int_value;
                write_name_and_type(buffer, key, 0x10);
                int_value = (int)ll_value;
                SAFE_WRITE(buffer, (char*)&int_value, 4);
            }
            break;
        }
    case T_TRUE:
        {
            write_name_and_type(buffer, key, 0x08);
            SAFE_WRITE(buffer, &one, 1);
            break;
        }
    case T_FALSE:
        {
            write_name_and_type(buffer, key, 0x08);
            SAFE_WRITE(buffer, &zero, 1);
            break;
        }
    case T_FLOAT:
        {
            double d = NUM2DBL(value);
            write_name_and_type(buffer, key, 0x01);
            SAFE_WRITE(buffer, (char*)&d, 8);
            break;
        }
    case T_NIL:
        {
            write_name_and_type(buffer, key, 0x0A);
            break;
        }
    case T_HASH:
        {
            write_name_and_type(buffer, key, 0x03);
            write_doc(buffer, value, check_keys, Qfalse);
            break;
        }
    case T_ARRAY:
        {
            buffer_position length_location, start_position, obj_length;
            int items, i;
            VALUE* values;

            write_name_and_type(buffer, key, 0x04);
            start_position = buffer_get_position(buffer);

            // save space for length
            length_location = buffer_save_space(buffer, 4);
            if (length_location == -1) {
                rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
            }

            items = RARRAY_LENINT(value);
            for(i = 0; i < items; i++) {
                char* name;
                VALUE key;
                INT2STRING(&name, i);
                key = rb_str_new2(name);
                write_element_with_id(key, rb_ary_entry(value, i), pack_extra(buffer, check_keys));
                FREE_INTSTRING(name);
            }

            // write null byte and fill in length
            SAFE_WRITE(buffer, &zero, 1);
            obj_length = buffer_get_position(buffer) - start_position;
            SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
            break;
        }
    case T_STRING:
        {
            int length;
            write_name_and_type(buffer, key, 0x02);
            length = RSTRING_LENINT(value) + 1;
            SAFE_WRITE(buffer, (char*)&length, 4);
            write_utf8(buffer, value, 0);
            SAFE_WRITE(buffer, &zero, 1);
            break;
        }
    case T_SYMBOL:
        {
            const char* str_value = rb_id2name(SYM2ID(value));
            int length = (int)strlen(str_value) + 1;
            write_name_and_type(buffer, key, 0x0E);
            SAFE_WRITE(buffer, (char*)&length, 4);
            SAFE_WRITE(buffer, str_value, length);
            break;
        }
    case T_OBJECT:
        {
            // TODO there has to be a better way to do these checks...
            const char* cls = rb_obj_classname(value);
            if (strcmp(cls, "BSON::Binary") == 0 ||
                strcmp(cls, "ByteBuffer") == 0) {
                const char subtype = strcmp(cls, "ByteBuffer") ?
                    (const char)FIX2INT(rb_funcall(value, rb_intern("subtype"), 0)) : 2;
                VALUE string_data = rb_funcall(value, rb_intern("to_s"), 0);
                int length = RSTRING_LENINT(string_data);
                write_name_and_type(buffer, key, 0x05);
                if (subtype == 2) {
                    const int other_length = length + 4;
                    SAFE_WRITE(buffer, (const char*)&other_length, 4);
                    SAFE_WRITE(buffer, &subtype, 1);
                }
                SAFE_WRITE(buffer, (const char*)&length, 4);
                if (subtype != 2) {
                    SAFE_WRITE(buffer, &subtype, 1);
                }
                SAFE_WRITE(buffer, RSTRING_PTR(string_data), length);
                break;
            }
            if (strcmp(cls, "BSON::ObjectId") == 0) {
                VALUE as_array = rb_funcall(value, rb_intern("to_a"), 0);
                int i;
                write_name_and_type(buffer, key, 0x07);
                for (i = 0; i < 12; i++) {
                    char byte = (char)FIX2INT(rb_ary_entry(as_array, i));
                    SAFE_WRITE(buffer, &byte, 1);
                }
                break;
            }
            if (strcmp(cls, "BSON::DBRef") == 0) {
                buffer_position length_location, start_position, obj_length;
                VALUE ns, oid;
                write_name_and_type(buffer, key, 0x03);

                start_position = buffer_get_position(buffer);

                // save space for length
                length_location = buffer_save_space(buffer, 4);
                if (length_location == -1) {
                    rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
                }

                ns = rb_funcall(value, rb_intern("namespace"), 0);
                write_element_with_id(rb_str_new2("$ref"), ns, pack_extra(buffer, Qfalse));
                oid = rb_funcall(value, rb_intern("object_id"), 0);
                write_element_with_id(rb_str_new2("$id"), oid, pack_extra(buffer, Qfalse));

                // write null byte and fill in length
                SAFE_WRITE(buffer, &zero, 1);
                obj_length = buffer_get_position(buffer) - start_position;
                SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
                break;
            }
            if (strcmp(cls, "BSON::Code") == 0) {
                buffer_position length_location, start_position, total_length;
                int length;
                VALUE code_str;
                write_name_and_type(buffer, key, 0x0F);

                start_position = buffer_get_position(buffer);
                length_location = buffer_save_space(buffer, 4);
                if (length_location == -1) {
                    rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
                }

                code_str = rb_funcall(value, rb_intern("code"), 0);
                length = RSTRING_LENINT(code_str) + 1;
                SAFE_WRITE(buffer, (char*)&length, 4);
                SAFE_WRITE(buffer, RSTRING_PTR(code_str), length - 1);
                SAFE_WRITE(buffer, &zero, 1);
                write_doc(buffer, rb_funcall(value, rb_intern("scope"), 0), Qfalse, Qfalse);

                total_length = buffer_get_position(buffer) - start_position;
                SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&total_length, 4);
                break;
            }
            if (strcmp(cls, "BSON::MaxKey") == 0) {
                write_name_and_type(buffer, key, 0x7f);
                break;
            }
            if (strcmp(cls, "BSON::MinKey") == 0) {
                write_name_and_type(buffer, key, 0xff);
                break;
            }
            if (strcmp(cls, "BSON::Timestamp") == 0) {
                write_name_and_type(buffer, key, 0x11);
                int seconds = FIX2INT(
                    rb_funcall(value, rb_intern("seconds"), 0));
                int increment = FIX2INT(
                    rb_funcall(value, rb_intern("increment"), 0));

                SAFE_WRITE(buffer, (const char*)&increment, 4);
                SAFE_WRITE(buffer, (const char*)&seconds, 4);
                break;
            }
            if (strcmp(cls, "DateTime") == 0 || strcmp(cls, "Date") == 0 || strcmp(cls, "ActiveSupport::TimeWithZone") == 0) {
                bson_buffer_free(buffer);
                rb_raise(InvalidDocument, "%s is not currently supported; use a UTC Time instance instead.", cls);
                break;
            }
            if(strcmp(cls, "Complex") == 0 || strcmp(cls, "Rational") == 0 || strcmp(cls, "BigDecimal") == 0) {
                bson_buffer_free(buffer);
                rb_raise(InvalidDocument, "Cannot serialize the Numeric type %s as BSON; only Bignum, Fixnum, and Float are supported.", cls);
                break;
            }
            bson_buffer_free(buffer);
            rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
            break;
        }
    case T_DATA:
        {
            const char* cls = rb_obj_classname(value);
            if (strcmp(cls, "Time") == 0) {
                double t = NUM2DBL(rb_funcall(value, rb_intern("to_f"), 0));
                long long time_since_epoch = (long long)round(t * 1000);
                write_name_and_type(buffer, key, 0x09);
                SAFE_WRITE(buffer, (const char*)&time_since_epoch, 8);
                break;
            }
            if(strcmp(cls, "BigDecimal") == 0) {
                bson_buffer_free(buffer);
                rb_raise(InvalidDocument, "Cannot serialize the Numeric type %s as BSON; only Bignum, Fixnum, and Float are supported.", cls);
                break;
            }
            bson_buffer_free(buffer);
            rb_raise(InvalidDocument, "Cannot serialize an object of class %s into BSON.", cls);
            break;
        }
    case T_REGEXP:
        {
            VALUE pattern = RREGEXP_SRC(value);
            long flags = RREGEXP_OPTIONS(value);
            VALUE has_extra;

            write_name_and_type(buffer, key, 0x0B);

            write_utf8(buffer, pattern, 1);
            SAFE_WRITE(buffer, &zero, 1);

            if (flags & IGNORECASE) {
                char ignorecase = 'i';
                SAFE_WRITE(buffer, &ignorecase, 1);
            }
            if (flags & MULTILINE) {
                char multiline = 'm';
                char dotall = 's';
                SAFE_WRITE(buffer, &multiline, 1);
                SAFE_WRITE(buffer, &dotall, 1);
            }
            if (flags & EXTENDED) {
                char extended = 'x';
                SAFE_WRITE(buffer, &extended, 1);
            }

            has_extra = rb_funcall(value, rb_intern("respond_to?"), 1, rb_str_new2("extra_options_str"));
            if (TYPE(has_extra) == T_TRUE) {
                VALUE extra = rb_funcall(value, rb_intern("extra_options_str"), 0);
                buffer_position old_position = buffer_get_position(buffer);
                SAFE_WRITE(buffer, RSTRING_PTR(extra), RSTRING_LENINT(extra));
                qsort(buffer_get_buffer(buffer) + old_position, RSTRING_LEN(extra), sizeof(char), cmp_char);
            }
            SAFE_WRITE(buffer, &zero, 1);

            break;
        }
    default:
        {
            const char* cls = rb_obj_classname(value);
            bson_buffer_free(buffer);
            rb_raise(InvalidDocument, "Cannot serialize an object of class %s (type %d) into BSON.", cls, TYPE(value));
            break;
        }
    }
    return ST_CONTINUE;
}
示例#9
0
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;
}
示例#10
0
static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow_id) {
    bson_buffer* buffer = (bson_buffer*)NUM2INT(rb_ary_entry(extra, 0));
    VALUE check_keys = rb_ary_entry(extra, 1);

    if (TYPE(key) == T_SYMBOL) {
        // TODO better way to do this... ?
        key = rb_str_new2(rb_id2name(SYM2ID(key)));
    }

    if (TYPE(key) != T_STRING) {
        rb_raise(rb_eTypeError, "keys must be strings or symbols");
    }

    if (!allow_id && strcmp("_id", RSTRING_PTR(key)) == 0) {
        return ST_CONTINUE;
    }

    if (check_keys == Qtrue) {
        if (RSTRING_LEN(key) > 0 && RSTRING_PTR(key)[0] == '$') {
            rb_raise(rb_eRuntimeError, "key must not start with '$'");
        }
        int i;
        for (i = 0; i < RSTRING_LEN(key); i++) {
            if (RSTRING_PTR(key)[i] == '.') {
                rb_raise(rb_eRuntimeError, "key must not contain '.'");
            }
        }
    }

    switch(TYPE(value)) {
    case T_BIGNUM:
        {
            if (rb_funcall(value, rb_intern(">"), 1, INT2NUM(2147483647)) == Qtrue ||
                rb_funcall(value, rb_intern("<"), 1, INT2NUM(-2147483648)) == Qtrue) {
                rb_raise(rb_eRangeError, "MongoDB can only handle 4-byte ints - try converting to a double before saving");
            }
            write_name_and_type(buffer, key, 0x10);
            VALUE as_f = rb_funcall(value, rb_intern("to_f"), 0);
            int int_value = NUM2LL(as_f);
            buffer_write_bytes(buffer, (char*)&int_value, 4);
            break;
        }
    case T_FIXNUM:
        {
            write_name_and_type(buffer, key, 0x10);
            int int_value = FIX2INT(value);
            buffer_write_bytes(buffer, (char*)&int_value, 4);
            break;
        }
    case T_TRUE:
        {
            write_name_and_type(buffer, key, 0x08);
            buffer_write_bytes(buffer, &one, 1);
            break;
        }
    case T_FALSE:
        {
            write_name_and_type(buffer, key, 0x08);
            buffer_write_bytes(buffer, &zero, 1);
            break;
        }
    case T_FLOAT:
        {
            write_name_and_type(buffer, key, 0x01);
            double d = NUM2DBL(value);
            buffer_write_bytes(buffer, (char*)&d, 8);
            break;
        }
    case T_NIL:
        {
            write_name_and_type(buffer, key, 0x0A);
            break;
        }
    case T_HASH:
        {
            write_name_and_type(buffer, key, 0x03);
            write_doc(buffer, value, check_keys);
            break;
        }
    case T_ARRAY:
        {
            write_name_and_type(buffer, key, 0x04);
            int start_position = buffer->position;

            // save space for length
            int length_location = buffer_save_bytes(buffer, 4);

            int items = RARRAY_LEN(value);
            VALUE* values = RARRAY_PTR(value);
            int i;
            for(i = 0; i < items; i++) {
                char* name;
                asprintf(&name, "%d", i);
                VALUE key = rb_str_new2(name);
                write_element(key, values[i], pack_extra(buffer, check_keys));
                free(name);
            }

            // write null byte and fill in length
            buffer_write_bytes(buffer, &zero, 1);
            int obj_length = buffer->position - start_position;
            memcpy(buffer->buffer + length_location, &obj_length, 4);
            break;
        }
    case T_STRING:
        {
            if (strcmp(rb_class2name(RBASIC(value)->klass),
                       "XGen::Mongo::Driver::Code") == 0) {
                write_name_and_type(buffer, key, 0x0F);

                int start_position = buffer->position;
                int length_location = buffer_save_bytes(buffer, 4);

                int length = RSTRING_LEN(value) + 1;
                buffer_write_bytes(buffer, (char*)&length, 4);
                buffer_write_bytes(buffer, RSTRING_PTR(value), length - 1);
                buffer_write_bytes(buffer, &zero, 1);
                write_doc(buffer, rb_funcall(value, rb_intern("scope"), 0), Qfalse);

                int total_length = buffer->position - start_position;
                memcpy(buffer->buffer + length_location, &total_length, 4);

                break;
            } else {
                write_name_and_type(buffer, key, 0x02);
                int length = RSTRING_LEN(value) + 1;
                buffer_write_bytes(buffer, (char*)&length, 4);
                buffer_write_bytes(buffer, RSTRING_PTR(value), length - 1);
                buffer_write_bytes(buffer, &zero, 1);
                break;
            }
        }
    case T_SYMBOL:
        {
            write_name_and_type(buffer, key, 0x0E);
            const char* str_value = rb_id2name(SYM2ID(value));
            int length = strlen(str_value) + 1;
            buffer_write_bytes(buffer, (char*)&length, 4);
            buffer_write_bytes(buffer, str_value, length);
            break;
        }
    case T_OBJECT:
        {
            // TODO there has to be a better way to do these checks...
            const char* cls = rb_class2name(RBASIC(value)->klass);
            if (strcmp(cls, "XGen::Mongo::Driver::Binary") == 0 ||
                strcmp(cls, "ByteBuffer") == 0) {
                write_name_and_type(buffer, key, 0x05);
                const char subtype = strcmp(cls, "ByteBuffer") ?
                    (const char)FIX2INT(rb_funcall(value, rb_intern("subtype"), 0)) : 2;
                VALUE string_data = rb_funcall(value, rb_intern("to_s"), 0);
                int length = RSTRING_LEN(string_data);
                if (subtype == 2) {
                    const int other_length = length + 4;
                    buffer_write_bytes(buffer, (const char*)&other_length, 4);
                    buffer_write_bytes(buffer, &subtype, 1);
                }
                buffer_write_bytes(buffer, (const char*)&length, 4);
                if (subtype != 2) {
                    buffer_write_bytes(buffer, &subtype, 1);
                }
                buffer_write_bytes(buffer, RSTRING_PTR(string_data), length);
                break;
            }
            if (strcmp(cls, "XGen::Mongo::Driver::ObjectID") == 0) {
                write_name_and_type(buffer, key, 0x07);
                VALUE as_array = rb_funcall(value, rb_intern("to_a"), 0);
                int i;
                for (i = 0; i < 12; i++) {
                    char byte = (char)FIX2INT(RARRAY_PTR(as_array)[i]);
                    buffer_write_bytes(buffer, &byte, 1);
                }
                break;
            }
            if (strcmp(cls, "XGen::Mongo::Driver::DBRef") == 0) {
                write_name_and_type(buffer, key, 0x03);

                int start_position = buffer->position;

                // save space for length
                int length_location = buffer_save_bytes(buffer, 4);

                VALUE ns = rb_funcall(value, rb_intern("namespace"), 0);
                write_element(rb_str_new2("$ref"), ns, pack_extra(buffer, Qfalse));
                VALUE oid = rb_funcall(value, rb_intern("object_id"), 0);
                write_element(rb_str_new2("$id"), oid, pack_extra(buffer, Qfalse));

                // write null byte and fill in length
                buffer_write_bytes(buffer, &zero, 1);
                int obj_length = buffer->position - start_position;
                memcpy(buffer->buffer + length_location, &obj_length, 4);
                break;
            }
            if (strcmp(cls, "XGen::Mongo::Driver::Undefined") == 0) {
                write_name_and_type(buffer, key, 0x06);
                break;
            }
        }
    case T_DATA:
        {
            // TODO again, is this really the only way to do this?
            const char* cls = rb_class2name(RBASIC(value)->klass);
            if (strcmp(cls, "Time") == 0) {
                write_name_and_type(buffer, key, 0x09);
                double t = NUM2DBL(rb_funcall(value, rb_intern("to_f"), 0));
                long long time_since_epoch = (long long)round(t * 1000);
                buffer_write_bytes(buffer, (const char*)&time_since_epoch, 8);
                break;
            }
        }
    case T_REGEXP:
        {
            write_name_and_type(buffer, key, 0x0B);

            int length = RREGEXP_SRC_LEN(value);
            char* pattern = (char*)RREGEXP_SRC_PTR(value);
            buffer_write_bytes(buffer, pattern, length);
            buffer_write_bytes(buffer, &zero, 1);

            long flags = RREGEXP(value)->ptr->options;
            if (flags & IGNORECASE) {
                char ignorecase = 'i';
                buffer_write_bytes(buffer, &ignorecase, 1);
            }
            if (flags & MULTILINE) {
                char multiline = 'm';
                buffer_write_bytes(buffer, &multiline, 1);
            }
            if (flags & EXTENDED) {
                char extended = 'x';
                buffer_write_bytes(buffer, &extended, 1);
            }

            VALUE has_extra = rb_funcall(value, rb_intern("respond_to?"), 1, rb_str_new2("extra_options_str"));
            if (TYPE(has_extra) == T_TRUE) {
                VALUE extra = rb_funcall(value, rb_intern("extra_options_str"), 0);
                int old_position = buffer->position;
                buffer_write_bytes(buffer, RSTRING_PTR(extra), RSTRING_LEN(extra));
                qsort(buffer->buffer + old_position, RSTRING_LEN(extra), sizeof(char), cmp_char);
            }
            buffer_write_bytes(buffer, &zero, 1);

            break;
        }
    default:
        {
            rb_raise(rb_eTypeError, "no c encoder for this type yet (%d)", TYPE(value));
            break;
        }
    }
    return ST_CONTINUE;
}
示例#11
0
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;
    int32_t int32_value;
    uint32_t uint32_value;
    int64_t int64_value;
    uint64_t uint64_value;
    int64_t time_value;
    double double_value;
    grn_id record_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_VIEW);
    if (string_p && !table_type_p) {
	return RVAL2GRNBULK(object, context, bulk);
    }

    switch (type_id) {
      case GRN_DB_INT32:
	int32_value = NUM2INT(object);
	string = (const char *)&int32_value;
	size = sizeof(int32_value);
	break;
      case GRN_DB_UINT32:
	uint32_value = NUM2UINT(object);
	string = (const char *)&uint32_value;
	size = sizeof(uint32_value);
	break;
      case GRN_DB_INT64:
	int64_value = NUM2LL(object);
	string = (const char *)&int64_value;
	size = sizeof(int64_value);
	break;
      case GRN_DB_UINT64:
	uint64_value = NUM2ULL(object);
	string = (const char *)&uint64_value;
	size = sizeof(uint64_value);
	break;
      case GRN_DB_FLOAT:
	double_value = NUM2DBL(object);
	string = (const char *)&double_value;
	size = sizeof(double_value);
	break;
      case GRN_DB_TIME:
	{
	    VALUE rb_sec, rb_usec;
            int64_t sec;
            int32_t usec;

            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;
            }

	    time_value = GRN_TIME_PACK(sec, usec);
	}
	string = (const char *)&time_value;
	size = sizeof(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_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))) {
	    record_id = GRN_ID_NIL;
	    string = (const char *)&record_id;
	    size = sizeof(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;
}
示例#12
0
VALUE method_atomic_fixnum_decrement(VALUE self) {
  long long value = NUM2LL((VALUE) DATA_PTR(self));
  return method_atomic_fixnum_value_set(self, LL2NUM(value - 1));
}
示例#13
0
static VALUE valid_cpf(VALUE self, VALUE ruby_cpf){
    long long cpf = 0;
    cpf = (long long)NUM2LL(ruby_cpf);
    if(cpf == 0) return Qfalse;
    return e_cpf(cpf) ? Qtrue : Qfalse;
}
示例#14
0
/* call-seq: stmt.bind_param(key, value)
 *
 * Binds value to the named (or positional) placeholder. If +param+ is a
 * Fixnum, it is treated as an index for a positional placeholder.
 * Otherwise it is used as the name of the placeholder to bind to.
 *
 * See also #bind_params.
 */
static VALUE bind_param(VALUE self, VALUE key, VALUE value)
{
  sqlite3StmtRubyPtr ctx;
  int status;
  int index;

  Data_Get_Struct(self, sqlite3StmtRuby, ctx);
  REQUIRE_OPEN_STMT(ctx);

  switch(TYPE(key)) {
    case T_SYMBOL:
      key = rb_funcall(key, rb_intern("to_s"), 0);
    case T_STRING:
      if(RSTRING_PTR(key)[0] != ':') key = rb_str_plus(rb_str_new2(":"), key);
      index = sqlite3_bind_parameter_index(ctx->st, StringValuePtr(key));
      break;
    default:
      index = (int)NUM2INT(key);
  }

  if(index == 0)
    rb_raise(rb_path2class("SQLite3::Exception"), "no such bind parameter");

  switch(TYPE(value)) {
    case T_STRING:
      if(CLASS_OF(value) == cSqlite3Blob
#ifdef HAVE_RUBY_ENCODING_H
              || rb_enc_get_index(value) == rb_ascii8bit_encindex()
#endif
        ) {
        status = sqlite3_bind_blob(
            ctx->st,
            index,
            (const char *)StringValuePtr(value),
            (int)RSTRING_LEN(value),
            SQLITE_TRANSIENT
            );
      } else {
#ifdef HAVE_RUBY_ENCODING_H
        if(!UTF8_P(value)) {
              VALUE db          = rb_iv_get(self, "@connection");
              VALUE encoding    = rb_funcall(db, rb_intern("encoding"), 0);
              rb_encoding * enc = rb_to_encoding(encoding);
              value = rb_str_export_to_enc(value, enc);
          }
#endif

        status = sqlite3_bind_text(
            ctx->st,
            index,
            (const char *)StringValuePtr(value),
            (int)RSTRING_LEN(value),
            SQLITE_TRANSIENT
            );
      }
      break;
    case T_BIGNUM:
#if SIZEOF_LONG < 8
      if (RBIGNUM_LEN(value) * SIZEOF_BDIGITS <= 8) {
          status = sqlite3_bind_int64(ctx->st, index, (sqlite3_int64)NUM2LL(value));
          break;
      }
#endif
    case T_FLOAT:
      status = sqlite3_bind_double(ctx->st, index, NUM2DBL(value));
      break;
    case T_FIXNUM:
      status = sqlite3_bind_int64(ctx->st, index, (sqlite3_int64)FIX2LONG(value));
      break;
    case T_NIL:
      status = sqlite3_bind_null(ctx->st, index);
      break;
    default:
      rb_raise(rb_eRuntimeError, "can't prepare %s",
          rb_class2name(CLASS_OF(value)));
      break;
  }

  CHECK(sqlite3_db_handle(ctx->st), status);

  return self;
}
示例#15
0
文件: sfcc.c 项目: miminar/ruby-sfcc
CIMCData sfcc_value_to_cimdata(VALUE value)
{
  CIMCData data;
  memset(&data, 0, sizeof(CIMCData));
  data.state = CIMC_goodValue;
  data.type = CIMC_null;

  switch (TYPE(value))
  {
  case T_NIL:
    data.type = CIMC_null;
    data.state = CIMC_nullValue;
    break;
  case T_STRING:
    data.type = CIMC_string;
    data.value.string = cimcEnv->ft->newString(cimcEnv, to_charptr(value), NULL);
    break;
  case T_TRUE:
    data.type = CIMC_boolean;
    data.value.boolean = 1;
    break;
  case T_FALSE:
    data.type = CIMC_boolean;
    data.value.boolean = 0;
    break;
  case T_FIXNUM:
    data.type = CIMC_sint64;
    data.value.Long = NUM2INT(value);
    break;
  case T_FLOAT:
    data.type = CIMC_real64;
    data.value.real64 = NUM2DBL(value);
    break;
  case T_BIGNUM:
    data.type = CIMC_sint64;
    data.value.Long = NUM2LL(value);
    break;
/* not yet supported
  case T_HASH:
    break;
  case T_SYMBOL:
    */
  case T_ARRAY: {
    data.value.array = sfcc_rubyarray_to_cimcarray(value, &data.type);
    if (!data.value.array) {
      data.state = CIMC_badValue;
    }
    break;
  }
  case T_DATA:
  default:
    if (CLASS_OF(value) == cSfccCimString) {
      Data_Get_Struct(value, CIMCString, data.value.string);
      if (data.value.string == NULL) { /* packed a NULL pointer ? */
        data.type = CIMC_null;
        data.state = CIMC_nullValue;
      }
      else {
        data.type = CIMC_string;
      }
    }
    else if (CLASS_OF(value) == cSfccCimData) {
      CIMCData *tmp;
      Data_Get_Struct(value, CIMCData, tmp);
      data = *tmp;
    }
    else if(CLASS_OF(value) == cSfccCimInstance) {
      rb_sfcc_instance *obj;
      Data_Get_Struct(value, rb_sfcc_instance, obj);
      data.value.inst = obj->inst;
      if (data.value.inst == NULL) {
        data.type = CIMC_null;
        data.state = CIMC_nullValue;
      }else {
        data.type = CIMC_instance;
      }
    }
    else if(CLASS_OF(value) == cSfccCimObjectPath) {
      rb_sfcc_object_path *obj;
      Data_Get_Struct(value, rb_sfcc_object_path, obj);
      data.value.ref = obj->op;
      if (data.value.ref == NULL) {
        data.type = CIMC_null;
        data.state = CIMC_nullValue;
      }else {
        data.type = CIMC_ref;
      }
    }
    else if(CLASS_OF(value) == cSfccCimEnumeration) {
      rb_sfcc_enumeration *obj;
      Data_Get_Struct(value, rb_sfcc_enumeration, obj);
      data.value.Enum = obj->enm;
      if (data.value.Enum == NULL) {
        data.type = CIMC_null;
        data.state = CIMC_nullValue;
      }else {
        data.type = CIMC_enumeration;
      }
    }
    else if (CLASS_OF(value) == cSfccCimClass) {
      Data_Get_Struct(value, CIMCClass, data.value.cls);
      if (data.value.cls == NULL) {
        data.type = CIMC_null;
        data.state = CIMC_nullValue;
      }else {
        data.type = CIMC_class;
      }
    }
    else {
      VALUE cname;
      const char *class_name;
      data.state = CIMC_badValue;
      data.type = CIMC_null;
      cname = rb_funcall(rb_funcall(value, rb_intern("class"), 0), rb_intern("to_s"), 0);
      class_name = to_charptr(cname);
      rb_raise(rb_eTypeError, "unsupported data type: %s", class_name);
      return data;
    }
  }
  return data;
}
示例#16
0
static VALUE valid_cnpj(VALUE self, VALUE ruby_cnpj) {
    long long cnpj=0;
    cnpj = (long long)NUM2LL(ruby_cnpj);
    if(cnpj == 0) return Qfalse;
    return is_cnpj(cnpj) ? Qtrue : Qfalse;
}
示例#17
0
void
rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes,
        FFIStorage* paramStorage, void** ffiValues,
        VALUE* callbackParameters, int callbackCount, VALUE enums)
{
    VALUE callbackProc = Qnil;
    FFIStorage* param = &paramStorage[0];
    int i, argidx, cbidx, argCount;

    if (unlikely(paramCount != -1 && paramCount != argc)) {
        if (argc == (paramCount - 1) && callbackCount == 1 && rb_block_given_p()) {
            callbackProc = rb_block_proc();
        } else {
            rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, paramCount);
        }
    }

    argCount = paramCount != -1 ? paramCount : argc;

    for (i = 0, argidx = 0, cbidx = 0; i < argCount; ++i) {
        Type* paramType = paramTypes[i];
        int type;

        
        if (unlikely(paramType->nativeType == NATIVE_MAPPED)) {
            VALUE values[] = { argv[argidx], Qnil };
            argv[argidx] = rb_funcall2(((MappedType *) paramType)->rbConverter, id_to_native, 2, values);
            paramType = ((MappedType *) paramType)->type;
        }

        type = argidx < argc ? TYPE(argv[argidx]) : T_NONE;
        ffiValues[i] = param;

        switch (paramType->nativeType) {

            case NATIVE_INT8:
                param->s8 = NUM2INT(argv[argidx]);
                ++argidx;
                ADJ(param, INT8);
                break;


            case NATIVE_INT16:
                param->s16 = NUM2INT(argv[argidx]);
                ++argidx;
                ADJ(param, INT16);
                break;


            case NATIVE_INT32:
                if (unlikely(type == T_SYMBOL && enums != Qnil)) {
                    VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]);
                    param->s32 = NUM2INT(value);

                } else {
                    param->s32 = NUM2INT(argv[argidx]);
                }

                ++argidx;
                ADJ(param, INT32);
                break;


            case NATIVE_BOOL:
                if (type != T_TRUE && type != T_FALSE) {
                    rb_raise(rb_eTypeError, "wrong argument type  (expected a boolean parameter)");
                }
                param->s8 = argv[argidx++] == Qtrue;
                ADJ(param, INT8);
                break;


            case NATIVE_UINT8:
                param->u8 = NUM2UINT(argv[argidx]);
                ADJ(param, INT8);
                ++argidx;
                break;


            case NATIVE_UINT16:
                param->u16 = NUM2UINT(argv[argidx]);
                ADJ(param, INT16);
                ++argidx;
                break;


            case NATIVE_UINT32:
                param->u32 = NUM2UINT(argv[argidx]);
                ADJ(param, INT32);
                ++argidx;
                break;


            case NATIVE_INT64:
                param->i64 = NUM2LL(argv[argidx]);
                ADJ(param, INT64);
                ++argidx;
                break;


            case NATIVE_UINT64:
                param->u64 = NUM2ULL(argv[argidx]);
                ADJ(param, INT64);
                ++argidx;
                break;

            case NATIVE_LONG:
                *(ffi_sarg *) param = NUM2LONG(argv[argidx]);
                ADJ(param, LONG);
                ++argidx;
                break;

            case NATIVE_ULONG:
                *(ffi_arg *) param = NUM2ULONG(argv[argidx]);
                ADJ(param, LONG);
                ++argidx;
                break;

            case NATIVE_FLOAT32:
                param->f32 = (float) NUM2DBL(argv[argidx]);
                ADJ(param, FLOAT32);
                ++argidx;
                break;

            case NATIVE_FLOAT64:
                param->f64 = NUM2DBL(argv[argidx]);
                ADJ(param, FLOAT64);
                ++argidx;
                break;

            case NATIVE_LONGDOUBLE:
                param->ld = rbffi_num2longdouble(argv[argidx]);
                ADJ(param, LONGDOUBLE);
                ++argidx;
                break;


            case NATIVE_STRING:
                if (type == T_NIL) {
                    param->ptr = NULL; 
                
                } else {
                    if (rb_safe_level() >= 1 && OBJ_TAINTED(argv[argidx])) {
                        rb_raise(rb_eSecurityError, "Unsafe string parameter");
                    }

                    param->ptr = StringValueCStr(argv[argidx]);
                }

                ADJ(param, ADDRESS);
                ++argidx;
                break;

            case NATIVE_POINTER:
            case NATIVE_BUFFER_IN:
            case NATIVE_BUFFER_OUT:
            case NATIVE_BUFFER_INOUT:
                param->ptr = getPointer(argv[argidx++], type);
                ADJ(param, ADDRESS);
                break;


            case NATIVE_FUNCTION:
            case NATIVE_CALLBACK:
                if (callbackProc != Qnil) {
                    param->ptr = callback_param(callbackProc, callbackParameters[cbidx++]);
                } else {
                    param->ptr = callback_param(argv[argidx], callbackParameters[cbidx++]);
                    ++argidx;
                }
                ADJ(param, ADDRESS);
                break;

            case NATIVE_STRUCT:
                ffiValues[i] = getPointer(argv[argidx++], type);
                break;

            default:
                rb_raise(rb_eArgError, "Invalid parameter type: %d", paramType->nativeType);
        }
    }
}
示例#18
0
void
callback(ffi_cif *cif, void *resp, void **args, void *ctx)
{
    VALUE self      = (VALUE)ctx;
    VALUE rbargs    = rb_iv_get(self, "@args");
    VALUE ctype     = rb_iv_get(self, "@ctype");
    int argc        = RARRAY_LENINT(rbargs);
    VALUE params    = rb_ary_tmp_new(argc);
    VALUE ret;
    VALUE cPointer;
    int i, type;

    cPointer = rb_const_get(mFiddle, rb_intern("Pointer"));

    for (i = 0; i < argc; i++) {
        type = NUM2INT(RARRAY_PTR(rbargs)[i]);
        switch (type) {
        case TYPE_VOID:
            argc = 0;
            break;
        case TYPE_INT:
            rb_ary_push(params, INT2NUM(*(int *)args[i]));
            break;
        case -TYPE_INT:
            rb_ary_push(params, UINT2NUM(*(unsigned int *)args[i]));
            break;
        case TYPE_VOIDP:
            rb_ary_push(params,
                        rb_funcall(cPointer, rb_intern("[]"), 1,
                                   PTR2NUM(*(void **)args[i])));
            break;
        case TYPE_LONG:
            rb_ary_push(params, LONG2NUM(*(long *)args[i]));
            break;
        case -TYPE_LONG:
            rb_ary_push(params, ULONG2NUM(*(unsigned long *)args[i]));
            break;
        case TYPE_CHAR:
            rb_ary_push(params, INT2NUM(*(signed char *)args[i]));
            break;
        case -TYPE_CHAR:
            rb_ary_push(params, UINT2NUM(*(unsigned char *)args[i]));
            break;
        case TYPE_SHORT:
            rb_ary_push(params, INT2NUM(*(signed short *)args[i]));
            break;
        case -TYPE_SHORT:
            rb_ary_push(params, UINT2NUM(*(unsigned short *)args[i]));
            break;
        case TYPE_DOUBLE:
            rb_ary_push(params, rb_float_new(*(double *)args[i]));
            break;
        case TYPE_FLOAT:
            rb_ary_push(params, rb_float_new(*(float *)args[i]));
            break;
#if HAVE_LONG_LONG
        case TYPE_LONG_LONG:
            rb_ary_push(params, LL2NUM(*(LONG_LONG *)args[i]));
            break;
        case -TYPE_LONG_LONG:
            rb_ary_push(params, ULL2NUM(*(unsigned LONG_LONG *)args[i]));
            break;
#endif
        default:
            rb_raise(rb_eRuntimeError, "closure args: %d", type);
        }
    }

    ret = rb_funcall2(self, rb_intern("call"), argc, RARRAY_PTR(params));
    RB_GC_GUARD(params);

    type = NUM2INT(ctype);
    switch (type) {
    case TYPE_VOID:
        break;
    case TYPE_LONG:
        *(long *)resp = NUM2LONG(ret);
        break;
    case -TYPE_LONG:
        *(unsigned long *)resp = NUM2ULONG(ret);
        break;
    case TYPE_CHAR:
    case TYPE_SHORT:
    case TYPE_INT:
        *(ffi_sarg *)resp = NUM2INT(ret);
        break;
    case -TYPE_CHAR:
    case -TYPE_SHORT:
    case -TYPE_INT:
        *(ffi_arg *)resp = NUM2UINT(ret);
        break;
    case TYPE_VOIDP:
        *(void **)resp = NUM2PTR(ret);
        break;
    case TYPE_DOUBLE:
        *(double *)resp = NUM2DBL(ret);
        break;
    case TYPE_FLOAT:
        *(float *)resp = (float)NUM2DBL(ret);
        break;
#if HAVE_LONG_LONG
    case TYPE_LONG_LONG:
        *(LONG_LONG *)resp = NUM2LL(ret);
        break;
    case -TYPE_LONG_LONG:
        *(unsigned LONG_LONG *)resp = NUM2ULL(ret);
        break;
#endif
    default:
        rb_raise(rb_eRuntimeError, "closure retval: %d", type);
    }
}
示例#19
0
文件: rbsigar.c 项目: mdkent/sigar
static VALUE rb_sigar_format_size(VALUE rclass, VALUE size)
{
    char buffer[56];
    return rb_str_new2(sigar_format_size(NUM2LL(size), buffer));
}
示例#20
0
grn_obj *
rb_grn_bulk_from_ruby_object (VALUE object, grn_ctx *context, grn_obj *bulk)
{
    if (bulk && bulk->header.domain == GRN_DB_TIME)
        return RVAL2GRNBULK_WITH_TYPE(object, context, bulk,
                                      bulk->header.domain,
                                      grn_ctx_at(context, bulk->header.domain));

    if (!bulk) {
        bulk = grn_obj_open(context, GRN_BULK, 0, GRN_ID_NIL);
        rb_grn_context_check(context, object);
    }

    switch (TYPE(object)) {
    case T_NIL:
        grn_obj_reinit(context, bulk, GRN_DB_VOID, 0);
        break;
    case T_SYMBOL:
        object = rb_funcall(object, rb_intern("to_s"), 0);
    case T_STRING:
        grn_obj_reinit(context, bulk, GRN_DB_TEXT, 0);
        rb_grn_context_text_set(context, bulk, object);
        break;
    case T_FIXNUM:
    case T_BIGNUM: {
        int64_t int64_value;
        int64_value = NUM2LL(object);
        if (int64_value <= INT32_MAX) {
            grn_obj_reinit(context, bulk, GRN_DB_INT32, 0);
            GRN_INT32_SET(context, bulk, int64_value);
        } else {
            grn_obj_reinit(context, bulk, GRN_DB_INT64, 0);
            GRN_INT64_SET(context, bulk, int64_value);
        }
        break;
    }
    case T_FLOAT:
        grn_obj_reinit(context, bulk, GRN_DB_FLOAT, 0);
        GRN_FLOAT_SET(context, bulk, NUM2DBL(object));
        break;
    case T_TRUE:
        grn_obj_reinit(context, bulk, GRN_DB_BOOL, 0);
        GRN_BOOL_SET(context, bulk, GRN_TRUE);
        break;
    case T_FALSE:
        grn_obj_reinit(context, bulk, GRN_DB_BOOL, 0);
        GRN_BOOL_SET(context, bulk, GRN_FALSE);
        break;
    default:
        if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cTime))) {
            VALUE sec, usec;
            int64_t time_value;

            sec = rb_funcall(object, rb_intern("to_i"), 0);
            usec = rb_funcall(object, rb_intern("usec"), 0);
            time_value = GRN_TIME_PACK(NUM2LL(sec), NUM2LL(usec));
            grn_obj_reinit(context, bulk, GRN_DB_TIME, 0);
            GRN_TIME_SET(context, bulk, time_value);
        } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnObject))) {
            grn_obj *grn_object;
            grn_id id_value;

            grn_object = RVAL2GRNOBJECT(object, &context);
            grn_obj_reinit(context, bulk, grn_object->header.domain, 0);
            id_value = grn_obj_id(context, grn_object);
            GRN_RECORD_SET(context, bulk, id_value);
        } else if (RVAL2CBOOL(rb_obj_is_kind_of(object, rb_cGrnRecord))) {
            grn_obj *table;
            grn_id id_value;

            table = RVAL2GRNOBJECT(rb_funcall(object, rb_intern("table"), 0),
                                   &context);
            id_value = NUM2UINT(rb_funcall(object, rb_intern("id"), 0));
            grn_obj_reinit(context, bulk, grn_obj_id(context, table), 0);
            GRN_RECORD_SET(context, bulk, id_value);
        } else {
            rb_raise(rb_eTypeError,
                     "bulked object should be one of "
                     "[nil, true, false, String, Symbol, Integer, Float, Time, "
                     "Groonga::Object, Groonga::Record]: %s",
                     rb_grn_inspect(object));
        }
        break;
    }

    return bulk;
}
示例#21
0
文件: rbsigar.c 项目: mdkent/sigar
static VALUE rb_sigar_net_interface_flags_to_s(VALUE rclass, VALUE flags)
{
    char buffer[1024];
    return rb_str_new2(sigar_net_interface_flags_to_string(NUM2LL(flags), buffer));
}
示例#22
0
文件: kernel.c 项目: silicon/MacRuby
static inline long long
rval_to_long_long(VALUE rval)
{
    return NUM2LL(rb_Integer(bool_to_fix(rval)));
}
示例#23
0
void native_slot_set_value_and_case(upb_fieldtype_t type, VALUE type_class,
                                    void* memory, VALUE value,
                                    uint32_t* case_memory,
                                    uint32_t case_number) {
    // Note that in order to atomically change the value in memory and the case
    // value (w.r.t. Ruby VM calls), we must set the value at |memory| only after
    // all Ruby VM calls are complete. The case is then set at the bottom of this
    // function.
    switch (type) {
    case UPB_TYPE_FLOAT:
        if (!is_ruby_num(value)) {
            rb_raise(rb_eTypeError, "Expected number type for float field.");
        }
        DEREF(memory, float) = NUM2DBL(value);
        break;
    case UPB_TYPE_DOUBLE:
        if (!is_ruby_num(value)) {
            rb_raise(rb_eTypeError, "Expected number type for double field.");
        }
        DEREF(memory, double) = NUM2DBL(value);
        break;
    case UPB_TYPE_BOOL: {
        int8_t val = -1;
        if (value == Qtrue) {
            val = 1;
        } else if (value == Qfalse) {
            val = 0;
        } else {
            rb_raise(rb_eTypeError, "Invalid argument for boolean field.");
        }
        DEREF(memory, int8_t) = val;
        break;
    }
    case UPB_TYPE_STRING:
    case UPB_TYPE_BYTES: {
        if (CLASS_OF(value) != rb_cString) {
            rb_raise(rb_eTypeError, "Invalid argument for string field.");
        }
        native_slot_validate_string_encoding(type, value);
        DEREF(memory, VALUE) = value;
        break;
    }
    case UPB_TYPE_MESSAGE: {
        if (CLASS_OF(value) == CLASS_OF(Qnil)) {
            value = Qnil;
        } else if (CLASS_OF(value) != type_class) {
            rb_raise(rb_eTypeError,
                     "Invalid type %s to assign to submessage field.",
                     rb_class2name(CLASS_OF(value)));
        }
        DEREF(memory, VALUE) = value;
        break;
    }
    case UPB_TYPE_ENUM: {
        if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
            rb_raise(rb_eTypeError,
                     "Expected number or symbol type for enum field.");
        }
        int32_t int_val = 0;
        if (TYPE(value) == T_SYMBOL) {
            // Ensure that the given symbol exists in the enum module.
            VALUE lookup = rb_funcall(type_class, rb_intern("resolve"), 1, value);
            if (lookup == Qnil) {
                rb_raise(rb_eRangeError, "Unknown symbol value for enum field.");
            } else {
                int_val = NUM2INT(lookup);
            }
        } else {
            native_slot_check_int_range_precision(UPB_TYPE_INT32, value);
            int_val = NUM2INT(value);
        }
        DEREF(memory, int32_t) = int_val;
        break;
    }
    case UPB_TYPE_INT32:
    case UPB_TYPE_INT64:
    case UPB_TYPE_UINT32:
    case UPB_TYPE_UINT64:
        native_slot_check_int_range_precision(type, value);
        switch (type) {
        case UPB_TYPE_INT32:
            DEREF(memory, int32_t) = NUM2INT(value);
            break;
        case UPB_TYPE_INT64:
            DEREF(memory, int64_t) = NUM2LL(value);
            break;
        case UPB_TYPE_UINT32:
            DEREF(memory, uint32_t) = NUM2UINT(value);
            break;
        case UPB_TYPE_UINT64:
            DEREF(memory, uint64_t) = NUM2ULL(value);
            break;
        default:
            break;
        }
        break;
    default:
        break;
    }

    if (case_memory != NULL) {
        *case_memory = case_number;
    }
}
示例#24
0
static VALUE db_execute(int argc, VALUE *argv, VALUE self)
{
	sqlite3 * db = NULL;
	void **ppDB = NULL;		
	sqlite3_stmt *statement = NULL;
	const char* sql = NULL;
	VALUE arRes = rb_ary_new();
    VALUE* colNames = NULL;
	int nRes = 0;
    char * szErrMsg = 0;
    int is_batch = 0;

	if ((argc < 2) || (argc > 3))
		rb_raise(rb_eArgError, "wrong # of arguments(%d for 3)",argc);
	
	Data_Get_Struct(self, void *, ppDB);
	db = (sqlite3 *)rho_db_get_handle(*ppDB);
	sql = RSTRING_PTR(argv[0]);
    is_batch = argv[1] == Qtrue ? 1 : 0;

    RAWTRACE1("db_execute: %s", sql);

    PROF_START_CREATED("SQLITE");
    if ( is_batch )
    {
        PROF_START_CREATED("SQLITE_EXEC");

        rho_db_lock(*ppDB);
        nRes = sqlite3_exec(db, sql,  NULL, NULL, &szErrMsg);
        rho_db_unlock(*ppDB);

        PROF_STOP("SQLITE_EXEC");
    }
    else
    {
        rho_db_lock(*ppDB);
        PROF_START_CREATED("SQLITE_PREPARE");
        nRes = rho_db_prepare_statement(*ppDB, sql, -1, &statement);
        PROF_STOP("SQLITE_PREPARE");
        //nRes = sqlite3_prepare_v2(db, sql, -1, &statement, NULL);
        if ( nRes != SQLITE_OK)
        {
            szErrMsg = (char *)sqlite3_errmsg(db);
            rho_db_unlock(*ppDB);

            rb_raise(rb_eArgError, "could not prepare statement: %d; Message: %s",nRes, (szErrMsg?szErrMsg:""));
        }

        if ( argc > 2 )
        {
            int i = 0;
            VALUE args = argv[2];
            if ( RARRAY_LEN(args) > 0 && TYPE(RARRAY_PTR(args)[0]) == T_ARRAY )
                args = RARRAY_PTR(args)[0];

            for( ; i < RARRAY_LEN(args); i++ )
            {
                VALUE arg = RARRAY_PTR(args)[i];
                if (NIL_P(arg))
                {
                    sqlite3_bind_null(statement, i+1);
                    continue;
                }

                switch( TYPE(arg) )
                {
                case T_STRING:
                    sqlite3_bind_text(statement, i+1, RSTRING_PTR(arg), RSTRING_LEN(arg), SQLITE_TRANSIENT);
                    break;
                case T_FLOAT:
                    sqlite3_bind_double(statement, i+1, NUM2DBL(arg));
                    break;
                case T_FIXNUM:
                case T_BIGNUM:
                    sqlite3_bind_int64(statement, i+1, NUM2LL(arg));
                    break;
                default:
					{
						VALUE strVal = rb_funcall(arg, rb_intern("to_s"), 0);	
	                    sqlite3_bind_text(statement, i+1, RSTRING_PTR(strVal), -1, SQLITE_TRANSIENT);	
					}
					break;
                }
            }
        }

        PROF_START_CREATED("SQLITE_EXEC");
        nRes = sqlite3_step(statement);
        PROF_STOP("SQLITE_EXEC");

	    while( nRes== SQLITE_ROW ) {
		    int nCount = sqlite3_data_count(statement);
		    int nCol = 0;
		    VALUE hashRec = rb_hash_new();

            //if ( !colNames )
            //    colNames = getColNames(statement, nCount);

		    for(;nCol<nCount;nCol++){
			    int nColType = sqlite3_column_type(statement,nCol);
			    const char* szColName = sqlite3_column_name(statement,nCol);
			    VALUE colName = rb_str_new2(szColName);
			    VALUE colValue = Qnil;
    			
			    switch(nColType){
				    case SQLITE_NULL:
					    break;
                    case SQLITE_FLOAT:
                    {
                        double dVal = sqlite3_column_double(statement, nCol);
                        colValue = DBL2NUM(dVal);
                        break;
                    }
                    case SQLITE_INTEGER:
                    {
                        sqlite_int64 nVal = sqlite3_column_int64(statement, nCol);
                        colValue = LL2NUM(nVal);
                        break;
                    }
				    default:{
                        sqlite3_value * sqlValue = sqlite3_column_value(statement, nCol);
                        int nLen = sqlite3_value_bytes(sqlValue);
                        const char*  szValue = (const char *)sqlite3_value_text(sqlValue);
					    //char *text = (char *)sqlite3_column_text(statement, nCol);
					    colValue = rb_str_new(szValue, nLen);
					    break;
				    }
			    }
    			
			    rb_hash_aset(hashRec, colName/*colNames[nCol]*/, colValue);
		    }
    		
		    rb_ary_push(arRes, hashRec);

            PROF_START_CREATED("SQLITE_EXEC");
            nRes = sqlite3_step(statement);
            PROF_STOP("SQLITE_EXEC");

	    }

        rho_db_unlock(*ppDB);

    }

    if ( statement )
        //sqlite3_finalize(statement);
        sqlite3_reset(statement);

    if ( colNames )
        free(colNames);

    if ( nRes != SQLITE_OK && nRes != SQLITE_ROW && nRes != SQLITE_DONE )
    {
        if ( !szErrMsg )
            szErrMsg = (char*)sqlite3_errmsg(db);

        rb_raise(rb_eArgError, "could not execute statement: %d; Message: %s",nRes, (szErrMsg?szErrMsg:""));
    }

    PROF_STOP("SQLITE");

	return arRes;
}
示例#25
0
void native_slot_set_value_and_case(const char* name,
                                    upb_fieldtype_t type, VALUE type_class,
                                    void* memory, VALUE value,
                                    uint32_t* case_memory,
                                    uint32_t case_number) {
  // Note that in order to atomically change the value in memory and the case
  // value (w.r.t. Ruby VM calls), we must set the value at |memory| only after
  // all Ruby VM calls are complete. The case is then set at the bottom of this
  // function.
  switch (type) {
    case UPB_TYPE_FLOAT:
      if (!is_ruby_num(value)) {
        rb_raise(cTypeError, "Expected number type for float field '%s' (given %s).",
                 name, rb_class2name(CLASS_OF(value)));
      }
      DEREF(memory, float) = NUM2DBL(value);
      break;
    case UPB_TYPE_DOUBLE:
      if (!is_ruby_num(value)) {
        rb_raise(cTypeError, "Expected number type for double field '%s' (given %s).",
                 name, rb_class2name(CLASS_OF(value)));
      }
      DEREF(memory, double) = NUM2DBL(value);
      break;
    case UPB_TYPE_BOOL: {
      int8_t val = -1;
      if (value == Qtrue) {
        val = 1;
      } else if (value == Qfalse) {
        val = 0;
      } else {
        rb_raise(cTypeError, "Invalid argument for boolean field '%s' (given %s).",
                 name, rb_class2name(CLASS_OF(value)));
      }
      DEREF(memory, int8_t) = val;
      break;
    }
    case UPB_TYPE_STRING:
      if (CLASS_OF(value) == rb_cSymbol) {
        value = rb_funcall(value, rb_intern("to_s"), 0);
      } else if (CLASS_OF(value) != rb_cString) {
        rb_raise(cTypeError, "Invalid argument for string field '%s' (given %s).",
                 name, rb_class2name(CLASS_OF(value)));
      }

      DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
      break;

    case UPB_TYPE_BYTES: {
      if (CLASS_OF(value) != rb_cString) {
        rb_raise(cTypeError, "Invalid argument for bytes field '%s' (given %s).",
                 name, rb_class2name(CLASS_OF(value)));
      }

      DEREF(memory, VALUE) = native_slot_encode_and_freeze_string(type, value);
      break;
    }
    case UPB_TYPE_MESSAGE: {
      if (CLASS_OF(value) == CLASS_OF(Qnil)) {
        value = Qnil;
      } else if (CLASS_OF(value) != type_class) {
        // check for possible implicit conversions
        VALUE converted_value = NULL;
        char* field_type_name = rb_class2name(type_class);

        if (strcmp(field_type_name, "Google::Protobuf::Timestamp") == 0 &&
            rb_obj_is_kind_of(value, rb_cTime)) {
          // Time -> Google::Protobuf::Timestamp
          VALUE hash = rb_hash_new();
          rb_hash_aset(hash, rb_str_new2("seconds"), rb_funcall(value, rb_intern("to_i"), 0));
          rb_hash_aset(hash, rb_str_new2("nanos"), rb_funcall(value, rb_intern("nsec"), 0));
          VALUE args[1] = { hash };
          converted_value = rb_class_new_instance(1, args, type_class);
        } else if (strcmp(field_type_name, "Google::Protobuf::Duration") == 0 &&
                   rb_obj_is_kind_of(value, rb_cNumeric)) {
          // Numeric -> Google::Protobuf::Duration
          VALUE hash = rb_hash_new();
          rb_hash_aset(hash, rb_str_new2("seconds"), rb_funcall(value, rb_intern("to_i"), 0));
          VALUE n_value = rb_funcall(value, rb_intern("remainder"), 1, INT2NUM(1));
          n_value = rb_funcall(n_value, rb_intern("*"), 1, INT2NUM(1000000000));
          n_value = rb_funcall(n_value, rb_intern("round"), 0);
          rb_hash_aset(hash, rb_str_new2("nanos"), n_value);
          VALUE args[1] = { hash };
          converted_value = rb_class_new_instance(1, args, type_class);
        }

        // raise if no suitable conversaion could be found
        if (converted_value == NULL) {
          rb_raise(cTypeError,
                   "Invalid type %s to assign to submessage field '%s'.",
                  rb_class2name(CLASS_OF(value)), name);
        } else {
          value = converted_value;
        }
      }
      DEREF(memory, VALUE) = value;
      break;
    }
    case UPB_TYPE_ENUM: {
      int32_t int_val = 0;
      if (TYPE(value) == T_STRING) {
        value = rb_funcall(value, rb_intern("to_sym"), 0);
      } else if (!is_ruby_num(value) && TYPE(value) != T_SYMBOL) {
        rb_raise(cTypeError,
                 "Expected number or symbol type for enum field '%s'.", name);
      }
      if (TYPE(value) == T_SYMBOL) {
        // Ensure that the given symbol exists in the enum module.
        VALUE lookup = rb_funcall(type_class, rb_intern("resolve"), 1, value);
        if (lookup == Qnil) {
          rb_raise(rb_eRangeError, "Unknown symbol value for enum field '%s'.", name);
        } else {
          int_val = NUM2INT(lookup);
        }
      } else {
        native_slot_check_int_range_precision(name, UPB_TYPE_INT32, value);
        int_val = NUM2INT(value);
      }
      DEREF(memory, int32_t) = int_val;
      break;
    }
    case UPB_TYPE_INT32:
    case UPB_TYPE_INT64:
    case UPB_TYPE_UINT32:
    case UPB_TYPE_UINT64:
      native_slot_check_int_range_precision(name, type, value);
      switch (type) {
      case UPB_TYPE_INT32:
        DEREF(memory, int32_t) = NUM2INT(value);
        break;
      case UPB_TYPE_INT64:
        DEREF(memory, int64_t) = NUM2LL(value);
        break;
      case UPB_TYPE_UINT32:
        DEREF(memory, uint32_t) = NUM2UINT(value);
        break;
      case UPB_TYPE_UINT64:
        DEREF(memory, uint64_t) = NUM2ULL(value);
        break;
      default:
        break;
      }
      break;
    default:
      break;
  }

  if (case_memory != NULL) {
    *case_memory = case_number;
  }
}
示例#26
0
文件: Call.c 项目: albanpeignier/ffi
void
rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, NativeType* paramTypes,
                      FFIStorage* paramStorage, void** ffiValues,
                      VALUE* callbackParameters, int callbackCount, VALUE enums)
{
    VALUE callbackProc = Qnil;
    FFIStorage* param = &paramStorage[0];
    int i, argidx, cbidx, argCount;

    if (paramCount != -1 && paramCount != argc) {
        if (argc == (paramCount - 1) && callbackCount == 1 && rb_block_given_p()) {
            callbackProc = rb_block_proc();
        } else {
            rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, paramCount);
        }
    }

    argCount = paramCount != -1 ? paramCount : argc;

    for (i = 0, argidx = 0, cbidx = 0; i < argCount; ++i) {
        int type = argidx < argc ? TYPE(argv[argidx]) : T_NONE;
        ffiValues[i] = param;

        switch (paramTypes[i]) {

        case NATIVE_INT8:
            param->s8 = getSignedInt(argv[argidx++], type, -128, 127, "char", Qnil);
            ADJ(param, INT8);
            break;


        case NATIVE_INT16:
            param->s16 = getSignedInt(argv[argidx++], type, -0x8000, 0x7fff, "short", Qnil);
            ADJ(param, INT16);
            break;


        case NATIVE_INT32:
        case NATIVE_ENUM:
            param->s32 = getSignedInt(argv[argidx++], type, -0x80000000, 0x7fffffff, "int", enums);
            ADJ(param, INT32);
            break;


        case NATIVE_BOOL:
            if (type != T_TRUE && type != T_FALSE) {
                rb_raise(rb_eTypeError, "wrong argument type  (expected a boolean parameter)");
            }
            param->s8 = argv[argidx++] == Qtrue;
            ADJ(param, INT8);
            break;


        case NATIVE_UINT8:
            param->u8 = getUnsignedInt(argv[argidx++], type, 0xff, "unsigned char");
            ADJ(param, INT8);
            break;


        case NATIVE_UINT16:
            param->u16 = getUnsignedInt(argv[argidx++], type, 0xffff, "unsigned short");
            ADJ(param, INT16);
            break;


        case NATIVE_UINT32:
            /* Special handling/checking for unsigned 32 bit integers */
            param->u32 = getUnsignedInt32(argv[argidx++], type);
            ADJ(param, INT32);
            break;


        case NATIVE_INT64:
            if (type != T_FIXNUM && type != T_BIGNUM) {
                rb_raise(rb_eTypeError, "Expected an Integer parameter");
            }
            param->i64 = NUM2LL(argv[argidx]);
            ADJ(param, INT64);
            ++argidx;
            break;


        case NATIVE_UINT64:
            if (type != T_FIXNUM && type != T_BIGNUM) {
                rb_raise(rb_eTypeError, "Expected an Integer parameter");
            }
            param->u64 = NUM2ULL(argv[argidx]);
            ADJ(param, INT64);
            ++argidx;
            break;

        case NATIVE_LONG:
            *(ffi_sarg *) param = NUM2LONG(argv[argidx]);
            ADJ(param, LONG);
            ++argidx;
            break;

        case NATIVE_ULONG:
            *(ffi_arg *) param = NUM2ULONG(argv[argidx]);
            ADJ(param, LONG);
            ++argidx;
            break;

        case NATIVE_FLOAT32:
            if (type != T_FLOAT && type != T_FIXNUM) {
                rb_raise(rb_eTypeError, "Expected a Float parameter");
            }
            param->f32 = (float) NUM2DBL(argv[argidx]);
            ADJ(param, FLOAT32);
            ++argidx;
            break;

        case NATIVE_FLOAT64:
            if (type != T_FLOAT && type != T_FIXNUM) {
                rb_raise(rb_eTypeError, "Expected a Float parameter");
            }
            param->f64 = NUM2DBL(argv[argidx]);
            ADJ(param, FLOAT64);
            ++argidx;
            break;


        case NATIVE_STRING:
            param->ptr = getString(argv[argidx++], type);
            ADJ(param, ADDRESS);
            break;

        case NATIVE_POINTER:
        case NATIVE_BUFFER_IN:
        case NATIVE_BUFFER_OUT:
        case NATIVE_BUFFER_INOUT:
            param->ptr = getPointer(argv[argidx++], type);
            ADJ(param, ADDRESS);
            break;


        case NATIVE_FUNCTION:
        case NATIVE_CALLBACK:
            if (callbackProc != Qnil) {
                param->ptr = callback_param(callbackProc, callbackParameters[cbidx++]);
            } else {
                param->ptr = callback_param(argv[argidx], callbackParameters[cbidx++]);
                ++argidx;
            }
            ADJ(param, ADDRESS);
            break;

        case NATIVE_STRUCT:
            ffiValues[i] = getPointer(argv[argidx++], type);
            break;

        default:
            rb_raise(rb_eArgError, "Invalid parameter type: %d", paramTypes[i]);
        }
    }
}
示例#27
0
static int write_element_allow_id(VALUE key, VALUE value, VALUE extra, int allow_id) {
    buffer_t buffer = (buffer_t)NUM2LL(rb_ary_entry(extra, 0));
    VALUE check_keys = rb_ary_entry(extra, 1);

    if (TYPE(key) == T_SYMBOL) {
        // TODO better way to do this... ?
        key = rb_str_new2(rb_id2name(SYM2ID(key)));
    }

    if (TYPE(key) != T_STRING) {
        buffer_free(buffer);
        rb_raise(rb_eTypeError, "keys must be strings or symbols");
    }

    if (!allow_id && strcmp("_id", RSTRING_PTR(key)) == 0) {
        return ST_CONTINUE;
    }

    if (check_keys == Qtrue) {
        int i;
        if (RSTRING_LEN(key) > 0 && RSTRING_PTR(key)[0] == '$') {
            buffer_free(buffer);
            rb_raise(InvalidName, "key must not start with '$'");
        }
        for (i = 0; i < RSTRING_LEN(key); i++) {
            if (RSTRING_PTR(key)[i] == '.') {
                buffer_free(buffer);
                rb_raise(InvalidName, "key must not contain '.'");
            }
        }
    }

    switch(TYPE(value)) {
    case T_BIGNUM:
    case T_FIXNUM:
        {
            if (rb_funcall(value, rb_intern(">"), 1, LL2NUM(9223372036854775807LL)) == Qtrue ||
                rb_funcall(value, rb_intern("<"), 1, LL2NUM(-9223372036854775808LL)) == Qtrue) {
                buffer_free(buffer);
                rb_raise(rb_eRangeError, "MongoDB can only handle 8-byte ints");
            }
            if (rb_funcall(value, rb_intern(">"), 1, INT2NUM(2147483647L)) == Qtrue ||
                rb_funcall(value, rb_intern("<"), 1, INT2NUM(-2147483648L)) == Qtrue) {
                long long ll_value;
                write_name_and_type(buffer, key, 0x12);
                ll_value = NUM2LL(value);
                SAFE_WRITE(buffer, (char*)&ll_value, 8);
            } else {
                int int_value;
                write_name_and_type(buffer, key, 0x10);
                int_value = NUM2LL(value);
                SAFE_WRITE(buffer, (char*)&int_value, 4);
            }
            break;
        }
    case T_TRUE:
        {
            write_name_and_type(buffer, key, 0x08);
            SAFE_WRITE(buffer, &one, 1);
            break;
        }
    case T_FALSE:
        {
            write_name_and_type(buffer, key, 0x08);
            SAFE_WRITE(buffer, &zero, 1);
            break;
        }
    case T_FLOAT:
        {
            double d = NUM2DBL(value);
            write_name_and_type(buffer, key, 0x01);
            SAFE_WRITE(buffer, (char*)&d, 8);
            break;
        }
    case T_NIL:
        {
            write_name_and_type(buffer, key, 0x0A);
            break;
        }
    case T_HASH:
        {
            write_name_and_type(buffer, key, 0x03);
            write_doc(buffer, value, check_keys);
            break;
        }
    case T_ARRAY:
        {
            buffer_position length_location, start_position, obj_length;
            int items, i;
            VALUE* values;

            write_name_and_type(buffer, key, 0x04);
            start_position = buffer_get_position(buffer);

            // save space for length
            length_location = buffer_save_space(buffer, 4);
            if (length_location == -1) {
                rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
            }

            items = RARRAY_LEN(value);
            values = RARRAY_PTR(value);
            for(i = 0; i < items; i++) {
                char* name;
                VALUE key;
                INT2STRING(&name, i);
                key = rb_str_new2(name);
                write_element(key, values[i], pack_extra(buffer, check_keys));
                free(name);
            }

            // write null byte and fill in length
            SAFE_WRITE(buffer, &zero, 1);
            obj_length = buffer_get_position(buffer) - start_position;
            SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
            break;
        }
    case T_STRING:
        {
            if (strcmp(rb_class2name(RBASIC(value)->klass),
                       "Mongo::Code") == 0) {
                buffer_position length_location, start_position, total_length;
                int length;
                write_name_and_type(buffer, key, 0x0F);

                start_position = buffer_get_position(buffer);
                length_location = buffer_save_space(buffer, 4);
                if (length_location == -1) {
                    rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
                }

                length = RSTRING_LEN(value) + 1;
                SAFE_WRITE(buffer, (char*)&length, 4);
                SAFE_WRITE(buffer, RSTRING_PTR(value), length - 1);
                SAFE_WRITE(buffer, &zero, 1);
                write_doc(buffer, rb_funcall(value, rb_intern("scope"), 0), Qfalse);

                total_length = buffer_get_position(buffer) - start_position;
                SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&total_length, 4);
                break;
            } else {
                int length;
                write_name_and_type(buffer, key, 0x02);
                value = TO_UTF8(value);
                length = RSTRING_LEN(value) + 1;
                SAFE_WRITE(buffer, (char*)&length, 4);
                write_utf8(buffer, value);
                SAFE_WRITE(buffer, &zero, 1);
                break;
            }
        }
    case T_SYMBOL:
        {
            const char* str_value = rb_id2name(SYM2ID(value));
            int length = strlen(str_value) + 1;
            write_name_and_type(buffer, key, 0x0E);
            SAFE_WRITE(buffer, (char*)&length, 4);
            SAFE_WRITE(buffer, str_value, length);
            break;
        }
    case T_OBJECT:
        {
            // TODO there has to be a better way to do these checks...
            const char* cls = rb_class2name(RBASIC(value)->klass);
            if (strcmp(cls, "Mongo::Binary") == 0 ||
                strcmp(cls, "ByteBuffer") == 0) {
                const char subtype = strcmp(cls, "ByteBuffer") ?
                    (const char)FIX2INT(rb_funcall(value, rb_intern("subtype"), 0)) : 2;
                VALUE string_data = rb_funcall(value, rb_intern("to_s"), 0);
                int length = RSTRING_LEN(string_data);
                write_name_and_type(buffer, key, 0x05);
                if (subtype == 2) {
                    const int other_length = length + 4;
                    SAFE_WRITE(buffer, (const char*)&other_length, 4);
                    SAFE_WRITE(buffer, &subtype, 1);
                }
                SAFE_WRITE(buffer, (const char*)&length, 4);
                if (subtype != 2) {
                    SAFE_WRITE(buffer, &subtype, 1);
                }
                SAFE_WRITE(buffer, RSTRING_PTR(string_data), length);
                break;
            }
            if (strcmp(cls, "Mongo::ObjectID") == 0) {
                VALUE as_array = rb_funcall(value, rb_intern("to_a"), 0);
                int i;
                write_name_and_type(buffer, key, 0x07);
                for (i = 0; i < 12; i++) {
                    char byte = (char)FIX2INT(RARRAY_PTR(as_array)[i]);
                    SAFE_WRITE(buffer, &byte, 1);
                }
                break;
            }
            if (strcmp(cls, "Mongo::DBRef") == 0) {
                buffer_position length_location, start_position, obj_length;
                VALUE ns, oid;
                write_name_and_type(buffer, key, 0x03);

                start_position = buffer_get_position(buffer);

                // save space for length
                length_location = buffer_save_space(buffer, 4);
                if (length_location == -1) {
                    rb_raise(rb_eNoMemError, "failed to allocate memory in buffer.c");
                }

                ns = rb_funcall(value, rb_intern("namespace"), 0);
                write_element(rb_str_new2("$ref"), ns, pack_extra(buffer, Qfalse));
                oid = rb_funcall(value, rb_intern("object_id"), 0);
                write_element(rb_str_new2("$id"), oid, pack_extra(buffer, Qfalse));

                // write null byte and fill in length
                SAFE_WRITE(buffer, &zero, 1);
                obj_length = buffer_get_position(buffer) - start_position;
                SAFE_WRITE_AT_POS(buffer, length_location, (const char*)&obj_length, 4);
                break;
            }
        }
    case T_DATA:
        {
            // TODO again, is this really the only way to do this?
            const char* cls = rb_class2name(RBASIC(value)->klass);
            if (strcmp(cls, "Time") == 0) {
                double t = NUM2DBL(rb_funcall(value, rb_intern("to_f"), 0));
                long long time_since_epoch = (long long)round(t * 1000);
                write_name_and_type(buffer, key, 0x09);
                SAFE_WRITE(buffer, (const char*)&time_since_epoch, 8);
                break;
            }
        }
    case T_REGEXP:
        {
            int length = RREGEXP_SRC_LEN(value);
            char* pattern = (char*)RREGEXP_SRC_PTR(value);
            long flags = RREGEXP(value)->ptr->options;
            VALUE has_extra;

            write_name_and_type(buffer, key, 0x0B);

            SAFE_WRITE(buffer, pattern, length);
            SAFE_WRITE(buffer, &zero, 1);

            if (flags & IGNORECASE) {
                char ignorecase = 'i';
                SAFE_WRITE(buffer, &ignorecase, 1);
            }
            if (flags & MULTILINE) {
                char multiline = 'm';
                SAFE_WRITE(buffer, &multiline, 1);
            }
            if (flags & EXTENDED) {
                char extended = 'x';
                SAFE_WRITE(buffer, &extended, 1);
            }

            has_extra = rb_funcall(value, rb_intern("respond_to?"), 1, rb_str_new2("extra_options_str"));
            if (TYPE(has_extra) == T_TRUE) {
                VALUE extra = rb_funcall(value, rb_intern("extra_options_str"), 0);
                buffer_position old_position = buffer_get_position(buffer);
                SAFE_WRITE(buffer, RSTRING_PTR(extra), RSTRING_LEN(extra));
                qsort(buffer_get_buffer(buffer) + old_position, RSTRING_LEN(extra), sizeof(char), cmp_char);
            }
            SAFE_WRITE(buffer, &zero, 1);

            break;
        }
    default:
        {
            buffer_free(buffer);
            rb_raise(rb_eTypeError, "no c encoder for this type yet (%d)", TYPE(value));
            break;
        }
    }
    return ST_CONTINUE;
}