/*
 * call-seq:
 *   conn.internal_encoding = value
 *
 * A wrapper of +PGconn#set_client_encoding+.
 * defined in Ruby 1.9 or later.
 *
 * +value+ can be one of:
 * * an Encoding
 * * a String - a name of Encoding
 * * +nil+ - sets 'SQL_ASCII' to the client_encoding.
 */
static VALUE
pgconn_internal_encoding_set(VALUE self, VALUE enc)
{
    if (NIL_P(enc)) {
        pgconn_set_client_encoding(self, rb_usascii_str_new_cstr("SQL_ASCII"));
        return enc;
    }
    else if (TYPE(enc) == T_STRING && strcasecmp("JOHAB", RSTRING_PTR(enc)) == 0) {
        pgconn_set_client_encoding(self, rb_usascii_str_new_cstr("JOHAB"));
        return enc;
    }
    else {
        int i;
        const char *name; 
        name = rb_enc_name(rb_to_encoding(enc));

        /* sequential search becuase rarely called */
        for (i = 0; i < sizeof(enc_pg2ruby_mapping)/sizeof(enc_pg2ruby_mapping[0]); ++i) {
            if (strcmp(name, enc_pg2ruby_mapping[i][1]) == 0) {
                if (PQsetClientEncoding(get_pgconn(self), enc_pg2ruby_mapping[i][0]) == -1) {
                    VALUE server_encoding = pgconn_external_encoding(self);
                    rb_raise(rb_eEncCompatError, "imcompatible character encodings: %s and %s",
                            rb_enc_name(rb_to_encoding(server_encoding)),
                            enc_pg2ruby_mapping[i][0]);
                }
                return enc;
            }
        }

        /* Ruby 1.9.1 does not support JOHAB */
        if (strcasecmp(name, "JOHAB") == 0) {
            pgconn_set_client_encoding(self, rb_usascii_str_new_cstr("JOHAB"));
            return enc;
        }
    }

    enc = rb_inspect(enc);
    rb_raise(rb_ePGError, "unknown encoding: %s", StringValuePtr(enc));
}