示例#1
0
/*
 * call-seq:
 *
 *    API::Function.new(address, prototype = 'V', return_type = 'L')
 *
 * Creates and returns an API::Function object. This object is similar to an
 * API object, except that instead of a character function name you pass a
 * function pointer address as the first argument, and there's no associated
 * DLL file.
 *
 * Once you have your API::Function object you can then call it the same way
 * you would an API object.
 *
 * Example:
 *
 *    require 'win32/api'
 *    include Win32
 *
 *    LoadLibrary = API.new('LoadLibrary', 'P', 'L')
 *    GetProcAddress = API.new('GetProcAddress', 'LP', 'L')
 *
 *    # Play a system beep
 *    hlib = LoadLibrary.call('user32')
 *    addr = GetProcAddress.call(hlib, 'MessageBeep')
 *    func = Win32::API::Function.new(addr, 'L', 'L')
 *    func.call(0)
 */
static VALUE func_init(int argc, VALUE* argv, VALUE self){
   Win32API* ptr;
   int i;
   VALUE v_address, v_proto, v_return;

   rb_scan_args(argc, argv, "12", &v_address, &v_proto, &v_return);

   Data_Get_Struct(self, Win32API, ptr);

   // Convert a string prototype to an array of characters
   if(rb_respond_to(v_proto, rb_intern("split")))
      v_proto = rb_str_split(v_proto, "");

   // Convert a nil or empty prototype to 'V' (void) automatically
   if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
      v_proto = rb_ary_new();
      rb_ary_push(v_proto, rb_str_new2("V"));
   }

   // Set an arbitrary limit of 20 parameters
   if(20 < RARRAY_LEN(v_proto))
      rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY_LEN(v_proto));

   // Set the default return type to 'L' (DWORD)
   if(NIL_P(v_return))
      v_return = rb_str_new2("L");

   ptr->function = (FARPROC)NUM2LONG(v_address);

   // Push the numeric prototypes onto our int array for later use.

   for(i = 0; i < RARRAY_LEN(v_proto); i++){
      SafeStringValue(RARRAY_PTR(v_proto)[i]);
      switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
         case 'L':
            ptr->prototype[i] = _T_LONG;
            break;
         case 'P':
            ptr->prototype[i] = _T_POINTER;
            break;
         case 'I': case 'B':
            ptr->prototype[i] = _T_INTEGER;
            break;
         case 'V':
            ptr->prototype[i] = _T_VOID;
            break;
         case 'K':
            ptr->prototype[i] = _T_CALLBACK;
            break;
         case 'S':
            ptr->prototype[i] = _T_STRING;
            break;
         default:
            rb_raise(cAPIProtoError, "Illegal prototype '%s'",
               StringValuePtr(RARRAY_PTR(v_proto)[i])
            );
      }
   }

   // Store the return type for later use.

   // Automatically convert empty strings or nil to type void.
   if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
      v_return = rb_str_new2("V");
      ptr->return_type = _T_VOID;
   }
   else{
      SafeStringValue(v_return);
      switch(*RSTRING_PTR(v_return)){
         case 'L':
            ptr->return_type = _T_LONG;
            break;
         case 'P':
            ptr->return_type = _T_POINTER;
            break;
         case 'I': case 'B':
            ptr->return_type = _T_INTEGER;
            break;
         case 'V':
            ptr->return_type = _T_VOID;
            break;
         case 'S':
            ptr->return_type = _T_STRING;
            break;
         default:
            rb_raise(cAPIProtoError, "Illegal return type '%s'",
               RSTRING_PTR(v_return)
            );
      }
   }

   rb_iv_set(self, "@address", v_address);
   rb_iv_set(self, "@prototype", v_proto);
   rb_iv_set(self, "@return_type", v_return);

   return self;
}
示例#2
0
/* Hash#foreach callback for ruby_curl_multi_requests */
static int ruby_curl_multi_requests_callback(VALUE key, VALUE value, VALUE result_array) {
  rb_ary_push(result_array, value);
  
  return ST_CONTINUE;
}
示例#3
0
文件: lob.c 项目: aq1018/ruby-oci8
static VALUE oci8_lob_read(int argc, VALUE *argv, VALUE self)
{
    oci8_lob_t *lob = DATA_PTR(self);
    oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc);
    ub4 length;
    ub4 nchar;
    ub4 amt;
    sword rv;
    char buf[8192];
    size_t buf_size_in_char;
    VALUE size;
    VALUE v = rb_ary_new();

    rb_scan_args(argc, argv, "01", &size);
    length = oci8_lob_get_length(lob);
    if (length <= lob->pos) /* EOF */
        return Qnil;
    length -= lob->pos;
    if (NIL_P(size)) {
        nchar = length; /* read until EOF */
    } else {
        nchar = NUM2UINT(size);
        if (nchar > length)
            nchar = length;
    }
    amt = nchar;
    buf_size_in_char = sizeof(buf) / lob->char_width;
    do {
        if (lob->state == S_BFILE_CLOSE) {
            rv = OCILobFileOpen_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, OCI_FILE_READONLY);
            if (rv == OCI_ERROR && oci8_get_error_code(oci8_errhp) == 22290) {
                /* ORA-22290: operation would exceed the maximum number of opened files or LOBs */
                /* close all opened BFILE implicitly. */
                oci8_base_t *base;
                for (base = &lob->base; base != &lob->base; base = base->next) {
                    if (base->type == OCI_DTYPE_LOB) {
                        oci8_lob_t *tmp = (oci8_lob_t *)base;
                        if (tmp->state == S_BFILE_OPEN) {
                            tmp->state = S_BFILE_CLOSE;
                        }
                    }
                }
                oci_lc(OCILobFileCloseAll_nb(svcctx, svcctx->base.hp.svc, oci8_errhp));
                continue;
            }
            if (rv != OCI_SUCCESS)
                oci8_raise(oci8_errhp, rv, NULL);
            lob->state = S_BFILE_OPEN;
        }
        /* initialize buf in zeros everytime to check a nul characters. */
        memset(buf, 0, sizeof(buf));
        rv = OCILobRead_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &amt, lob->pos + 1, buf, sizeof(buf), NULL, NULL, 0, lob->csfrm);
        if (rv == OCI_ERROR && oci8_get_error_code(oci8_errhp) == 22289) {
            /* ORA-22289: cannot perform FILEREAD operation on an unopened file or LOB */
            if (lob->state == S_BFILE_CLOSE)
                continue;
        }
        if (rv != OCI_SUCCESS && rv != OCI_NEED_DATA)
            oci8_raise(oci8_errhp, rv, NULL);

        /* Workaround when using Oracle 10.2.0.4 or 11.1.0.6 client and
         * variable-length character set (e.g. AL32UTF8).
         *
         * When the above mentioned condition, amt may be shorter. So
         * amt is increaded until a nul character to know the actually
         * read size.
         */
        while (amt < sizeof(buf) && buf[amt] != '\0') {
            amt++;
        }

        if (amt == 0)
            break;
        /* for fixed size charset, amt is the number of characters stored in buf. */
        if (amt > buf_size_in_char)
            rb_raise(eOCIException, "Too large buffer fetched or you set too large size of a character.");
        amt *= lob->char_width;
        rb_ary_push(v, rb_str_new(buf, amt));
    } while (rv == OCI_NEED_DATA);
    lob->pos += nchar;
    if (nchar == length) {
        lob_close(lob);
        bfile_close(lob);
    }
    if (RARRAY_LEN(v) == 0) {
        return Qnil;
    }
    v = rb_ary_join(v, Qnil);
    OBJ_TAINT(v);
    if (lob->lobtype == OCI_TEMP_CLOB) {
        /* set encoding */
        rb_enc_associate(v, oci8_encoding);
        return rb_str_conv_enc(v, oci8_encoding, rb_default_internal_encoding());
    } else {
        /* ASCII-8BIT */
        return v;
    }
}
示例#4
0
static NODE *
build_Array_each_node(rb_iseq_t *iseq, NODE * node, NODE * lnode,
		      VALUE param_vars, VALUE local_vars)
{
    /* Special block for Array#each
       ary.each{|e|
       BODY
       }
       =>
       {|e, _self|
       _i = 0
       while _i < _self.length
       e = _self[_i]
       redo_point:
       BODY
       next_point:
       _i = _i.succ
       end
       }

       ary.each{
       BODY
       }
       =>
       {|_i, _self|
       _i = 0
       while _i < _self.length
       redo_point:
       BODY
       next_point:
       _i = _i.succ
       end
       }
     */

    ID _self = rb_intern("#_self");
    ID _i = rb_intern("#_i");

    if (iseq->argc == 0) {
	ID _e = rb_intern("#_e");
	rb_ary_push(param_vars, ID2SYM(_e));
	rb_ary_push(param_vars, ID2SYM(_self));
	iseq->argc += 2;
	rb_ary_push(local_vars, ID2SYM(_i));

	node =
	    new_block(NEW_DASGN(_i, NEW_LIT(INT2FIX(0))),
		      NEW_WHILE(NEW_CALL(NEW_DVAR(_i), idLT,
					 new_ary(NEW_CALL
						 (NEW_DVAR(_self), idLength,
						  0), 0)),
				new_block(NEW_OPTBLOCK(node),
					  NEW_DASGN(_i,
						    NEW_CALL(NEW_DVAR(_i),
							     idSucc, 0))),
				Qundef));
    }
    else {
	ID e = SYM2ID(rb_ary_entry(param_vars, 0));
	NODE *assign;

	rb_ary_push(param_vars, ID2SYM(_self));
	iseq->argc++;
	rb_ary_push(local_vars, ID2SYM(_i));

	if (nd_type(lnode) == NODE_DASGN_CURR) {
	    assign = NEW_DASGN(e,
			       NEW_CALL(NEW_DVAR(_self), idAREF,
					new_ary(NEW_DVAR(_i), 0)));
	}
	else {
	    assign = new_assign(lnode,
				NEW_CALL(NEW_DVAR(_self), idAREF,
					 new_ary(NEW_DVAR(_i), 0)));
	}

	node =
	    new_block(NEW_DASGN(_i, NEW_LIT(INT2FIX(0))),
		      NEW_WHILE(NEW_CALL(NEW_DVAR(_i), idLT,
					 new_ary(NEW_CALL
						 (NEW_DVAR(_self), idLength,
						  0), 0)), new_block(assign,
								     new_block
								     (NEW_OPTBLOCK
								      (node),
								      NEW_DASGN
								      (_i,
								       NEW_CALL
								       (NEW_DVAR
									(_i),
									idSucc,
									0)))),
				Qundef));
    }
    return node;
}
示例#5
0
文件: load.c 项目: Sophrinix/MacRuby
static void
rb_provide_feature(VALUE feature)
{
    rb_ary_push(get_loaded_features(), feature);
}
示例#6
0
static VALUE get_value(const char* buffer, int* position, int type) {
    VALUE value;
    switch (type) {
    case 1:
        {
            double d;
            memcpy(&d, buffer + *position, 8);
            value = rb_float_new(d);
            *position += 8;
            break;
        }
    case 2:
    case 13:
        {
            *position += 4;
            int value_length = strlen(buffer + *position);
            value = rb_str_new(buffer+ *position, value_length);
            *position += value_length + 1;
            break;
        }
    case 3:
        {
            int size;
            memcpy(&size, buffer + *position, 4);
            if (strcmp(buffer + *position + 5, "$ref") == 0) { // DBRef
                int offset = *position + 14;
                VALUE argv[2];
                int collection_length = strlen(buffer + offset);
                argv[0] = rb_str_new(buffer + offset, collection_length);
                offset += collection_length + 1;
                char id_type = buffer[offset];
                offset += 5;
                argv[1] = get_value(buffer, &offset, (int)id_type);
                value = rb_class_new_instance(2, argv, DBRef);
            } else {
                value = elements_to_hash(buffer + *position + 4, size - 5);
            }
            *position += size;
            break;
        }
    case 4:
        {
            int size;
            memcpy(&size, buffer + *position, 4);
            int end = *position + size - 1;
            *position += 4;

            value = rb_ary_new();
            while (*position < end) {
                int type = (int)buffer[(*position)++];
                int key_size = strlen(buffer + *position);
                *position += key_size + 1; // just skip the key, they're in order.
                VALUE to_append = get_value(buffer, position, type);
                rb_ary_push(value, to_append);
            }
            (*position)++;
            break;
        }
    case 5:
        {
            int length;
            memcpy(&length, buffer + *position, 4);
            int subtype = (unsigned char)buffer[*position + 4];
            VALUE data;
            if (subtype == 2) {
                data = rb_str_new(buffer + *position + 9, length - 4);
            } else {
                data = rb_str_new(buffer + *position + 5, length);
            }
            VALUE st = INT2FIX(subtype);
            VALUE argv[2] = {data, st};
            value = rb_class_new_instance(2, argv, Binary);
            *position += length + 5;
            break;
        }
    case 6:
        {
            value = rb_class_new_instance(0, NULL, Undefined);
            break;
        }
    case 7:
        {
            VALUE str = rb_str_new(buffer + *position, 12);
            VALUE oid = rb_funcall(str, rb_intern("unpack"), 1, rb_str_new2("C*"));
            value = rb_class_new_instance(1, &oid, ObjectID);
            *position += 12;
            break;
        }
    case 8:
        {
            value = buffer[(*position)++] ? Qtrue : Qfalse;
            break;
        }
    case 9:
        {
            long long millis;
            memcpy(&millis, buffer + *position, 8);
            VALUE seconds = INT2NUM(millis / 1000);
            VALUE microseconds = INT2NUM((millis % 1000) * 1000);

            value = rb_funcall(Time, rb_intern("at"), 2, seconds, microseconds);
            *position += 8;
            break;
        }
    case 10:
        {
            value = Qnil;
            break;
        }
    case 11:
        {
            int pattern_length = strlen(buffer + *position);
            VALUE pattern = rb_str_new(buffer + *position, pattern_length);
            *position += pattern_length + 1;

            int flags_length = strlen(buffer + *position);
            int i = 0;

            int flags = 0;
            char extra[10];
            extra[0] = 0;
            for (i = 0; i < flags_length; i++) {
                char flag = buffer[*position + i];
                if (flag == 'i') {
                    flags |= IGNORECASE;
                }
                else if (flag == 'm') {
                    flags |= MULTILINE;
                }
                else if (flag == 'x') {
                    flags |= EXTENDED;
                }
                else if (strlen(extra) < 9) {
                    strncat(extra, &flag, 1);
                }
            }
            VALUE argv[3] = {
                pattern,
                INT2FIX(flags),
                rb_str_new2(extra)
            };
            value = rb_class_new_instance(3, argv, RegexpOfHolding);
            *position += flags_length + 1;
            break;
        }
    case 12:
        {
            *position += 4;
            int collection_length = strlen(buffer + *position);
            VALUE collection = rb_str_new(buffer + *position, collection_length);
            *position += collection_length + 1;

            VALUE str = rb_str_new(buffer + *position, 12);
            VALUE oid = rb_funcall(str, rb_intern("unpack"), 1, rb_str_new2("C*"));
            VALUE id = rb_class_new_instance(1, &oid, ObjectID);
            *position += 12;

            VALUE argv[2] = {collection, id};
            value = rb_class_new_instance(2, argv, DBRef);
            break;
        }
    case 14:
        {
            int value_length;
            memcpy(&value_length, buffer + *position, 4);
            value = ID2SYM(rb_intern(buffer + *position + 4));
            *position += value_length + 4;
            break;
        }
    case 15:
        {
            *position += 8;
            int code_length = strlen(buffer + *position);
            VALUE code = rb_str_new(buffer + *position, code_length);
            *position += code_length + 1;

            int scope_size;
            memcpy(&scope_size, buffer + *position, 4);
            VALUE scope = elements_to_hash(buffer + *position + 4, scope_size - 5);
            *position += scope_size;

            VALUE argv[2] = {code, scope};
            value = rb_class_new_instance(2, argv, Code);
            break;
        }
    case 16:
        {
            int i;
            memcpy(&i, buffer + *position, 4);
            value = LL2NUM(i);
            *position += 4;
            break;
        }
    case 17:
        {
            int i;
            int j;
            memcpy(&i, buffer + *position, 4);
            memcpy(&j, buffer + *position + 4, 4);
            value = rb_ary_new3(2, LL2NUM(i), LL2NUM(j));
            *position += 8;
            break;
        }
    default:
        {
            rb_raise(rb_eTypeError, "no c decoder for this type yet (%d)", type);
            break;
        }
    }
    return value;
}
示例#7
0
static NODE *
build_Integer_times_node(rb_iseq_t *iseq, NODE * node, NODE * lnode,
			 VALUE param_vars, VALUE local_vars)
{
    /* Special Block for Integer#times
       {|e, _self|
       _e = e
       while(e < _self)
       e = _e
       redo_point:
       BODY
       next_point:
       _e = _e.succ
       end
       }

       {|e, _self|
       while(e < _self)
       BODY
       next_point:
       e = e.succ
       end
       }
     */
    ID _self = rb_intern("#_self");
    if (iseq->argc == 0) {
	ID e = rb_intern("#e");
	rb_ary_push(param_vars, ID2SYM(e));
	rb_ary_push(param_vars, ID2SYM(_self));
	iseq->argc += 2;

	node =
	    NEW_WHILE(NEW_CALL
		      (NEW_DVAR(e), idLT, new_ary(NEW_DVAR(_self), 0)),
		      new_block(NEW_OPTBLOCK(node),
				NEW_DASGN(e,
					  NEW_CALL(NEW_DVAR(e), idSucc, 0))),
		      Qundef);
    }
    else {
	ID _e = rb_intern("#_e");
	ID e = SYM2ID(rb_ary_entry(param_vars, 0));
	NODE *assign;

	rb_ary_push(param_vars, ID2SYM(_self));
	rb_ary_push(local_vars, ID2SYM(_e));
	iseq->argc++;

	if (nd_type(lnode) == NODE_DASGN_CURR) {
	    assign = NEW_DASGN(e, NEW_DVAR(_e));
	}
	else {
	    assign = new_assign(lnode, NEW_DVAR(_e));
	}

	node =
	    new_block(NEW_DASGN(_e, NEW_DVAR(e)),
		      NEW_WHILE(NEW_CALL
				(NEW_DVAR(_e), idLT,
				 new_ary(NEW_DVAR(_self), 0)),
				new_block(assign,
					  new_block(NEW_OPTBLOCK(node),
						    NEW_DASGN(_e,
							      NEW_CALL
							      (NEW_DVAR(_e),
							       idSucc, 0)))),
				Qundef));
    }
    return node;
}
示例#8
0
static VALUE rb_keychain_find(int argc, VALUE *argv, VALUE self){

  VALUE kind;
  VALUE attributes;
  VALUE first_or_all;
  rb_scan_args(argc, argv, "2:", &first_or_all, &kind, &attributes);

  Check_Type(first_or_all, T_SYMBOL);
  Check_Type(kind, T_STRING);
  
  CFMutableDictionaryRef query = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

  CFDictionarySetValue(query, kSecReturnAttributes, kCFBooleanTrue);
  CFDictionarySetValue(query, kSecReturnRef, kCFBooleanTrue);
  

  if(rb_to_id(first_or_all) == rb_intern("all")){
    CFDictionarySetValue(query, kSecMatchLimit, kSecMatchLimitAll);
  }

  rb_add_value_to_cf_dictionary(query, kSecClass, kind);


  if(!NIL_P(attributes)){
    Check_Type(attributes, T_HASH);
    VALUE rb_keychains = rb_hash_aref(attributes, ID2SYM(rb_intern("keychains")));
    if(!NIL_P(rb_keychains)){
      Check_Type(rb_keychains, T_ARRAY);
      CFMutableArrayRef searchArray = CFArrayCreateMutable(NULL, RARRAY_LEN(rb_keychains), &kCFTypeArrayCallBacks);
      for(int index=0; index < RARRAY_LEN(rb_keychains); index++){
        SecKeychainRef keychain = NULL;
        Data_Get_Struct(RARRAY_PTR(rb_keychains)[index], struct OpaqueSecKeychainRef, keychain);
        CFArrayAppendValue(searchArray, keychain);
      }
      CFDictionarySetValue(query, kSecMatchSearchList,searchArray);
      CFRelease(searchArray);
    }  

    VALUE limit = rb_hash_aref(attributes, ID2SYM(rb_intern("limit")));
    if(!NIL_P(limit)){
      Check_Type(limit, T_FIXNUM);
      long c_limit = FIX2LONG(limit);
      CFNumberRef cf_limit = CFNumberCreate(NULL, kCFNumberLongType, &c_limit);
      CFDictionarySetValue(query, kSecMatchLimit, cf_limit);
      CFRelease(cf_limit);
    }

    VALUE conditions = rb_hash_aref(attributes, ID2SYM(rb_intern("conditions")));
    
    if(!NIL_P(conditions)){
      Check_Type(conditions, T_HASH);
      VALUE rQuery = Data_Wrap_Struct(rb_cPointerWrapper, NULL, NULL, query);
      rb_block_call(conditions, rb_intern("each"), 0, NULL, RUBY_METHOD_FUNC(add_conditions_to_query), rQuery);
    }
  }

  CFDictionaryRef result;

  OSStatus status = SecItemCopyMatching(query, (CFTypeRef*)&result);
  CFRelease(query);

  VALUE rb_item = rb_ary_new2(0);

  switch(status){
    case errSecItemNotFound: 
      break;
    default:
    CheckOSStatusOrRaise(status);
    if(CFArrayGetTypeID() == CFGetTypeID(result)){
      CFArrayRef result_array = (CFArrayRef)result;
      for(CFIndex i = 0; i < CFArrayGetCount(result_array); i++){
        rb_ary_push(rb_item,rb_keychain_item_from_sec_dictionary(CFArrayGetValueAtIndex(result_array,i)));
      }
    }
    else{
      rb_ary_push(rb_item, rb_keychain_item_from_sec_dictionary(result));
    }
    CFRelease(result);
  }

  if(rb_to_id(first_or_all) == rb_intern("first")){
    return rb_ary_entry(rb_item,0);
  }
  else{
    return rb_item;
  }
}
示例#9
0
文件: machine.c 项目: eki/dorothy
VALUE machine_marshal_dump( VALUE self ) {
  VALUE ary = rb_ary_new();
  VALUE dynamic, stack;
  long i;
  zmachine *zm;

  Data_Get_Struct( self, zmachine, zm );

  rb_ary_push( ary, rb_iv_get( self, "@program" ) );
  rb_ary_push( ary, rb_iv_get( self, "@output" ) );
  rb_ary_push( ary, rb_iv_get( self, "@keyboard" ) );
  rb_ary_push( ary, rb_iv_get( self, "@rng" ) );

  dynamic = rb_ary_new();
  for( i = 0; i < zm->m->dynamic_length; i++ ) {
    rb_ary_push( dynamic, UINT2NUM(zm->m->m_dynamic[i]) );
  }

  rb_ary_push( ary, dynamic );

  stack = rb_ary_new();
  for( i = 0; i < STACK_SIZE; i++ ) {
    rb_ary_push( stack, UINT2NUM(zm->stack[i]) );
  }

  rb_ary_push( ary, stack );

  rb_ary_push( ary, UINT2NUM(PC(zm)) );
  rb_ary_push( ary, UINT2NUM(zm->sp - zm->stack) );
  rb_ary_push( ary, UINT2NUM(zm->fp - zm->stack) );
  rb_ary_push( ary, UINT2NUM(zm->frame_count) );
  rb_ary_push( ary, UINT2NUM(zm->finished) );

  return ary;
}
示例#10
0
void
ruby_init_loadpath_safe(int safe_level, const char* szRoot)
{
    VALUE load_path;
    ID id_initial_load_path_mark;
    extern const char ruby_initial_load_paths[];
    const char *paths = ruby_initial_load_paths;
#if defined LOAD_RELATIVE
# if defined HAVE_DLADDR || (defined __CYGWIN__ && defined CCP_WIN_A_TO_POSIX)
#   define VARIABLE_LIBPATH 1
# else
#   define VARIABLE_LIBPATH 0
# endif
# if VARIABLE_LIBPATH
    char *libpath;
    VALUE sopath;
# else
    char libpath[MAXPATHLEN + 1];
# endif
    size_t baselen;
    char *p;
	if ( szRoot )
		strncpy(libpath, szRoot, sizeof(libpath) - 1);
	else
	{
#if defined _WIN32 || defined __CYGWIN__
# if VARIABLE_LIBPATH
    sopath = rb_str_new(0, MAXPATHLEN);
    libpath = RSTRING_PTR(sopath);
    GetModuleFileName(libruby, libpath, MAXPATHLEN);
# else
    GetModuleFileName(libruby, libpath, sizeof libpath);
# endif
#elif defined(__EMX__)
    _execname(libpath, sizeof(libpath) - 1);
#elif defined(HAVE_DLADDR)
    Dl_info dli;
    if (dladdr((void *)(VALUE)expand_include_path, &dli)) {
	VALUE fname = rb_str_new_cstr(dli.dli_fname);
	sopath = rb_file_absolute_path(fname, Qnil);
	rb_str_resize(fname, 0);
    }
    else {
	sopath = rb_str_new(0, 0);
    }
    libpath = RSTRING_PTR(sopath);
#endif
    }
//RHO

#if !VARIABLE_LIBPATH
    libpath[sizeof(libpath) - 1] = '\0';
#endif
#if defined DOSISH
    translit_char(libpath, '\\', '/');
#elif defined __CYGWIN__
    {
# if VARIABLE_LIBPATH
	const int win_to_posix = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
	size_t newsize = cygwin_conv_path(win_to_posix, libpath, 0, 0);
	if (newsize > 0) {
	    VALUE rubylib = rb_str_new(0, newsize);
	    p = RSTRING_PTR(rubylib);
	    if (cygwin_conv_path(win_to_posix, libpath, p, newsize) == 0) {
		rb_str_resize(sopath, 0);
		sopath = rubylib;
		libpath = p;
	    }
	}
# else
	char rubylib[FILENAME_MAX];
	cygwin_conv_to_posix_path(libpath, rubylib);
	strncpy(libpath, rubylib, sizeof(libpath));
# endif
    }
#endif
    p = strrchr(libpath, '/');
    if (p) {
	*p = 0;
	if (p - libpath > 3 && !(STRCASECMP(p - 4, "/bin") && strcmp(p - 4, "/lib"))) {
	    p -= 4;
	    *p = 0;
	}
    }
#if !VARIABLE_LIBPATH
    else {
	strlcpy(libpath, ".", sizeof(libpath));
	p = libpath + 1;
    }
    baselen = p - libpath;
#define PREFIX_PATH() rb_str_new(libpath, baselen)
#else
    baselen = p - libpath;
    rb_str_set_len(sopath, baselen);
    libpath = RSTRING_PTR(sopath);
#define PREFIX_PATH() sopath
#endif

#define BASEPATH() rb_str_buf_cat(rb_str_buf_new(baselen+len), libpath, baselen)

#define RUBY_RELATIVE(path, len) rb_str_buf_cat(BASEPATH(), path, len)
#else
    static const char exec_prefix[] = RUBY_EXEC_PREFIX;
#define RUBY_RELATIVE(path, len) rubylib_mangled_path(path, len)
#define PREFIX_PATH() RUBY_RELATIVE(exec_prefix, sizeof(exec_prefix)-1)
#endif
    load_path = GET_VM()->load_path;

    if (safe_level == 0) {
	ruby_push_include(getenv("RUBYLIB"), identical_path);
    }

    id_initial_load_path_mark = rb_intern_const("@gem_prelude_index");
    while (*paths) {
	size_t len = strlen(paths);
	VALUE path = RUBY_RELATIVE(paths, len);
	rb_ivar_set(path, id_initial_load_path_mark, path);
	rb_ary_push(load_path, path);
	paths += len + 1;
    }

    rb_const_set(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"), rb_obj_freeze(PREFIX_PATH()));
}
示例#11
0
static VALUE step(VALUE self)
{
  sqlite3StmtRubyPtr ctx;
  sqlite3_stmt *stmt;
  int value, length;
  VALUE list;
  rb_encoding * internal_encoding;

  Data_Get_Struct(self, sqlite3StmtRuby, ctx);

  REQUIRE_OPEN_STMT(ctx);

  if(ctx->done_p) return Qnil;

  {
      VALUE db          = rb_iv_get(self, "@connection");
      rb_funcall(db, rb_intern("encoding"), 0);
      internal_encoding = rb_default_internal_encoding();
  }

  stmt = ctx->st;

  value = sqlite3_step(stmt);
  length = sqlite3_column_count(stmt);
  list = rb_ary_new2((long)length);

  switch(value) {
    case SQLITE_ROW:
      {
        int i;
        for(i = 0; i < length; i++) {
          switch(sqlite3_column_type(stmt, i)) {
            case SQLITE_INTEGER:
              rb_ary_push(list, LL2NUM(sqlite3_column_int64(stmt, i)));
              break;
            case SQLITE_FLOAT:
              rb_ary_push(list, rb_float_new(sqlite3_column_double(stmt, i)));
              break;
            case SQLITE_TEXT:
              {
                VALUE str = rb_tainted_str_new(
                    (const char *)sqlite3_column_text(stmt, i),
                    (long)sqlite3_column_bytes(stmt, i)
                );
                rb_enc_associate_index(str, rb_utf8_encindex());
                if(internal_encoding)
                  str = rb_str_export_to_enc(str, internal_encoding);
                rb_ary_push(list, str);
              }
              break;
            case SQLITE_BLOB:
              {
                VALUE str = rb_tainted_str_new(
                    (const char *)sqlite3_column_blob(stmt, i),
                    (long)sqlite3_column_bytes(stmt, i)
                );
                rb_ary_push(list, str);
              }
              break;
            case SQLITE_NULL:
              rb_ary_push(list, Qnil);
              break;
            default:
              rb_raise(rb_eRuntimeError, "bad type");
          }
        }
      }
      break;
    case SQLITE_DONE:
      ctx->done_p = 1;
      return Qnil;
      break;
    default:
      sqlite3_reset(stmt);
      ctx->done_p = 0;
      CHECK(sqlite3_db_handle(ctx->st), value);
  }

  return list;
}
示例#12
0
文件: struct.c 项目: ggPeti/thrift
static VALUE read_anything(VALUE protocol, field_metadata* fmd, protocol_method_table *pmt) {
  VALUE result = Qnil;

  if (fmd->type == TTYPE_BOOL) {
    result = fastcall_call(pmt->read_bool, protocol, Qnil);
  } else if (fmd->type == TTYPE_BYTE) {
    result = fastcall_call(pmt->read_byte, protocol, Qnil);
  } else if (fmd->type == TTYPE_I16) {
    result = fastcall_call(pmt->read_i16, protocol, Qnil);
  } else if (fmd->type == TTYPE_I32) {
    result = fastcall_call(pmt->read_i32, protocol, Qnil);
  } else if (fmd->type == TTYPE_I64) {
    result = fastcall_call(pmt->read_i64, protocol, Qnil);
  } else if (fmd->type == TTYPE_STRING) {
    result = fastcall_call(pmt->read_string, protocol, Qnil);
  } else if (fmd->type == TTYPE_DOUBLE) {
    result = fastcall_call(pmt->read_double, protocol, Qnil);
  } else if (fmd->type == TTYPE_STRUCT) {

    result = rb_class_new_instance(0, NULL, fmd->klass_v);

    if (rb_obj_is_kind_of(result, thrift_union_class)) {
      union_read(result, protocol, pmt);
    } else {
      struct_read(result, protocol, pmt);
    }
  } else if (fmd->type == TTYPE_MAP) {
    int i;

    VALUE map_header = fastcall_call(pmt->read_map_begin, protocol, Qnil);
    int key_ttype = FIX2INT(rb_ary_entry(map_header, 0));
    int value_ttype = FIX2INT(rb_ary_entry(map_header, 1));
    int num_entries = FIX2INT(rb_ary_entry(map_header, 2));

    // Check the declared key and value types against the expected ones and skip the map contents
    // if the types don't match.
    field_metadata* key_md = fmd->key;
    field_metadata* value_md = fmd->value;

    if (key_md && value_md) {
      int specified_key_type = key_md->type;
      int specified_value_type = value_md->type;
      if (num_entries == 0 || (specified_key_type == key_ttype && specified_value_type == value_ttype)) {
        result = rb_hash_new();

        for (i = 0; i < num_entries; ++i) {
          VALUE key, val;

          key = read_anything(protocol, key_md, pmt);
          val = read_anything(protocol, value_md, pmt);

          rb_hash_aset(result, key, val);
        }
      } else {
        skip_map_contents(protocol, INT2FIX(key_ttype), INT2FIX(value_ttype), num_entries);
      }
    } else {
      skip_map_contents(protocol, INT2FIX(key_ttype), INT2FIX(value_ttype), num_entries);
    }

    fastcall_call(pmt->read_map_end, protocol, Qnil);
  } else if (fmd->type == TTYPE_LIST) {
    int i;

    VALUE list_header = fastcall_call(pmt->read_list_begin, protocol, Qnil);
    int element_ttype = FIX2INT(rb_ary_entry(list_header, 0));
    int num_elements = FIX2INT(rb_ary_entry(list_header, 1));

    // Check the declared element type against the expected one and skip the list contents
    // if the types don't match.
    field_metadata* element_md = fmd->element;

    if (element_md) {
      int specified_element_type = element_md->type;
      if (specified_element_type == element_ttype) {
        result = rb_ary_new2(num_elements);

        for (i = 0; i < num_elements; ++i) {
          rb_ary_push(result, read_anything(protocol, element_md, pmt));
        }
      } else {
        skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
      }
    } else {
      skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
    }

    fastcall_call(pmt->read_list_end, protocol, Qnil);
  } else if (fmd->type == TTYPE_SET) {
    VALUE items;
    int i;

    VALUE set_header = fastcall_call(pmt->read_set_begin, protocol, Qnil);
    int element_ttype = FIX2INT(rb_ary_entry(set_header, 0));
    int num_elements = FIX2INT(rb_ary_entry(set_header, 1));

    // Check the declared element type against the expected one and skip the set contents
    // if the types don't match.
    field_metadata* element_md = fmd->element;
    if (element_md) {
      int specified_element_type = element_md->type;
      if (specified_element_type == element_ttype) {
        items = rb_ary_new2(num_elements);

        for (i = 0; i < num_elements; ++i) {
          rb_ary_push(items, read_anything(protocol, element_md, pmt));
        }

        result = rb_class_new_instance(1, &items, rb_cSet);
      } else {
        skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
      }
    } else {
      skip_list_or_set_contents(protocol, INT2FIX(element_ttype), num_elements);
    }

    fastcall_call(pmt->read_set_end, protocol, Qnil);
  } else {
    rb_raise(rb_eNotImpError, "read_anything not implemented for type %d!", fmd->type);
  }

  return result;
}
示例#13
0
static VALUE
rb_matrix_form(VALUE self, VALUE n)
{
    VALUE base_ary;
    VALUE res_ary;
    VALUE tmp_ary;
    long ary_len = 2;

    if(TYPE(n) != T_FIXNUM)
    {
        rb_raise(rb_eArgError, "Invalid argument for type Fixnum");
        return Qnil;
    }

    if(RTEST(rb_funcall(n, id_lt, 1, ZERO)))
    {
        rb_raise(rb_eArgError, "n cannot be negative");
        return Qnil;
    }
    else
    {
        base_ary = rb_ary_new2(ARY_LEN);
        res_ary =  rb_ary_new2(ARY_LEN);
        tmp_ary = rb_ary_new2(ARY_LEN);

        /* base is {{1, 1}, {1, 0}} */
        rb_ary_push(tmp_ary, ONE);
        rb_ary_push(tmp_ary, ONE);
        rb_ary_push(base_ary, tmp_ary);

        tmp_ary = rb_ary_new2(ARY_LEN);
        rb_ary_push(tmp_ary, ONE);
        rb_ary_push(tmp_ary, ZERO);
        rb_ary_push(base_ary, tmp_ary);

        /* res is {{1, 0}, {0, 1}} */
        tmp_ary = rb_ary_new2(ARY_LEN);
        rb_ary_push(tmp_ary, ONE);
        rb_ary_push(tmp_ary, ZERO);
        rb_ary_push(res_ary, tmp_ary);

        tmp_ary = rb_ary_new2(ARY_LEN);
        rb_ary_push(tmp_ary, ZERO);
        rb_ary_push(tmp_ary, ONE);
        rb_ary_push(res_ary, tmp_ary);

        while(!rb_equal(n, ZERO))
        {
            if(rb_equal(rb_funcall(n, id_mod, 1, TWO), ZERO))
            {
                n = rb_funcall(n, id_div, 1, TWO);
                base_ary = rb_matrix_mul(base_ary, base_ary);
            }
            else
            {
                n = rb_funcall(n, id_minus, 1, ONE);
                res_ary = rb_matrix_mul(res_ary, base_ary);
            }
        }
    }

    return res_ary;
}
示例#14
0
/*
 * call-seq:
 *    Win32::API#call(arg1, arg2, ...)
 *
 * Calls the function pointer with the given arguments (if any). Note that,
 * while this method will catch some prototype mismatches (raising a TypeError
 * in the process), it is not fulproof.  It is ultimately your job to make
 * sure the arguments match the +prototype+ specified in the constructor.
 *
 * For convenience, nil is converted to NULL, true is converted to TRUE (1)
 * and false is converted to FALSE (0).
 */
static VALUE api_call(int argc, VALUE* argv, VALUE self){
   VALUE v_proto, v_args, v_arg, v_return;
   Win32API* ptr;
   unsigned long return_value;
   int i = 0;
   int len;

   struct{
      unsigned long params[20];
   } param;

   Data_Get_Struct(self, Win32API, ptr);

   rb_scan_args(argc, argv, "0*", &v_args);

   v_proto = rb_iv_get(self, "@prototype");

   // For void prototypes, allow either no args or an explicit nil
   if(RARRAY_LEN(v_proto) != RARRAY_LEN(v_args)){
      char* c = StringValuePtr(RARRAY_PTR(v_proto)[0]);
      if(!strcmp(c, "V")){
         rb_ary_push(v_args, Qnil);
      }
      else{
         rb_raise(rb_eArgError,
            "wrong number of parameters: expected %d, got %d",
            RARRAY_LEN(v_proto), RARRAY_LEN(v_args)
         );
      }
   }

   len = RARRAY_LEN(v_proto);

   for(i = 0; i < len; i++){
      v_arg = RARRAY_PTR(v_args)[i];

      // Convert nil to NULL.  Otherwise convert as appropriate.
      if(NIL_P(v_arg))
         param.params[i] = (unsigned long)NULL;
      else if(v_arg == Qtrue)
         param.params[i] = TRUE;
      else if(v_arg == Qfalse)
         param.params[i] = FALSE;
      else
         switch(ptr->prototype[i]){
            case _T_LONG:
               param.params[i] = NUM2ULONG(v_arg);
               break;
            case _T_INTEGER:
               param.params[i] = NUM2INT(v_arg);
               break;
            case _T_POINTER:
               if(FIXNUM_P(v_arg)){
                  param.params[i] = NUM2ULONG(v_arg);
               }
               else{
                  StringValue(v_arg);
                  rb_str_modify(v_arg);
                  param.params[i] = (unsigned long)StringValuePtr(v_arg);
               }
               break;
            case _T_CALLBACK:
               ActiveCallback = v_arg;
               v_proto = rb_iv_get(ActiveCallback, "@prototype");
               param.params[i] = (LPARAM)NUM2ULONG(rb_iv_get(ActiveCallback, "@address"));;
               break;
            case _T_STRING:
               param.params[i] = (unsigned long)RSTRING_PTR(v_arg);
               break;
            default:
               param.params[i] = NUM2ULONG(v_arg);
         }
   }

   /* Call the function, get the return value */
   return_value = ptr->function(param);


   /* Return the appropriate type based on the return type specified
    * in the constructor.
    */
   switch(ptr->return_type){
      case _T_INTEGER:
         v_return = INT2NUM(return_value);
         break;
      case _T_LONG:
         v_return = ULONG2NUM(return_value);
         break;
      case _T_VOID:
         v_return = Qnil;
         break;
      case _T_POINTER:
         if(!return_value){
            v_return = Qnil;
         }
         else{
            VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
            char* efunc = RSTRING_PTR(v_efunc);
            if(efunc[strlen(efunc)-1] == 'W'){
               v_return = rb_str_new(
                  (TCHAR*)return_value,
                  wcslen((wchar_t*)return_value)*2
               );
            }
            else{
               v_return = rb_str_new2((TCHAR*)return_value);
            }
         }
         break;
      case _T_STRING:
         {
            VALUE v_efunc = rb_iv_get(self, "@effective_function_name");
            char* efunc = RSTRING_PTR(v_efunc);

            if(efunc[strlen(efunc)-1] == 'W'){
               v_return = rb_str_new(
                  (TCHAR*)return_value,
                  wcslen((wchar_t*)return_value)*2
               );
            }
            else{
               v_return = rb_str_new2((TCHAR*)return_value);
            }
         }
         break;
      default:
         v_return = INT2NUM(0);
   }

   return v_return;
}
示例#15
0
static VALUE rb_mysql_result_fetch_row(VALUE self, MYSQL_FIELD * fields, const result_each_args *args)
{
  VALUE rowVal;
  MYSQL_ROW row;
  unsigned int i = 0;
  unsigned long * fieldLengths;
  void * ptr;
#ifdef HAVE_RUBY_ENCODING_H
  rb_encoding *default_internal_enc;
  rb_encoding *conn_enc;
#endif
  GET_RESULT(self);

#ifdef HAVE_RUBY_ENCODING_H
  default_internal_enc = rb_default_internal_encoding();
  conn_enc = rb_to_encoding(wrapper->encoding);
#endif

  ptr = wrapper->result;
  row = (MYSQL_ROW)rb_thread_call_without_gvl(nogvl_fetch_row, ptr, RUBY_UBF_IO, 0);
  if (row == NULL) {
    return Qnil;
  }

  if (args->asArray) {
    rowVal = rb_ary_new2(wrapper->numberOfFields);
  } else {
    rowVal = rb_hash_new();
  }
  fieldLengths = mysql_fetch_lengths(wrapper->result);
  if (wrapper->fields == Qnil) {
    wrapper->numberOfFields = mysql_num_fields(wrapper->result);
    wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
  }

  for (i = 0; i < wrapper->numberOfFields; i++) {
    VALUE field = rb_mysql_result_fetch_field(self, i, args->symbolizeKeys);
    if (row[i]) {
      VALUE val = Qnil;
      enum enum_field_types type = fields[i].type;

      if (!args->cast) {
        if (type == MYSQL_TYPE_NULL) {
          val = Qnil;
        } else {
          val = rb_str_new(row[i], fieldLengths[i]);
#ifdef HAVE_RUBY_ENCODING_H
          val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
#endif
        }
      } else {
        switch(type) {
        case MYSQL_TYPE_NULL:       /* NULL-type field */
          val = Qnil;
          break;
        case MYSQL_TYPE_BIT:        /* BIT field (MySQL 5.0.3 and up) */
          if (args->castBool && fields[i].length == 1) {
            val = *row[i] == 1 ? Qtrue : Qfalse;
          }else{
            val = rb_str_new(row[i], fieldLengths[i]);
          }
          break;
        case MYSQL_TYPE_TINY:       /* TINYINT field */
          if (args->castBool && fields[i].length == 1) {
            val = *row[i] != '0' ? Qtrue : Qfalse;
            break;
          }
        case MYSQL_TYPE_SHORT:      /* SMALLINT field */
        case MYSQL_TYPE_LONG:       /* INTEGER field */
        case MYSQL_TYPE_INT24:      /* MEDIUMINT field */
        case MYSQL_TYPE_LONGLONG:   /* BIGINT field */
        case MYSQL_TYPE_YEAR:       /* YEAR field */
          val = rb_cstr2inum(row[i], 10);
          break;
        case MYSQL_TYPE_DECIMAL:    /* DECIMAL or NUMERIC field */
        case MYSQL_TYPE_NEWDECIMAL: /* Precision math DECIMAL or NUMERIC field (MySQL 5.0.3 and up) */
          if (fields[i].decimals == 0) {
            val = rb_cstr2inum(row[i], 10);
          } else if (strtod(row[i], NULL) == 0.000000){
            val = rb_funcall(cBigDecimal, intern_new, 1, opt_decimal_zero);
          }else{
            val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(row[i], fieldLengths[i]));
          }
          break;
        case MYSQL_TYPE_FLOAT:      /* FLOAT field */
        case MYSQL_TYPE_DOUBLE: {     /* DOUBLE or REAL field */
          double column_to_double;
          column_to_double = strtod(row[i], NULL);
          if (column_to_double == 0.000000){
            val = opt_float_zero;
          }else{
            val = rb_float_new(column_to_double);
          }
          break;
        }
        case MYSQL_TYPE_TIME: {     /* TIME field */
          int tokens;
          unsigned int hour=0, min=0, sec=0, msec=0;
          char msec_char[7] = {'0','0','0','0','0','0','\0'};

          tokens = sscanf(row[i], "%2u:%2u:%2u.%6s", &hour, &min, &sec, msec_char);
          if (tokens < 3) {
            val = Qnil;
            break;
          }
          msec = msec_char_to_uint(msec_char, sizeof(msec_char));
          val = rb_funcall(rb_cTime, args->db_timezone, 7, opt_time_year, opt_time_month, opt_time_month, UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), UINT2NUM(msec));
          if (!NIL_P(args->app_timezone)) {
            if (args->app_timezone == intern_local) {
              val = rb_funcall(val, intern_localtime, 0);
            } else { /* utc */
              val = rb_funcall(val, intern_utc, 0);
            }
          }
          break;
        }
        case MYSQL_TYPE_TIMESTAMP:  /* TIMESTAMP field */
        case MYSQL_TYPE_DATETIME: { /* DATETIME field */
          int tokens;
          unsigned int year=0, month=0, day=0, hour=0, min=0, sec=0, msec=0;
          char msec_char[7] = {'0','0','0','0','0','0','\0'};
          uint64_t seconds;

          tokens = sscanf(row[i], "%4u-%2u-%2u %2u:%2u:%2u.%6s", &year, &month, &day, &hour, &min, &sec, msec_char);
          if (tokens < 6) { /* msec might be empty */
            val = Qnil;
            break;
          }
          seconds = (year*31557600ULL) + (month*2592000ULL) + (day*86400ULL) + (hour*3600ULL) + (min*60ULL) + sec;

          if (seconds == 0) {
            val = Qnil;
          } else {
            if (month < 1 || day < 1) {
              rb_raise(cMysql2Error, "Invalid date in field '%.*s': %s", fields[i].name_length, fields[i].name, row[i]);
              val = Qnil;
            } else {
              if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { /* use DateTime for larger date range, does not support microseconds */
                VALUE offset = INT2NUM(0);
                if (args->db_timezone == intern_local) {
                  offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
                }
                val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day), UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), offset);
                if (!NIL_P(args->app_timezone)) {
                  if (args->app_timezone == intern_local) {
                    offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
                    val = rb_funcall(val, intern_new_offset, 1, offset);
                  } else { /* utc */
                    val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset);
                  }
                }
              } else {
                msec = msec_char_to_uint(msec_char, sizeof(msec_char));
                val = rb_funcall(rb_cTime, args->db_timezone, 7, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day), UINT2NUM(hour), UINT2NUM(min), UINT2NUM(sec), UINT2NUM(msec));
                if (!NIL_P(args->app_timezone)) {
                  if (args->app_timezone == intern_local) {
                    val = rb_funcall(val, intern_localtime, 0);
                  } else { /* utc */
                    val = rb_funcall(val, intern_utc, 0);
                  }
                }
              }
            }
          }
          break;
        }
        case MYSQL_TYPE_DATE:       /* DATE field */
        case MYSQL_TYPE_NEWDATE: {  /* Newer const used > 5.0 */
          int tokens;
          unsigned int year=0, month=0, day=0;
          tokens = sscanf(row[i], "%4u-%2u-%2u", &year, &month, &day);
          if (tokens < 3) {
            val = Qnil;
            break;
          }
          if (year+month+day == 0) {
            val = Qnil;
          } else {
            if (month < 1 || day < 1) {
              rb_raise(cMysql2Error, "Invalid date in field '%.*s': %s", fields[i].name_length, fields[i].name, row[i]);
              val = Qnil;
            } else {
              val = rb_funcall(cDate, intern_new, 3, UINT2NUM(year), UINT2NUM(month), UINT2NUM(day));
            }
          }
          break;
        }
        case MYSQL_TYPE_TINY_BLOB:
        case MYSQL_TYPE_MEDIUM_BLOB:
        case MYSQL_TYPE_LONG_BLOB:
        case MYSQL_TYPE_BLOB:
        case MYSQL_TYPE_VAR_STRING:
        case MYSQL_TYPE_VARCHAR:
        case MYSQL_TYPE_STRING:     /* CHAR or BINARY field */
        case MYSQL_TYPE_SET:        /* SET field */
        case MYSQL_TYPE_ENUM:       /* ENUM field */
        case MYSQL_TYPE_GEOMETRY:   /* Spatial fielda */
        default:
          val = rb_str_new(row[i], fieldLengths[i]);
