Пример #1
0
static VALUE cmethod_proj4_transform(VALUE method, VALUE from, VALUE to, VALUE x, VALUE y, VALUE z)
{
  VALUE result = Qnil;
  projPJ from_pj = RGEO_PROJ4_DATA_PTR(from)->pj;
  projPJ to_pj = RGEO_PROJ4_DATA_PTR(to)->pj;
  if (from_pj && to_pj) {
    double xval = rb_num2dbl(x);
    double yval = rb_num2dbl(y);
    double zval = 0.0;
    if (!NIL_P(z)) {
      zval = rb_num2dbl(z);
    }
    int err = pj_transform(from_pj, to_pj, 1, 1, &xval, &yval, NIL_P(z) ? NULL : &zval);
    if (!err && xval != HUGE_VAL && yval != HUGE_VAL && (NIL_P(z) || zval != HUGE_VAL)) {
      result = rb_ary_new2(NIL_P(z) ? 2 : 3);
      rb_ary_push(result, rb_float_new(xval));
      rb_ary_push(result, rb_float_new(yval));
      if (!NIL_P(z)) {
        rb_ary_push(result, rb_float_new(zval));
      }
    }
  }
  return result;
}
Пример #2
0
static VALUE
ossl_x509crl_get_revoked(VALUE self)
{
    X509_CRL *crl;
    int i, num;
    X509_REVOKED *rev;
    VALUE ary, revoked;

    GetX509CRL(self, crl);
    num = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
    if (num < 0) {
	OSSL_Debug("num < 0???");
	return rb_ary_new();
    }
    ary = rb_ary_new2(num);
    for(i=0; i<num; i++) {
	/* NO DUP - don't free! */
	rev = sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
	revoked = ossl_x509revoked_new(rev);
	rb_ary_push(ary, revoked);
    }

    return ary;
}
Пример #3
0
Файл: load.c Проект: 217/ruby
VALUE
rb_get_expanded_load_path(void)
{
    VALUE load_path = rb_get_load_path();
    VALUE ary;
    long i;

    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
	VALUE str = rb_check_string_type(RARRAY_PTR(load_path)[i]);
	if (NIL_P(str) || !rb_is_absolute_path(RSTRING_PTR(str)))
	    goto relative_path_found;
    }
    return load_path;

  relative_path_found:
    ary = rb_ary_new2(RARRAY_LEN(load_path));
    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
	VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil);
	rb_str_freeze(path);
	rb_ary_push(ary, path);
    }
    rb_obj_freeze(ary);
    return ary;
}
Пример #4
0
static VALUE value_to_ruby(value_t*v)
{
    switch(v->type) {
        case TYPE_VOID:
            return Qnil;
        break;
        case TYPE_FLOAT32:
            return rb_float_new(v->f32);
        break;
        case TYPE_INT32:
            return INT2FIX(v->i32);
        break;
        case TYPE_BOOLEAN:
            if(v->b) {
                return Qtrue;
            } else {
                return Qfalse;
            }
        break;
        case TYPE_STRING: {
            return rb_str_new2(v->str);
        }
        break;
        case TYPE_ARRAY: {
            volatile VALUE a = rb_ary_new2(v->length);
            int i;
            for(i=0;i<v->length;i++) {
                rb_ary_store(a, i, value_to_ruby(v->data[i]));
            }
            return a;
        }
        break;
        default:
            return Qnil;
    }
}
Пример #5
0
VALUE
rb_struct_define_without_accessor(const char *class_name, VALUE super, rb_alloc_func_t alloc, ...)
{
    VALUE klass;
    va_list ar;
    VALUE members;
    long i;
    char *name;

    members = rb_ary_new2(0);
    va_start(ar, alloc);
    i = 0;
    while ((name = va_arg(ar, char*)) != NULL) {
        rb_ary_push(members, ID2SYM(rb_intern(name)));
    }
    va_end(ar);
    OBJ_FREEZE(members);

    if (class_name) {
        klass = rb_define_class(class_name, super);
    }
    else {
	klass = rb_class_new(super);
	rb_make_metaclass(klass, RBASIC(super)->klass);
	rb_class_inherited(super, klass);
    }

    rb_iv_set(klass, "__size__", LONG2NUM(RARRAY_LEN(members)));
    rb_iv_set(klass, "__members__", members);

    rb_objc_define_method(*(VALUE *)klass, "alloc",
	    alloc != NULL ? alloc : struct_alloc,
	    0);

    return klass;
}
Пример #6
0
static VALUE
attrary2rval(GArray *attrs)
{
    long i, len;
    VALUE rb_attrs, rb_class;

    len = attrs->len;
    rb_attrs = rb_ary_new2(len);
    rb_class = rb_const_get(rb_const_get(rb_cObject, rb_intern("Vte")), rb_intern("CharAttributes"));

    for (i = 0; i < len; i++) {
        VteCharAttributes *attr;
        attr = &g_array_index(attrs, VteCharAttributes, i);
        rb_ary_push(rb_attrs, rb_funcall(rb_class, id_new, 6,
                                         LONG2NUM(attr->row),
                                         LONG2NUM(attr->column),
                                         COLOR2RVAL(&(attr->fore)),
                                         COLOR2RVAL(&(attr->back)),
                                         CBOOL2RVAL(attr->underline),
                                         CBOOL2RVAL(attr->strikethrough)));
    }

    return rb_attrs;
}
Пример #7
0
static VALUE
fntype_initialize(int argc, VALUE* argv, VALUE self)
{
    FunctionType *fnInfo;
    ffi_status status;
    VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbOptions = Qnil;
    VALUE rbEnums = Qnil, rbConvention = Qnil, rbBlocking = Qnil;
#if defined(_WIN32) || defined(__WIN32__)
    VALUE rbConventionStr;
#endif
    int i, nargs;

    nargs = rb_scan_args(argc, argv, "21", &rbReturnType, &rbParamTypes, &rbOptions);
    if (nargs >= 3 && rbOptions != Qnil) {
        rbConvention = rb_hash_aref(rbOptions, ID2SYM(rb_intern("convention")));
        rbEnums = rb_hash_aref(rbOptions, ID2SYM(rb_intern("enums")));
        rbBlocking = rb_hash_aref(rbOptions, ID2SYM(rb_intern("blocking")));
    }

    Check_Type(rbParamTypes, T_ARRAY);

    Data_Get_Struct(self, FunctionType, fnInfo);
    fnInfo->parameterCount = RARRAY_LEN(rbParamTypes);
    fnInfo->parameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->parameterTypes));
    fnInfo->ffiParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(ffi_type *));
    fnInfo->nativeParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->nativeParameterTypes));
    fnInfo->rbParameterTypes = rb_ary_new2(fnInfo->parameterCount);
    fnInfo->rbEnums = rbEnums;
    fnInfo->blocking = RTEST(rbBlocking);
    fnInfo->hasStruct = false;

    for (i = 0; i < fnInfo->parameterCount; ++i) {
        VALUE entry = rb_ary_entry(rbParamTypes, i);
        VALUE type = rbffi_Type_Lookup(entry);

        if (!RTEST(type)) {
            VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
            rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
        }

        if (rb_obj_is_kind_of(type, rbffi_FunctionTypeClass)) {
            REALLOC_N(fnInfo->callbackParameters, VALUE, fnInfo->callbackCount + 1);
            fnInfo->callbackParameters[fnInfo->callbackCount++] = type;
        }

        if (rb_obj_is_kind_of(type, rbffi_StructByValueClass)) {
            fnInfo->hasStruct = true;
        }

        rb_ary_push(fnInfo->rbParameterTypes, type);
        Data_Get_Struct(type, Type, fnInfo->parameterTypes[i]);
        fnInfo->ffiParameterTypes[i] = fnInfo->parameterTypes[i]->ffiType;
        fnInfo->nativeParameterTypes[i] = fnInfo->parameterTypes[i]->nativeType;
    }

    fnInfo->rbReturnType = rbffi_Type_Lookup(rbReturnType);
    if (!RTEST(fnInfo->rbReturnType)) {
        VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
        rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
    }
    
    if (rb_obj_is_kind_of(fnInfo->rbReturnType, rbffi_StructByValueClass)) {
        fnInfo->hasStruct = true;
    }

    Data_Get_Struct(fnInfo->rbReturnType, Type, fnInfo->returnType);
    fnInfo->ffiReturnType = fnInfo->returnType->ffiType;


#if defined(_WIN32) || defined(__WIN32__)
    rbConventionStr = (rbConvention != Qnil) ? rb_funcall2(rbConvention, rb_intern("to_s"), 0, NULL) : Qnil;
    fnInfo->abi = (rbConventionStr != Qnil && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0)
            ? FFI_STDCALL : FFI_DEFAULT_ABI;
#else
    fnInfo->abi = FFI_DEFAULT_ABI;
