VALUE
pg_tmbc_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
{
	t_pg_coder *p_coder = NULL;
	t_pg_result *p_result = pgresult_get_this(result);
	t_tmbc *this = (t_tmbc *) p_typemap;
	t_typemap *default_tm;

	if (PQgetisnull(p_result->pgresult, tuple, field)) {
		return Qnil;
	}

	p_coder = this->convs[field].cconv;

	if( p_coder ){
		char * val = PQgetvalue( p_result->pgresult, tuple, field );
		int len = PQgetlength( p_result->pgresult, tuple, field );

		if( p_coder->dec_func ){
			return p_coder->dec_func(p_coder, val, len, tuple, field, ENCODING_GET(result));
		} else {
			t_pg_coder_dec_func dec_func;
			dec_func = pg_coder_dec_func( p_coder, PQfformat(p_result->pgresult, field) );
			return dec_func(p_coder, val, len, tuple, field, ENCODING_GET(result));
		}
	}

	default_tm = DATA_PTR( this->typemap.default_typemap );
	return default_tm->funcs.typecast_result_value( default_tm, result, tuple, field );
}
/*
 * call-seq:
 *    coder.decode( string, tuple=nil, field=nil )
 *
 * Decodes the given string representation into a Ruby object, without
 * sending data to/from the database server.
 *
 * A nil value is passed through and non String values are expected to have
 * #to_str defined.
 *
 */
static VALUE
pg_coder_decode(int argc, VALUE *argv, VALUE self)
{
	char *val;
	int tuple = -1;
	int field = -1;
	VALUE res;
	t_pg_coder *this = DATA_PTR(self);

	if(argc < 1 || argc > 3){
		rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..3)", argc);
	}else if(argc >= 3){
		tuple = NUM2INT(argv[1]);
		field = NUM2INT(argv[2]);
	}

	if( NIL_P(argv[0]) )
		return Qnil;

	if( this->format == 0 ){
		val = StringValueCStr(argv[0]);
	}else{
		val = StringValuePtr(argv[0]);
	}
	if( !this->dec_func ){
		rb_raise(rb_eRuntimeError, "no decoder function defined");
	}

	res = this->dec_func(this, val, RSTRING_LEN(argv[0]), tuple, field, ENCODING_GET(argv[0]));
	OBJ_INFECT(res, argv[0]);

	return res;
}
Exemple #3
0
/*
 * Result constructor
 */
