[macruby-changes] [3547] MacRuby/branches/icu
source_changes at macosforge.org
source_changes at macosforge.org
Mon Feb 15 18:54:52 PST 2010
Revision: 3547
http://trac.macosforge.org/projects/ruby/changeset/3547
Author: lsansonetti at apple.com
Date: 2010-02-15 18:54:51 -0800 (Mon, 15 Feb 2010)
Log Message:
-----------
indented code, better type checking, removed rb_cCFString, started adding MRI functions
Modified Paths:
--------------
MacRuby/branches/icu/class.c
MacRuby/branches/icu/dispatcher.cpp
MacRuby/branches/icu/encoding.c
MacRuby/branches/icu/encoding.h
MacRuby/branches/icu/include/ruby/ruby.h
MacRuby/branches/icu/object.c
MacRuby/branches/icu/string.c
Modified: MacRuby/branches/icu/class.c
===================================================================
--- MacRuby/branches/icu/class.c 2010-02-16 01:31:05 UTC (rev 3546)
+++ MacRuby/branches/icu/class.c 2010-02-16 02:54:51 UTC (rev 3547)
@@ -225,19 +225,17 @@
{
VALUE klass;
- if (super == rb_cCFString) {
- super = rb_cNSMutableString;
- }
- else {
- if (!RCLASS_RUBY(super)) {
- const long v = RCLASS_VERSION(super);
- if (v & RCLASS_IS_HASH_SUBCLASS) {
- super = rb_cNSMutableHash;
- }
- else if (v & RCLASS_IS_ARRAY_SUBCLASS) {
- super = rb_cNSMutableArray;
- }
+ if (!RCLASS_RUBY(super)) {
+ const long v = RCLASS_VERSION(super);
+ if (v & RCLASS_IS_STRING_SUBCLASS) {
+ super = rb_cNSMutableString;
}
+ else if (v & RCLASS_IS_HASH_SUBCLASS) {
+ super = rb_cNSMutableHash;
+ }
+ else if (v & RCLASS_IS_ARRAY_SUBCLASS) {
+ super = rb_cNSMutableArray;
+ }
}
klass = rb_objc_alloc_class(name, super, T_CLASS, rb_cClass);
Modified: MacRuby/branches/icu/dispatcher.cpp
===================================================================
--- MacRuby/branches/icu/dispatcher.cpp 2010-02-16 01:31:05 UTC (rev 3546)
+++ MacRuby/branches/icu/dispatcher.cpp 2010-02-16 02:54:51 UTC (rev 3547)
@@ -824,10 +824,6 @@
if (self == Qfalse) {
return rb_cFalseClass;
}
- if (klass == (Class)rb_cCFString) {
- return RSTRING_IMMUTABLE(self)
- ? rb_cNSString : rb_cNSMutableString;
- }
return rb_class_real((VALUE)klass);
}
@@ -1325,12 +1321,14 @@
}
break;
+#if 0 // TODO
case T_STRING:
if (*(VALUE *)obj == rb_cCFString) {
rb_str_concat(obj, other);
return obj;
}
break;
+#endif
}
}
return __rb_vm_dispatch(GET_VM(), cache, 0, obj, NULL, selLTLT, NULL, 0, 1,
Modified: MacRuby/branches/icu/encoding.c
===================================================================
--- MacRuby/branches/icu/encoding.c 2010-02-16 01:31:05 UTC (rev 3546)
+++ MacRuby/branches/icu/encoding.c 2010-02-16 02:54:51 UTC (rev 3547)
@@ -7,7 +7,6 @@
VALUE rb_cEncoding = 0;
#define ENC(x) ((encoding_t *)(x))
-#define OBJC_CLASS(x) (*(VALUE *)(x))
encoding_t *default_internal = NULL;
encoding_t *default_external = NULL;
@@ -82,7 +81,8 @@
static VALUE
mr_enc_inspect(VALUE self, SEL sel)
{
- return rb_sprintf("#<%s:%s>", rb_obj_classname(self), ENC(self)->public_name);
+ return rb_sprintf("#<%s:%s>", rb_obj_classname(self),
+ ENC(self)->public_name);
}
static VALUE
@@ -144,13 +144,16 @@
static void
add_encoding(
- unsigned int encoding_index, // index of the encoding in the encodings array
+ unsigned int encoding_index, // index of the encoding in the encodings
+ // array
unsigned int encoding_type,
const char *public_name, // public name for the encoding
unsigned char min_char_size,
- bool single_byte_encoding, // in the encoding a character takes only one byte
+ bool single_byte_encoding, // in the encoding a character takes only
+ // one byte
bool ascii_compatible, // is the encoding ASCII compatible or not
- ... // aliases for the encoding (should no include the public name) - must end with a NULL
+ ... // aliases for the encoding (should no include the public name)
+ // - must end with a NULL
)
{
assert(encoding_index < ENCODINGS_COUNT);
@@ -163,7 +166,8 @@
++aliases_count;
}
va_end(va_aliases);
- const char **aliases = (const char **) malloc(sizeof(const char *) * aliases_count);
+ const char **aliases = (const char **)
+ malloc(sizeof(const char *) * aliases_count);
va_start(va_aliases, ascii_compatible);
for (unsigned int i = 0; i < aliases_count; ++i) {
aliases[i] = va_arg(va_aliases, const char *);
@@ -189,11 +193,14 @@
// fill the default implementations with aborts
encoding->methods.update_flags = str_undefined_update_flags;
encoding->methods.make_data_binary = str_undefined_make_data_binary;
- encoding->methods.try_making_data_uchars = str_undefined_try_making_data_uchars;
+ encoding->methods.try_making_data_uchars =
+ str_undefined_try_making_data_uchars;
encoding->methods.length = str_undefined_length;
encoding->methods.bytesize = str_undefined_bytesize;
- encoding->methods.get_character_boundaries = str_undefined_get_character_boundaries;
- encoding->methods.offset_in_bytes_to_index = str_undefined_offset_in_bytes_to_index;
+ encoding->methods.get_character_boundaries =
+ str_undefined_get_character_boundaries;
+ encoding->methods.offset_in_bytes_to_index =
+ str_undefined_offset_in_bytes_to_index;
switch (encoding_type) {
case ENCODING_TYPE_SPECIAL:
@@ -210,8 +217,6 @@
for (unsigned int i = 0; i < aliases_count; ++i) {
define_encoding_constant(aliases[i], encoding);
}
-
- free(aliases);
}
static void
@@ -249,20 +254,27 @@
rb_objc_define_method(rb_cEncoding, "name", mr_enc_name, 0);
rb_objc_define_method(rb_cEncoding, "names", mr_enc_names, 0);
rb_objc_define_method(rb_cEncoding, "dummy?", mr_enc_dummy_p, 0);
- rb_objc_define_method(rb_cEncoding, "ascii_compatible?", mr_enc_ascii_compatible_p, 0);
- rb_objc_define_method(OBJC_CLASS(rb_cEncoding), "list", mr_enc_s_list, 0);
- rb_objc_define_method(OBJC_CLASS(rb_cEncoding), "name_list", mr_enc_s_name_list, 0);
- rb_objc_define_method(OBJC_CLASS(rb_cEncoding), "aliases", mr_enc_s_aliases, 0);
+ rb_objc_define_method(rb_cEncoding, "ascii_compatible?",
+ mr_enc_ascii_compatible_p, 0);
+ rb_objc_define_method(CLASS_OF(rb_cEncoding), "list", mr_enc_s_list, 0);
+ rb_objc_define_method(CLASS_OF(rb_cEncoding), "name_list",
+ mr_enc_s_name_list, 0);
+ rb_objc_define_method(CLASS_OF(rb_cEncoding), "aliases",
+ mr_enc_s_aliases, 0);
//rb_define_singleton_method(rb_cEncoding, "find", enc_find, 1);
- // it's defined on Encoding, but it requires String's internals so it's defined with String
- rb_objc_define_method(OBJC_CLASS(rb_cEncoding), "compatible?", mr_enc_s_is_compatible, 2);
+ // it's defined on Encoding, but it requires String's internals so it's
+ // defined with String
+ rb_objc_define_method(CLASS_OF(rb_cEncoding), "compatible?",
+ mr_enc_s_is_compatible, 2);
//rb_define_method(rb_cEncoding, "_dump", enc_dump, -1);
//rb_define_singleton_method(rb_cEncoding, "_load", enc_load, 1);
- rb_objc_define_method(OBJC_CLASS(rb_cEncoding), "default_external", mr_enc_s_default_external, 0);
+ rb_objc_define_method(CLASS_OF(rb_cEncoding), "default_external",
+ mr_enc_s_default_external, 0);
//rb_define_singleton_method(rb_cEncoding, "default_external=", set_default_external, 1);
- rb_objc_define_method(OBJC_CLASS(rb_cEncoding), "default_internal", mr_enc_s_default_internal, 0);
+ rb_objc_define_method(CLASS_OF(rb_cEncoding), "default_internal",
+ mr_enc_s_default_internal, 0);
//rb_define_singleton_method(rb_cEncoding, "default_internal=", set_default_internal, 1);
//rb_define_singleton_method(rb_cEncoding, "locale_charmap", rb_locale_charmap, 0);
Modified: MacRuby/branches/icu/encoding.h
===================================================================
--- MacRuby/branches/icu/encoding.h 2010-02-16 01:31:05 UTC (rev 3546)
+++ MacRuby/branches/icu/encoding.h 2010-02-16 02:54:51 UTC (rev 3547)
@@ -21,12 +21,18 @@
#define ENCODING_UTF32_NON_NATIVE ENCODING_UTF32LE
#endif
-#define NATIVE_UTF16_ENC(encoding) ((encoding) == encodings[ENCODING_UTF16_NATIVE])
-#define NON_NATIVE_UTF16_ENC(encoding) ((encoding) == encodings[ENCODING_UTF16_NON_NATIVE])
-#define UTF16_ENC(encoding) (NATIVE_UTF16_ENC(encoding) || NON_NATIVE_UTF16_ENC(encoding))
-#define NATIVE_UTF32_ENC(encoding) ((encoding) == encodings[ENCODING_UTF32_NATIVE])
-#define NON_NATIVE_UTF32_ENC(encoding) ((encoding) == encodings[ENCODING_UTF32_NON_NATIVE])
-#define UTF32_ENC(encoding) (NATIVE_UTF32_ENC(encoding) || NON_NATIVE_UTF32_ENC(encoding))
+#define NATIVE_UTF16_ENC(encoding) \
+ ((encoding) == encodings[ENCODING_UTF16_NATIVE])
+#define NON_NATIVE_UTF16_ENC(encoding) \
+ ((encoding) == encodings[ENCODING_UTF16_NON_NATIVE])
+#define UTF16_ENC(encoding) \
+ (NATIVE_UTF16_ENC(encoding) || NON_NATIVE_UTF16_ENC(encoding))
+#define NATIVE_UTF32_ENC(encoding) \
+ ((encoding) == encodings[ENCODING_UTF32_NATIVE])
+#define NON_NATIVE_UTF32_ENC(encoding) \
+ ((encoding) == encodings[ENCODING_UTF32_NON_NATIVE])
+#define UTF32_ENC(encoding) \
+ (NATIVE_UTF32_ENC(encoding) || NON_NATIVE_UTF32_ENC(encoding))
#define BINARY_ENC(encoding) ((encoding) == encodings[ENCODING_BINARY])
typedef uint8_t str_flag_t;
@@ -43,6 +49,26 @@
str_flag_t flags;
} string_t;
+#define RSTR(x) ((string_t *)x)
+
+static inline bool
+rb_klass_is_rstr(VALUE klass)
+{
+ do {
+ if (klass == rb_cRubyString) {
+ return true;
+ }
+ if (klass == rb_cNSString) {
+ return false;
+ }
+ klass = RCLASS_SUPER(klass);
+ }
+ while (klass != 0);
+ return false;
+}
+
+#define IS_RSTR(x) (rb_klass_is_rstr(*(VALUE *)x))
+
typedef struct {
long start_offset_in_bytes;
long end_offset_in_bytes;
@@ -103,8 +129,6 @@
#define STRING_REQUIRED_FLAGS STRING_STORED_IN_UCHARS
-#define STR(x) ((string_t *)(x))
-
#define BYTES_TO_UCHARS(len) ((len) / sizeof(UChar))
#define UCHARS_TO_BYTES(len) ((len) * sizeof(UChar))
@@ -116,29 +140,32 @@
return ((a) + (b - 1)) / b;
}
-void
-str_update_flags(string_t *self);
+void str_update_flags(string_t *self);
static inline void
str_unset_facultative_flags(string_t *self)
{
- self->flags &= ~STRING_HAS_SUPPLEMENTARY_SET & ~STRING_ASCII_ONLY_SET & ~STRING_VALID_ENCODING_SET;
+ self->flags &= ~STRING_HAS_SUPPLEMENTARY_SET & ~STRING_ASCII_ONLY_SET
+ & ~STRING_VALID_ENCODING_SET;
}
static inline bool
str_known_to_have_an_invalid_encoding(string_t *self)
{
- return (self->flags & (STRING_VALID_ENCODING_SET | STRING_VALID_ENCODING)) == STRING_VALID_ENCODING_SET;
+ return (self->flags & (STRING_VALID_ENCODING_SET
+ | STRING_VALID_ENCODING)) == STRING_VALID_ENCODING_SET;
}
static inline bool
str_known_not_to_have_any_supplementary(string_t *self)
{
- return (self->flags & (STRING_HAS_SUPPLEMENTARY_SET | STRING_HAS_SUPPLEMENTARY)) == STRING_HAS_SUPPLEMENTARY_SET;
+ return (self->flags & (STRING_HAS_SUPPLEMENTARY_SET
+ | STRING_HAS_SUPPLEMENTARY)) == STRING_HAS_SUPPLEMENTARY_SET;
}
static inline bool
-str_check_flag_and_update_if_needed(string_t *self, str_flag_t flag_set, str_flag_t flag)
+str_check_flag_and_update_if_needed(string_t *self, str_flag_t flag_set,
+ str_flag_t flag)
{
if (!(self->flags & flag_set)) {
str_update_flags(self);
@@ -150,24 +177,26 @@
static inline bool
str_is_valid_encoding(string_t *self)
{
- return str_check_flag_and_update_if_needed(self, STRING_VALID_ENCODING_SET, STRING_VALID_ENCODING);
+ return str_check_flag_and_update_if_needed(self, STRING_VALID_ENCODING_SET,
+ STRING_VALID_ENCODING);
}
static inline bool
str_is_ascii_only(string_t *self)
{
- return str_check_flag_and_update_if_needed(self, STRING_ASCII_ONLY_SET, STRING_ASCII_ONLY);
+ return str_check_flag_and_update_if_needed(self, STRING_ASCII_ONLY_SET,
+ STRING_ASCII_ONLY);
}
static inline bool
str_is_ruby_ascii_only(string_t *self)
{
// for MRI, a string in a non-ASCII-compatible encoding (like UTF-16)
- // containing only ASCII characters is not "ASCII only" though for us it is internally
+ // containing only ASCII characters is not "ASCII only" though for us it
+ // is internally
if (!self->encoding->ascii_compatible) {
return false;
}
-
return str_is_ascii_only(self);
}
@@ -195,7 +224,8 @@
}
static inline void
-str_set_facultative_flag(string_t *self, bool status, str_flag_t flag_set, str_flag_t flag)
+str_set_facultative_flag(string_t *self, bool status, str_flag_t flag_set,
+ str_flag_t flag)
{
if (status) {
self->flags = self->flags | flag_set | flag;
@@ -208,23 +238,26 @@
static inline void
str_set_has_supplementary(string_t *self, bool status)
{
- str_set_facultative_flag(self, status, STRING_HAS_SUPPLEMENTARY_SET, STRING_HAS_SUPPLEMENTARY);
+ str_set_facultative_flag(self, status, STRING_HAS_SUPPLEMENTARY_SET,
+ STRING_HAS_SUPPLEMENTARY);
}
static inline void
str_set_ascii_only(string_t *self, bool status)
{
- str_set_facultative_flag(self, status, STRING_ASCII_ONLY_SET, STRING_ASCII_ONLY);
+ str_set_facultative_flag(self, status, STRING_ASCII_ONLY_SET,
+ STRING_ASCII_ONLY);
}
static inline void
str_set_valid_encoding(string_t *self, bool status)
{
- str_set_facultative_flag(self, status, STRING_VALID_ENCODING_SET, STRING_VALID_ENCODING);
+ str_set_facultative_flag(self, status, STRING_VALID_ENCODING_SET,
+ STRING_VALID_ENCODING);
}
#if defined(__cplusplus)
-}
+} // extern "C"
#endif
#endif /* __ENCODING_H_ */
Modified: MacRuby/branches/icu/include/ruby/ruby.h
===================================================================
--- MacRuby/branches/icu/include/ruby/ruby.h 2010-02-16 01:31:05 UTC (rev 3546)
+++ MacRuby/branches/icu/include/ruby/ruby.h 2010-02-16 02:54:51 UTC (rev 3547)
@@ -1134,9 +1134,9 @@
RUBY_EXTERN VALUE rb_cRandom;
#if WITH_OBJC
-RUBY_EXTERN VALUE rb_cCFString;
RUBY_EXTERN VALUE rb_cNSString;
RUBY_EXTERN VALUE rb_cNSMutableString;
+RUBY_EXTERN VALUE rb_cRubyString;
RUBY_EXTERN VALUE rb_cNSArray;
RUBY_EXTERN VALUE rb_cNSMutableArray;
RUBY_EXTERN VALUE rb_cRubyArray;
@@ -1147,11 +1147,6 @@
RUBY_EXTERN VALUE rb_cBoxed;
RUBY_EXTERN VALUE rb_cPointer;
RUBY_EXTERN VALUE rb_cTopLevel;
-
-bool __CFStringIsMutable(void *);
-#define RSTRING_IMMUTABLE(o) \
- (*(VALUE *)o == rb_cCFString ? !__CFStringIsMutable((void *)o) : false)
-
#endif
RUBY_EXTERN VALUE rb_eException;
@@ -1257,7 +1252,7 @@
}
#if WITH_OBJC
else if ((k = *(Class *)obj) != NULL) {
- if (k == (Class)rb_cCFString) {
+ if (k == (Class)rb_cRubyString) {
return T_STRING;
}
if (k == (Class)rb_cRubyArray) {
Modified: MacRuby/branches/icu/object.c
===================================================================
--- MacRuby/branches/icu/object.c 2010-02-16 01:31:05 UTC (rev 3546)
+++ MacRuby/branches/icu/object.c 2010-02-16 02:54:51 UTC (rev 3547)
@@ -163,11 +163,11 @@
while (RCLASS_SINGLETON(cl)) {
cl = RCLASS_SUPER(cl);
}
- if (cl == rb_cCFString) {
- return rb_cNSMutableString;
- }
if (!RCLASS_RUBY(cl)) {
const long v = RCLASS_VERSION(cl);
+ if (v & RCLASS_IS_STRING_SUBCLASS) {
+ return rb_cRubyString;
+ }
if (v & RCLASS_IS_HASH_SUBCLASS) {
return rb_cRubyHash;
}
Modified: MacRuby/branches/icu/string.c
===================================================================
--- MacRuby/branches/icu/string.c 2010-02-16 01:31:05 UTC (rev 3546)
+++ MacRuby/branches/icu/string.c 2010-02-16 02:54:51 UTC (rev 3547)
@@ -15,8 +15,9 @@
#include <stdio.h>
#include <stdarg.h>
-#define OBJC_CLASS(x) (*(VALUE *)(x))
+VALUE rb_cSymbol; // XXX move me outside
+VALUE rb_cString;
VALUE rb_cNSString;
VALUE rb_cNSMutableString;
VALUE rb_cRubyString;
@@ -24,7 +25,8 @@
static void
str_update_flags_utf16(string_t *self)
{
- assert(str_is_stored_in_uchars(self) || NON_NATIVE_UTF16_ENC(self->encoding));
+ assert(str_is_stored_in_uchars(self)
+ || NON_NATIVE_UTF16_ENC(self->encoding));
bool ascii_only = true;
bool has_supplementary = false;
@@ -161,7 +163,8 @@
if (str1->length_in_bytes == 0) {
return str2->encoding;
}
- if (!str1->encoding->ascii_compatible || !str2->encoding->ascii_compatible) {
+ if (!str1->encoding->ascii_compatible
+ || !str2->encoding->ascii_compatible) {
return NULL;
}
if (str_is_ruby_ascii_only(str1) && str_is_ruby_ascii_only(str2)) {
@@ -175,13 +178,13 @@
{
encoding_t *new_encoding = str_compatible_encoding(str1, str2);
if (new_encoding == NULL) {
- rb_raise(rb_eEncCompatError, "incompatible character encodings: %s and %s",
+ rb_raise(rb_eEncCompatError,
+ "incompatible character encodings: %s and %s",
str1->encoding->public_name, str2->encoding->public_name);
}
return new_encoding;
}
-
static string_t *
str_alloc(void)
{
@@ -196,12 +199,22 @@
return str;
}
-extern VALUE rb_cString;
-extern VALUE rb_cCFString;
-extern VALUE rb_cNSString;
-extern VALUE rb_cNSMutableString;
-extern VALUE rb_cSymbol;
-extern VALUE rb_cByteString;
+static void
+str_replace_with_bytes(string_t *self, const char *bytes, long len,
+ encoding_t *enc)
+{
+ assert(len >= 0);
+ self->flags = 0;
+ self->encoding = enc;
+ self->capacity_in_bytes = self->length_in_bytes = len;
+ if (len > 0) {
+ GC_WB(&self->data.bytes, xmalloc(len));
+ memcpy(self->data.bytes, bytes, len);
+ }
+ else {
+ self->data.bytes = NULL;
+ }
+}
static void
str_replace_with_string(string_t *self, string_t *source)
@@ -209,14 +222,9 @@
if (self == source) {
return;
}
- self->flags = 0;
- self->encoding = source->encoding;
- self->capacity_in_bytes = self->length_in_bytes = source->length_in_bytes;
+ str_replace_with_bytes(self, source->data.bytes, source->length_in_bytes,
+ source->encoding);
self->flags = source->flags;
- if (self->length_in_bytes != 0) {
- GC_WB(&self->data.bytes, xmalloc(self->length_in_bytes));
- memcpy(self->data.bytes, source->data.bytes, self->length_in_bytes);
- }
}
static void
@@ -224,10 +232,13 @@
{
self->flags = 0;
self->encoding = encodings[ENCODING_UTF16_NATIVE];
- self->capacity_in_bytes = self->length_in_bytes = UCHARS_TO_BYTES(CFStringGetLength(source));
+ self->capacity_in_bytes = self->length_in_bytes =
+ UCHARS_TO_BYTES(CFStringGetLength(source));
if (self->length_in_bytes != 0) {
GC_WB(&self->data.uchars, xmalloc(self->length_in_bytes));
- CFStringGetCharacters((CFStringRef)source, CFRangeMake(0, BYTES_TO_UCHARS(self->length_in_bytes)), self->data.uchars);
+ CFStringGetCharacters((CFStringRef)source,
+ CFRangeMake(0, BYTES_TO_UCHARS(self->length_in_bytes)),
+ self->data.uchars);
str_set_stored_in_uchars(self, true);
}
}
@@ -235,28 +246,21 @@
static void
str_replace(string_t *self, VALUE arg)
{
- VALUE klass = CLASS_OF(arg);
- if (klass == rb_cRubyString) {
- str_replace_with_string(self, STR(arg));
+ if (IS_RSTR(arg)) {
+ str_replace_with_string(self, RSTR(arg));
}
- else if (klass == rb_cByteString) {
- self->encoding = encodings[ENCODING_BINARY];
- self->capacity_in_bytes = self->length_in_bytes = rb_bytestring_length(arg);
- if (self->length_in_bytes != 0) {
- GC_WB(&self->data.bytes, xmalloc(self->length_in_bytes));
- assert(self->data.bytes != NULL);
- memcpy(self->data.bytes, rb_bytestring_byte_pointer(arg), self->length_in_bytes);
+ else {
+ switch (TYPE(arg)) {
+ case T_STRING:
+ str_replace_with_cfstring(self, (CFStringRef)arg);
+ break;
+ case T_SYMBOL:
+ abort(); // TODO
+ default:
+ str_replace(self, rb_str_to_str(arg));
+ break;
}
}
- else if (TYPE(arg) == T_STRING) {
- str_replace_with_cfstring(self, (CFStringRef)arg);
- }
- else if (klass == rb_cSymbol) {
- abort(); // TODO
- }
- else {
- str_replace(self, rb_str_to_str(arg));
- }
}
static string_t *
@@ -289,7 +293,6 @@
return destination;
}
-
static void
str_make_data_binary(string_t *self)
{
@@ -364,7 +367,8 @@
// we must return the length in Unicode code points,
// not the number of UChars, even if the probability
// we have surrogates is very low
- length = u_countChar32(self->data.uchars, BYTES_TO_UCHARS(self->length_in_bytes));
+ length = u_countChar32(self->data.uchars,
+ BYTES_TO_UCHARS(self->length_in_bytes));
}
if (ODD_NUMBER(self->length_in_bytes)) {
return length + 1;
@@ -487,14 +491,16 @@
}
static string_t *
-str_new_copy_of_part(string_t *self, long offset_in_bytes, long length_in_bytes)
+str_new_copy_of_part(string_t *self, long offset_in_bytes,
+ long length_in_bytes)
{
string_t *str = str_alloc();
str->encoding = self->encoding;
str->capacity_in_bytes = str->length_in_bytes = length_in_bytes;
str->flags = self->flags & STRING_REQUIRED_FLAGS;
GC_WB(&str->data.bytes, xmalloc(length_in_bytes));
- memcpy(str->data.bytes, &self->data.bytes[offset_in_bytes], length_in_bytes);
+ memcpy(str->data.bytes, &self->data.bytes[offset_in_bytes],
+ length_in_bytes);
return str;
}
@@ -521,10 +527,12 @@
}
}
boundaries.start_offset_in_bytes = UCHARS_TO_BYTES(index);
- boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + 2;
+ boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes
+ + 2;
if (!UTF16_ENC(self->encoding)) {
long length = BYTES_TO_UCHARS(self->length_in_bytes);
- if ((index < length) && U16_IS_SURROGATE(self->data.uchars[index])) {
+ if ((index < length)
+ && U16_IS_SURROGATE(self->data.uchars[index])) {
if (U16_IS_SURROGATE_LEAD(self->data.uchars[index])) {
boundaries.end_offset_in_bytes = -1;
}
@@ -535,8 +543,8 @@
}
}
else {
- // we don't have the length of the string, just the number of UChars
- // (uchars_count >= number of characters)
+ // we don't have the length of the string, just the number of
+ // UChars (uchars_count >= number of characters)
long uchars_count = BYTES_TO_UCHARS(self->length_in_bytes);
if ((index < -uchars_count) || (index >= uchars_count)) {
return boundaries;
@@ -550,7 +558,8 @@
--offset;
// if the next character is a paired surrogate
// we need to go to the start of the whole surrogate
- if (U16_IS_TRAIL(uchars[offset]) && (offset > 0) && U16_IS_LEAD(uchars[offset-1])) {
+ if (U16_IS_TRAIL(uchars[offset]) && (offset > 0)
+ && U16_IS_LEAD(uchars[offset-1])) {
--offset;
}
++index;
@@ -571,15 +580,18 @@
}
long length_in_bytes;
- if (U16_IS_LEAD(uchars[offset]) && (offset < uchars_count - 1) && (U16_IS_TRAIL(uchars[offset+1]))) {
- // if it's a lead surrogate we must also copy the trail surrogate
+ if (U16_IS_LEAD(uchars[offset]) && (offset < uchars_count - 1)
+ && (U16_IS_TRAIL(uchars[offset+1]))) {
+ // if it's a lead surrogate we must also copy the trail
+ // surrogate
length_in_bytes = UCHARS_TO_BYTES(2);
}
else {
length_in_bytes = UCHARS_TO_BYTES(1);
}
boundaries.start_offset_in_bytes = UCHARS_TO_BYTES(offset);
- boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + length_in_bytes;
+ boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes
+ + length_in_bytes;
}
}
else { // data in binary
@@ -591,9 +603,12 @@
}
}
boundaries.start_offset_in_bytes = index;
- boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + 1;
+ boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes
+ + 1;
}
- else if (UTF32_ENC(self->encoding) && (!ucs2_mode || str_known_not_to_have_any_supplementary(self))) {
+ else if (UTF32_ENC(self->encoding)
+ && (!ucs2_mode
+ || str_known_not_to_have_any_supplementary(self))) {
if (index < 0) {
index += div_round_up(self->length_in_bytes, 4);
if (index < 0) {
@@ -601,9 +616,12 @@
}
}
boundaries.start_offset_in_bytes = index * 4;
- boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + 4;
+ boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes
+ + 4;
}
- else if (NON_NATIVE_UTF16_ENC(self->encoding) && (ucs2_mode || str_known_not_to_have_any_supplementary(self))) {
+ else if (NON_NATIVE_UTF16_ENC(self->encoding)
+ && (ucs2_mode
+ || str_known_not_to_have_any_supplementary(self))) {
if (index < 0) {
index += div_round_up(self->length_in_bytes, 2);
if (index < 0) {
@@ -611,10 +629,12 @@
}
}
boundaries.start_offset_in_bytes = UCHARS_TO_BYTES(index);
- boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes + 2;
+ boundaries.end_offset_in_bytes = boundaries.start_offset_in_bytes
+ + 2;
}
else {
- boundaries = self->encoding->methods.get_character_boundaries(self, index, ucs2_mode);
+ boundaries = self->encoding->methods.get_character_boundaries(self,
+ index, ucs2_mode);
}
}
@@ -632,11 +652,14 @@
return NULL;
}
}
- if (!self->encoding->single_byte_encoding && !str_is_stored_in_uchars(self)) {
+ if (!self->encoding->single_byte_encoding
+ && !str_is_stored_in_uchars(self)) {
str_try_making_data_uchars(self);
}
- character_boundaries_t first_boundaries = str_get_character_boundaries(self, first, ucs2_mode);
- character_boundaries_t last_boundaries = str_get_character_boundaries(self, last, ucs2_mode);
+ character_boundaries_t first_boundaries =
+ str_get_character_boundaries(self, first, ucs2_mode);
+ character_boundaries_t last_boundaries =
+ str_get_character_boundaries(self, last, ucs2_mode);
if (first_boundaries.start_offset_in_bytes == -1) {
if (last_boundaries.end_offset_in_bytes == -1) {
@@ -663,7 +686,8 @@
}
return str_new_copy_of_part(self, first_boundaries.start_offset_in_bytes,
- last_boundaries.end_offset_in_bytes - first_boundaries.start_offset_in_bytes);
+ last_boundaries.end_offset_in_bytes
+ - first_boundaries.start_offset_in_bytes);
}
static string_t *
@@ -672,12 +696,14 @@
if (self->length_in_bytes == 0) {
return NULL;
}
- if (!self->encoding->single_byte_encoding && !str_is_stored_in_uchars(self)) {
+ if (!self->encoding->single_byte_encoding
+ && !str_is_stored_in_uchars(self)) {
// if we can't access the bytes directly,
// try to convert the string in UTF-16
str_try_making_data_uchars(self);
}
- character_boundaries_t boundaries = str_get_character_boundaries(self, index, ucs2_mode);
+ character_boundaries_t boundaries = str_get_character_boundaries(self,
+ index, ucs2_mode);
if (boundaries.start_offset_in_bytes == -1) {
if (boundaries.end_offset_in_bytes == -1) {
return NULL;
@@ -699,7 +725,9 @@
boundaries.end_offset_in_bytes = self->length_in_bytes;
}
- return str_new_copy_of_part(self, boundaries.start_offset_in_bytes, boundaries.end_offset_in_bytes - boundaries.start_offset_in_bytes);
+ return str_new_copy_of_part(self, boundaries.start_offset_in_bytes,
+ boundaries.end_offset_in_bytes
+ - boundaries.start_offset_in_bytes);
}
static string_t *
@@ -717,12 +745,13 @@
str_set_stored_in_uchars(new_str, str_is_stored_in_uchars(str1));
long length_in_bytes = str1->length_in_bytes + str2->length_in_bytes;
- new_str->data.bytes = xmalloc(length_in_bytes);
+ GC_WB(&new_str->data.bytes, xmalloc(length_in_bytes));
if (str1->length_in_bytes > 0) {
memcpy(new_str->data.bytes, str1->data.bytes, str1->length_in_bytes);
}
if (str2->length_in_bytes > 0) {
- memcpy(new_str->data.bytes + str1->length_in_bytes, str2->data.bytes, str2->length_in_bytes);
+ memcpy(new_str->data.bytes + str1->length_in_bytes, str2->data.bytes,
+ str2->length_in_bytes);
}
new_str->capacity_in_bytes = new_str->length_in_bytes = length_in_bytes;
@@ -754,7 +783,8 @@
GC_WB(&self->data.bytes, bytes);
self->capacity_in_bytes = new_length_in_bytes;
}
- memcpy(self->data.bytes + self->length_in_bytes, str->data.bytes, str->length_in_bytes);
+ memcpy(self->data.bytes + self->length_in_bytes, str->data.bytes,
+ str->length_in_bytes);
self->length_in_bytes = new_length_in_bytes;
}
@@ -786,19 +816,23 @@
return false;
}
else {
- return (memcmp(self->data.bytes, str->data.bytes, self->length_in_bytes) == 0);
+ return (memcmp(self->data.bytes, str->data.bytes,
+ self->length_in_bytes) == 0);
}
}
else { // one is in uchars and the other is in binary
- if (!str_try_making_data_uchars(self) || !str_try_making_data_uchars(str)) {
- // one is in uchars but the other one can't be converted in uchars
+ if (!str_try_making_data_uchars(self)
+ || !str_try_making_data_uchars(str)) {
+ // one is in uchars but the other one can't be converted in
+ // uchars
return false;
}
if (self->length_in_bytes != str->length_in_bytes) {
return false;
}
else {
- return (memcmp(self->data.bytes, str->data.bytes, self->length_in_bytes) == 0);
+ return (memcmp(self->data.bytes, str->data.bytes,
+ self->length_in_bytes) == 0);
}
}
}
@@ -808,7 +842,8 @@
}
static long
-str_offset_in_bytes_to_index(string_t *self, long offset_in_bytes, bool ucs2_mode)
+str_offset_in_bytes_to_index(string_t *self, long offset_in_bytes,
+ bool ucs2_mode)
{
if ((offset_in_bytes >= self->length_in_bytes) || (offset_in_bytes < 0)) {
return -1;
@@ -825,7 +860,8 @@
long length = BYTES_TO_UCHARS(self->length_in_bytes);
long index = 0, i = 0;
for (;;) {
- if (U16_IS_LEAD(self->data.uchars[i]) && (i+1 < length) && U16_IS_TRAIL(self->data.uchars[i+1])) {
+ if (U16_IS_LEAD(self->data.uchars[i]) && (i+1 < length)
+ && U16_IS_TRAIL(self->data.uchars[i+1])) {
i += 2;
}
else {
@@ -845,20 +881,26 @@
if (self->encoding->single_byte_encoding) {
return offset_in_bytes;
}
- else if (UTF32_ENC(self->encoding) && (!ucs2_mode || str_known_not_to_have_any_supplementary(self))) {
+ else if (UTF32_ENC(self->encoding)
+ && (!ucs2_mode
+ || str_known_not_to_have_any_supplementary(self))) {
return offset_in_bytes / 4;
}
- else if (NON_NATIVE_UTF16_ENC(self->encoding) && (ucs2_mode || str_known_not_to_have_any_supplementary(self))) {
+ else if (NON_NATIVE_UTF16_ENC(self->encoding)
+ && (ucs2_mode
+ || str_known_not_to_have_any_supplementary(self))) {
return BYTES_TO_UCHARS(offset_in_bytes);
}
else {
- return self->encoding->methods.offset_in_bytes_to_index(self, offset_in_bytes, ucs2_mode);
+ return self->encoding->methods.offset_in_bytes_to_index(self,
+ offset_in_bytes, ucs2_mode);
}
}
}
static long
-str_offset_in_bytes_for_string(string_t *self, string_t *searched, long start_offset_in_bytes)
+str_offset_in_bytes_for_string(string_t *self, string_t *searched,
+ long start_offset_in_bytes)
{
if (start_offset_in_bytes >= self->length_in_bytes) {
return -1;
@@ -881,9 +923,13 @@
else {
increment = self->encoding->min_char_size;
}
- long max_offset_in_bytes = self->length_in_bytes - searched->length_in_bytes + 1;
- for (long offset_in_bytes = start_offset_in_bytes; offset_in_bytes < max_offset_in_bytes; offset_in_bytes += increment) {
- if (memcmp(self->data.bytes+offset_in_bytes, searched->data.bytes, searched->length_in_bytes) == 0) {
+ long max_offset_in_bytes = self->length_in_bytes
+ - searched->length_in_bytes + 1;
+ for (long offset_in_bytes = start_offset_in_bytes;
+ offset_in_bytes < max_offset_in_bytes;
+ offset_in_bytes += increment) {
+ if (memcmp(self->data.bytes+offset_in_bytes, searched->data.bytes,
+ searched->length_in_bytes) == 0) {
return offset_in_bytes;
}
}
@@ -891,7 +937,8 @@
}
static long
-str_index_for_string(string_t *self, string_t *searched, long start_index, bool ucs2_mode)
+str_index_for_string(string_t *self, string_t *searched, long start_index,
+ bool ucs2_mode)
{
str_must_have_compatible_encoding(self, searched);
str_make_same_format(self, searched);
@@ -901,7 +948,8 @@
start_offset_in_bytes = 0;
}
else {
- character_boundaries_t boundaries = str_get_character_boundaries(self, start_index, ucs2_mode);
+ character_boundaries_t boundaries = str_get_character_boundaries(self,
+ start_index, ucs2_mode);
if (boundaries.start_offset_in_bytes == -1) {
if (boundaries.end_offset_in_bytes == -1) {
return -1;
@@ -914,12 +962,13 @@
start_offset_in_bytes = boundaries.start_offset_in_bytes;
}
- long offset_in_bytes = str_offset_in_bytes_for_string(STR(self), searched, start_offset_in_bytes);
+ long offset_in_bytes = str_offset_in_bytes_for_string(RSTR(self), searched,
+ start_offset_in_bytes);
if (offset_in_bytes == -1) {
return -1;
}
- return str_offset_in_bytes_to_index(STR(self), offset_in_bytes, ucs2_mode);
+ return str_offset_in_bytes_to_index(RSTR(self), offset_in_bytes, ucs2_mode);
}
static bool
@@ -931,19 +980,16 @@
static string_t *
str_need_string(VALUE str)
{
- if (CLASS_OF(str) == rb_cRubyString) {
+ if (IS_RSTR(str)) {
return (string_t *)str;
}
-
if (TYPE(str) != T_STRING) {
str = rb_str_to_str(str);
}
- if (OBJC_CLASS(str) != rb_cRubyString) {
- return str_new_from_cfstring((CFStringRef)str);
- }
- else {
+ if (IS_RSTR(str)) {
return (string_t *)str;
}
+ return str_new_from_cfstring((CFStringRef)str);
}
//----------------------------------------------
@@ -955,9 +1001,9 @@
if (SPECIAL_CONST_P(str1) || SPECIAL_CONST_P(str2)) {
return Qnil;
}
- assert(OBJC_CLASS(str1) == rb_cRubyString); // TODO
- assert(OBJC_CLASS(str2) == rb_cRubyString); // TODO
- encoding_t *encoding = str_compatible_encoding(STR(str1), STR(str2));
+ assert(IS_RSTR(str1)); // TODO
+ assert(IS_RSTR(str2)); // TODO
+ encoding_t *encoding = str_compatible_encoding(RSTR(str1), RSTR(str2));
if (encoding == NULL) {
return Qnil;
}
@@ -966,20 +1012,18 @@
}
}
-
static VALUE
mr_str_s_alloc(VALUE klass)
{
return (VALUE)str_alloc();
}
-
static VALUE
mr_str_initialize(VALUE self, SEL sel, int argc, VALUE *argv)
{
if (argc > 0) {
assert(argc == 1);
- str_replace(STR(self), argv[0]);
+ str_replace(RSTR(self), argv[0]);
}
return self;
}
@@ -987,46 +1031,46 @@
static VALUE
mr_str_replace(VALUE self, SEL sel, VALUE arg)
{
- str_replace(STR(self), arg);
+ str_replace(RSTR(self), arg);
return self;
}
static VALUE
mr_str_clear(VALUE self, SEL sel)
{
- str_clear(STR(self));
+ str_clear(RSTR(self));
return self;
}
static VALUE
mr_str_chars_count(VALUE self, SEL sel)
{
- return INT2NUM(str_length(STR(self), false));
+ return INT2NUM(str_length(RSTR(self), false));
}
static VALUE
mr_str_length(VALUE self, SEL sel)
{
- return INT2NUM(str_length(STR(self), true));
+ return INT2NUM(str_length(RSTR(self), true));
}
static VALUE
mr_str_bytesize(VALUE self, SEL sel)
{
- return INT2NUM(str_bytesize(STR(self)));
+ return INT2NUM(str_bytesize(RSTR(self)));
}
static VALUE
mr_str_encoding(VALUE self, SEL sel)
{
- return (VALUE)STR(self)->encoding;
+ return (VALUE)RSTR(self)->encoding;
}
static VALUE
mr_str_getbyte(VALUE self, SEL sel, VALUE index)
{
unsigned char c;
- if (str_getbyte(STR(self), NUM2LONG(index), &c)) {
+ if (str_getbyte(RSTR(self), NUM2LONG(index), &c)) {
return INT2NUM(c);
}
else {
@@ -1037,7 +1081,8 @@
static VALUE
mr_str_setbyte(VALUE self, SEL sel, VALUE index, VALUE value)
{
- str_setbyte(STR(self), NUM2LONG(index), 0xFF & (unsigned long)NUM2LONG(value));
+ str_setbyte(RSTR(self), NUM2LONG(index),
+ 0xFF & (unsigned long)NUM2LONG(value));
return value;
}
@@ -1045,24 +1090,24 @@
mr_str_force_encoding(VALUE self, SEL sel, VALUE encoding)
{
encoding_t *enc;
- if (SPECIAL_CONST_P(encoding) || (OBJC_CLASS(encoding) != rb_cEncoding)) {
+ if (SPECIAL_CONST_P(encoding) || (CLASS_OF(encoding) != rb_cEncoding)) {
abort(); // TODO
}
enc = (encoding_t *)encoding;
- str_force_encoding(STR(self), enc);
+ str_force_encoding(RSTR(self), enc);
return self;
}
static VALUE
mr_str_is_valid_encoding(VALUE self, SEL sel)
{
- return str_is_valid_encoding(STR(self)) ? Qtrue : Qfalse;
+ return str_is_valid_encoding(RSTR(self)) ? Qtrue : Qfalse;
}
static VALUE
mr_str_is_ascii_only(VALUE self, SEL sel)
{
- return str_is_ruby_ascii_only(STR(self)) ? Qtrue : Qfalse;
+ return str_is_ruby_ascii_only(RSTR(self)) ? Qtrue : Qfalse;
}
static VALUE
@@ -1073,9 +1118,7 @@
VALUE index = argv[0];
switch (TYPE(index)) {
case T_FIXNUM:
- {
- ret = str_get_character_at(STR(self), FIX2LONG(index), true);
- }
+ ret = str_get_character_at(RSTR(self), FIX2LONG(index), true);
break;
case T_REGEXP:
@@ -1083,16 +1126,18 @@
case T_STRING:
{
- if (OBJC_CLASS(index) == rb_cRubyString) {
- string_t *searched = STR(index);
- if (str_include_string(STR(self), searched)) {
+ if (IS_RSTR(index)) {
+ string_t *searched = RSTR(index);
+ if (str_include_string(RSTR(self), searched)) {
return (VALUE)str_new_from_string(searched);
}
}
else {
- string_t *searched = str_new_from_cfstring((CFStringRef)index);
- if (str_include_string(STR(self), searched)) {
- // no need to duplicate the string as we just created it
+ string_t *searched =
+ str_new_from_cfstring((CFStringRef)index);
+ if (str_include_string(RSTR(self), searched)) {
+ // no need to duplicate the string as we just
+ // created it
return (VALUE)searched;
}
}
@@ -1103,16 +1148,18 @@
{
VALUE rb_start = 0, rb_end = 0;
int exclude_end = false;
- if (rb_range_values(index, &rb_start, &rb_end, &exclude_end)) {
+ if (rb_range_values(index, &rb_start, &rb_end,
+ &exclude_end)) {
long start = NUM2LONG(rb_start);
long end = NUM2LONG(rb_end);
if (exclude_end) {
--end;
}
- ret = str_get_characters(STR(self), start, end, true);
+ ret = str_get_characters(RSTR(self), start, end, true);
}
else {
- ret = str_get_character_at(STR(self), NUM2LONG(index), true);
+ ret = str_get_character_at(RSTR(self), NUM2LONG(index),
+ true);
}
}
break;
@@ -1128,7 +1175,7 @@
if ((start < 0) && (end >= 0)) {
end = -1;
}
- ret = str_get_characters(STR(self), start, end, true);
+ ret = str_get_characters(RSTR(self), start, end, true);
}
else {
rb_raise(rb_eArgError, "wrong number of arguments (%d for 1..2)", argc);
@@ -1160,7 +1207,7 @@
}
string_t *searched = str_need_string(rb_searched);
- long index = str_index_for_string(STR(self), searched, start_index, true);
+ long index = str_index_for_string(RSTR(self), searched, start_index, true);
if (index == -1) {
return Qnil;
}
@@ -1169,11 +1216,10 @@
}
}
-
static VALUE
mr_str_getchar(VALUE self, SEL sel, VALUE index)
{
- string_t *ret = str_get_character_at(STR(self), FIX2LONG(index), false);
+ string_t *ret = str_get_character_at(RSTR(self), FIX2LONG(index), false);
if (ret == NULL) {
return Qnil;
}
@@ -1185,7 +1231,7 @@
static VALUE
mr_str_plus(VALUE self, SEL sel, VALUE to_add)
{
- return (VALUE)str_plus_string(STR(self), str_need_string(to_add));
+ return (VALUE)str_plus_string(RSTR(self), str_need_string(to_add));
}
static VALUE
@@ -1197,7 +1243,7 @@
abort(); // TODO
default:
- str_concat_string(STR(self), str_need_string(to_concat));
+ str_concat_string(RSTR(self), str_need_string(to_concat));
}
return self;
}
@@ -1211,13 +1257,13 @@
if (TYPE(compared_to) == T_STRING) {
string_t *str;
- if (OBJC_CLASS(compared_to) == rb_cRubyString) {
- str = STR(compared_to);
+ if (IS_RSTR(compared_to)) {
+ str = RSTR(compared_to);
}
else {
str = str_new_from_cfstring((CFStringRef)compared_to);
}
- return str_is_equal_to_string(STR(self), str) ? Qtrue : Qfalse;
+ return str_is_equal_to_string(RSTR(self), str) ? Qtrue : Qfalse;
}
else {
return Qfalse;
@@ -1227,41 +1273,54 @@
static VALUE
mr_str_not_equal(VALUE self, SEL sel, VALUE compared_to)
{
- return mr_str_equal(self, sel, compared_to) == Qfalse ? Qtrue : Qfalse;
+ return RTEST(mr_str_equal(self, sel, compared_to)) ? Qfalse : Qtrue;
}
static VALUE
mr_str_include(VALUE self, SEL sel, VALUE searched)
{
- return str_include_string(STR(self), str_need_string(searched)) ? Qtrue : Qfalse;
+ return str_include_string(RSTR(self), str_need_string(searched))
+ ? Qtrue : Qfalse;
}
static VALUE
mr_str_is_stored_in_uchars(VALUE self, SEL sel)
{
- return str_is_stored_in_uchars(STR(self)) ? Qtrue : Qfalse;
+ return str_is_stored_in_uchars(RSTR(self)) ? Qtrue : Qfalse;
}
static VALUE
mr_str_to_s(VALUE self, SEL sel)
{
- if (OBJC_CLASS(self) != rb_cRubyString) {
+ if (CLASS_OF(self) != rb_cRubyString) {
return (VALUE)str_dup(self);
}
return self;
}
+static VALUE
+mr_str_intern(VALUE self, SEL sel)
+{
+ if (OBJ_TAINTED(self) && rb_safe_level() >= 1) {
+ rb_raise(rb_eSecurityError, "Insecure: can't intern tainted string");
+ }
+ str_make_data_binary(RSTR(self));
+ return ID2SYM(rb_intern(RSTR(self)->data.bytes));
+}
+
void
Init_String(void)
{
// TODO create NSString.m
rb_cNSString = (VALUE)objc_getClass("NSString");
assert(rb_cNSString != 0);
+ rb_cString = rb_cNSString;
rb_cNSMutableString = (VALUE)objc_getClass("NSMutableString");
assert(rb_cNSMutableString != 0);
rb_cRubyString = rb_define_class("String", rb_cNSMutableString);
- rb_objc_define_method(OBJC_CLASS(rb_cRubyString), "alloc", mr_str_s_alloc, 0);
+ rb_objc_define_method(*(VALUE *)rb_cRubyString, "alloc",
+ mr_str_s_alloc, 0);
rb_objc_define_method(rb_cRubyString, "initialize", mr_str_initialize, -1);
rb_objc_define_method(rb_cRubyString, "initialize_copy", mr_str_replace, 1);
@@ -1273,9 +1332,12 @@
rb_objc_define_method(rb_cRubyString, "bytesize", mr_str_bytesize, 0);
rb_objc_define_method(rb_cRubyString, "getbyte", mr_str_getbyte, 1);
rb_objc_define_method(rb_cRubyString, "setbyte", mr_str_setbyte, 2);
- rb_objc_define_method(rb_cRubyString, "force_encoding", mr_str_force_encoding, 1);
- rb_objc_define_method(rb_cRubyString, "valid_encoding?", mr_str_is_valid_encoding, 0);
- rb_objc_define_method(rb_cRubyString, "ascii_only?", mr_str_is_ascii_only, 0);
+ rb_objc_define_method(rb_cRubyString, "force_encoding",
+ mr_str_force_encoding, 1);
+ rb_objc_define_method(rb_cRubyString, "valid_encoding?",
+ mr_str_is_valid_encoding, 0);
+ rb_objc_define_method(rb_cRubyString, "ascii_only?",
+ mr_str_is_ascii_only, 0);
rb_objc_define_method(rb_cRubyString, "[]", mr_str_aref, -1);
rb_objc_define_method(rb_cRubyString, "index", mr_str_index, -1);
rb_objc_define_method(rb_cRubyString, "+", mr_str_plus, 1);
@@ -1286,11 +1348,87 @@
rb_objc_define_method(rb_cRubyString, "include?", mr_str_include, 1);
rb_objc_define_method(rb_cRubyString, "to_s", mr_str_to_s, 0);
rb_objc_define_method(rb_cRubyString, "to_str", mr_str_to_s, 0);
+ rb_objc_define_method(rb_cRubyString, "intern", mr_str_intern, 0);
// added for MacRuby
rb_objc_define_method(rb_cRubyString, "chars_count", mr_str_chars_count, 0);
rb_objc_define_method(rb_cRubyString, "getchar", mr_str_getchar, 1);
- // this method does not exist in Ruby and is there only for debugging purpose
- rb_objc_define_method(rb_cRubyString, "stored_in_uchars?", mr_str_is_stored_in_uchars, 0);
+ // this method does not exist in Ruby and is there only for debugging
+ // purpose
+ rb_objc_define_method(rb_cRubyString, "stored_in_uchars?",
+ mr_str_is_stored_in_uchars, 0);
}
+
+// MRI C-API compatibility.
+
+VALUE
+rb_str_new(const char *cstr, long len)
+{
+ string_t *str = str_alloc();
+ str_replace_with_bytes(str, cstr, len, ENCODING_BINARY);
+ return (VALUE)str;
+}
+
+VALUE
+rb_str_new2(const char *cstr)
+{
+ return rb_str_new(cstr, strlen(cstr));
+}
+
+VALUE
+rb_str_new3(VALUE source)
+{
+ string_t *str = str_alloc();
+ str_replace(str, source);
+ return (VALUE)str;
+}
+
+VALUE
+rb_str_new4(VALUE source)
+{
+ VALUE str = rb_str_new3(source);
+ // TODO: freeze str
+ return str;
+}
+
+const char *
+rb_str_cstr(VALUE str)
+{
+ if (IS_RSTR(str)) {
+ str_make_data_binary(RSTR(str));
+ return RSTR(str)->data.bytes;
+ }
+ return ""; // TODO
+}
+
+long
+rb_str_clen(VALUE str)
+{
+ if (IS_RSTR(str)) {
+ str_make_data_binary(RSTR(str));
+ return RSTR(str)->length_in_bytes;
+ }
+ return 0; // TODO
+}
+
+ID
+rb_to_id(VALUE name)
+{
+ VALUE tmp;
+ switch (TYPE(name)) {
+ default:
+ tmp = rb_check_string_type(name);
+ if (NIL_P(tmp)) {
+ rb_raise(rb_eTypeError, "%s is not a symbol",
+ RSTRING_PTR(rb_inspect(name)));
+ }
+ name = tmp;
+ /* fall through */
+ case T_STRING:
+ name = mr_str_intern(name, 0);
+ /* fall through */
+ case T_SYMBOL:
+ return SYM2ID(name);
+ }
+}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20100215/9d8d19fb/attachment-0001.html>
More information about the macruby-changes
mailing list