#ifdef HAVE_RUBY_ENCODING_H
          val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
#endif
          break;
        }
      }
      if (args->asArray) {
        rb_ary_push(rowVal, val);
      } else {
        rb_hash_aset(rowVal, field, val);
      }
    } else {
      if (args->asArray) {
        rb_ary_push(rowVal, Qnil);
      } else {
        rb_hash_aset(rowVal, field, Qnil);
      }
    }
  }
  return rowVal;
}
示例#16
0
/* Convert an OR'd list of KMODs into a Ruby array of keysyms. */
VALUE convert_keymod( SDLMod mods )
{
  VALUE array;

  array = rb_ary_new();
  if(mods != 0)
  {
    /*        KEY MODIFIER                              KEY SYM */
    if(mods & KMOD_LSHIFT)   rb_ary_push(array,INT2NUM( SDLK_LSHIFT    ));
    if(mods & KMOD_RSHIFT)   rb_ary_push(array,INT2NUM( SDLK_RSHIFT    ));
    if(mods & KMOD_LCTRL)    rb_ary_push(array,INT2NUM( SDLK_LCTRL     ));
    if(mods & KMOD_RCTRL)    rb_ary_push(array,INT2NUM( SDLK_RCTRL     ));
    if(mods & KMOD_LALT)     rb_ary_push(array,INT2NUM( SDLK_LALT      ));
    if(mods & KMOD_RALT)     rb_ary_push(array,INT2NUM( SDLK_RALT      ));
    if(mods & KMOD_LMETA)    rb_ary_push(array,INT2NUM( SDLK_LMETA     ));
    if(mods & KMOD_RMETA)    rb_ary_push(array,INT2NUM( SDLK_RMETA     ));
    if(mods & KMOD_NUM)      rb_ary_push(array,INT2NUM( SDLK_NUMLOCK   ));
    if(mods & KMOD_CAPS)     rb_ary_push(array,INT2NUM( SDLK_CAPSLOCK  ));
    if(mods & KMOD_MODE)     rb_ary_push(array,INT2NUM( SDLK_MODE      ));
  }
  return array;
}
示例#17
0
static void
rb_set_to_a_callback(const void *value, void *context)
{
    rb_ary_push((VALUE)context, (VALUE)value);
}
示例#18
0
static VALUE statement_Execute(VALUE self) {
	int i;
	CS_DATAFMT col;
	CS_DATAFMT *cols;
	EX_COLUMN_DATA *col_data;
	CS_INT rc;
	CS_INT resulttype;
	CS_INT num_cols;
	CS_INT col_len;
	CS_INT row_count = 0;
	CS_INT rows_read;
	
	CS_INT num_errors = 0;
	CS_SERVERMSG servermsg;
	VALUE err;
	char *error_msg;
	
	struct timeval start, stop;
	int print_rows = 1;
	char message[128];
	char* buf;
	CS_DATEREC date_rec;
	char output[200];
	CS_INT output_len;
	int tempInt;
	CS_BIGINT tempBigInt;
	double tempDouble;
	CS_NUMERIC tempNumeric;
	char* tempText;
	char* newTempText;
	int tempTextLen;
	CS_INT data_rc;
	int isNull = 0;
	CS_DATE tempDate;
	CS_DATETIME tempDateTime;

	TDS_Connection* conn;
	CS_COMMAND * cmd;
	
	VALUE connection;
	VALUE query;
	VALUE columns;
	VALUE rows;
	VALUE status;
	VALUE errors;
	
	VALUE date_parts[8];
	
	VALUE column;
	VALUE row;
	
	VALUE column_name = rb_str_new2("name");
	VALUE column_type = rb_str_new2("type");
	VALUE column_size = rb_str_new2("size");
	VALUE column_scale = rb_str_new2("scale");
	VALUE column_precision = rb_str_new2("precision");
	
	VALUE column_value;
	
	connection = rb_iv_get(self, "@connection");
	query = rb_iv_get(self, "@query");
	
	columns = rb_ary_new();
	rb_iv_set(self, "@columns", columns);

	rows = rb_ary_new();
	rb_iv_set(self, "@rows", rows);
	
	Data_Get_Struct(connection, TDS_Connection, conn);
	buf = value_to_cstr(query);

	rb_iv_set(self, "@status", Qnil);
	
	rb_iv_set(self, "@messages", rb_ary_new());
	errors = rb_ary_new();
	rb_iv_set(self, "@errors", errors);

	ct_diag(conn->connection, CS_INIT, CS_UNUSED, CS_UNUSED, NULL);
	// if ( ct_callback(conn->context, NULL, CS_SET, CS_CLIENTMSG_CB, (CS_VOID *)clientmsg_cb) != CS_SUCCEED ) {
	// 	error_message("ct_callback CS_CLIENTMSG_CB failed\n");
	// }
	// if ( ct_callback(conn->context, NULL, CS_SET, CS_SERVERMSG_CB, (CS_VOID *)servermsg_cb) != CS_SUCCEED ) {
	// 	error_message("ct_callback CS_SERVERMSG_CB failed\n");
	// }
	ct_cmd_alloc(conn->connection, &cmd);
	ct_command(cmd, CS_LANG_CMD, buf, CS_NULLTERM, CS_UNUSED);
	ct_send(cmd);

	if ( ct_diag(conn->connection, CS_STATUS, CS_SERVERMSG_TYPE, CS_UNUSED, &num_errors) != CS_SUCCEED ) {
		error_message("ct_diag CS_STATUS CS_SERVERMSG_TYPE failed");
	}
	if (num_errors > 0) {
		// fprintf(stderr, "%d errors found\n", num_errors);
		for (i = 0; i < num_errors; i++) {
			if ( ct_diag(conn->connection, CS_GET, CS_SERVERMSG_TYPE, i+1, &servermsg) != CS_SUCCEED ) {
				error_message("ct_diag CS_GET CS_SERVERMSG_TYPE failed");
			}
			if (servermsg.severity > 0) {
				// error_message(servermsg.text);
				rb_ary_push(errors, rb_str_new2(servermsg.text));
			}
		}
		if ( ct_diag(conn->connection, CS_CLEAR, CS_SERVERMSG_TYPE, CS_UNUSED, NULL) != CS_SUCCEED ) {
			error_message("ct_diag CS_CLEAR CS_SERVERMSG_TYPE failed");
		}
	}
	
	// Raise errors from ct_command/ct_send
	err = rb_funcall(errors, rb_intern("first"), 0); // FIXME: should probably display all errors instead of just first
	if(RTEST(err)) {
		error_msg = value_to_cstr(err);
		rb_raise(rb_eIOError, error_msg);

		ct_cmd_drop(cmd);

		return Qnil;
	}
	// TODO:
	// - We should have an array of malloc'd cols
	// - Then we bind / fetch to those
	// - Finish conversions...
	
	while ((rc = ct_results(cmd, &resulttype)) == CS_SUCCEED) {
		switch (resulttype) {
		case CS_ROW_RESULT:
			rc = ct_res_info(cmd, CS_NUMDATA, &num_cols, sizeof(num_cols), &col_len);
			if (rc != CS_SUCCEED)
			{
				fprintf(stderr, "ct_res_info() failed\n");
				return 1;
			}

			col_data = (EX_COLUMN_DATA *)malloc(num_cols * sizeof (EX_COLUMN_DATA));
			if (col_data == NULL)
			 {
			    fprintf(stderr, "ex_fetch_data: malloc() failed");
			    return CS_MEM_ERROR;
			 }
			 cols = (CS_DATAFMT *)malloc(num_cols * sizeof (CS_DATAFMT));
			 if (cols == NULL)
			 {
			    fprintf(stderr, "ex_fetch_data: malloc() failed");
			    free(col_data);
			    return CS_MEM_ERROR;
			 }
			
			
			// Get column information
			for (i = 0; i < num_cols; i++) {
				rc = ct_describe(cmd, (i+1), &cols[i]);
				if ( rc != CS_SUCCEED ) {
					fprintf(stderr, "ct_describe failed on col #%d", i+1);
				}

				column_value = rb_hash_new();
				// fprintf(stderr, "%s\n", cols[i].name);
				if (cols[i].name) {
					rb_hash_aset(column_value, column_name, rb_str_new2(cols[i].name));
				} else {
					rb_hash_aset(column_value, column_name, Qnil);
				}
				
				rb_hash_aset(column_value, column_type, rb_str_new2(column_type_name(cols[i])));
				rb_hash_aset(column_value, column_size, INT2FIX(cols[i].maxlength));
				rb_hash_aset(column_value, column_scale, INT2FIX(cols[i].scale));
				rb_hash_aset(column_value, column_precision, INT2FIX(cols[i].precision));

				rb_ary_push(columns, column_value);
			}
			
			// Fetch data
			while (((rc = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &rows_read)) == CS_SUCCEED) || (rc == CS_ROW_FAIL)) {
				row_count = row_count + rows_read;

				row = rb_hash_new();
				rb_ary_push(rows, row);
				
				// Create Ruby objects
				for (i = 0; i < num_cols; i++) {
					// if (col_data[i].indicator == -1) {
					// 	rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
					// 	continue;
					// }
					switch (cols[i].datatype) {
					case CS_TINYINT_TYPE:
					case CS_BIT_TYPE:
						data_rc = ct_get_data(cmd, (i + 1), &tempInt, sizeof(tempInt), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							if(tempInt == 1) {
								rb_hash_aset(row, rb_str_new2(cols[i].name), Qtrue);
							} else {
								rb_hash_aset(row, rb_str_new2(cols[i].name), Qfalse);
							}
						}
						tempInt = -1;
						break;
					case CS_INT_TYPE:
					case CS_SMALLINT_TYPE:
						data_rc = ct_get_data(cmd, (i + 1), &tempInt, sizeof(tempInt), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							rb_hash_aset(row, rb_str_new2(cols[i].name), INT2FIX(tempInt));
						}
						tempInt = -1;
						break;
					
					case CS_DATETIME_TYPE:
					case CS_DATETIME4_TYPE:
						data_rc = ct_get_data(cmd, (i + 1), &tempDateTime, sizeof(tempDateTime), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							if ( cs_dt_crack(conn->context, CS_DATETIME_TYPE, &tempDateTime, &date_rec) == CS_SUCCEED ) {
								if(date_rec.dateyear && date_rec.datemonth && date_rec.datedmonth) {
									date_parts[0] = INT2FIX(date_rec.dateyear);
									date_parts[1] = INT2FIX(date_rec.datemonth+1);
									date_parts[2] = INT2FIX(date_rec.datedmonth);
									date_parts[3] = INT2FIX(date_rec.datehour);
									date_parts[4] = INT2FIX(date_rec.dateminute);
									date_parts[5] = INT2FIX(date_rec.datesecond);
									date_parts[6] = INT2FIX(date_rec.datemsecond);
									date_parts[7] = INT2FIX(date_rec.datetzone);
							
									// String (fastest known so far, but pushes the burden to ActiveRecord for parsing)
									sprintf(output, "%d-%02d-%02d %02d:%02d:%02d.%03d", date_rec.dateyear, date_rec.datemonth+1, date_rec.datedmonth, date_rec.datehour, date_rec.dateminute, date_rec.datesecond, date_rec.datemsecond);
									rb_hash_aset(row, rb_str_new2(cols[i].name), rb_str_new2(output));
								
									// DateTime - this is slow a f*ck
									//rb_hash_aset(row, rb_str_new2(cols[i].name), rb_funcall2(rb_DateTime, rb_intern("civil"), 6, &date_parts[0]));
								
									// Time - way faster than DateTime
									// FIXME: should we be assuming utc?!
									// rb_hash_aset(row, rb_str_new2(cols[i].name), rb_funcall2(rb_cTime, rb_intern("utc"), 6, &date_parts[0]));
								} else {
									rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
								}
							} else {
								fprintf(stderr, "cs_dt_crack failed\n");
							}
						}
						// tempDateTime = 0; // not sure how to clear this...
						break;
					
					// case CS_REAL_TYPE:
					case CS_FLOAT_TYPE:
					// case CS_MONEY_TYPE:
					// case CS_MONEY4_TYPE: 
						data_rc = ct_get_data(cmd, (i + 1), &tempDouble, sizeof(tempDouble), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							rb_hash_aset(row, rb_str_new2(cols[i].name), rb_float_new(tempDouble));
						}
						tempDouble = -1.0;
						break;
					
					// case CS_BIGINT_TYPE:
					// 	error_message("HELLO BIGINT!");
					// 	break;
						
					case CS_DECIMAL_TYPE:
					case CS_NUMERIC_TYPE:
						// fprintf(stderr, "CS_NUMERIC_TYPE detected - name: %s\n", cols[i].name);
						
						data_rc = ct_get_data(cmd, (i + 1), &tempNumeric, sizeof(tempNumeric), &output_len);
						if (output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							// fprintf(stderr, "tempNumeric output_len: %d, precision: %d, scale: %d, array: %s\n", output_len, tempNumeric.precision, tempNumeric.scale, tempNumeric.array);
							col.datatype = CS_CHAR_TYPE;
							col.format = CS_FMT_NULLTERM;
							col.maxlength = 200;
							// col.maxlength = cols[i].precision + 1;
							data_rc = cs_convert(conn->context, &cols[i], &tempNumeric, &col, output, &output_len);
							if ( data_rc != CS_SUCCEED ) {
								error_message("CS_NUMERIC_TYPE conversion failed");
								fprintf(stderr, "cs_convert returned: %d\n", data_rc);
							}
							// fprintf(stderr, "numeric output_len: %d, output: %s\n", output_len, output);
							rb_hash_aset(row, rb_str_new2(cols[i].name), LL2NUM(strtoll(output, NULL, 10)));
						}
						break;
						
					case CS_CHAR_TYPE:
					case CS_LONGCHAR_TYPE:
					case CS_TEXT_TYPE:
					case CS_VARCHAR_TYPE:
					case CS_UNICHAR_TYPE:
					case CS_UNIQUE_TYPE: // @todo should this one be handled differently?
						isNull = 0;
						tempTextLen = 1; // 1 for \0
						do {
							newTempText = realloc((tempTextLen == 1 ? NULL : tempText), tempTextLen + (1000 * sizeof(char))); // allocate another 1000 chars
							if (newTempText != NULL) {
								tempText = newTempText;
							} else {
								fprintf(stderr, "realloc error\n");
							}
							
							data_rc = ct_get_data(cmd, (i + 1), tempText + tempTextLen - 1, 1000, &output_len);

							if (tempTextLen == 1 && output_len == 0 && (data_rc == CS_END_DATA || data_rc == CS_END_ITEM)) {
								isNull = 1;
							}
								
							tempTextLen = tempTextLen + output_len;
						} while (data_rc == CS_SUCCEED);
						if (data_rc != CS_END_DATA && data_rc != CS_END_ITEM)
						{
							fprintf(stderr, "ct_get_data failed, data_rc = %d\n", data_rc);
							return data_rc;
						}
						tempText[tempTextLen-1] = '\0';
						if (isNull == 1) {
							rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						} else {
							rb_hash_aset(row, rb_str_new2(cols[i].name), rb_str_new2(tempText));
						}
						
						free(tempText);
						tempText = NULL;
						break;
					
					case CS_BINARY_TYPE:
					case CS_LONGBINARY_TYPE:
					case CS_VARBINARY_TYPE:
					case CS_IMAGE_TYPE:
						// rb_hash_aset(row, rb_str_new2(tds->res_info->columns[i]->column_name), rb_str_new((char *) ((TDSBLOB *) src)->textvalue, tds->res_info->columns[i]->column_cur_size));						
						rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						break;

					default:
						rb_hash_aset(row, rb_str_new2(cols[i].name), Qnil);
						printf("\nUnexpected datatype: %d\n", cols[i].datatype);
					}

				
				}
			}
			
			if( rc != CS_END_DATA )
			{
			    fprintf(stderr, "ct_fetch failed");
			}
			
			free(cols);
			cols = NULL;
			free(col_data);
			col_data = NULL;
			
			break;
		case CS_CMD_SUCCEED:
			rb_iv_set(self, "@status", Qnil);
			break;
		case CS_CMD_FAIL:
			if ( ct_diag(conn->connection, CS_STATUS, CS_SERVERMSG_TYPE, CS_UNUSED, &num_errors) != CS_SUCCEED ) {
				error_message("ct_diag CS_STATUS CS_SERVERMSG_TYPE failed");
			}
			if (num_errors > 0) {
				// fprintf(stderr, "%d errors found\n", num_errors);
				for (i = 0; i < num_errors; i++) {
					if ( ct_diag(conn->connection, CS_GET, CS_SERVERMSG_TYPE, i+1, &servermsg) != CS_SUCCEED ) {
						error_message("ct_diag CS_GET CS_SERVERMSG_TYPE failed");
					}
					if (servermsg.severity > 0) {
						// error_message(servermsg.text);
						rb_ary_push(errors, rb_str_new2(servermsg.text));
					}
				}
				if ( ct_diag(conn->connection, CS_CLEAR, CS_SERVERMSG_TYPE, CS_UNUSED, NULL) != CS_SUCCEED ) {
					error_message("ct_diag CS_CLEAR CS_SERVERMSG_TYPE failed");
				}
			}
		
			err = rb_funcall(errors, rb_intern("first"), 0); // FIXME: should probably display all errors instead of just first
			if(RTEST(err)) {
				error_msg = value_to_cstr(err);
				rb_raise(rb_eIOError, error_msg);
			} else {
				rb_raise(rb_eIOError, "CS_CMD_FAIL without server error message");
			}
			// rb_iv_set(self, "@status", INT2FIX(0));
			break;
		case CS_CMD_DONE:
			rb_iv_set(self, "@status", Qnil);
			break;
		case CS_STATUS_RESULT:
			// FIXME: We should probably do something here, right?
			break;
		default:
			fprintf(stderr, "ct_results returned unexpected result type: %d\n", resulttype);
			break;
		}
	}

	ct_cmd_drop(cmd);
	
	return Qnil;	
}
示例#19
0
VALUE
rb_grn_uvector_to_ruby_object (grn_ctx *context, grn_obj *uvector,
                               grn_obj *range, VALUE related_object)
{
    VALUE array = Qnil;

    if (!uvector)
        return Qnil;

    if (!range) {
        rb_raise(rb_eTypeError,
                 "unknown range uvector can't be converted: <%s>",
                 rb_grn_inspect(related_object));
    }

    switch (range->header.type) {
    case GRN_TYPE: {
        const char *current, *end;
        grn_id range_id;
        grn_obj value;
        int value_size;
        value_size = grn_obj_get_range(context, range);
        array = rb_ary_new();
        current = GRN_BULK_HEAD(uvector);
        end = GRN_BULK_CURR(uvector);
        range_id = grn_obj_id(context, range);
        GRN_OBJ_INIT(&value, GRN_BULK, GRN_OBJ_DO_SHALLOW_COPY, range_id);
        while (current < end) {
            VALUE rb_value;
            GRN_TEXT_SET(context, &value, current, value_size);
            rb_value = GRNBULK2RVAL(context, &value, range, related_object);
            rb_ary_push(array, rb_value);
            current += value_size;
        }
        GRN_OBJ_FIN(context, &value);
        break;
    }
    case GRN_TABLE_HASH_KEY:
    case GRN_TABLE_PAT_KEY:
    case GRN_TABLE_DAT_KEY:
    case GRN_TABLE_NO_KEY: {
        grn_id *current, *end;
        VALUE rb_range = Qnil;
        array = rb_ary_new();
        rb_range = GRNTABLE2RVAL(context, range, GRN_FALSE);
        current = (grn_id *)GRN_BULK_HEAD(uvector);
        end = (grn_id *)GRN_BULK_CURR(uvector);
        while (current < end) {
            VALUE record = Qnil;
            if (*current != GRN_ID_NIL) {
                record = rb_grn_record_new(rb_range, *current, Qnil);
            }
            rb_ary_push(array, record);
            current++;
        }
        break;
    }
    default:
        rb_raise(rb_eTypeError,
                 "unknown range uvector can't be converted: %s(%#x): <%s>",
                 rb_grn_inspect_type(range->header.type),
                 range->header.type,
                 rb_grn_inspect(related_object));
        break;
    }

    return array;
}
示例#20
0
static VALUE get_value(const char* buffer, int* position, int type) {
    VALUE value;
    switch (type) {
    case -1:
        {
            value = rb_class_new_instance(0, NULL, MinKey);
            break;
        }
    case 1:
        {
            double d;
            memcpy(&d, buffer + *position, 8);
            value = rb_float_new(d);
            *position += 8;
            break;
        }
    case 2:
    case 13:
        {
            int value_length;
            value_length = *(int*)(buffer + *position) - 1;
            *position += 4;
            value = STR_NEW(buffer + *position, value_length);
            *position += value_length + 1;
            break;
        }
    case 3:
        {
            int size;
            memcpy(&size, buffer + *position, 4);
            if (strcmp(buffer + *position + 5, "$ref") == 0) { // DBRef
                int offset = *position + 10;
                VALUE argv[2];
                int collection_length = *(int*)(buffer + offset) - 1;
                char id_type;
                offset += 4;

                argv[0] = STR_NEW(buffer + offset, collection_length);
                offset += collection_length + 1;
                id_type = buffer[offset];
                offset += 5;
                argv[1] = get_value(buffer, &offset, (int)id_type);
                value = rb_class_new_instance(2, argv, DBRef);
            } else {
                value = elements_to_hash(buffer + *position + 4, size - 5);
            }
            *position += size;
            break;
        }
    case 4:
        {
            int size, end;
            memcpy(&size, buffer + *position, 4);
            end = *position + size - 1;
            *position += 4;

            value = rb_ary_new();
            while (*position < end) {
                int type = (int)buffer[(*position)++];
                int key_size = strlen(buffer + *position);
                VALUE to_append;

                *position += key_size + 1; // just skip the key, they're in order.
                to_append = get_value(buffer, position, type);
                rb_ary_push(value, to_append);
            }
            (*position)++;
            break;
        }
    case 5:
        {
            int length, subtype;
            VALUE data, st;
            VALUE argv[2];
            memcpy(&length, buffer + *position, 4);
            subtype = (unsigned char)buffer[*position + 4];
            if (subtype == 2) {
                data = rb_str_new(buffer + *position + 9, length - 4);
            } else {
                data = rb_str_new(buffer + *position + 5, length);
            }
            st = INT2FIX(subtype);
            argv[0] = data;
            argv[1] = st;
            value = rb_class_new_instance(2, argv, Binary);
            *position += length + 5;
            break;
        }
    case 6:
        {
            value = Qnil;
            break;
        }
    case 7:
        {
            VALUE str = rb_str_new(buffer + *position, 12);
            VALUE oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
            value = rb_class_new_instance(1, &oid, ObjectId);
            *position += 12;
            break;
        }
    case 8:
        {
            value = buffer[(*position)++] ? Qtrue : Qfalse;
            break;
        }
    case 9:
        {
            long long millis;
            memcpy(&millis, buffer + *position, 8);

            value = rb_time_new(millis / 1000, (millis % 1000) * 1000);
            value = rb_funcall(value, utc_method, 0);
            *position += 8;
            break;
        }
    case 10:
        {
            value = Qnil;
            break;
        }
    case 11:
        {
            int pattern_length = strlen(buffer + *position);
            VALUE pattern = STR_NEW(buffer + *position, pattern_length);
            int flags_length, flags = 0, i = 0;
            VALUE argv[3];
            *position += pattern_length + 1;

            flags_length = strlen(buffer + *position);
            for (i = 0; i < flags_length; i++) {
                char flag = buffer[*position + i];
                if (flag == 'i') {
                    flags |= IGNORECASE;
                }
                else if (flag == 'm') {
                    flags |= MULTILINE;
                }
                else if (flag == 'x') {
                    flags |= EXTENDED;
                }
            }
            argv[0] = pattern;
            argv[1] = INT2FIX(flags);
            value = rb_class_new_instance(2, argv, Regexp);
            *position += flags_length + 1;
            break;
        }
    case 12:
        {
            int collection_length;
            VALUE collection, str, oid, id, argv[2];
            collection_length = *(int*)(buffer + *position) - 1;
            *position += 4;
            collection = STR_NEW(buffer + *position, collection_length);
            *position += collection_length + 1;

            str = rb_str_new(buffer + *position, 12);
            oid = rb_funcall(str, unpack_method, 1, rb_str_new2("C*"));
            id = rb_class_new_instance(1, &oid, ObjectId);
            *position += 12;

            argv[0] = collection;
            argv[1] = id;
            value = rb_class_new_instance(2, argv, DBRef);
            break;
        }
    case 14:
        {
            int value_length;
            memcpy(&value_length, buffer + *position, 4);
            value = ID2SYM(rb_intern(buffer + *position + 4));
            *position += value_length + 4;
            break;
        }
    case 15:
        {
            int code_length, scope_size;
            VALUE code, scope, argv[2];
            *position += 4;
            code_length = *(int*)(buffer + *position) - 1;
            *position += 4;
            code = STR_NEW(buffer + *position, code_length);
            *position += code_length + 1;

            memcpy(&scope_size, buffer + *position, 4);
            scope = elements_to_hash(buffer + *position + 4, scope_size - 5);
            *position += scope_size;

            argv[0] = code;
            argv[1] = scope;
            value = rb_class_new_instance(2, argv, Code);
            break;
        }
    case 16:
        {
            int i;
            memcpy(&i, buffer + *position, 4);
            value = LL2NUM(i);
            *position += 4;
            break;
        }
    case 17:
        {
            int i;
            int j;
            memcpy(&i, buffer + *position, 4);
            memcpy(&j, buffer + *position + 4, 4);
            value = rb_ary_new3(2, LL2NUM(i), LL2NUM(j));
            *position += 8;
            break;
        }
    case 18:
        {
            long long ll;
            memcpy(&ll, buffer + *position, 8);
            value = LL2NUM(ll);
            *position += 8;
            break;
        }
    case 127:
        {
            value = rb_class_new_instance(0, NULL, MaxKey);
            break;
        }
    default:
        {
            rb_raise(rb_eTypeError, "no c decoder for this type yet (%d)", type);
            break;
        }
    }
    return value;
}
示例#21
0
static NODE *
build_Range_each_node(rb_iseq_t *iseq, NODE * node, NODE * lnode,
		      VALUE param_vars, VALUE local_vars, ID mid)
{
    /* Special Block for Range#each
       {|e, _last|
       _e = e
       while _e < _last
       e = _e
       next_point:
       BODY
       redo_point:
       _e = _e.succ
       end
       }
       {|e, _last|
       while e < _last
       BODY
       redo_point:
       e = e.succ
       end
       }
     */
    ID _last = rb_intern("#_last");
    if (iseq->argc == 0) {
	ID e = rb_intern("#e");
	rb_ary_push(param_vars, ID2SYM(e));
	rb_ary_push(param_vars, ID2SYM(_last));
	iseq->argc += 2;

	node =
	    NEW_WHILE(NEW_CALL(NEW_DVAR(e), mid, new_ary(NEW_DVAR(_last), 0)),
		      new_block(NEW_OPTBLOCK(node),
				NEW_DASGN(e,
					  NEW_CALL(NEW_DVAR(e), idSucc, 0))),
		      Qundef);
    }
    else {
	ID _e = rb_intern("#_e");
	ID e = SYM2ID(rb_ary_entry(param_vars, 0));
	NODE *assign;

	rb_ary_push(param_vars, ID2SYM(_last));
	rb_ary_push(local_vars, ID2SYM(_e));
	iseq->argc++;

	if (nd_type(lnode) == NODE_DASGN_CURR) {
	    assign = NEW_DASGN(e, NEW_DVAR(_e));
	}
	else {
	    assign = new_assign(lnode, NEW_DVAR(_e));
	}

	node =
	    new_block(NEW_DASGN(_e, NEW_DVAR(e)),
		      NEW_WHILE(NEW_CALL
				(NEW_DVAR(_e), mid,
				 new_ary(NEW_DVAR(_last), 0)),
				new_block(assign,
					  new_block(NEW_OPTBLOCK(node),
						    NEW_DASGN(_e,
							      NEW_CALL
							      (NEW_DVAR(_e),
							       idSucc, 0)))),
				Qundef));
    }
    return node;
}
示例#22
0
文件: load.c 项目: scorpion007/ruby
/*
 * returns
 *  0: if already loaded (false)
 *  1: successfully loaded (true)
 * <0: not found (LoadError)
 * >1: exception
 */