#endif

    status = ffi_prep_cif(&fnInfo->ffi_cif, fnInfo->abi, fnInfo->parameterCount,
            fnInfo->ffiReturnType, fnInfo->ffiParameterTypes);
    switch (status) {
        case FFI_BAD_ABI:
            rb_raise(rb_eArgError, "Invalid ABI specified");
        case FFI_BAD_TYPEDEF:
            rb_raise(rb_eArgError, "Invalid argument type specified");
        case FFI_OK:
            break;
        default:
            rb_raise(rb_eArgError, "Unknown FFI error");
    }

    fnInfo->invoke = rbffi_GetInvoker(fnInfo);

    return self;
}
Пример #8
0
VALUE rb_curl_easy_error(CURLcode code) {
  VALUE exclz;
  const char *exmsg = NULL;
  VALUE results;

  switch (code) {
    case CURLE_OK:                      /* 0 */
      exclz = eCurlErrOK;
      break;
    case CURLE_UNSUPPORTED_PROTOCOL:    /* 1 */
      exclz = eCurlErrUnsupportedProtocol;
      break;
    case CURLE_FAILED_INIT:             /* 2 */
      exclz = eCurlErrFailedInit;
      break;
    case CURLE_URL_MALFORMAT:           /* 3 */
      exclz = eCurlErrMalformedURL;
      break;
#ifdef HAVE_CURLE_NOT_BUILT_IN
    case CURLE_NOT_BUILT_IN:            /* 4 - [was obsoleted in August 2007 for 7.17.0, reused in April 2011 for 7.21.5] */
      exclz = eCurlErrNotBuiltIn;
      break;
#else
    case CURLE_URL_MALFORMAT_USER:      /* 4 (NOT USED) */
      exclz = eCurlErrMalformedURLUser;
      break;
#endif
    case CURLE_COULDNT_RESOLVE_PROXY:   /* 5 */
      exclz = eCurlErrProxyResolution;
      break;
    case CURLE_COULDNT_RESOLVE_HOST:    /* 6 */
      exclz = eCurlErrHostResolution;
      break;
    case CURLE_COULDNT_CONNECT:         /* 7 */
      exclz = eCurlErrConnectFailed;
      break;
    case CURLE_FTP_WEIRD_SERVER_REPLY:  /* 8 */
      exclz = eCurlErrFTPWierdReply;
      break;
    case CURLE_FTP_ACCESS_DENIED:       /* 9 denied due to lack of access. */
      exclz = eCurlErrFTPAccessDenied;
      break;
    case CURLE_FTP_USER_PASSWORD_INCORRECT: /* 10 */
      exclz = eCurlErrFTPBadPassword;
      break;
    case CURLE_FTP_WEIRD_PASS_REPLY:    /* 11 */
      exclz = eCurlErrFTPWierdPassReply;
      break;
    case CURLE_FTP_WEIRD_USER_REPLY:    /* 12 */
      exclz = eCurlErrFTPWierdUserReply;
      break;
    case CURLE_FTP_WEIRD_PASV_REPLY:    /* 13 */
      exclz = eCurlErrFTPWierdPasvReply;
      break;
    case CURLE_FTP_WEIRD_227_FORMAT:    /* 14 */
      exclz = eCurlErrFTPWierd227Format;
      break;
    case CURLE_FTP_CANT_GET_HOST:       /* 15 */
      exclz = eCurlErrFTPCantGetHost;
      break;
    case CURLE_FTP_CANT_RECONNECT:      /* 16 */
      exclz = eCurlErrFTPCantReconnect;
      break;
    case CURLE_FTP_COULDNT_SET_BINARY:  /* 17 */
      exclz = eCurlErrFTPCouldntSetBinary;
      break;
    case CURLE_PARTIAL_FILE:            /* 18 */
      exclz = eCurlErrPartialFile;
      break;
    case CURLE_FTP_COULDNT_RETR_FILE:   /* 19 */
      exclz = eCurlErrFTPCouldntRetrFile;
      break;
    case CURLE_FTP_WRITE_ERROR:         /* 20 */
      exclz = eCurlErrFTPWrite;
      break;
    case CURLE_FTP_QUOTE_ERROR:         /* 21 */
      exclz = eCurlErrFTPQuote;
      break;
    case CURLE_HTTP_RETURNED_ERROR:     /* 22 */
      exclz = eCurlErrHTTPFailed;
      break;
    case CURLE_WRITE_ERROR:             /* 23 */
      exclz = eCurlErrWriteError;
      break;
    case CURLE_MALFORMAT_USER:          /* 24 - NOT USED */
      exclz = eCurlErrMalformedUser;
      break;
    case CURLE_FTP_COULDNT_STOR_FILE:   /* 25 - failed FTP upload */
      exclz = eCurlErrFTPCouldntStorFile;
      break;
    case CURLE_READ_ERROR:              /* 26 - could open/read from file */
      exclz = eCurlErrReadError;
      break;
    case CURLE_OUT_OF_MEMORY:           /* 27 */
      exclz = eCurlErrOutOfMemory;
      break;
    case CURLE_OPERATION_TIMEOUTED:     /* 28 - the timeout time was reached */
      exclz = eCurlErrTimeout;
      break;
    case CURLE_FTP_COULDNT_SET_ASCII:   /* 29 - TYPE A failed */
      exclz = eCurlErrFTPCouldntSetASCII;
      break;
    case CURLE_FTP_PORT_FAILED:         /* 30 - FTP PORT operation failed */
      exclz = eCurlErrFTPPortFailed;
      break;
    case CURLE_FTP_COULDNT_USE_REST:    /* 31 - the REST command failed */
      exclz = eCurlErrFTPCouldntUseRest;
      break;
    case CURLE_FTP_COULDNT_GET_SIZE:    /* 32 - the SIZE command failed */
      exclz = eCurlErrFTPCouldntGetSize;
      break;
    case CURLE_HTTP_RANGE_ERROR:        /* 33 - RANGE "command" didn't work */
      exclz = eCurlErrHTTPRange;
      break;
    case CURLE_HTTP_POST_ERROR:         /* 34 */
      exclz = eCurlErrHTTPPost;
      break;
    case CURLE_SSL_CONNECT_ERROR:       /* 35 - wrong when connecting with SSL */
      exclz = eCurlErrSSLConnectError;
      break;
    case CURLE_BAD_DOWNLOAD_RESUME:     /* 36 - couldn't resume download */
      exclz = eCurlErrBadResume;
      break;
    case CURLE_FILE_COULDNT_READ_FILE:  /* 37 */
      exclz = eCurlErrFileCouldntRead;
      break;
    case CURLE_LDAP_CANNOT_BIND:        /* 38 */
      exclz = eCurlErrLDAPCouldntBind;
      break;
    case CURLE_LDAP_SEARCH_FAILED:      /* 39 */
      exclz = eCurlErrLDAPSearchFailed;
      break;
    case CURLE_LIBRARY_NOT_FOUND:       /* 40 */
      exclz = eCurlErrLibraryNotFound;
      break;
    case CURLE_FUNCTION_NOT_FOUND:      /* 41 */
      exclz = eCurlErrFunctionNotFound;
      break;
    case CURLE_ABORTED_BY_CALLBACK:     /* 42 */
      exclz = eCurlErrAbortedByCallback;
      break;
    case CURLE_BAD_FUNCTION_ARGUMENT:   /* 43 */
      exclz = eCurlErrBadFunctionArgument;
      break;
    case CURLE_BAD_CALLING_ORDER:       /* 44 - NOT USED */
      exclz = eCurlErrBadCallingOrder;
      break;
    case CURLE_INTERFACE_FAILED:        /* 45 - CURLOPT_INTERFACE failed */
      exclz = eCurlErrInterfaceFailed;
      break;
    case CURLE_BAD_PASSWORD_ENTERED:    /* 46 - NOT USED */
      exclz = eCurlErrBadPasswordEntered;
      break;
    case CURLE_TOO_MANY_REDIRECTS:      /* 47 - catch endless re-direct loops */
      exclz = eCurlErrTooManyRedirects;
      break;
    case CURLE_UNKNOWN_TELNET_OPTION:   /* 48 - User specified an unknown option */
      exclz = eCurlErrTelnetUnknownOption;
      break;
    case CURLE_TELNET_OPTION_SYNTAX:    /* 49 - Malformed telnet option */
      exclz = eCurlErrTelnetBadOptionSyntax;
      break;
#ifdef HAVE_CURLE_OBSOLETE
    case CURLE_OBSOLETE:                /* 50 - NOT USED */
      exclz = eCurlErrObsolete;
      break;
#endif
    case CURLE_SSL_PEER_CERTIFICATE:    /* 51 - peer's certificate wasn't ok */
      exclz = eCurlErrSSLPeerCertificate;
      break;
    case CURLE_GOT_NOTHING:             /* 52 - when this is a specific error */
      exclz = eCurlErrGotNothing;
      break;
    case CURLE_SSL_ENGINE_NOTFOUND:     /* 53 - SSL crypto engine not found */
      exclz = eCurlErrSSLEngineNotFound;
      break;
    case CURLE_SSL_ENGINE_SETFAILED:    /* 54 - can not set SSL crypto engine as default */
      exclz = eCurlErrSSLEngineSetFailed;
      break;
    case CURLE_SEND_ERROR:              /* 55 - failed sending network data */
      exclz = eCurlErrSendError;
      break;
    case CURLE_RECV_ERROR:              /* 56 - failure in receiving network data */
      exclz = eCurlErrRecvError;
      break;
    case CURLE_SHARE_IN_USE:            /* 57 - share is in use */
      exclz = eCurlErrShareInUse;
      break;
    case CURLE_SSL_CERTPROBLEM:         /* 58 - problem with the local certificate */
      exclz = eCurlErrSSLCertificate;
      break;
    case CURLE_SSL_CIPHER:              /* 59 - couldn't use specified cipher */
      exclz = eCurlErrSSLCipher;
      break;
    case CURLE_SSL_CACERT:              /* 60 - problem with the CA cert (path?) */
      exclz = eCurlErrSSLCACertificate;
      break;
    case CURLE_BAD_CONTENT_ENCODING:    /* 61 - Unrecognized transfer encoding */
      exclz = eCurlErrBadContentEncoding;
      break;
    case CURLE_LDAP_INVALID_URL:        /* 62 - Invalid LDAP URL */
      exclz = eCurlErrLDAPInvalidURL;
      break;
    case CURLE_FILESIZE_EXCEEDED:       /* 63 - Maximum file size exceeded */
      exclz = eCurlErrFileSizeExceeded;
      break;
    case CURLE_FTP_SSL_FAILED:          /* 64 - Requested FTP SSL level failed */
      exclz = eCurlErrFTPSSLFailed;
      break;
#ifdef HAVE_CURLE_SEND_FAIL_REWIND
    case CURLE_SEND_FAIL_REWIND:        /* 65 - Sending the data requires a rewind that failed */
      exclz = eCurlErrSendFailedRewind;
      break;
#endif
#ifdef HAVE_CURLE_SSL_ENGINE_INITFAILED
    case CURLE_SSL_ENGINE_INITFAILED:   /* 66 - failed to initialise ENGINE */
      exclz = eCurlErrSSLEngineInitFailed;
      break;
#endif
#ifdef HAVE_CURLE_LOGIN_DENIED
    case CURLE_LOGIN_DENIED:            /* 67 - user, password or similar was not accepted and we failed to login */
      exclz = eCurlErrLoginDenied;
      break;
#endif

      // recent additions, may not be present in all supported versions
#ifdef HAVE_CURLE_TFTP_NOTFOUND
    case CURLE_TFTP_NOTFOUND:           /* 68 - file not found on server */
      exclz = eCurlErrTFTPNotFound;
      break;
#endif
#ifdef HAVE_CURLE_TFTP_PERM
    case CURLE_TFTP_PERM:               /* 69 - permission problem on server */
      exclz = eCurlErrTFTPPermission;
      break;
#endif
#ifdef HAVE_CURLE_TFTP_DISKFULL
    case CURLE_TFTP_DISKFULL:           /* 70 - out of disk space on server */
      exclz = eCurlErrTFTPDiskFull;
      break;
#endif
#ifdef HAVE_CURLE_TFTP_ILLEGAL
    case CURLE_TFTP_ILLEGAL:            /* 71 - Illegal TFTP operation */
      exclz = eCurlErrTFTPIllegalOperation;
      break;
#endif
#ifdef HAVE_CURLE_TFTP_UNKNOWNID
    case CURLE_TFTP_UNKNOWNID:          /* 72 - Unknown transfer ID */
      exclz = eCurlErrTFTPUnknownID;
      break;
#endif
#ifdef HAVE_CURLE_TFTP_EXISTS
    case CURLE_TFTP_EXISTS:             /* 73 - File already exists */
      exclz = eCurlErrTFTPFileExists;
      break;
#endif
#ifdef HAVE_CURLE_TFTP_NOSUCHUSER
    case CURLE_TFTP_NOSUCHUSER:         /* 74 - No such user */
      exclz = eCurlErrTFTPNotFound;
      break;
#endif
#ifdef HAVE_CURLE_CONV_FAILED
    case CURLE_CONV_FAILED:             /* 75 - conversion failed */
      exclz = eCurlErrConvFailed;
      break;
#endif
#ifdef HAVE_CURLE_CONV_REQD
    case CURLE_CONV_REQD:               /* 76 - caller must register conversion
                                                callbacks using curl_easy_setopt options
                                                CURLOPT_CONV_FROM_NETWORK_FUNCTION,
                                                CURLOPT_CONV_TO_NETWORK_FUNCTION, and
                                                CURLOPT_CONV_FROM_UTF8_FUNCTION */
      exclz = eCurlErrConvReqd;
      break;
#endif
#ifdef HAVE_CURLE_SSL_CACERT_BADFILE
    case CURLE_SSL_CACERT_BADFILE:      /* 77 - could not load CACERT file, missing
                                                or wrong format */
      exclz = eCurlErrSSLCacertBadfile;
      break;
#endif
#ifdef  HAVE_CURLE_REMOTE_FILE_NOT_FOUND
    case CURLE_REMOTE_FILE_NOT_FOUND:   /* 78 - remote file not found */
      exclz = eCurlErrRemoteFileNotFound;
      break;
#endif
#ifdef  HAVE_CURLE_SSH
    case CURLE_SSH:                     /* 79 - error from the SSH layer, somewhat
                                    generic so the error message will be of
                                    interest when this has happened */
      exclz = eCurlErrSSH;
      break;
#endif
#ifdef  HAVE_CURLE_SSL_SHUTDOWN_FAILED
    case CURLE_SSL_SHUTDOWN_FAILED:     /* 80 - Failed to shut down the SSL
                                    connection */
      exclz = eCurlErrSSLShutdownFailed;
      break;
#endif
#ifdef  HAVE_CURLE_AGAIN
    case CURLE_AGAIN:                   /* 81 - socket is not ready for send/recv,
                                    wait till it's ready and try again (Added
                                    in 7.18.2) */
      exclz = eCurlErrAgain;
      break;
#endif
#ifdef  HAVE_CURLE_SSL_CRL_BADFILE
    case CURLE_SSL_CRL_BADFILE:         /* 82 - could not load CRL file, missing or
                                    wrong format (Added in 7.19.0) */
      exclz = eCurlErrSSLCRLBadfile;
      break;
#endif
#ifdef  HAVE_CURLE_SSL_ISSUER_ERROR
    case CURLE_SSL_ISSUER_ERROR:        /* 83 - Issuer check failed.  (Added in
                                    7.19.0) */
      exclz = eCurlErrSSLIssuerError;
      break;
#endif
    default:
      exclz = eCurlErrError;
      exmsg = "Unknown error result from libcurl";
  }

  if (!exmsg) {
    exmsg = curl_easy_strerror(code);
  }

  results = rb_ary_new2(2);
  rb_ary_push(results, exclz);
  rb_ary_push(results, rb_str_new2(exmsg));
  return results;
}
Пример #9
0
static VALUE rb_gsl_deriv_eval(VALUE obj, VALUE xx, VALUE hh,
                               int (*deriv)(const gsl_function *,
                                            double, double,
                                            double *, double *))
{
  gsl_function *f = NULL;
  double result, abserr, h;
  VALUE x, ary, aerr;
  gsl_vector *v = NULL, *vnew = NULL, *verr = NULL;
  gsl_matrix *m = NULL, *mnew = NULL, *merr = NULL;
  size_t n, i, j;
  int status;
  Need_Float(hh);
  Data_Get_Struct(obj, gsl_function, f);
  h = NUM2DBL(hh);
  if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
  switch (TYPE(xx)) {
  case T_FIXNUM:
  case T_BIGNUM:
  case T_FLOAT:
    status = (*deriv)(f, NUM2DBL(xx), h, &result, &abserr);
    return rb_ary_new3(3, rb_float_new(result), rb_float_new(abserr), INT2FIX(status));
    break;
  case T_ARRAY:
    //    n = RARRAY(xx)->len;
    n = RARRAY_LEN(xx);
    ary = rb_ary_new2(n);
    aerr = rb_ary_new2(n);
    for (i = 0; i < n; i++) {
      x = rb_ary_entry(xx, i);
      Need_Float(x);
      (*deriv)(f, NUM2DBL(x), h, &result, &abserr);
      rb_ary_store(ary, i, rb_float_new(result));
      rb_ary_store(aerr, i, rb_float_new(abserr));
    }
    return rb_ary_new3(2, ary, aerr);
    break;
  default:
#ifdef HAVE_NARRAY_H
    if (NA_IsNArray(xx)) {
      struct NARRAY *na;
      double *ptr1, *ptr2, *ptr3;
      VALUE ary2, ary3;
      GetNArray(xx, na);
      n = na->total;
      ptr1 = (double*) na->ptr;
      ary2 = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
      ary3 = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
      ptr2 = NA_PTR_TYPE(ary2, double*);
      ptr3 = NA_PTR_TYPE(ary3, double*);
      for (i = 0; i < n; i++) {
        (*deriv)(f, ptr1[i], h, &result, &abserr);
        ptr2[i] = result;
        ptr3[i] = abserr;
      }
      return rb_ary_new3(2, ary2, ary3);
    }
#endif
    if (VECTOR_P(xx)) {
      Data_Get_Struct(xx, gsl_vector, v);
      vnew = gsl_vector_alloc(v->size);
      verr = gsl_vector_alloc(v->size);
      for (i = 0; i < v->size; i++) {
        (*deriv)(f, gsl_vector_get(v, i), h, &result, &abserr);
        gsl_vector_set(vnew, i, result);
        gsl_vector_set(verr, i, abserr);
      }
      return rb_ary_new3(2,
                         Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew),
                         Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, verr));
    } else if (MATRIX_P(xx)) {
      Data_Get_Struct(xx, gsl_matrix, m);
      mnew = gsl_matrix_alloc(m->size1, m->size2);
      merr = gsl_matrix_alloc(m->size1, m->size2);
      for (i = 0; i < m->size1; i++) {
        for (j = 0; j < m->size2; j++) {
          (*deriv)(f, gsl_matrix_get(m, i, j), h, &result, &abserr);
          gsl_matrix_set(mnew, i, j, result);
          gsl_matrix_set(merr, i, j, abserr);
        }
      }
      return rb_ary_new3(2,
                         Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew),
                         Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, merr));
    } else {
      rb_raise(rb_eTypeError, "wrong argument type");
    }
    break;
  }
  return Qnil; /* never reach here */
}
Пример #10
0
static VALUE rb_gsl_cheb_eval_n_err(VALUE obj, VALUE nn, VALUE xx)
{
  gsl_cheb_series *p = NULL;
  double result, err;
  VALUE x, ary, aerr;
  size_t n, order, i, j;
  gsl_vector *v, *vnew, *verr;
  gsl_matrix *m, *mnew, *merr;
  CHECK_FIXNUM(nn);
  order = FIX2INT(nn);
  Data_Get_Struct(obj, gsl_cheb_series, p);
  if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
  switch (TYPE(xx)) {
  case T_FIXNUM:
  case T_BIGNUM:
  case T_FLOAT:
    gsl_cheb_eval_n_err(p, order, NUM2DBL(xx), &result, &err);
    return rb_ary_new3(2, rb_float_new(result), rb_float_new(err));
    break;
  case T_ARRAY:
    //    n = RARRAY(xx)->len;
    n = RARRAY_LEN(xx);
    ary = rb_ary_new2(n);
    aerr = rb_ary_new2(n);
    for (i = 0; i < n; i++) {
      x = rb_ary_entry(xx, i);
      Need_Float(xx);
      gsl_cheb_eval_n_err(p, order, NUM2DBL(x), &result, &err);
      rb_ary_store(ary, i, rb_float_new(result));
      rb_ary_store(aerr, i, rb_float_new(err));
    }
    return rb_ary_new3(2, ary, aerr);
    break;
  default:
#ifdef HAVE_NARRAY_H
    if (NA_IsNArray(xx)) {
      struct NARRAY *na;
      double *ptr1, *ptr2, *ptr3;
      GetNArray(xx, na);
      ptr1 = (double*) na->ptr;
      n = na->total;
      ary = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
      aerr = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
      ptr2 = NA_PTR_TYPE(ary,double*);
      ptr3 = NA_PTR_TYPE(aerr,double*);
      for (i = 0; i < n; i++) {
        gsl_cheb_eval_n_err(p, order, ptr1[i], &result, &err);
        ptr2[i] = result;
        ptr3[i] = err;
      }
      return rb_ary_new3(2, ary, aerr);
    }
#endif
    if (VECTOR_P(xx)) {
      Data_Get_Struct(xx, gsl_vector, v);
      vnew = gsl_vector_alloc(v->size);
      verr = gsl_vector_alloc(v->size);
      for (i = 0; i < v->size; i++) {
        gsl_cheb_eval_n_err(p, order, gsl_vector_get(v, i), &result, &err);
        gsl_vector_set(vnew, i, result);
        gsl_vector_set(verr, i, err);
      }
      return rb_ary_new3(2,
                         Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew),
                         Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, verr));
    } else if (MATRIX_P(xx)) {
      Data_Get_Struct(xx, gsl_matrix, m);
      mnew = gsl_matrix_alloc(m->size1, m->size2);
      merr = gsl_matrix_alloc(m->size1, m->size2);
      for (i = 0; i < m->size1; i++) {
        for (j = 0; j < m->size2; j++) {
          gsl_cheb_eval_n_err(p, order, gsl_matrix_get(m, i, j), &result, &err);
          gsl_matrix_set(mnew, i, j, result);
          gsl_matrix_set(merr, i, j, err);
        }
      }
      return rb_ary_new3(2,
                         Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew),
                         Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, merr));
    } else {
      rb_raise(rb_eTypeError, "wrong argument type");
    }
    break;
  }
  return Qnil;   /* never reach here */
}
Пример #11
0
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
  result_each_args args;
  VALUE defaults, opts, block, (*fetch_row_func)(VALUE, MYSQL_FIELD *fields, const result_each_args *args);
  ID db_timezone, app_timezone, dbTz, appTz;
  int symbolizeKeys, asArray, castBool, cacheRows, cast;

  GET_RESULT(self);

  if (wrapper->stmt_wrapper && wrapper->stmt_wrapper->closed) {
    rb_raise(cMysql2Error, "Statement handle already closed");
  }

  defaults = rb_iv_get(self, "@query_options");
  Check_Type(defaults, T_HASH);
  if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
    opts = rb_funcall(defaults, intern_merge, 1, opts);
  } else {
    opts = defaults;
  }

  symbolizeKeys = RTEST(rb_hash_aref(opts, sym_symbolize_keys));
  asArray       = rb_hash_aref(opts, sym_as) == sym_array;
  castBool      = RTEST(rb_hash_aref(opts, sym_cast_booleans));
  cacheRows     = RTEST(rb_hash_aref(opts, sym_cache_rows));
  cast          = RTEST(rb_hash_aref(opts, sym_cast));

  if (wrapper->is_streaming && cacheRows) {
    rb_warn(":cache_rows is ignored if :stream is true");
  }

  if (wrapper->stmt_wrapper && !cacheRows && !wrapper->is_streaming) {
    rb_warn(":cache_rows is forced for prepared statements (if not streaming)");
  }

  if (wrapper->stmt_wrapper && !cast) {
    rb_warn(":cast is forced for prepared statements");
  }

  dbTz = rb_hash_aref(opts, sym_database_timezone);
  if (dbTz == sym_local) {
    db_timezone = intern_local;
  } else if (dbTz == sym_utc) {
    db_timezone = intern_utc;
  } else {
    if (!NIL_P(dbTz)) {
      rb_warn(":database_timezone option must be :utc or :local - defaulting to :local");
    }
    db_timezone = intern_local;
  }

  appTz = rb_hash_aref(opts, sym_application_timezone);
  if (appTz == sym_local) {
    app_timezone = intern_local;
  } else if (appTz == sym_utc) {
    app_timezone = intern_utc;
  } else {
    app_timezone = Qnil;
  }

  if (wrapper->lastRowProcessed == 0 && !wrapper->is_streaming) {
    wrapper->numberOfRows = wrapper->stmt_wrapper ? mysql_stmt_num_rows(wrapper->stmt_wrapper->stmt) : mysql_num_rows(wrapper->result);
    if (wrapper->numberOfRows == 0) {
      rb_mysql_result_free_result(wrapper);
      wrapper->rows = rb_ary_new();
      return wrapper->rows;
    }
    wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
  }

  // Backward compat
  args.symbolizeKeys = symbolizeKeys;
  args.asArray = asArray;
  args.castBool = castBool;
  args.cacheRows = cacheRows;
  args.cast = cast;
  args.db_timezone = db_timezone;
  args.app_timezone = app_timezone;
  args.block_given = block;

  if (wrapper->stmt_wrapper) {
    fetch_row_func = rb_mysql_result_fetch_row_stmt;
  } else {
    fetch_row_func = rb_mysql_result_fetch_row;
  }

  return rb_mysql_result_each_(self, fetch_row_func, &args);
}
Пример #12
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;
}
Пример #13
0
static VALUE array_spec_rb_ary_new2(VALUE self, VALUE length) {
  return rb_ary_new2(NUM2LONG(length));
}
Пример #14
0
static VALUE
variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE rbReturnType, VALUE options)
{
    VariadicInvoker* invoker = NULL;
    VALUE retval = Qnil;
    VALUE convention = Qnil;
    VALUE fixed = Qnil;
#if defined(X86_WIN32)
    VALUE rbConventionStr;
#endif
    int i;

    Check_Type(options, T_HASH);
    convention = rb_hash_aref(options, ID2SYM(rb_intern("convention")));

    Data_Get_Struct(self, VariadicInvoker, invoker);
    invoker->rbEnums = rb_hash_aref(options, ID2SYM(rb_intern("enums")));
    invoker->rbAddress = rbFunction;
    invoker->function = rbffi_AbstractMemory_Cast(rbFunction, rbffi_PointerClass)->address;

#if defined(X86_WIN32)
    rbConventionStr = rb_funcall2(convention, rb_intern("to_s"), 0, NULL);
    invoker->abi = (RTEST(convention) && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0)
                   ? FFI_STDCALL : FFI_DEFAULT_ABI;
#else
    invoker->abi = FFI_DEFAULT_ABI;
#endif

    invoker->rbReturnType = rbffi_Type_Lookup(rbReturnType);
    if (!RTEST(invoker->rbReturnType)) {
        VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL);
        rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName));
    }

    Data_Get_Struct(rbReturnType, Type, invoker->returnType);

    invoker->paramCount = -1;

    fixed = rb_ary_new2(RARRAY_LEN(rbParameterTypes) - 1);
    for (i = 0; i < RARRAY_LEN(rbParameterTypes); ++i) {
        VALUE entry = rb_ary_entry(rbParameterTypes, i);
        VALUE rbType = rbffi_Type_Lookup(entry);
        Type* type;

        if (!RTEST(rbType)) {
            VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL);
            rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName));
        }
        Data_Get_Struct(rbType, Type, type);
        if (type->nativeType != NATIVE_VARARGS) {
            rb_ary_push(fixed, entry);
        }
    }
    /*
     * @fixed and @type_map are used by the parameter mangling ruby code
     */
    rb_iv_set(self, "@fixed", fixed);
    rb_iv_set(self, "@type_map", rb_hash_aref(options, ID2SYM(rb_intern("type_map"))));

    return retval;
}
Пример #15
0
static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
  VALUE defaults, opts, block;
  ID db_timezone, app_timezone, dbTz, appTz;
  mysql2_result_wrapper * wrapper;
  unsigned long i;
  const char * errstr;
  int symbolizeKeys = 0, asArray = 0, castBool = 0, cacheRows = 1, cast = 1, streaming = 0;
  MYSQL_FIELD * fields = NULL;

  GetMysql2Result(self, wrapper);

  defaults = rb_iv_get(self, "@query_options");
  Check_Type(defaults, T_HASH);
  if (rb_scan_args(argc, argv, "01&", &opts, &block) == 1) {
    opts = rb_funcall(defaults, intern_merge, 1, opts);
  } else {
    opts = defaults;
  }

  if (rb_hash_aref(opts, sym_symbolize_keys) == Qtrue) {
    symbolizeKeys = 1;
  }

  if (rb_hash_aref(opts, sym_as) == sym_array) {
    asArray = 1;
  }

  if (rb_hash_aref(opts, sym_cast_booleans) == Qtrue) {
    castBool = 1;
  }

  if (rb_hash_aref(opts, sym_cache_rows) == Qfalse) {
    cacheRows = 0;
  }

  if (rb_hash_aref(opts, sym_cast) == Qfalse) {
    cast = 0;
  }

  if(rb_hash_aref(opts, sym_stream) == Qtrue) {
    streaming = 1;
  }

  if(streaming && cacheRows) {
    rb_warn("cacheRows is ignored if streaming is true");
  }

  dbTz = rb_hash_aref(opts, sym_database_timezone);
  if (dbTz == sym_local) {
    db_timezone = intern_local;
  } else if (dbTz == sym_utc) {
    db_timezone = intern_utc;
  } else {
    if (!NIL_P(dbTz)) {
      rb_warn(":database_timezone option must be :utc or :local - defaulting to :local");
    }
    db_timezone = intern_local;
  }

  appTz = rb_hash_aref(opts, sym_application_timezone);
  if (appTz == sym_local) {
    app_timezone = intern_local;
  } else if (appTz == sym_utc) {
    app_timezone = intern_utc;
  } else {
    app_timezone = Qnil;
  }

  if (wrapper->lastRowProcessed == 0) {
    if (streaming) {
      /* We can't get number of rows if we're streaming, */
      /* until we've finished fetching all rows */
      wrapper->numberOfRows = 0;
      wrapper->rows = rb_ary_new();
    } else {
      wrapper->numberOfRows = mysql_num_rows(wrapper->result);
      if (wrapper->numberOfRows == 0) {
        wrapper->rows = rb_ary_new();
        return wrapper->rows;
      }
      wrapper->rows = rb_ary_new2(wrapper->numberOfRows);
    }
  }

  if (streaming) {
    if (!wrapper->streamingComplete) {
      VALUE row;

      fields = mysql_fetch_fields(wrapper->result);

      do {
        row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);

        if (block != Qnil && row != Qnil) {
          rb_yield(row);
          wrapper->lastRowProcessed++;
        }
      } while(row != Qnil);

      rb_mysql_result_free_result(wrapper);

      wrapper->numberOfRows = wrapper->lastRowProcessed;
      wrapper->streamingComplete = 1;

      // Check for errors, the connection might have gone out from under us
      // mysql_error returns an empty string if there is no error
      errstr = mysql_error(wrapper->client_wrapper->client);
      if (errstr[0]) {
        rb_raise(cMysql2Error, "%s", errstr);
      }
    } else {
      rb_raise(cMysql2Error, "You have already fetched all the rows for this query and streaming is true. (to reiterate you must requery).");
    }
  } else {
    if (cacheRows && wrapper->lastRowProcessed == wrapper->numberOfRows) {
      /* we've already read the entire dataset from the C result into our */
      /* internal array. Lets hand that over to the user since it's ready to go */
      for (i = 0; i < wrapper->numberOfRows; i++) {
        rb_yield(rb_ary_entry(wrapper->rows, i));
      }
    } else {
      unsigned long rowsProcessed = 0;
      rowsProcessed = RARRAY_LEN(wrapper->rows);
      fields = mysql_fetch_fields(wrapper->result);

      for (i = 0; i < wrapper->numberOfRows; i++) {
        VALUE row;
        if (cacheRows && i < rowsProcessed) {
          row = rb_ary_entry(wrapper->rows, i);
        } else {
          row = rb_mysql_result_fetch_row(self, db_timezone, app_timezone, symbolizeKeys, asArray, castBool, cast, fields);
          if (cacheRows) {
            rb_ary_store(wrapper->rows, i, row);
          }
          wrapper->lastRowProcessed++;
        }

        if (row == Qnil) {
          /* we don't need the mysql C dataset around anymore, peace it */
          rb_mysql_result_free_result(wrapper);
          return Qnil;
        }

        if (block != Qnil) {
          rb_yield(row);
        }
      }
      if (wrapper->lastRowProcessed == wrapper->numberOfRows) {
        /* we don't need the mysql C dataset around anymore, peace it */
        rb_mysql_result_free_result(wrapper);
      }
    }
  }

  return wrapper->rows;
}
Пример #16
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;
}
Пример #17
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;
  }
}
Пример #18
0
static VALUE read_anything(VALUE protocol, int ttype, VALUE field_info) {
  VALUE result = Qnil;

  if (ttype == TTYPE_BOOL) {
    result = mt->read_bool(protocol);
  } else if (ttype == TTYPE_BYTE) {
    result = mt->read_byte(protocol);
  } else if (ttype == TTYPE_I16) {
    result = mt->read_i16(protocol);
  } else if (ttype == TTYPE_I32) {
    result = mt->read_i32(protocol);
  } else if (ttype == TTYPE_I64) {
    result = mt->read_i64(protocol);
  } else if (ttype == TTYPE_STRING) {
    result = mt->read_string(protocol);
  } else if (ttype == TTYPE_DOUBLE) {
    result = mt->read_double(protocol);
  } else if (ttype == TTYPE_STRUCT) {
    VALUE klass = rb_hash_aref(field_info, class_sym);
    result = rb_class_new_instance(0, NULL, klass);
    rb_thrift_struct_read(result, protocol);
  } else if (ttype == TTYPE_MAP) {
    int i;

    VALUE map_header = mt->read_map_begin(protocol);
    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));

    VALUE key_info = rb_hash_aref(field_info, key_sym);
    VALUE value_info = rb_hash_aref(field_info, value_sym);

    result = rb_hash_new();

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

      key = read_anything(protocol, key_ttype, key_info);
      val = read_anything(protocol, value_ttype, value_info);

      rb_hash_aset(result, key, val);
    }

    mt->read_map_end(protocol);
  } else if (ttype == TTYPE_LIST) {
    int i;

    VALUE list_header = mt->read_list_begin(protocol);
    int element_ttype = FIX2INT(rb_ary_entry(list_header, 0));
    int num_elements = FIX2INT(rb_ary_entry(list_header, 1));
    result = rb_ary_new2(num_elements);

    for (i = 0; i < num_elements; ++i) {
      rb_ary_push(result, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
    }


    mt->read_list_end(protocol);
  } else if (ttype == TTYPE_SET) {
    VALUE items;
    int i;

    VALUE set_header = mt->read_set_begin(protocol);
    int element_ttype = FIX2INT(rb_ary_entry(set_header, 0));
    int num_elements = FIX2INT(rb_ary_entry(set_header, 1));
    items = rb_ary_new2(num_elements);

    for (i = 0; i < num_elements; ++i) {
      rb_ary_push(items, read_anything(protocol, element_ttype, rb_hash_aref(field_info, element_sym)));
    }


    mt->read_set_end(protocol);

    result = rb_class_new_instance(1, &items, rb_cSet);
  } else {
    rb_raise(rb_eNotImpError, "read_anything not implemented for type %d!", ttype);
  }

  return result;
}
Пример #19
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;
}
Пример #20
0
static VALUE rb_gsl_math_eval2(double (*func)(const double, const double), VALUE xx,
                               VALUE yy)
{
  VALUE x, y, ary;
  size_t i, j, size;
  gsl_vector *v = NULL, *v2 = NULL, *vnew = NULL;
  gsl_matrix *m = NULL, *m2 = NULL, *mnew = NULL;
  if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
  switch (TYPE(xx)) {
  case T_FIXNUM:
  case T_BIGNUM:
  case T_FLOAT:
    Need_Float(yy);
    return rb_float_new((*func)(NUM2DBL(xx), NUM2DBL(yy)));
    break;
  case T_ARRAY:
    Check_Type(yy, T_ARRAY);
    size = RARRAY_LEN(xx);
    //    if (size != RARRAY(yy)->len) rb_raise(rb_eRuntimeError, "array sizes are different.");
    if ((int) size != RARRAY_LEN(yy)) rb_raise(rb_eRuntimeError, "array sizes are different.");
    ary = rb_ary_new2(size);
    for (i = 0; i < size; i++) {
      x = rb_ary_entry(xx, i);
      y = rb_ary_entry(yy, i);
      Need_Float(x); Need_Float(y);
      //      rb_ary_store(ary, i, rb_float_new((*func)(RFLOAT(x)->value, RFLOAT(y)->value)));
      rb_ary_store(ary, i, rb_float_new((*func)(NUM2DBL(x), NUM2DBL(y))));
    }
    return ary;
    break;
  default:
#ifdef HAVE_NARRAY_H
    if (NA_IsNArray(xx)) {
      struct NARRAY *nax, *nay;
      double *ptr1, *ptr2, *ptr3;
      GetNArray(xx, nax);
      GetNArray(yy, nay);
      ptr1 = (double*) nax->ptr;
      ptr2 = (double*) nay->ptr;
      size = nax->total;
      ary = na_make_object(NA_DFLOAT, nax->rank, nax->shape, CLASS_OF(xx));
      ptr3 = NA_PTR_TYPE(ary, double*);
      for (i = 0; i < size; i++) ptr3[i] = (*func)(ptr1[i], ptr2[i]);
      return ary;
    }
#endif
    if (VECTOR_P(xx)) {
      CHECK_VECTOR(yy);
      Data_Get_Struct(xx, gsl_vector, v);
      Data_Get_Struct(yy, gsl_vector, v2);
      vnew = gsl_vector_alloc(v->size);
      for (i = 0; i < v->size; i++) {
        gsl_vector_set(vnew, i, (*func)(gsl_vector_get(v, i), gsl_vector_get(v2, i)));
      }
      return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
    } else if (MATRIX_P(xx)) {
      CHECK_MATRIX(yy);
      Data_Get_Struct(xx, gsl_matrix, m);
      Data_Get_Struct(yy, gsl_matrix, m2);
      mnew = gsl_matrix_alloc(m->size1, m->size2);
      for (i = 0; i < m->size1; i++) {
        for (j = 0; j < m->size2; j++) {
          gsl_matrix_set(mnew, i, j, (*func)(gsl_matrix_get(m, i, j), gsl_matrix_get(m2, i, j)));
        }
      }
      return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
    } else {
      rb_raise(rb_eTypeError,
               "wrong argument type %s "
               "(Array or Vector or Matrix expected)", rb_class2name(CLASS_OF(xx)));
    }
    break;
  }
  /* never reach here */
  return Qnil;
}
Пример #21
0
VALUE ruby_libvirt_ary_new2_wrap(VALUE arg)
{
    return rb_ary_new2(*((int *)arg));
}
Пример #22
0
static VALUE rb_gsl_pow_int(VALUE obj, VALUE xx, VALUE nn)
{
  VALUE x, ary, argv[2];
  size_t i, j, size;
  int n;
  gsl_vector *v = NULL, *vnew = NULL;
  gsl_matrix *m = NULL, *mnew = NULL;

  if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
  switch (TYPE(xx)) {
  case T_FIXNUM:
  case T_BIGNUM:
  case T_FLOAT:
    return rb_float_new(gsl_pow_int(NUM2DBL(xx), FIX2INT(nn)));
    break;
  case T_ARRAY:
    CHECK_FIXNUM(nn);
    n = FIX2INT(nn);
    size = RARRAY_LEN(xx);
    ary = rb_ary_new2(size);
    for (i = 0; i < size; i++) {
      x = rb_ary_entry(xx, i);
      Need_Float(x);
      //      rb_ary_store(ary, i, rb_float_new(gsl_pow_int(RFLOAT(x)->value, n)));
      rb_ary_store(ary, i, rb_float_new(gsl_pow_int(NUM2DBL(x), n)));
    }
    return ary;
    break;
  default:
#ifdef HAVE_NARRAY_H
    if (NA_IsNArray(xx)) {
      struct NARRAY *na;
      double *ptr1, *ptr2;
      CHECK_FIXNUM(nn);
      n = FIX2INT(nn);
      GetNArray(xx, na);
      ptr1 = (double*) na->ptr;
      size = na->total;
      ary = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
      ptr2 = NA_PTR_TYPE(ary, double*);
      for (i = 0; i < size; i++) ptr2[i] = gsl_pow_int(ptr1[i], n);
      return ary;
    }
#endif
    if (VECTOR_P(xx)) {
      CHECK_FIXNUM(nn);
      n = FIX2INT(nn);
      Data_Get_Struct(xx, gsl_vector, v);
      vnew = gsl_vector_alloc(v->size);
      for (i = 0; i < v->size; i++) {
        gsl_vector_set(vnew, i, gsl_pow_int(gsl_vector_get(v, i), n));
      }
      return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
    } else if (MATRIX_P(xx)) {
      CHECK_FIXNUM(nn);
      n = FIX2INT(nn);
      Data_Get_Struct(xx, gsl_matrix, m);
      mnew = gsl_matrix_alloc(m->size1, m->size2);
      for (i = 0; i < m->size1; i++) {
        for (j = 0; j < m->size2; j++) {
          gsl_matrix_set(mnew, i, j, gsl_pow_int(gsl_matrix_get(m, i, j), n));
        }
      }
      return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
    } else if (COMPLEX_P(xx) || VECTOR_COMPLEX_P(xx) || MATRIX_COMPLEX_P(xx)) {
      argv[0] = xx;
      argv[1] = nn;
      return rb_gsl_complex_pow_real(2, argv, obj);
    } else {
      rb_raise(rb_eTypeError, "wrong argument type %s (Array or Vector or Matrix expected)", rb_class2name(CLASS_OF(xx)));
    }
    break;
  }
  /* never reach here */
  return Qnil;
}
Пример #23
0
static VALUE rb_gsl_cheb_eval(VALUE obj, VALUE xx)
{
  gsl_cheb_series *p = NULL;
  VALUE x, ary;
  size_t i, j, n;
  gsl_vector *v = NULL, *vnew = NULL;
  gsl_matrix *m = NULL, *mnew = NULL;
  Data_Get_Struct(obj, gsl_cheb_series, p);
  if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
  switch (TYPE(xx)) {
  case T_FIXNUM:
  case T_BIGNUM:
  case T_FLOAT:
    return rb_float_new(gsl_cheb_eval(p, NUM2DBL(xx)));
    break;
  case T_ARRAY:
    //    n = RARRAY(xx)->len;
    n = RARRAY_LEN(xx);
    ary = rb_ary_new2(n);
    for (i = 0; i < n; i++) {
      x = rb_ary_entry(xx, i);
      Need_Float(xx);
      rb_ary_store(ary, i, rb_float_new(gsl_cheb_eval(p, NUM2DBL(x))));
    }
    return ary;
    break;
  default:
#ifdef HAVE_NARRAY_H
    if (NA_IsNArray(xx)) {
      struct NARRAY *na;
      double *ptr1, *ptr2;
      GetNArray(xx, na);
      ptr1 = (double*) na->ptr;
      n = na->total;
      ary = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
      ptr2 = NA_PTR_TYPE(ary,double*);
      for (i = 0; i < n; i++) ptr2[i] = gsl_cheb_eval(p, ptr1[i]);
      return ary;
    }
#endif
    if (VECTOR_P(xx)) {
      Data_Get_Struct(xx, gsl_vector, v);
      vnew = gsl_vector_alloc(v->size);
      for (i = 0; i < v->size; i++) {
        gsl_vector_set(vnew, i, gsl_cheb_eval(p, gsl_vector_get(v, i)));
      }
      return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
    } else if (MATRIX_P(xx)) {
      Data_Get_Struct(xx, gsl_matrix, m);
      mnew = gsl_matrix_alloc(m->size1, m->size2);
      for (i = 0; i < m->size1; i++) {
        for (j = 0; j < m->size2; j++) {
          gsl_matrix_set(mnew, i, j, gsl_cheb_eval(p, gsl_matrix_get(m, i, j)));
        }
      }
      return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
    } else {
      rb_raise(rb_eTypeError, "wrong argument type");
    }
    break;
  }
  return Qnil;   /* never reach here */
}
Пример #24
0
static VALUE rb_gsl_interp_evaluate(VALUE obj, VALUE xxa, VALUE yya, VALUE xx,
				    double (*eval)(const gsl_interp *, const double [], 
						   const double [], double, 
						   gsl_interp_accel *))
{
  rb_gsl_interp *rgi = NULL;
  double *ptrx = NULL, *ptry = NULL;
  gsl_vector *v = NULL, *vnew = NULL;
  gsl_matrix *m = NULL, *mnew = NULL;
  VALUE ary, x;
  double val;
  size_t n, i, j, size, stridex, stridey;
#ifdef HAVE_NARRAY_H
  struct NARRAY *na = NULL;
  double *ptrz = NULL, *ptr = NULL;
#endif
  Data_Get_Struct(obj, rb_gsl_interp, rgi);
  ptrx = get_vector_ptr(xxa, &stridex, &size);
  if (size != rgi->p->size ){
    rb_raise(rb_eTypeError, "size mismatch (xa:%d != %d)",  (int) size, (int) rgi->p->size);
  }
  ptry = get_vector_ptr(yya, &stridey, &size);
  if (size != rgi->p->size ){
    rb_raise(rb_eTypeError, "size mismatch (ya:%d != %d)", (int) size, (int) rgi->p->size);
  }
  if (CLASS_OF(xx) == rb_cRange) xx = rb_gsl_range2ary(xx);
  switch (TYPE(xx)) {
  case T_FIXNUM:  case T_BIGNUM:  case T_FLOAT:
    Need_Float(xx);
    return rb_float_new((*eval)(rgi->p, ptrx, ptry, NUM2DBL(xx), rgi->a));
    break;
  case T_ARRAY:
    n = RARRAY(xx)->len;
    ary = rb_ary_new2(n);
    for (i = 0; i < n; i++) {
      x = rb_ary_entry(xx, i);
      Need_Float(x);
      val = (*eval)(rgi->p, ptrx, ptry, NUM2DBL(x), rgi->a);
      rb_ary_store(ary, i, rb_float_new(val));
    }
    return ary;
    break;
  default:
#ifdef HAVE_NARRAY_H
    if (NA_IsNArray(xx)) {
      GetNArray(xx, na);
      ptrz = (double*) na->ptr;
      ary = na_make_object(NA_DFLOAT, na->rank, na->shape, CLASS_OF(xx));
      ptr = NA_PTR_TYPE(ary, double*);
      for (i = 0; i < na->total; i++)
	ptr[i] = (*eval)(rgi->p, ptrx, ptry, ptrz[i], rgi->a);
      return ary;
    }
#endif
    if (VECTOR_P(xx)) {
      Data_Get_Struct(xx, gsl_vector, v);
      vnew = gsl_vector_alloc(v->size);
      for (i = 0; i < v->size; i++) {
	val = (*eval)(rgi->p, ptrx, ptry, gsl_vector_get(v, i), rgi->a);
	gsl_vector_set(vnew, i, val);
      }
      return Data_Wrap_Struct(cgsl_vector, 0, gsl_vector_free, vnew);
    } else if (MATRIX_P(xx)) {
      Data_Get_Struct(xx, gsl_matrix, m);
      mnew = gsl_matrix_alloc(m->size1, m->size2);
      for (i = 0; i < m->size1; i++) {
	for (j = 0; j < m->size2; j++) {
	  val = (*eval)(rgi->p, ptrx, ptry, gsl_matrix_get(m, i, j), rgi->a);
	  gsl_matrix_set(mnew, i, j, val);
	}
      }
      return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, mnew);
    } else {
      rb_raise(rb_eTypeError, "wrong argument type %s", rb_class2name(CLASS_OF(xx)));
    }
    break;
  }

  /* never reach here */
  return Qnil;
}
Пример #25
0
/*
 * Reads the specified list of items and returns their values and limits
 * state.
 *
 * @param item_array [Array<Array(String String String)>] An array
 *   consisting of [target name, packet name, item name]
 * @param value_types [Symbol|Array<Symbol>] How to convert the items before
 *   returning. A single symbol of {Packet::VALUE_TYPES}
 *   can be passed which will convert all items the same way. Or
 *   an array of symbols can be passed to control how each item is
 *   converted.
 * @return [Array, Array, Array] The first array contains the item values, the
 *   second their limits state, and the third the limits settings which includes
 *   red, yellow, and green (if given) limits values.
 */
