Browse files

Expose all encodings, copies, and aliases.

  • Loading branch information...
1 parent 2ccd544 commit 1fff6c63806b7f5e0918d53c90083907bc57e76c @brixen brixen committed Dec 15, 2011
Showing with 82 additions and 35 deletions.
  1. +10 −12 kernel/common/encoding.rb
  2. +62 −18 vm/builtin/encoding.cpp
  3. +10 −5 vm/builtin/encoding.hpp
View
22 kernel/common/encoding.rb
@@ -5,6 +5,9 @@ class Encoding
class UndefinedConversionError < EncodingError
end
+ EncodingMap = Rubinius::Encoding::EncodingMap
+ EncodingList = Rubinius::Encoding::EncodingList
+
class Converter
def initialize(from, to, options={})
end
@@ -15,8 +18,9 @@ def convert(str)
def self.aliases
aliases = {}
- Rubinius::Encoding::SymbolMap.each do |n, e|
- aliases[n] = e.name unless n.to_s == e.name
+ EncodingMap.each do |n, i|
+ e = EncodingList[i]
+ aliases[n.to_s] = e.name unless n.to_s == e.name
end
aliases
@@ -41,28 +45,22 @@ def self.default_internal=(enc)
def self.find(name)
key = StringValue(name).upcase
-
- Rubinius::Encoding::SymbolMap.each do |n, e|
- return e if n.to_s.upcase == key
+ EncodingMap.each do |n, i|
+ return EncodingList[i] if n.to_s.upcase == key
end
raise ArgumentError, "unknown encoding name - #{name}"
end
def self.list
- list = []
- Rubinius::Encoding::SymbolMap.each do |n, e|
- list << e if n.to_s == e.name
- end
-
- list
+ EncodingList
end
def self.locale_charmap
end
def self.name_list
- Rubinius::Encoding::SymbolMap.keys.map { |name| name.to_s }
+ EncodingList.map { |e| e.to_s }
end
def inspect
View
80 vm/builtin/encoding.cpp
@@ -1,5 +1,6 @@
#include "oniguruma.h" // Must be first.
+#include "builtin/array.hpp"
#include "builtin/class.hpp"
#include "builtin/encoding.hpp"
#include "builtin/lookuptable.hpp"
@@ -12,6 +13,11 @@
#include <ctype.h>
+#define ENC_DEFINE(name, data) define(state, name, ONIG_ENCODING_##data);
+#define ENC_REPLICATE(name, orig) replicate(state, name, orig);
+#define ENC_ALIAS(name, orig) alias(state, name, orig);
+#define ENC_DUMMY(name) set_dummy(state, name);
+
namespace rubinius {
void Encoding::init(STATE) {
onig_init(); // in regexp.cpp too, but idempotent.
@@ -23,13 +29,15 @@ namespace rubinius {
G(encoding)->set_object_type(state, EncodingType);
G(encoding)->name(state, state->symbol("Encoding"));
- enc->set_const(state, "SymbolMap", LookupTable::create(state));
- enc->set_const(state, "IndexMap", LookupTable::create(state));
+ enc->set_const(state, "EncodingMap", LookupTable::create(state));
+ enc->set_const(state, "EncodingList", Array::create(state, 3));
- Encoding* ascii = create_bootstrap(state, "US-ASCII", eAscii, ONIG_ENCODING_ASCII);
+ Encoding* ascii = create_bootstrap(state, "US-ASCII", eAscii, ONIG_ENCODING_US_ASCII);
+ Encoding* binary = create_bootstrap(state, "ASCII-8BIT", eBinary, ONIG_ENCODING_ASCII);
Encoding* utf8 = create_bootstrap(state, "UTF-8", eUtf8, ONIG_ENCODING_UTF_8);
ascii->name(state, String::create(state, "US-ASCII"));
+ binary->name(state, String::create(state, "ASCII-8BIT"));
utf8->name(state, String::create(state, "UTF-8"));
#include "vm/gen/encoding_database.cpp"
@@ -48,8 +56,8 @@ namespace rubinius {
Index index, OnigEncodingType* enc)
{
Encoding* e = create(state, enc);
- symbol_map(state)->store(state, state->symbol(name), e);
- index_map(state)->store(state, Fixnum::from(index), e);
+ encoding_map(state)->store(state, state->symbol(name), Fixnum::from(index));
+ encoding_list(state)->set(state, index, e);
add_constant(state, name, e);
return e;
@@ -62,25 +70,43 @@ namespace rubinius {
e->name(state, String::create(state, name));
- symbol_map(state)->store(state, state->symbol(name), e);
+ Array* list = encoding_list(state);
+ size_t index = list->size();
+
+ encoding_map(state)->store(state, state->symbol(name), Fixnum::from(index));
+ list->set(state, index, e);
add_constant(state, name, e);
return e;
}
- Encoding* Encoding::alias(STATE, const char* name, Encoding* enc) {
- symbol_map(state)->store(state, state->symbol(name), enc);
- add_constant(state, name, enc);
+ Encoding* Encoding::alias(STATE, const char* name, const char* original) {
+ int index = find_index(state, original);
+ if(index < 0) return nil<Encoding>();
+
+ encoding_map(state)->store(state, state->symbol(name), Fixnum::from(index));
+
+ return as<Encoding>(encoding_list(state)->get(state, index));
+ }
+
+ Encoding* Encoding::set_dummy(STATE, const char* name) {
+ Encoding* enc = find(state, name);
+ if(enc->nil_p()) return nil<Encoding>();
+ enc->dummy(state, Qtrue);
return enc;
}
Encoding* Encoding::ascii_encoding(STATE) {
- return as<Encoding>(index_map(state)->fetch(state, Fixnum::from(eAscii)));
+ return as<Encoding>(encoding_list(state)->get(state, eAscii));
}
Encoding* Encoding::utf8_encoding(STATE) {
- return as<Encoding>(index_map(state)->fetch(state, Fixnum::from(eUtf8)));
+ return as<Encoding>(encoding_list(state)->get(state, eUtf8));
+ }
+
+ Encoding* Encoding::binary_encoding(STATE) {
+ return as<Encoding>(encoding_list(state)->get(state, eBinary));
}
#define ENCODING_NAMELEN_MAX 63
@@ -139,18 +165,36 @@ namespace rubinius {
return as<Class>(G(rubinius)->get_const(state, state->symbol("Encoding")));
}
- LookupTable* Encoding::symbol_map(STATE) {
+ LookupTable* Encoding::encoding_map(STATE) {
return as<LookupTable>(internal_class(state)->get_const(
- state, state->symbol("SymbolMap")));
+ state, state->symbol("EncodingMap")));
}
- LookupTable* Encoding::index_map(STATE) {
- return as<LookupTable>(internal_class(state)->get_const(
- state, state->symbol("IndexMap")));
+ Array* Encoding::encoding_list(STATE) {
+ return as<Array>(internal_class(state)->get_const(
+ state, state->symbol("EncodingList")));
+ }
+
+ int Encoding::find_index(STATE, const char* name) {
+ Object* obj = encoding_map(state)->fetch(state, state->symbol(name));
+ if(Fixnum* index = try_as<Fixnum>(obj)) {
+ return index->to_native();
+ } else {
+ return -1;
+ }
+ }
+
+ Encoding* Encoding::find(STATE, const char* name) {
+ int index = find_index(state, name);
+ if(index < 0) return nil<Encoding>();
+ return as<Encoding>(encoding_list(state)->get(state, index));
}
- Encoding* Encoding::find(STATE, Symbol* name) {
- return as<Encoding>(symbol_map(state)->fetch(state, name));
+ Encoding* Encoding::replicate(STATE, const char* name, const char* original) {
+ Encoding* enc = find(state, original);
+ if(enc->nil_p()) return nil<Encoding>();
+
+ return define(state, name, enc->get_encoding(), enc->dummy());
}
Encoding* Encoding::replicate(STATE, String* name) {
View
15 vm/builtin/encoding.hpp
@@ -10,6 +10,7 @@ struct OnigEncodingType;
#endif
namespace rubinius {
+ class Array;
class LookupTable;
class Symbol;
class String;
@@ -19,7 +20,7 @@ namespace rubinius {
const static object_type type = EncodingType;
enum Index {
- eAscii,
+ eAscii = 0,
eBinary,
eUtf8
};
@@ -37,22 +38,26 @@ namespace rubinius {
static void init(STATE);
static Class* internal_class(STATE);
- static LookupTable* symbol_map(STATE);
- static LookupTable* index_map(STATE);
+ static LookupTable* encoding_map(STATE);
+ static Array* encoding_list(STATE);
static void add_constant(STATE, const char* name, Encoding* enc);
static Encoding* ascii_encoding(STATE);
static Encoding* utf8_encoding(STATE);
+ static Encoding* binary_encoding(STATE);
static Encoding* create_bootstrap(STATE, const char* name,
Index index, OnigEncodingType* enc);
static Encoding* create(STATE, OnigEncodingType* enc, Object* dummy = Qfalse);
static Encoding* define(STATE, const char* name, OnigEncodingType* enc,
Object* dummy = Qfalse);
- static Encoding* alias(STATE, const char* name, Encoding* enc);
+ static Encoding* replicate(STATE, const char* name, const char* original);
+ static Encoding* alias(STATE, const char* name, const char* original);
+ static Encoding* set_dummy(STATE, const char* name);
- static Encoding* find(STATE, Symbol* name);
+ static int find_index(STATE, const char* name);
+ static Encoding* find(STATE, const char* name);
OnigEncodingType* get_encoding() {
return encoding_;

0 comments on commit 1fff6c6

Please sign in to comment.