int
rb_require_internal(VALUE fname, int safe)
{
    volatile int result = -1;
    rb_thread_t *th = GET_THREAD();
    volatile VALUE errinfo = th->errinfo;
    int state;
    struct {
	int safe;
    } volatile saved;
    char *volatile ftptr = 0;

    if (RUBY_DTRACE_REQUIRE_ENTRY_ENABLED()) {
	RUBY_DTRACE_REQUIRE_ENTRY(StringValuePtr(fname),
				  rb_sourcefile(),
				  rb_sourceline());
    }

    TH_PUSH_TAG(th);
    saved.safe = rb_safe_level();
    if ((state = EXEC_TAG()) == 0) {
	VALUE path;
	long handle;
	int found;

	rb_set_safe_level_force(safe);
	FilePathValue(fname);
	rb_set_safe_level_force(0);

	if (RUBY_DTRACE_FIND_REQUIRE_ENTRY_ENABLED()) {
	    RUBY_DTRACE_FIND_REQUIRE_ENTRY(StringValuePtr(fname),
					   rb_sourcefile(),
					   rb_sourceline());
	}

	path = rb_str_encode_ospath(fname);
	found = search_required(path, &path, safe);

	if (RUBY_DTRACE_FIND_REQUIRE_RETURN_ENABLED()) {
	    RUBY_DTRACE_FIND_REQUIRE_RETURN(StringValuePtr(fname),
					    rb_sourcefile(),
					    rb_sourceline());
	}
	if (found) {
	    if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
		result = 0;
	    }
	    else if (!*ftptr) {
		rb_provide_feature(path);
		result = TAG_RETURN;
	    }
	    else {
		switch (found) {
		  case 'r':
		    rb_load_internal(path, 0);
		    break;

		  case 's':
		    handle = (long)rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
						    path, 0, path);
		    rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
		    break;
		}
		rb_provide_feature(path);
		result = TAG_RETURN;
	    }
	}
    }
    TH_POP_TAG();
    load_unlock(ftptr, !state);

    rb_set_safe_level_force(saved.safe);
    if (state) {
	/* never TAG_RETURN */
	return state;
    }

    th->errinfo = errinfo;

    if (RUBY_DTRACE_REQUIRE_RETURN_ENABLED()) {
	RUBY_DTRACE_REQUIRE_RETURN(StringValuePtr(fname),
				  rb_sourcefile(),
				  rb_sourceline());
    }

    return result;
}
示例#23
0
文件: common.c 项目: agx/ruby-libvirt
VALUE ruby_libvirt_ary_push_wrap(VALUE arg)
{
    struct ruby_libvirt_ary_push_arg *e = (struct ruby_libvirt_ary_push_arg *)arg;

    return rb_ary_push(e->arr, e->value);
}
示例#24
0
static int
convert_hash_to_a(VALUE key, VALUE value, VALUE ary) {
  if (key == Qundef) return ST_CONTINUE;
  rb_ary_push(ary, key);
  return rb_ary_push(ary, value);
}
示例#25
0
VALUE lorcon_cap_to_list(int cap) {
	VALUE list;
	list = rb_ary_new();
	
	if ((cap & TX80211_CAP_SNIFF) != 0) 
		rb_ary_push(list, rb_str_new2("SNIFF"));
	
	if ((cap & TX80211_CAP_TRANSMIT) != 0)
		rb_ary_push(list, rb_str_new2("TRANSMIT"));
	
	if ((cap & TX80211_CAP_SEQ) != 0)
		rb_ary_push(list, rb_str_new2("SEQ"));
	
	if ((cap & TX80211_CAP_BSSTIME) != 0)
		rb_ary_push(list, rb_str_new2("BSSTIME"));
	
	if ((cap & TX80211_CAP_FRAG) != 0)
		rb_ary_push(list, rb_str_new2("FRAG"));
	
	if ((cap & TX80211_CAP_CTRL) != 0)
		rb_ary_push(list, rb_str_new2("CTRL"));
	
	if ((cap & TX80211_CAP_DURID) != 0)
		rb_ary_push(list, rb_str_new2("DURID"));
	
	if ((cap & TX80211_CAP_SNIFFACK) != 0)
		rb_ary_push(list, rb_str_new2("SNIFFACK"));
	
	if ((cap & TX80211_CAP_SELFACK) != 0)
		rb_ary_push(list, rb_str_new2("SELFACK"));
	
	if ((cap & TX80211_CAP_TXNOWAIT) != 0)
		rb_ary_push(list, rb_str_new2("TXNOWAIT"));
	
	if ((cap & TX80211_CAP_DSSSTX) != 0)
		rb_ary_push(list, rb_str_new2("DSSSTX"));
	
	if ((cap & TX80211_CAP_OFDMTX) != 0)
		rb_ary_push(list, rb_str_new2("OFDMTX"));
	
	if ((cap & TX80211_CAP_MIMOTX) != 0)
		rb_ary_push(list, rb_str_new2("MIMOTX"));
	
	if ((cap & TX80211_CAP_SETRATE) != 0)
		rb_ary_push(list, rb_str_new2("SETRATE"));
	
	if ((cap & TX80211_CAP_SETMODULATION) != 0)
		rb_ary_push(list, rb_str_new2("SETMODULATION"));
	
	if ((cap & TX80211_CAP_NONE) != 0)
		rb_ary_push(list, rb_str_new2("NONE"));

	return list;
}
示例#26
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);
    }
}
示例#27
0
static VALUE
ossl_asn1_decode0(unsigned char **pp, long length, long *offset, long depth,
		  int once, int yield)
{
    unsigned char *start, *p;
    const unsigned char *p0;
    long len, off = *offset;
    int hlen, tag, tc, j;
    VALUE ary, asn1data, value, tag_class;

    ary = rb_ary_new();
    p = *pp;
    while(length > 0){
	start = p;
	p0 = p;
	j = ASN1_get_object(&p0, &len, &tag, &tc, length);
	p = (unsigned char *)p0;
	if(j & 0x80) ossl_raise(eASN1Error, NULL);
	hlen = p - start;
	if(yield){
	    VALUE arg = rb_ary_new();
	    rb_ary_push(arg, LONG2NUM(depth));
	    rb_ary_push(arg, LONG2NUM(off));
	    rb_ary_push(arg, LONG2NUM(hlen));
	    rb_ary_push(arg, LONG2NUM(len));
	    rb_ary_push(arg, (j & V_ASN1_CONSTRUCTED) ? Qtrue : Qfalse);
	    rb_ary_push(arg, ossl_asn1_class2sym(tc));
	    rb_ary_push(arg, INT2NUM(tag));
	    rb_yield(arg);
	}
	length -= hlen;
	off += hlen;
	if(len > length) ossl_raise(eASN1Error, "value is too short");
	if((tc & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
	    tag_class = sPRIVATE;
	else if((tc & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
	    tag_class = sCONTEXT_SPECIFIC;
	else if((tc & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
	    tag_class = sAPPLICATION;
	else
	    tag_class = sUNIVERSAL;
	if(j & V_ASN1_CONSTRUCTED){
	    /* TODO: if j == 0x21 it is indefinite length object. */
	    if((j == 0x21) && (len == 0)){
		long lastoff = off;
		value = ossl_asn1_decode0(&p, length, &off, depth+1, 0, yield);
		len = off - lastoff;
	    }
	    else value = ossl_asn1_decode0(&p, len, &off, depth+1, 0, yield);
	}
	else{
	    value = rb_str_new((const char *)p, len);
	    p += len;
	    off += len;
	}
	if(tag_class == sUNIVERSAL &&
	   tag < ossl_asn1_info_size && ossl_asn1_info[tag].klass){
	    VALUE klass = *ossl_asn1_info[tag].klass;
	    long flag = 0;
	    if(!rb_obj_is_kind_of(value, rb_cArray)){
		switch(tag){
		case V_ASN1_BOOLEAN:
		    value = decode_bool(start, hlen+len);
		    break;
		case V_ASN1_INTEGER:
		    value = decode_int(start, hlen+len);
		    break;
		case V_ASN1_BIT_STRING:
		    value = decode_bstr(start, hlen+len, &flag);
		    break;
		case V_ASN1_NULL:
		    value = decode_null(start, hlen+len);
		    break;
		case V_ASN1_ENUMERATED:
		    value = decode_enum(start, hlen+len);
		    break;
		case V_ASN1_OBJECT:
		    value = decode_obj(start, hlen+len);
		    break;
		case V_ASN1_UTCTIME:           /* FALLTHROUGH */
		case V_ASN1_GENERALIZEDTIME:
		    value = decode_time(start, hlen+len);
		    break;
		default:
		    /* use original value */
		    break;
		}
	    }
	    asn1data = rb_funcall(klass, rb_intern("new"), 1, value);
	    if(tag == V_ASN1_BIT_STRING){
		rb_iv_set(asn1data, "@unused_bits", LONG2NUM(flag));
	    }
	}
	else{
	    asn1data = rb_funcall(cASN1Data, rb_intern("new"), 3,
				  value, INT2NUM(tag), ID2SYM(tag_class));
	}
	rb_ary_push(ary, asn1data);
	length -= len;
        if(once) break;
    }
    *pp = p;
    *offset = off;

    return ary;
}
示例#28
0
static VALUE rb_mysql_result_fetch_row_stmt(VALUE self, MYSQL_FIELD * fields, const result_each_args *args)
{
  VALUE rowVal;
  unsigned int i = 0;

#ifdef HAVE_RUBY_ENCODING_H
  rb_encoding *default_internal_enc;
  rb_encoding *conn_enc;
#endif
  GET_RESULT(self);

#ifdef HAVE_RUBY_ENCODING_H
  default_internal_enc = rb_default_internal_encoding();
  conn_enc = rb_to_encoding(wrapper->encoding);
#endif

  if (args->asArray) {
    rowVal = rb_ary_new2(wrapper->numberOfFields);
  } else {
    rowVal = rb_hash_new();
  }
  if (wrapper->fields == Qnil) {
    wrapper->numberOfFields = mysql_num_fields(wrapper->result);
    wrapper->fields = rb_ary_new2(wrapper->numberOfFields);
  }

  if (wrapper->result_buffers == NULL) {
    rb_mysql_result_alloc_result_buffers(self, fields);
  }

  if (mysql_stmt_bind_result(wrapper->stmt_wrapper->stmt, wrapper->result_buffers)) {
    rb_raise_mysql2_stmt_error(wrapper->stmt_wrapper);
  }

  {
    switch((uintptr_t)rb_thread_call_without_gvl(nogvl_stmt_fetch, wrapper->stmt_wrapper->stmt, RUBY_UBF_IO, 0)) {
      case 0:
        /* success */
        break;

      case 1:
        /* error */
        rb_raise_mysql2_stmt_error(wrapper->stmt_wrapper);

      case MYSQL_NO_DATA:
        /* no more row */
        return Qnil;

      case MYSQL_DATA_TRUNCATED:
        rb_raise(cMysql2Error, "IMPLBUG: caught MYSQL_DATA_TRUNCATED. should not come here as buffer_length is set to fields[i].max_length.");
    }
  }

  for (i = 0; i < wrapper->numberOfFields; i++) {
    VALUE field = rb_mysql_result_fetch_field(self, i, args->symbolizeKeys);
    VALUE val = Qnil;
    MYSQL_TIME *ts;

    if (wrapper->is_null[i]) {
      val = Qnil;
    } else {
      const MYSQL_BIND* const result_buffer = &wrapper->result_buffers[i];

      switch(result_buffer->buffer_type) {
        case MYSQL_TYPE_TINY:         // signed char
          if (args->castBool && fields[i].length == 1) {
            val = (*((unsigned char*)result_buffer->buffer) != 0) ? Qtrue : Qfalse;
            break;
          }
          if (result_buffer->is_unsigned) {
            val = UINT2NUM(*((unsigned char*)result_buffer->buffer));
          } else {
            val = INT2NUM(*((signed char*)result_buffer->buffer));
          }
          break;
        case MYSQL_TYPE_SHORT:        // short int
          if (result_buffer->is_unsigned) {
            val = UINT2NUM(*((unsigned short int*)result_buffer->buffer));
          } else  {
            val = INT2NUM(*((short int*)result_buffer->buffer));
          }
          break;
        case MYSQL_TYPE_INT24:        // int
        case MYSQL_TYPE_LONG:         // int
        case MYSQL_TYPE_YEAR:         // int
          if (result_buffer->is_unsigned) {
            val = UINT2NUM(*((unsigned int*)result_buffer->buffer));
          } else {
            val = INT2NUM(*((int*)result_buffer->buffer));
          }
          break;
        case MYSQL_TYPE_LONGLONG:     // long long int
          if (result_buffer->is_unsigned) {
            val = ULL2NUM(*((unsigned long long int*)result_buffer->buffer));
          } else {
            val = LL2NUM(*((long long int*)result_buffer->buffer));
          }
          break;
        case MYSQL_TYPE_FLOAT:        // float
          val = rb_float_new((double)(*((float*)result_buffer->buffer)));
          break;
        case MYSQL_TYPE_DOUBLE:       // double
          val = rb_float_new((double)(*((double*)result_buffer->buffer)));
          break;
        case MYSQL_TYPE_DATE:         // MYSQL_TIME
        case MYSQL_TYPE_NEWDATE:      // MYSQL_TIME
          ts = (MYSQL_TIME*)result_buffer->buffer;
          val = rb_funcall(cDate, intern_new, 3, INT2NUM(ts->year), INT2NUM(ts->month), INT2NUM(ts->day));
          break;
        case MYSQL_TYPE_TIME:         // MYSQL_TIME
          ts = (MYSQL_TIME*)result_buffer->buffer;
          val = rb_funcall(rb_cTime, args->db_timezone, 7, opt_time_year, opt_time_month, opt_time_month, UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part));
          if (!NIL_P(args->app_timezone)) {
            if (args->app_timezone == intern_local) {
              val = rb_funcall(val, intern_localtime, 0);
            } else { // utc
              val = rb_funcall(val, intern_utc, 0);
            }
          }
          break;
        case MYSQL_TYPE_DATETIME:     // MYSQL_TIME
        case MYSQL_TYPE_TIMESTAMP: {  // MYSQL_TIME
          uint64_t seconds;

          ts = (MYSQL_TIME*)result_buffer->buffer;
          seconds = (ts->year*31557600ULL) + (ts->month*2592000ULL) + (ts->day*86400ULL) + (ts->hour*3600ULL) + (ts->minute*60ULL) + ts->second;

          if (seconds < MYSQL2_MIN_TIME || seconds > MYSQL2_MAX_TIME) { // use DateTime instead
            VALUE offset = INT2NUM(0);
            if (args->db_timezone == intern_local) {
              offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
            }
            val = rb_funcall(cDateTime, intern_civil, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), offset);
            if (!NIL_P(args->app_timezone)) {
              if (args->app_timezone == intern_local) {
                offset = rb_funcall(cMysql2Client, intern_local_offset, 0);
                val = rb_funcall(val, intern_new_offset, 1, offset);
              } else { // utc
                val = rb_funcall(val, intern_new_offset, 1, opt_utc_offset);
              }
            }
          } else {
            val = rb_funcall(rb_cTime, args->db_timezone, 7, UINT2NUM(ts->year), UINT2NUM(ts->month), UINT2NUM(ts->day), UINT2NUM(ts->hour), UINT2NUM(ts->minute), UINT2NUM(ts->second), ULONG2NUM(ts->second_part));
            if (!NIL_P(args->app_timezone)) {
              if (args->app_timezone == intern_local) {
                val = rb_funcall(val, intern_localtime, 0);
              } else { // utc
                val = rb_funcall(val, intern_utc, 0);
              }
            }
          }
          break;
        }
        case MYSQL_TYPE_DECIMAL:      // char[]
        case MYSQL_TYPE_NEWDECIMAL:   // char[]
          val = rb_funcall(cBigDecimal, intern_new, 1, rb_str_new(result_buffer->buffer, *(result_buffer->length)));
          break;
        case MYSQL_TYPE_STRING:       // char[]
        case MYSQL_TYPE_VAR_STRING:   // char[]
        case MYSQL_TYPE_VARCHAR:      // char[]
        case MYSQL_TYPE_TINY_BLOB:    // char[]
        case MYSQL_TYPE_BLOB:         // char[]
        case MYSQL_TYPE_MEDIUM_BLOB:  // char[]
        case MYSQL_TYPE_LONG_BLOB:    // char[]
        case MYSQL_TYPE_BIT:          // char[]
        case MYSQL_TYPE_SET:          // char[]
        case MYSQL_TYPE_ENUM:         // char[]
        case MYSQL_TYPE_GEOMETRY:     // char[]
        default:
          val = rb_str_new(result_buffer->buffer, *(result_buffer->length));
#ifdef HAVE_RUBY_ENCODING_H
          val = mysql2_set_field_string_encoding(val, fields[i], default_internal_enc, conn_enc);
#endif
          break;
      }
    }

    if (args->asArray) {
      rb_ary_push(rowVal, val);
    } else {
      rb_hash_aset(rowVal, field, val);
    }
  }

  return rowVal;
}
示例#29
0
/*
 * call-seq:
 *    ProcTable.ps(pid=nil)
 *    ProcTable.ps(pid=nil){ |ps| ... }
 *
 * In block form, yields a ProcTableStruct for each process entry that you
 * have rights to.  This method returns an array of ProcTableStruct's in
 * non-block form.
 *
 * If a +pid+ is provided, then only a single ProcTableStruct is yielded or
 * returned, or nil if no process information is found for that +pid+.
 */
static VALUE pt_ps(int argc, VALUE* argv, VALUE klass){
   int err;
   char state[8];
   struct kinfo_proc* procs;
   VALUE v_pid, v_tty_num, v_tty_dev, v_start_time;
   VALUE v_pstruct = Qnil;
   VALUE v_array = rb_ary_new();
   size_t length, count;
   size_t i = 0;
   char args[ARGS_MAX_LEN+1];

   // Passed into sysctl call
   static const int name_mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};

   rb_scan_args(argc, argv, "01", &v_pid);

   // Get size of proc kproc buffer
   err = sysctl( (int *) name_mib, PROC_MIB_LEN, NULL, &length, NULL, 0);

   if(err == -1)
      rb_raise(cProcTableError, "sysctl: %s", strerror(errno));

   // Populate the kproc buffer
   procs = malloc(length);

   if(procs == NULL)
      rb_raise(cProcTableError, "malloc: %s", strerror(errno));

   err = sysctl( (int *) name_mib, PROC_MIB_LEN, procs, &length, NULL, 0);

   if(err == -1)
      rb_raise(cProcTableError, "sysctl: %s", strerror(errno));

   // If we're here, we got our list
   count = length / sizeof(struct kinfo_proc);

   for(i = 0; i < count; i++) {
      v_tty_num = Qnil;
      v_tty_dev = Qnil;
      v_start_time = Qnil;

      // If a PID is provided, skip unless the PID matches
      if( (!NIL_P(v_pid)) && (procs[i].kp_proc.p_pid != NUM2INT(v_pid)) )
         continue;

      *args = '\0';

      /* Query the command line args */
      /* TODO: Cmd line not working for now - fix */

      /*args_mib[ARGS_MIB_LEN - 1] = procs[i].kp_proc.p_pid;
      args_err = sysctl( (int *) args_mib, ARGS_MIB_LEN, args, &args_size, NULL, 0);

      if(args_err >= 0) {
         fprintf(stderr, "Ret: %d LEN: %d\n", err, args_size);
         char *c;
         for(c = args; c < args+args_size; c++)
            if(*c == '\0') *c = ' ';
         args[args_size] = '\0';
      } else {
         fprintf(stderr, "err: %s LEN: %d\n", strerror(errno), args_size);
      }*/
      char cmdline[ARGS_MAX_LEN+1];

      argv_of_pid(procs[i].kp_proc.p_pid, &cmdline);
      /* free(cmdline); */

      // Get the start time of the process
      v_start_time = rb_time_new(
         procs[i].kp_proc.p_un.__p_starttime.tv_sec,
         procs[i].kp_proc.p_un.__p_starttime.tv_usec
      );

      // Get the state of the process
      switch(procs[i].kp_proc.p_stat)
      {
         case SIDL:
            strcpy(state, "idle");
            break;
         case SRUN:
            strcpy(state, "run");
            break;
         case SSLEEP:
            strcpy(state, "sleep");
            break;
         case SSTOP:
            strcpy(state, "stop");
            break;
         case SZOMB:
            strcpy(state, "zombie");
            break;
         default:
            strcpy(state, "unknown");
            break;
      }

      // Get ttynum and ttydev. If ttynum is -1, there is no tty.
      if(procs[i].kp_eproc.e_tdev != -1){
         v_tty_num = INT2FIX(procs[i].kp_eproc.e_tdev),
         v_tty_dev = rb_str_new2(devname(procs[i].kp_eproc.e_tdev, S_IFCHR));
      }

      v_pstruct = rb_struct_new(
         sProcStruct,
         INT2FIX(procs[i].kp_proc.p_pid),
         INT2FIX(procs[i].kp_eproc.e_ppid),
         INT2FIX(procs[i].kp_eproc.e_pgid),
         INT2FIX(procs[i].kp_eproc.e_pcred.p_ruid),
         INT2FIX(procs[i].kp_eproc.e_pcred.p_rgid),
         rb_str_new2(procs[i].kp_proc.p_comm),
         rb_str_new2(state),
         rb_float_new(procs[i].kp_proc.p_pctcpu),
         Qnil,
         v_tty_num,
         v_tty_dev,
         rb_str_new2(procs[i].kp_eproc.e_wmesg),
         INT2FIX(procs[i].kp_proc.p_rtime.tv_sec),
         INT2FIX(procs[i].kp_proc.p_priority),
         INT2FIX(procs[i].kp_proc.p_usrpri),
         INT2FIX(procs[i].kp_proc.p_nice),
         rb_str_new2(cmdline),
         v_start_time,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_maxrss) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_ixrss) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_idrss) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_isrss) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_minflt) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_majflt) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nswap) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_inblock) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_oublock) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgsnd) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgrcv) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nsignals) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nvcsw) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nivcsw) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_utime.tv_sec) : Qnil,
         (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_stime.tv_sec) : Qnil
      );

      OBJ_FREEZE(v_pstruct); // This is read-only data

      if(rb_block_given_p())
         rb_yield(v_pstruct);
      else
         rb_ary_push(v_array, v_pstruct);
   }

   if(procs) free(procs);

   if(!rb_block_given_p()){
      if(NIL_P(v_pid))
         return v_array;
      else
         return v_pstruct;
   }

   return Qnil;
}
示例#30
0
/*
 * call-seq:
 *    Win32::API.new(function, prototype='V', return='L', dll='kernel32')
 *
 * Creates and returns a new Win32::API object. The +function+ is the name
 * of the Windows function.
 *
 * The +prototype+ is the function prototype for +function+. This can be a
 * string or an array of characters.  The possible valid characters are 'I'
 * (integer), 'L' (long), 'V' (void), 'P' (pointer), 'K' (callback) or 'S'
 * (string).
 *
 * The default is void ('V').
 *
 * Constant (const char*) strings should use 'S'. Pass by reference string
 * buffers should use 'P'. The former is faster, but cannot be modified.
 *
 * The +return+ argument is the return type for the function.  The valid
 * characters are the same as for the +prototype+.  The default is 'L' (long).
 *
 * The +dll+ is the name of the DLL file that the function is exported from.
 * The default is 'kernel32'.
 *
 * If the function cannot be found then an API::Error is raised (a subclass
 * of RuntimeError).
 *
 * Example:
 *
 *    require 'win32/api'
 *    include Win32
 *
 *    buf = 0.chr * 260
 *    len = [buf.length].pack('L')
 *
 *    GetUserName = API.new('GetUserName', 'PP', 'I', 'advapi32')
 *    GetUserName.call(buf, len)
 *
 *    puts buf.strip
 */
