Skip to content
Browse files

Make Symbol NSCoding compliant

 - Added `-classForKeyedArchiver`, `-encodeWithCoder:` and `-initWithCoder:` so that symbols can be archived in Cocoa
 - Added `-copy` returning `self` (copying a symbol does not make sense) so that copied symbols return symbols, not strings
 - Fixes 7716974



git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@3863 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
1 parent a86d5f2 commit a8bd277f135849eba71a5da018280b02d9bba0ef Thibault Martin-Lagardette committed Mar 25, 2010
Showing with 69 additions and 0 deletions.
  1. +14 −0 NSString.m
  2. +3 −0 encoding.h
  3. +16 −0 spec/macruby/core/symbol_spec.rb
  4. +36 −0 symbol.c
View
14 NSString.m
@@ -180,6 +180,20 @@
}
void
+rb_str_NSCoder_encode(void *coder, VALUE str, const char *key)
+{
+ NSString *nskey = [NSString stringWithUTF8String:key];
+ [(NSCoder *)coder encodeObject:(NSString *)str forKey:nskey];
+}
+
+VALUE
+rb_str_NSCoder_decode(void *coder, const char *key)
+{
+ NSString *nskey = [NSString stringWithUTF8String:key];
+ return OC2RB([(NSCoder *)coder decodeObjectForKey:nskey]);
+}
+
+void
Init_NSString(void)
{
rb_cNSString = (VALUE)objc_getClass("NSString");
View
3 encoding.h
@@ -289,6 +289,9 @@ str_set_valid_encoding(rb_str_t *self, bool status)
STRING_VALID_ENCODING);
}
+void rb_str_NSCoder_encode(void *coder, VALUE str, const char *key);
+VALUE rb_str_NSCoder_decode(void *coder, const char *key);
+
VALUE mr_enc_s_is_compatible(VALUE klass, SEL sel, VALUE str1, VALUE str2);
VALUE rb_str_intern_fast(VALUE str);
VALUE rstr_aref(VALUE str, SEL sel, int argc, VALUE *argv);
View
16 spec/macruby/core/symbol_spec.rb
@@ -0,0 +1,16 @@
+require File.dirname(__FILE__) + "/../spec_helper"
+
+describe "A Symbol" do
+ it "should conform to the NSCoding protocol" do
+ # framework 'Foundation'
+ NSKeyedUnarchiver.unarchiveObjectWithData(NSKeyedArchiver.archivedDataWithRootObject(:test)).should == :test
+ end
+
+ it "should return 'Symbol' on -classForKeyedArchiver" do
+ :sym.classForKeyedArchiver.class.should == Symbol.class
+ end
+
+ it "should return self on -copy" do
+ :sym.copy.__id__.should == :sym.__id__
+ end
+end
View
36 symbol.c
@@ -673,6 +673,14 @@ rsym_swapcase(VALUE sym, SEL sel)
return ID2SYM(rb_intern_str(rstr_swapcase(RSYM(sym)->str, sel)));
}
+// Cocoa primitives
+
+static void *
+rsym_imp_copy(void *rcv, SEL sel)
+{
+ return rcv;
+}
+
static CFIndex
rsym_imp_length(void *rcv, SEL sel)
{
@@ -685,6 +693,26 @@ rsym_imp_characterAtIndex(void *rcv, SEL sel, CFIndex idx)
return CFStringGetCharacterAtIndex((CFStringRef)RSYM(rcv)->str, idx);
}
+#define RSYM_NSCODER_KEY "MRSymbolStr"
+
+static void
+rsym_imp_encodeWithCoder(void *rcv, SEL sel, void *coder)
+{
+ rb_str_NSCoder_encode(coder, RSYM(rcv)->str, RSYM_NSCODER_KEY);
+}
+
+static VALUE
+rsym_imp_initWithCoder(void *rcv, SEL sel, void *coder)
+{
+ return ID2SYM(rb_intern_str(rb_str_NSCoder_decode(coder, RSYM_NSCODER_KEY)));
+}
+
+static Class
+rsym_imp_classForKeyedArchiver(void *rcv, SEL sel)
+{
+ return (Class)rb_cSymbol;
+}
+
void
Init_Symbol(void)
{
@@ -720,8 +748,16 @@ Init_Symbol(void)
rb_objc_define_method(rb_cSymbol, "capitalize", rsym_capitalize, 0);
// Cocoa primitives.
+ rb_objc_install_method2((Class)rb_cSymbol, "copy",
+ (IMP)rsym_imp_copy);
rb_objc_install_method2((Class)rb_cSymbol, "length",
(IMP)rsym_imp_length);
rb_objc_install_method2((Class)rb_cSymbol, "characterAtIndex:",
(IMP)rsym_imp_characterAtIndex);
+ rb_objc_install_method2((Class)rb_cSymbol, "encodeWithCoder:",
+ (IMP)rsym_imp_encodeWithCoder);
+ rb_objc_install_method2((Class)rb_cSymbol, "initWithCoder:",
+ (IMP)rsym_imp_initWithCoder);
+ rb_objc_install_method2((Class)rb_cSymbol, "classForKeyedArchiver",
+ (IMP)rsym_imp_classForKeyedArchiver);
}

0 comments on commit a8bd277

Please sign in to comment.
Something went wrong with that request. Please try again.