static VALUE values_and_limits_states(int argc, VALUE* argv, VALUE self) {
  volatile VALUE item_array = Qnil;
  volatile VALUE value_types = Qnil;
  volatile VALUE items = Qnil;
  volatile VALUE states = Qnil;
  volatile VALUE settings = Qnil;
  volatile VALUE entry = Qnil;
  volatile VALUE target_name = Qnil;
  volatile VALUE packet_name = Qnil;
  volatile VALUE item_name = Qnil;
  volatile VALUE value_type = Qnil;
  volatile VALUE result = Qnil;
  volatile VALUE return_value = Qnil;
  volatile VALUE limits = Qnil;
  volatile VALUE limits_set = Qnil;
  volatile VALUE limits_values = Qnil;
  volatile VALUE limits_settings = Qnil;
  long length = 0;
  long value_types_length = 0;
  int index = 0;

  switch (argc) {
    case 1:
      item_array = argv[0];
      value_types = symbol_CONVERTED;
      break;
    case 2:
      item_array = argv[0];
      value_types = argv[1];
      break;
    default:
      /* Invalid number of arguments given */
      rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
      break;
  };

  items = rb_ary_new();
  /* Verify items is a nested array */
  entry = rb_ary_entry(item_array, index);
  if (TYPE(entry) != T_ARRAY) {
    rb_raise(rb_eArgError, "item_array must be a nested array consisting of [[tgt,pkt,item],[tgt,pkt,item],...]");
  }
  states = rb_ary_new();
  settings = rb_ary_new();
  limits_set = rb_funcall(cSystem, id_method_limits_set, 0);
  length = RARRAY_LEN(item_array);
  if (TYPE(value_types) == T_ARRAY) {
    value_types_length = RARRAY_LEN(value_types);
    if (length != value_types_length) {
      rb_raise(rb_eArgError, "Passed %ld items but only %ld value types", length, value_types_length);
    }

    for (index = 0; index < length; index++) {
      entry = rb_ary_entry(item_array, index);
      target_name = rb_ary_entry(entry, 0);
      packet_name = rb_ary_entry(entry, 1);
      item_name = rb_ary_entry(entry, 2);
      value_type = rb_ary_entry(value_types, index);
      value_type = rb_funcall(value_type, id_method_intern, 0);

      result = packet_and_item(self, target_name, packet_name, item_name);
      rb_ary_push(items, rb_funcall(rb_ary_entry(result, 0), id_method_read, 2, item_name, value_type));
      limits = rb_funcall(rb_ary_entry(result, 1), id_method_limits, 0);
      rb_ary_push(states, rb_funcall(limits, id_method_state, 0));
      limits_values = rb_funcall(limits, id_method_values, 0);
      if (RTEST(limits_values)) {
        limits_settings = rb_hash_aref(limits_values, limits_set);
      } else {
        limits_settings = Qnil;
      }
      rb_ary_push(settings, limits_settings);
    }
  } else {
    value_type = rb_funcall(value_types, id_method_intern, 0);
    for (index = 0; index < length; index++) {
      entry = rb_ary_entry(item_array, index);
      target_name = rb_ary_entry(entry, 0);
      packet_name = rb_ary_entry(entry, 1);
      item_name = rb_ary_entry(entry, 2);

      result = packet_and_item(self, target_name, packet_name, item_name);
      rb_ary_push(items, rb_funcall(rb_ary_entry(result, 0), id_method_read, 2, item_name, value_type));
      limits = rb_funcall(rb_ary_entry(result, 1), id_method_limits, 0);
      rb_ary_push(states, rb_funcall(limits, id_method_state, 0));
      limits_values = rb_funcall(limits, id_method_values, 0);
      if (RTEST(limits_values)) {
        limits_settings = rb_hash_aref(limits_values, limits_set);
      } else {
        limits_settings = Qnil;
      }
      rb_ary_push(settings, limits_settings);
    }
  }

  return_value = rb_ary_new2(3);
  rb_ary_push(return_value, items);
  rb_ary_push(return_value, states);
  rb_ary_push(return_value, settings);
  return return_value;
}
Пример #26
0
Файл: track.c Проект: one-k/rmov
/*
  call-seq: track_get_audio_channel_map() -> array
    
    Returns an array n-channels in length
    Array contains Hashes in the form: {:assignment => :description} where :description is a symbol representing an audio channel description.  eg. :Left, :Right, :Mono
  
*/
static VALUE track_get_audio_channel_map(VALUE obj)
{
  AudioChannelLayout *layout = track_get_audio_channel_layout(obj);
  if (layout == NULL) return Qnil;
  
  VALUE channels = Qnil;
  UInt32 numChannels, x, highLayoutTag;
  VALUE channel;
  char message[256];
  AudioChannelLayoutTag layoutTag = layout->mChannelLayoutTag;
  
  if (layoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) {
    // using the descriptions
    // not implemented
    numChannels = layout->mNumberChannelDescriptions;
    channels = rb_ary_new2(numChannels);
    
    // loop through all channels, adding assignment descriptions
    AudioChannelDescription desc;
    char *trackStr;
    for (x=0; x < numChannels; x++) {
      desc = layout->mChannelDescriptions[x];
      trackStr = track_str_for_AudioChannelLabel(desc.mChannelLabel);

      if (trackStr != NULL) {
        ADD_CHANNEL(channels, channel, trackStr);

      } else {
         // unsupported audio channel labels
         ADD_CHANNEL(channels, channel, "UnsupportedByRMov");
         sprintf(message, "ChannelLabel unsupported by rmov: %d", (int)desc.mChannelLabel);
         rb_hash_aset(channel, ID2SYM(rb_intern("message")), rb_str_new2(message));
      }
    }
    

  } else {
    numChannels = AudioChannelLayoutTag_GetNumberOfChannels(layoutTag);
    channels = rb_ary_new2(numChannels);

    if (layoutTag == kAudioChannelLayoutTag_UseChannelBitmap) {
      // use the bitmap approach
      // not implemented
      //rb_raise(eQuickTime, "Not Implemented: kAudioChannelLayoutTag_UseChannelBitmap in track_get_audio_channel_map");
      for (x=0; x < numChannels; x++) {
        ADD_CHANNEL(channels, channel, "UnsupportedByRMov");
        rb_hash_aset(channel, ID2SYM(rb_intern("message")), rb_str_new2("UseChannelBitmap unsupported by rmov"));
      }



    } else {
      // using a standard LayoutTag
      switch (layoutTag) {

        case kAudioChannelLayoutTag_Mono:
          ADD_CHANNEL(channels, channel, "Mono");
          break;
        
        case kAudioChannelLayoutTag_Stereo:
          ADD_CHANNEL(channels, channel, "Left");
          ADD_CHANNEL(channels, channel, "Right");
          break;
          
        case kAudioChannelLayoutTag_MatrixStereo:
          ADD_CHANNEL(channels, channel, "LeftTotal");
          ADD_CHANNEL(channels, channel, "RightTotal");
          break;
          
        case kAudioChannelLayoutTag_SMPTE_DTV:
          ADD_CHANNEL(channels, channel, "Left");
          ADD_CHANNEL(channels, channel, "Right");
          ADD_CHANNEL(channels, channel, "Center");
          ADD_CHANNEL(channels, channel, "LFEScreen");
          ADD_CHANNEL(channels, channel, "LeftSurround");
          ADD_CHANNEL(channels, channel, "RightSurround");
          ADD_CHANNEL(channels, channel, "LeftTotal");
          ADD_CHANNEL(channels, channel, "RightTotal");
          break;

        default:
          // unsupported channels
          highLayoutTag = (layoutTag & 0xff0000) >> 16;
          sprintf(message, "layoutTag unsupported by rmov: (%dL << 16) | %d", (int)highLayoutTag, (int)numChannels);
          for (x=0; x < numChannels; x++) {
            ADD_CHANNEL(channels, channel, "UnsupportedByRMov");
            rb_hash_aset(channel, ID2SYM(rb_intern("message")), rb_str_new2(message));
          }
          //rb_raise(eQuickTime, "Unsupported ChannelLayoutTag in track_get_audio_channel_map: %d", layoutTag);
          break;
      }

    }

  }
  
  free(layout);
  
  return channels;
}
Пример #27
0
/*
 * call-seq:
 *    OpenLDAP.split_url( str )   -> array
 *
 * Split an LDAP URL into an array of its parts:
 * - uri_scheme
 * - host
 * - port
 * - base
 * - attrs
 * - scope
 * - filter
 * - exts
 * - crit_exts
 */