static VALUE api_init(int argc, VALUE* argv, VALUE self)
{
   HMODULE hLibrary;
   FARPROC fProc;
   Win32API* ptr;
   int i;
   char* first  = "A";
   char* second = "W";
   VALUE v_proc, v_proto, v_return, v_dll;

   rb_scan_args(argc, argv, "13", &v_proc, &v_proto, &v_return, &v_dll);

   Data_Get_Struct(self, Win32API, ptr);

   // Convert a string prototype to an array of characters
   if(rb_respond_to(v_proto, rb_intern("split")))
      v_proto = rb_str_split(v_proto, "");

   // Convert a nil or empty prototype to 'V' (void) automatically
   if(NIL_P(v_proto) || RARRAY_LEN(v_proto) == 0){
      v_proto = rb_ary_new();
      rb_ary_push(v_proto, rb_str_new2("V"));
   }

   // Set an arbitrary limit of 20 parameters
   if(20 < RARRAY_LEN(v_proto))
      rb_raise(rb_eArgError, "too many parameters: %d\n", RARRAY_LEN(v_proto));

   // Set the default dll to 'kernel32'
   if(NIL_P(v_dll))
      v_dll = rb_str_new2("kernel32");

   // Set the default return type to 'L' (DWORD)
   if(NIL_P(v_return))
      v_return = rb_str_new2("L");

   SafeStringValue(v_dll);
   SafeStringValue(v_proc);

   hLibrary = LoadLibrary(TEXT(RSTRING_PTR(v_dll)));

   // The most likely cause of failure is a bad DLL load path
   if(!hLibrary){
      rb_raise(cAPILoadError, "LoadLibrary() function failed for '%s': %s",
         RSTRING_PTR(v_dll),
         StringError(GetLastError())
      );
   }

   ptr->library = hLibrary;

   /* Attempt to get the function.  If it fails, try again with an 'A'
    * appended.  If that fails, try again with a 'W' appended. If that
    * still fails, raise an API::LoadLibraryError.
    */

   fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_proc)));

   // Skip the ANSI and Wide function checks for MSVCRT functions.
   if(!fProc){
      if(strstr(RSTRING_PTR(v_dll), "msvcr")){
         rb_raise(
            cAPILoadError,
            "Unable to load function '%s'",
            RSTRING_PTR(v_proc)
         );
      }
      else{
         VALUE v_ascii = rb_str_new3(v_proc);
         v_ascii = rb_str_cat(v_ascii, first, 1);
         fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_ascii)));

         if(!fProc){
            VALUE v_unicode = rb_str_new3(v_proc);
            v_unicode = rb_str_cat(v_unicode, second, 1);
            fProc = GetProcAddress(hLibrary, TEXT(RSTRING_PTR(v_unicode)));

            if(!fProc){
               rb_raise(
                  cAPILoadError,
                  "Unable to load function '%s', '%s', or '%s'",
                  RSTRING_PTR(v_proc),
                  RSTRING_PTR(v_ascii),
                  RSTRING_PTR(v_unicode)
               );
            }
            else{
               rb_iv_set(self, "@effective_function_name", v_unicode);
            }
         }
         else{
            rb_iv_set(self, "@effective_function_name", v_ascii);
         }
      }
   }
   else{
      rb_iv_set(self, "@effective_function_name", v_proc);
   }

   ptr->function = fProc;

   // Push the numeric prototypes onto our int array for later use.

   for(i = 0; i < RARRAY_LEN(v_proto); i++){
      SafeStringValue(RARRAY_PTR(v_proto)[i]);
      switch(*(char*)StringValuePtr(RARRAY_PTR(v_proto)[i])){
         case 'L':
            ptr->prototype[i] = _T_LONG;
            break;
         case 'P':
            ptr->prototype[i] = _T_POINTER;
            break;
         case 'I': case 'B':
            ptr->prototype[i] = _T_INTEGER;
            break;
         case 'V':
            ptr->prototype[i] = _T_VOID;
            break;
         case 'K':
            ptr->prototype[i] = _T_CALLBACK;
            break;
         case 'S':
            ptr->prototype[i] = _T_STRING;
            break;
         default:
            rb_raise(cAPIProtoError, "Illegal prototype '%s'",
               StringValuePtr(RARRAY_PTR(v_proto)[i])
            );
      }
   }

   // Store the return type for later use.

   // Automatically convert empty strings or nil to type void.
   if(NIL_P(v_return) || RSTRING_LEN(v_return) == 0){
      v_return = rb_str_new2("V");
      ptr->return_type = _T_VOID;
   }
   else{
      SafeStringValue(v_return);
      switch(*RSTRING_PTR(v_return)){
         case 'L':
            ptr->return_type = _T_LONG;
            break;
         case 'P':
            ptr->return_type = _T_POINTER;
            break;
         case 'I': case 'B':
            ptr->return_type = _T_INTEGER;
            break;
         case 'V':
            ptr->return_type = _T_VOID;
            break;
         case 'S':
            ptr->return_type = _T_STRING;
            break;
         default:
            rb_raise(cAPIProtoError, "Illegal return type '%s'",
               RSTRING_PTR(v_return)
            );
      }
   }

   rb_iv_set(self, "@dll_name", v_dll);
   rb_iv_set(self, "@function_name", v_proc);
   rb_iv_set(self, "@prototype", v_proto);
   rb_iv_set(self, "@return_type", v_return);

   return self;
}