VALUE
pg_new_result(PGresult *result, VALUE rb_pgconn)
{
	int nfields = result ? PQnfields(result) : 0;
	VALUE self = pgresult_s_allocate( rb_cPGresult );
	t_pg_result *this;

	this = (t_pg_result *)xmalloc(sizeof(*this) +  sizeof(*this->fnames) * nfields);
	DATA_PTR(self) = this;

	this->pgresult = result;
	this->connection = rb_pgconn;
	this->typemap = pg_typemap_all_strings;
	this->p_typemap = DATA_PTR( this->typemap );
	this->autoclear = 0;
	this->nfields = -1;
	this->tuple_hash = Qnil;

	PG_ENCODING_SET_NOCHECK(self, ENCODING_GET(rb_pgconn));

	if( result ){
		t_pg_connection *p_conn = pg_get_connection(rb_pgconn);
		VALUE typemap = p_conn->type_map_for_results;

		/* Type check is done when assigned to PG::Connection. */
		t_typemap *p_typemap = DATA_PTR(typemap);

		this->typemap = p_typemap->funcs.fit_to_result( typemap, self );
		this->p_typemap = DATA_PTR( this->typemap );
	}

	return self;
}
static VALUE
spgd_compute_name(VALUE self, VALUE split_rule, VALUE values)
{
    VALUE res = 0;
    int encoding = -1;
    char *result = (char*) xmalloc(INITIAL_CAPA);
    int pos = 0, capa = INITIAL_CAPA;
    long i, rule_len = RARRAY_LEN(split_rule);
    if (!result) {
	rb_memerror();
    }
    for (i = 0; i < rule_len; i++) {
	VALUE rule = rb_ary_entry(split_rule, i);
	if (rb_class_of(rule) == rb_cArray) {
	    long fieldnum = NUM2LONG(rb_ary_entry(rule, 0));
	    VALUE actions = rb_ary_entry(rule, 1);
	    rule = rb_ary_entry(values, fieldnum);
	    encoding = ENCODING_GET(rule);
	    if (RTEST(actions) && RARRAY_LEN(actions)) {
		rule = apply_actions(rule, actions);
	    }
	}
	if (rb_class_of(rule) == rb_cString) {
	    long size = RSTRING_LEN(rule);
	    if (capa < pos + size + 1) {
		char *tmp;
		capa = pos + size + 1;
		if (i + 1 != rule_len) capa = (capa * 3) >> 1;
		tmp = (char*) xrealloc(result, capa);
		if (!tmp) {
		    xfree(result);
		    rb_memerror();
		}
		result = tmp;
	    }
	    if (encoding == -1) encoding = ENCODING_GET(rule);
	    strncpy(result + pos, RSTRING_PTR(rule), size + 1);
	    pos += size;
	}
static VALUE
pg_tmas_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
{
	VALUE ret;
	char * val;
	int len;
	t_pg_result *p_result = pgresult_get_this(result);

	if (PQgetisnull(p_result->pgresult, tuple, field)) {
		return Qnil;
	}

	val = PQgetvalue( p_result->pgresult, tuple, field );
	len = PQgetlength( p_result->pgresult, tuple, field );

	if ( 0 == PQfformat(p_result->pgresult, field) ) {
		ret = pg_text_dec_string(NULL, val, len, tuple, field, ENCODING_GET(result));
	} else {
		ret = pg_bin_dec_bytea(NULL, val, len, tuple, field, ENCODING_GET(result));
	}

	return ret;
}
Exemple #6
0
/*
 * call-seq:
 *    res.check -> nil
 *
 * Raises appropriate exception if PG::Result is in a bad state.
 */
VALUE
pg_result_check( VALUE self )
{
	t_pg_result *this = pgresult_get_this(self);
	VALUE error, exception, klass;
	char * sqlstate;

	if(this->pgresult == NULL)
	{
		PGconn *conn = pg_get_pgconn(this->connection);
		error = rb_str_new2( PQerrorMessage(conn) );
	}
	else
	{
		switch (PQresultStatus(this->pgresult))
		{
		case PGRES_TUPLES_OK:
		case PGRES_COPY_OUT:
		case PGRES_COPY_IN:
#ifdef HAVE_CONST_PGRES_COPY_BOTH
		case PGRES_COPY_BOTH:
#endif
#ifdef HAVE_CONST_PGRES_SINGLE_TUPLE
		case PGRES_SINGLE_TUPLE:
#endif
		case PGRES_EMPTY_QUERY:
		case PGRES_COMMAND_OK:
			return self;
		case PGRES_BAD_RESPONSE:
		case PGRES_FATAL_ERROR:
		case PGRES_NONFATAL_ERROR:
			error = rb_str_new2( PQresultErrorMessage(this->pgresult) );
			break;
		default:
			error = rb_str_new2( "internal error : unknown result status." );
		}
	}

	PG_ENCODING_SET_NOCHECK( error, ENCODING_GET(self) );

	sqlstate = PQresultErrorField( this->pgresult, PG_DIAG_SQLSTATE );
	klass = lookup_error_class( sqlstate );
	exception = rb_exc_new3( klass, error );
	rb_iv_set( exception, "@connection", this->connection );
	rb_iv_set( exception, "@result", this->pgresult ? self : Qnil );
	rb_exc_raise( exception );

	/* Not reached */
	return self;
}
Exemple #7
0
/*
 * Document-method: String#to_msgpack
 *
 * call-seq:
 *   string.to_msgpack(out = '') -> String
 *
 * Serializes the String into raw bytes.
 */
static VALUE MessagePack_String_to_msgpack(int argc, VALUE *argv, VALUE self)
{
	ARG_BUFFER(out, argc, argv);
#ifdef COMPAT_HAVE_ENCODING
	int enc = ENCODING_GET(self);
	if(enc != s_enc_utf8 && enc != s_enc_ascii8bit && enc != s_enc_usascii) {
		if(!ENC_CODERANGE_ASCIIONLY(self)) {
			self = rb_str_encode(self, s_enc_utf8_value, 0, Qnil);
		}
	}
#endif
	msgpack_pack_raw(out, RSTRING_LEN(self));
	msgpack_pack_raw_body(out, RSTRING_PTR(self), RSTRING_LEN(self));
	return out;
}
Exemple #8
0
void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object)
{
	switch (rb_type(rb_object)) {
	case T_NIL:
		mochilo_buf_putc(buf, MSGPACK_T_NIL);
		return;

	case T_TRUE:
		mochilo_buf_putc(buf, MSGPACK_T_TRUE);
		return;

	case T_FALSE:
		mochilo_buf_putc(buf, MSGPACK_T_FALSE);
		return;

	case T_FIXNUM:
		mochilo_pack_fixnum(buf, rb_object);
		return;

	case T_STRING:
		if (ENCODING_GET(rb_object) != 0)
			mochilo_pack_str(buf, rb_object);
		else
			mochilo_pack_bytes(buf, rb_object);
		return;

	case T_HASH:
		mochilo_pack_hash(buf, rb_object);
		return;

	case T_ARRAY:
		mochilo_pack_array(buf, rb_object);
		return;

	case T_FLOAT:
		mochilo_pack_double(buf, rb_object);
		return;

	case T_BIGNUM:
		mochilo_pack_bignum(buf, rb_object);
		return;

	default:
		rb_raise(rb_eMochiloPackError,
				"Unsupported object type: %s", rb_obj_classname(rb_object));
		return;
	}
}
static VALUE
pg_tmir_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx )
{
	t_tmir *this = (t_tmir *) p_typemap;
	rb_encoding *p_encoding = rb_enc_from_index(enc_idx);
	VALUE enc = rb_enc_from_encoding(p_encoding);
	/* field_str is reused in-place by pg_text_dec_copy_row(), so we need to make
	 * a copy of the string buffer before used in ruby space.
	 * This requires rb_str_new() instead of rb_str_dup() for Rubinius.
	 */
	VALUE field_str_copy = rb_str_new(RSTRING_PTR(field_str), RSTRING_LEN(field_str));
	PG_ENCODING_SET_NOCHECK(field_str_copy, ENCODING_GET(field_str));
	OBJ_INFECT(field_str_copy, field_str);

	return rb_funcall( this->self, s_id_typecast_copy_get, 4, field_str_copy, INT2NUM(fieldno), INT2NUM(format), enc );
}
Exemple #10
0
static VALUE
file_path_convert(VALUE name)
{
#ifndef _WIN32 /* non Windows == Unix */
    rb_encoding *fname_encoding = rb_enc_from_index(ENCODING_GET(name));
    rb_encoding *fs_encoding;
    if (rb_default_internal_encoding() != NULL
	    && rb_usascii_encoding() != fname_encoding
	    && rb_ascii8bit_encoding() != fname_encoding
	    && (fs_encoding = rb_filesystem_encoding()) != fname_encoding
	    && !rb_enc_str_asciionly_p(name)) {
	/* Don't call rb_filesystem_encoding() before US-ASCII and ASCII-8BIT */
	/* fs_encoding should be ascii compatible */
	name = rb_str_conv_enc(name, fname_encoding, fs_encoding);
    }
#endif
    return name;
}
Exemple #11
0
void native_slot_validate_string_encoding(upb_fieldtype_t type, VALUE value) {
    bool bad_encoding = false;
    rb_encoding* string_encoding = rb_enc_from_index(ENCODING_GET(value));
    if (type == UPB_TYPE_STRING) {
        bad_encoding =
            string_encoding != kRubyStringUtf8Encoding &&
            string_encoding != kRubyStringASCIIEncoding;
    } else {
        bad_encoding =
            string_encoding != kRubyString8bitEncoding;
    }
    // Check that encoding is UTF-8 or ASCII (for string fields) or ASCII-8BIT
    // (for bytes fields).
    if (bad_encoding) {
        rb_raise(rb_eTypeError, "Encoding for '%s' fields must be %s (was %s)",
                 (type == UPB_TYPE_STRING) ? "string" : "bytes",
                 (type == UPB_TYPE_STRING) ? "UTF-8 or ASCII" : "ASCII-8BIT",
                 rb_enc_name(string_encoding));
    }
}
Exemple #12
0
static VALUE encoding_spec_rb_ENCODING_GET(VALUE self, VALUE obj) {
  return INT2NUM(ENCODING_GET(obj));
}
Exemple #13
0
VALUE bamfcsv_parse_string(VALUE self, VALUE string) {
  char *buf = RSTRING_PTR(string);
  long bufsize = RSTRING_LEN(string);
  rb_encoding *enc = rb_enc_from_index(ENCODING_GET(string));

  unsigned long num_rows = 1, cell_count = 1;
  int quote_count = 0, quotes_matched = 1;

  VALUE matrix = rb_ary_new();
  VALUE row = rb_ary_new();

  char *cur = buf, *cell_start = buf;

  if (bufsize > 0 && *(buf+bufsize-1) == '\n') {
    *(buf+bufsize-1) = 0;
    --bufsize;
  }

  VALUE dbl_dquote = rb_str_new("\"\"", 2), dquote = rb_str_new("\"", 1);
  ID gsub_bang = rb_intern("gsub!");
  
  for (; cur < buf+bufsize; cur++) {

    if (*cur == '"') {
      if (0 == quote_count && cell_start != cur) /* Quotes begin past opening of cell */
        rb_raise(BAMFCSV_MalformedCSVError_class, "Illegal quoting on line %lu, cell %lu: Quoted cell must open with '\"'", num_rows, cell_count);
      else
        ++quote_count;
    }

    quotes_matched = !(quote_count & 1); /* count is even */

    if (quotes_matched) { 

      if (*cur == ',') {
        
        if (quote_count && *(cur-1) != '"')
          rb_raise(BAMFCSV_MalformedCSVError_class, "Unclosed quoted field on line %lu, cell %lu.", num_rows, cell_count);

        VALUE cell_str = bamfcsv_finalize_cell(cell_start, cur-1, quote_count, enc);
        if (quote_count)
          rb_funcall(cell_str, gsub_bang, 2, dbl_dquote, dquote);

        rb_ary_push(row, cell_str);
        cell_start = cur+1;

        quote_count = 0;
        ++cell_count;

      } else if (*cur == '\n') {
        
        if (quote_count && !quotes_end_line(cur))
            rb_raise(BAMFCSV_MalformedCSVError_class, "Unclosed quoted field on line %lu, cell %lu: EOL", num_rows, cell_count);

        VALUE cell_str = bamfcsv_finalize_cell(cell_start, cur-1, quote_count, enc);
        if (quote_count)
          rb_funcall(cell_str, gsub_bang, 2, dbl_dquote, dquote);
        /* Completely blank lines don't even get a nil. This matches CSV's behavior. */
        if (cell_count > 1 || cell_str != Qnil)
          rb_ary_push(row, cell_str);
        rb_ary_push(matrix, row);
        row = rb_ary_new();
        cell_start = cur+1;
        
        quote_count = 0;
        ++num_rows;
        cell_count = 0;

      } else if (quote_count && *cur != '\r' && *cur != '"')
        rb_raise(BAMFCSV_MalformedCSVError_class, "Illegal quoting on line %lu, cell %lu", num_rows, cell_count);
      
    }

  }

  if (!quotes_matched) /* Reached EOF without matching quotes */
    rb_raise(BAMFCSV_MalformedCSVError_class, "Illegal quoting on line %lu, cell %lu: File ends without closing '\"'", num_rows, cell_count);
  else if (quote_count && !quotes_end_line(cur)) /* Quotes closed before end of final cell */
    rb_raise(BAMFCSV_MalformedCSVError_class, "Unclosed quoted field on line %lu, cell %lu: EOF", num_rows, cell_count);

  VALUE cell_str = bamfcsv_finalize_cell(cell_start, cur-1, quote_count, enc);
  if (quote_count)
    rb_funcall(cell_str, gsub_bang, 2, dbl_dquote, dquote);
  /* Completely blank lines don't even get a nil. This matches CSV's behavior. */
  if (cell_count > 1 || cell_str != Qnil)
    rb_ary_push(row, cell_str);
  rb_ary_push(matrix, row);

  return matrix;

}
Exemple #14
0
void mochilo_pack_one(mochilo_buf *buf, VALUE rb_object, int trusted)
{
#ifndef RUBINIUS
	if (rb_object == Qnil) {
		mochilo_buf_putc(buf, MSGPACK_T_NIL);
	}
	else if (rb_object == Qtrue) {
		mochilo_buf_putc(buf, MSGPACK_T_TRUE);
	}
	else if (rb_object == Qfalse) {
		mochilo_buf_putc(buf, MSGPACK_T_FALSE);
	}
	else if (FIXNUM_P(rb_object)) {
		mochilo_pack_fixnum(buf, rb_object);
	}
	else if (SYMBOL_P(rb_object)) {
		if (trusted)
			mochilo_pack_symbol(buf, rb_object);
		else
			mochilo_pack_str(buf, rb_obj_as_string(rb_object));
	}
	else {
		switch (BUILTIN_TYPE(rb_object)) {
		case T_STRING:
#ifdef HAVE_RUBY_ENCODING_H
			if (ENCODING_GET(rb_object) != 0)
				mochilo_pack_str(buf, rb_object);
			else
#endif
				mochilo_pack_bytes(buf, rb_object);
			return;

		case T_HASH:
			mochilo_pack_hash(buf, rb_object, trusted);
			return;

		case T_ARRAY:
			mochilo_pack_array(buf, rb_object, trusted);
			return;

		case T_FLOAT:
			mochilo_pack_double(buf, rb_object);
			return;

		case T_BIGNUM:
			mochilo_pack_bignum(buf, rb_object);
			return;

		default:
			rb_raise(rb_eMochiloPackError,
				"Unsupported object type: %s", rb_obj_classname(rb_object));
			return;
		}
	}
#else // RUBINIUS
	switch (rb_type(rb_object)) {
		case T_NIL:
			mochilo_buf_putc(buf, MSGPACK_T_NIL);
			return;

		case T_FALSE:
			mochilo_buf_putc(buf, MSGPACK_T_FALSE);
			return;

		case T_TRUE:
			mochilo_buf_putc(buf, MSGPACK_T_TRUE);
			return;

		case T_FIXNUM:
			mochilo_pack_fixnum(buf, rb_object);
			return;

		case T_BIGNUM:
			mochilo_pack_bignum(buf, rb_object);
			return;

		case T_SYMBOL:
			if (trusted)
				mochilo_pack_symbol(buf, rb_object);
			else
				mochilo_pack_str(buf, rb_obj_as_string(rb_object));
			return;

		case T_STRING:
#ifdef HAVE_RUBY_ENCODING_H
			if (ENCODING_GET(rb_object) != 0)
				mochilo_pack_str(buf, rb_object);
			else
#endif
				mochilo_pack_bytes(buf, rb_object);
			return;

		case T_HASH:
			mochilo_pack_hash(buf, rb_object, trusted);
			return;

		case T_ARRAY:
			mochilo_pack_array(buf, rb_object, trusted);
			return;

		case T_FLOAT:
			mochilo_pack_double(buf, rb_object);
			return;

		default:
			rb_raise(rb_eMochiloPackError,
				"Unsupported object type: %s", rb_obj_classname(rb_object));
			return;
	}
#endif
}