static VALUE
ropenldap_s_split_url( VALUE UNUSED(module), VALUE urlstring )
{
	const char *url = StringValueCStr( urlstring );
	LDAPURLDesc *urldesc;
	VALUE rval = Qnil, obj = Qnil;

	if ( !ldap_is_ldap_url(url) )
		rb_raise( rb_eArgError, "Not an LDAP URL." );

	/* Parse the URL */
	if ( ldap_url_parse(url, &urldesc) != 0 )
		rb_raise( rb_eRuntimeError, "Error parsing %s as an LDAP URL!", url );

	rval = rb_ary_new2( 9 );

	/* Scheme */
	if ( urldesc->lud_scheme ) {
		ropenldap_log( "debug", "  parsed scheme: %s", urldesc->lud_scheme );
		obj = rb_str_new2( urldesc->lud_scheme );
		OBJ_INFECT( obj, urlstring );
		rb_ary_store( rval, 0L, obj );
	}

	/* LDAP host to contact */
	if ( urldesc->lud_host ) {
		ropenldap_log( "debug", "  parsed host: %s", urldesc->lud_host );
		obj = rb_str_new2( urldesc->lud_host );
		OBJ_INFECT( obj, urlstring );
		rb_ary_store( rval, 1L, obj );
	}

	/* Port */
	rb_ary_store( rval, 2L, INT2FIX(urldesc->lud_port) );

	/* Base DN */
	if ( urldesc->lud_dn ) {
		ropenldap_log( "debug", "  parsed DN: %s", urldesc->lud_dn );
		obj = rb_str_new2( urldesc->lud_dn );
		OBJ_INFECT( obj, urlstring );
		rb_ary_store( rval, 3L, obj );
	}

	/* Attributes */
	rb_ary_store( rval, 4L, ropenldap_rb_string_array(urldesc->lud_attrs) );

	/* Numeric scope (LDAP_SCOPE_*) */
	rb_ary_store( rval, 5L, INT2FIX(urldesc->lud_scope) );

	/* Filter */
	if ( urldesc->lud_filter ) {
		ropenldap_log( "debug", "  parsed filter: %s", urldesc->lud_filter );
		obj = rb_str_new2( urldesc->lud_filter );
		OBJ_INFECT( obj, urlstring );
		rb_ary_store( rval, 6L, obj );
	}

	/* lists of LDAP extensions */
	rb_ary_store( rval, 7L, ropenldap_rb_string_array(urldesc->lud_exts) );

	/* Critical extension/s flag */
	rb_ary_store( rval, 8L, urldesc->lud_crit_exts ? Qtrue : Qfalse );

	ldap_free_urldesc( urldesc );

	return rval;
}
Пример #28
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;
}
Пример #29
0
/*
 * call-seq: initialize(fields, size, align)
 * @param [Array<StructLayout::Field>] fields
 * @param [Numeric] size
 * @param [Numeric] align
 * @return [self]
 * A new StructLayout instance.
 */
static VALUE
struct_layout_initialize(VALUE self, VALUE fields, VALUE size, VALUE align)
{
    StructLayout* layout;
    ffi_type* ltype;
    int i;

    Data_Get_Struct(self, StructLayout, layout);
    layout->fieldCount = (int) RARRAY_LEN(fields);
    layout->rbFieldMap = rb_hash_new();
    layout->rbFieldNames = rb_ary_new2(layout->fieldCount);
    layout->size = (int) FFI_ALIGN(NUM2INT(size),  NUM2INT(align));
    layout->align = NUM2INT(align);
    layout->fields = xcalloc(layout->fieldCount, sizeof(StructField *));
    layout->ffiTypes = xcalloc(layout->fieldCount + 1, sizeof(ffi_type *));
    layout->rbFields = rb_ary_new2(layout->fieldCount);
    layout->referenceFieldCount = 0;
    layout->base.ffiType->elements = layout->ffiTypes;
    layout->base.ffiType->size = layout->size;
    layout->base.ffiType->alignment = layout->align;

    ltype = layout->base.ffiType;
    for (i = 0; i < (int) layout->fieldCount; ++i) {
        VALUE rbField = rb_ary_entry(fields, i);
        VALUE rbName;
        StructField* field;
        ffi_type* ftype;


        if (!rb_obj_is_kind_of(rbField, rbffi_StructLayoutFieldClass)) {
            rb_raise(rb_eTypeError, "wrong type for field %d.", i);
        }
        rbName = rb_funcall2(rbField, rb_intern("name"), 0, NULL);

        Data_Get_Struct(rbField, StructField, field);
        layout->fields[i] = field;

        if (field->type == NULL || field->type->ffiType == NULL) {
            rb_raise(rb_eRuntimeError, "type of field %d not supported", i);
        }

        ftype = field->type->ffiType;
        if (ftype->size == 0 && i < ((int) layout->fieldCount - 1)) {
            rb_raise(rb_eTypeError, "type of field %d has zero size", i);
        }

        if (field->referenceRequired) {
            field->referenceIndex = layout->referenceFieldCount++;
        }


        layout->ffiTypes[i] = ftype->size > 0 ? ftype : NULL;
        st_insert(layout->fieldSymbolTable, rbName, rbField);
        rb_hash_aset(layout->rbFieldMap, rbName, rbField);
        rb_ary_push(layout->rbFields, rbField);
        rb_ary_push(layout->rbFieldNames, rbName);
    }

    if (ltype->size == 0) {
        rb_raise(rb_eRuntimeError, "Struct size is zero");
    }

    return self;
}
Пример #30
0
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;
}