rubycf 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
@@ -0,0 +1,20 @@
1
+ Ruby extension for dealing with CoreFoundation types. Mostly designed for marshaling structures through binary plists.
2
+
3
+ See tests for usage.
4
+
5
+ To get this to work outside of the OS X, you need to compile lib/CoreFoundation and link against it when building the gem. This isn't build into extconf.rb yet, but it will need to be in the future.
6
+
7
+ About CFData:
8
+ Since Ruby doesn't treat strings any differently from raw data and CoreFoundation does, there needed to be a way to specify if a string is a string or if it's just data. For this purpose, I've created the class RubyCF::Data, which is just a container for a ruby string. When a RubyCF::Data object is passed into the plist encoder, it will encode the data as CFData. Likewise, when a CFData object is encountered while decoding a plist, a RubyCF::Data object will be created.
9
+
10
+ TODO
11
+ --------------
12
+ - rubyland convenience methods
13
+
14
+
15
+ ==========
16
+ notes:
17
+
18
+ Building CFLite:
19
+ http://cafeine.crulrg.ulaval.ca/users/dccote/weblog/0514e/CoreFoundation_Lite_on_Linux.html
20
+ http://developer.apple.com/opensource/cflite.html
data/extconf.rb ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby -wKU
2
+
3
+ require 'mkmf'
4
+
5
+ if RUBY_PLATFORM.downcase.include?("darwin")
6
+ with_ldflags($LDFLAGS + ' -framework Foundation') {true}
7
+ else
8
+ with_ldflags($LIBS + ' -lCoreFoundation') {true}
9
+ end
10
+ create_makefile('rubycf', 'lib')
data/lib/cfarray.c ADDED
@@ -0,0 +1,32 @@
1
+ #import "cfarray.h"
2
+ #import "plist.h"
3
+
4
+ VALUE rbcf_array_convert_to_ruby(CFArrayRef array_ref) {
5
+
6
+ CFIndex count = CFArrayGetCount(array_ref);
7
+ CFIndex i = 0;
8
+
9
+ VALUE array = rb_ary_new();
10
+
11
+ for(i=0; i < count; ++i){
12
+ rb_ary_push(array, rbcf_plist_convert_to_ruby(CFArrayGetValueAtIndex(array_ref, i)));
13
+ }
14
+
15
+ OBJ_TAINT(array);
16
+
17
+ return array;
18
+ }
19
+
20
+ CFArrayRef rbcf_array_convert_to_cf(VALUE array) {
21
+ CFIndex size = FIX2INT(rb_funcall(array, rb_intern("size"), 0));
22
+ CFIndex i;
23
+ CFTypeRef *values = (CFTypeRef *)malloc(size * sizeof(CFTypeRef));
24
+ for(i = 0; i < size; ++i){
25
+ values[i] = rbcf_plist_convert_to_cf(rb_ary_entry(array, i));
26
+ }
27
+
28
+ CFArrayRef newArray = CFArrayCreate(kCFAllocatorDefault, values, size, &kCFTypeArrayCallBacks);
29
+ rbcf_register_for_release(newArray);
30
+
31
+ return newArray;
32
+ }
data/lib/cfarray.h ADDED
@@ -0,0 +1,5 @@
1
+ #include <ruby.h>
2
+ #include <CoreFoundation/CFArray.h>
3
+
4
+ VALUE rbcf_array_convert_to_ruby(CFArrayRef array_ref);
5
+ CFArrayRef rbcf_array_convert_to_cf(VALUE array);
data/lib/cfdata.c ADDED
@@ -0,0 +1,19 @@
1
+ #include "cfdata.h"
2
+ #include "plist.h"
3
+
4
+ VALUE rbcf_data_convert_to_ruby(CFDataRef data_ref) {
5
+ VALUE rubydata = rb_eval_string("RubyCF::Data.new('')");
6
+ rb_funcall(rubydata, rb_intern("data="), 1, rb_str_new((char *)CFDataGetBytePtr(data_ref), CFDataGetLength(data_ref)));
7
+ OBJ_TAINT(rubydata);
8
+ return rubydata;
9
+ }
10
+
11
+
12
+ CFDataRef rbcf_data_convert_to_cf(VALUE data_obj) {
13
+ VALUE data_str = rb_iv_get(data_obj, "@data");
14
+
15
+ CFDataRef outData = CFDataCreate(kCFAllocatorDefault, (UInt8 *)RSTRING(data_str)->ptr, RSTRING(data_str)->len);
16
+ rbcf_register_for_release(outData);
17
+
18
+ return outData;
19
+ }
data/lib/cfdata.h ADDED
@@ -0,0 +1,5 @@
1
+ #include <ruby.h>
2
+ #include <CoreFoundation/CFData.h>
3
+
4
+ VALUE rbcf_data_convert_to_ruby(CFDataRef data_ref);
5
+ CFDataRef rbcf_data_convert_to_cf(VALUE data);
data/lib/cfdate.c ADDED
@@ -0,0 +1,18 @@
1
+ #import "cfdate.h"
2
+
3
+ VALUE rbcf_date_convert_to_ruby(CFDateRef date_ref) {
4
+ //fixme: this isn't 100% accurate, but should be close enough
5
+ CFDateRef currentTime = CFDateCreate(NULL, CFAbsoluteTimeGetCurrent());
6
+ CFTimeInterval difference = CFDateGetTimeIntervalSinceDate(date_ref, currentTime);
7
+
8
+ return rb_funcall(rb_funcall(rb_cTime, rb_intern("now"), 0), rb_intern("+"), 1, rb_float_new(difference));
9
+ }
10
+
11
+ CFDateRef rbcf_date_convert_to_cf(VALUE time) {
12
+ VALUE reference_date = rb_eval_string("Time.gm(2001, 'jan', 1)");
13
+ CFTimeInterval difference = NUM2DBL(rb_funcall(time, rb_intern("-"), 1, reference_date));
14
+ CFDateRef date = CFDateCreate(kCFAllocatorDefault, difference);
15
+ rbcf_register_for_release(date);
16
+
17
+ return date;
18
+ }
data/lib/cfdate.h ADDED
@@ -0,0 +1,5 @@
1
+ #include <ruby.h>
2
+ #include <CoreFoundation/CFDate.h>
3
+
4
+ VALUE rbcf_date_convert_to_ruby(CFDateRef date_ref);
5
+ CFDateRef rbcf_date_convert_to_cf(VALUE time);
@@ -0,0 +1,49 @@
1
+ #import "cfdictionary.h"
2
+ #import "plist.h"
3
+ #import "cfstring.h"
4
+
5
+ VALUE rbcf_dict_convert_to_ruby(CFDictionaryRef dict_ref) {
6
+
7
+ CFIndex count = CFDictionaryGetCount(dict_ref);
8
+ CFIndex i;
9
+
10
+ CFTypeRef *keys = (CFTypeRef *)malloc(count * sizeof(CFTypeRef));
11
+ CFTypeRef *values = (CFTypeRef *)malloc(count * sizeof(CFTypeRef));
12
+ CFDictionaryGetKeysAndValues(dict_ref, (const void **)keys, (const void **)values);
13
+
14
+ VALUE hash = rb_hash_new();
15
+
16
+ for(i=0; i < count; ++i){
17
+ rb_hash_aset(hash, rbcf_string_convert_to_ruby(keys[i]), rbcf_plist_convert_to_ruby(values[i]));
18
+ }
19
+
20
+ free(keys);
21
+ free(values);
22
+
23
+ OBJ_TAINT(hash);
24
+
25
+ return hash;
26
+ }
27
+
28
+ CFDictionaryRef rbcf_dict_convert_to_cf(VALUE hash) {
29
+
30
+ VALUE flat_hash = rb_funcall(hash, rb_intern("to_a"), 0);
31
+ CFIndex size = FIX2INT(rb_funcall(hash, rb_intern("size"), 0));
32
+ CFTypeRef *keys = (CFTypeRef *)malloc(size * sizeof(CFTypeRef));
33
+ CFTypeRef *values = (CFTypeRef *)malloc(size * sizeof(CFTypeRef));
34
+
35
+ CFIndex i;
36
+ for(i = 0; i < size; ++i){
37
+ // Ruby Hash keys can be any object. Convert keys into strings before using as CFDictionary keys.
38
+ keys[i] = rbcf_plist_convert_to_cf(rb_funcall(rb_ary_entry(rb_ary_entry(flat_hash, i), 0), rb_intern("to_s"), 0));
39
+ values[i] = rbcf_plist_convert_to_cf(rb_ary_entry(rb_ary_entry(flat_hash, i), 1));
40
+ }
41
+
42
+ CFDictionaryRef dictionary = CFDictionaryCreate(kCFAllocatorDefault, keys, values, size, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
43
+ rbcf_register_for_release(dictionary);
44
+
45
+ free(keys);
46
+ free(values);
47
+
48
+ return dictionary;
49
+ }
@@ -0,0 +1,5 @@
1
+ #include <ruby.h>
2
+ #include <CoreFoundation/CFDictionary.h>
3
+
4
+ VALUE rbcf_dict_convert_to_ruby(CFDictionaryRef dict_ref);
5
+ CFDictionaryRef rbcf_dict_convert_to_cf(VALUE hash);
data/lib/cfnumber.c ADDED
@@ -0,0 +1,55 @@
1
+ #include "cfnumber.h"
2
+
3
+ VALUE rbcf_boolean_convert_to_ruby(CFBooleanRef bool_ref) {
4
+ if(bool_ref == kCFBooleanTrue){
5
+ return Qtrue;
6
+ }
7
+ else {
8
+ return Qfalse;
9
+ }
10
+ }
11
+
12
+ VALUE rbcf_number_convert_to_ruby(CFNumberRef number_ref) {
13
+ if(CFNumberIsFloatType(number_ref)){
14
+ double value = 0.0;
15
+ if(CFNumberGetValue(number_ref, kCFNumberDoubleType, &value)){
16
+ return rb_float_new(value);
17
+ }
18
+ }
19
+ else{
20
+ long value = 0;
21
+ if(CFNumberGetValue(number_ref, kCFNumberLongType, &value)){
22
+ return INT2NUM(value);
23
+ }
24
+ }
25
+
26
+ return Qnil;
27
+ }
28
+
29
+ CFBooleanRef rbcf_boolean_convert_to_cf(VALUE boolean) {
30
+ if(boolean == Qtrue){
31
+ return kCFBooleanTrue;
32
+ }
33
+ else {
34
+ return kCFBooleanFalse;
35
+ }
36
+ }
37
+
38
+ CFNumberRef rbcf_number_convert_to_cf(VALUE number) {
39
+ if(rb_obj_is_kind_of(number, rb_cInteger) == Qtrue){
40
+ long value = NUM2LONG(number);
41
+ CFNumberRef outnum = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &value);
42
+ rbcf_register_for_release(outnum);
43
+ return outnum;
44
+ }
45
+ else if(rb_obj_is_kind_of(number, rb_cFloat) == Qtrue) {
46
+ double value = NUM2DBL(number);
47
+ CFNumberRef outnum = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value);
48
+ rbcf_register_for_release(outnum);
49
+ return outnum;
50
+ }
51
+ else {
52
+ return NULL;
53
+ }
54
+
55
+ }
data/lib/cfnumber.h ADDED
@@ -0,0 +1,8 @@
1
+ #include <ruby.h>
2
+ #include <CoreFoundation/CFNumber.h>
3
+
4
+ VALUE rbcf_boolean_convert_to_ruby(CFBooleanRef bool_ref);
5
+ VALUE rbcf_number_convert_to_ruby(CFNumberRef number_ref);
6
+
7
+ CFBooleanRef rbcf_boolean_convert_to_cf(VALUE boolean);
8
+ CFNumberRef rbcf_number_convert_to_cf(VALUE number);
data/lib/cfstring.c ADDED
@@ -0,0 +1,30 @@
1
+ #include "cfstring.h"
2
+
3
+ VALUE rbcf_string_convert_to_ruby(CFStringRef string_ref) {
4
+
5
+ char *buffer;
6
+ CFIndex bufferSize = CFStringGetLength(string_ref) + 1;
7
+ VALUE rubystring;
8
+
9
+ buffer = malloc(bufferSize + 1);
10
+
11
+ if(CFStringGetCString(string_ref, buffer, bufferSize, kCFStringEncodingASCII)){
12
+ rubystring = rb_str_new2(buffer);
13
+ OBJ_TAINT(rubystring);
14
+ }
15
+ else{
16
+ rubystring = Qnil;
17
+ }
18
+
19
+ free(buffer);
20
+ return rubystring;
21
+ }
22
+
23
+ CFStringRef rbcf_string_convert_to_cf(VALUE string) {
24
+
25
+ CFIndex num_bytes;
26
+ char *bytes = rb_str2cstr(string, &num_bytes);
27
+ CFStringRef cfstring = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)bytes, num_bytes, kCFStringEncodingASCII, false);
28
+ rbcf_register_for_release(cfstring);
29
+ return cfstring;
30
+ }
data/lib/cfstring.h ADDED
@@ -0,0 +1,5 @@
1
+ #include <ruby.h>
2
+ #include <CoreFoundation/CFString.h>
3
+
4
+ VALUE rbcf_string_convert_to_ruby(CFStringRef string_ref);
5
+ CFStringRef rbcf_string_convert_to_cf(VALUE string);
data/lib/plist.c ADDED
@@ -0,0 +1,180 @@
1
+ #include "plist.h"
2
+
3
+ #include <CoreFoundation/CFBase.h>
4
+ #include <CoreFoundation/CFString.h>
5
+ #include <CoreFoundation/CFNumber.h>
6
+ #include <CoreFoundation/CFStream.h>
7
+ #include <CoreFoundation/CFDictionary.h>
8
+ #include <CoreFoundation/CFArray.h>
9
+
10
+ #include "cfstring.h"
11
+ #include "cfnumber.h"
12
+ #include "cfdate.h"
13
+ #include "cfdictionary.h"
14
+ #include "cfarray.h"
15
+ #include "cfdata.h"
16
+
17
+ void rbcf_reset_release_pool();
18
+ static CFMutableArrayRef rbcf_plist_generation_release_pool;
19
+
20
+ static const void *rbcf_retain(CFAllocatorRef ref, const void *obj){
21
+ CFRetain(obj);
22
+ }
23
+
24
+ static void rbcf_release(CFAllocatorRef ref, const void *obj){
25
+ CFRelease(obj);
26
+ }
27
+
28
+ static const CFArrayCallBacks poolarraycallbacks = {
29
+ 0,
30
+ rbcf_retain,
31
+ rbcf_release,
32
+ NULL,
33
+ NULL
34
+ };
35
+
36
+ void rbcf_register_for_release(CFTypeRef obj) {
37
+ if(!rbcf_plist_generation_release_pool){
38
+ rbcf_plist_generation_release_pool = CFArrayCreateMutable(kCFAllocatorDefault, 0, &poolarraycallbacks);
39
+ }
40
+ CFArrayAppendValue(rbcf_plist_generation_release_pool, obj);
41
+ CFRelease(obj);
42
+ }
43
+
44
+ void rbcf_reset_release_pool() {
45
+ if(rbcf_plist_generation_release_pool){
46
+ CFRelease(rbcf_plist_generation_release_pool);
47
+ rbcf_plist_generation_release_pool = NULL;
48
+ }
49
+ }
50
+
51
+ VALUE rbcf_plist_convert_to_ruby(CFPropertyListRef plist) {
52
+ CFTypeID plist_type_id = CFGetTypeID(plist);
53
+
54
+ if(plist_type_id == CFStringGetTypeID()){
55
+ return rbcf_string_convert_to_ruby(plist);
56
+ }
57
+ else if(plist_type_id == CFBooleanGetTypeID()){
58
+ return rbcf_boolean_convert_to_ruby(plist);
59
+ }
60
+ else if(plist_type_id == CFNumberGetTypeID()){
61
+ return rbcf_number_convert_to_ruby(plist);
62
+ }
63
+ else if(plist_type_id == CFDateGetTypeID()){
64
+ return rbcf_date_convert_to_ruby(plist);
65
+ }
66
+ else if(plist_type_id == CFDataGetTypeID()){
67
+ return rbcf_data_convert_to_ruby(plist);
68
+ }
69
+ else if(plist_type_id == CFDictionaryGetTypeID()){
70
+ return rbcf_dict_convert_to_ruby(plist);
71
+ }
72
+ else if(plist_type_id == CFArrayGetTypeID()){
73
+ return rbcf_array_convert_to_ruby(plist);
74
+ }
75
+ else{
76
+ return Qnil;
77
+ }
78
+ }
79
+
80
+ CFPropertyListRef rbcf_plist_convert_to_cf(VALUE structure) {
81
+ VALUE out;
82
+
83
+ if(rb_obj_is_kind_of(structure, rb_cString) == Qtrue){
84
+ return rbcf_string_convert_to_cf(structure);
85
+ }
86
+ else if(structure == Qtrue || structure == Qfalse){
87
+ return rbcf_boolean_convert_to_cf(structure);
88
+ }
89
+ else if(rb_obj_is_kind_of(structure, rb_cNumeric) == Qtrue){
90
+ return rbcf_number_convert_to_cf(structure);
91
+ }
92
+ else if(rb_obj_is_kind_of(structure, rb_cTime) == Qtrue){
93
+ return rbcf_date_convert_to_cf(structure);
94
+ }
95
+ else if(rb_obj_is_kind_of(structure, rb_eval_string("RubyCF::Data")) == Qtrue){
96
+ return rbcf_data_convert_to_cf(structure);
97
+ }
98
+ else if(rb_obj_is_kind_of(structure, rb_cArray) == Qtrue){
99
+ return rbcf_array_convert_to_cf(structure);
100
+ }
101
+ else if(rb_obj_is_kind_of(structure, rb_cHash) == Qtrue){
102
+ return rbcf_dict_convert_to_cf(structure);
103
+ }
104
+ else if(rb_respond_to(structure, rb_intern("to_hash"))){
105
+ return rbcf_dict_convert_to_cf(rb_funcall(structure, rb_intern("to_hash"), 0));
106
+ }
107
+ // default (depricated) behavior of to_a is to return [self], which is not helpful
108
+ else if(rb_respond_to(structure, rb_intern("to_a")) &&
109
+ rb_funcall(out = rb_funcall(structure, rb_intern("to_a"), 0), rb_intern("=="), 1, rb_ary_new3(1, structure)) == Qfalse
110
+ ){
111
+ return rbcf_array_convert_to_cf(out);
112
+ }
113
+ else if(rb_respond_to(structure, rb_intern("to_f"))){
114
+ return rbcf_number_convert_to_cf(rb_funcall(structure, rb_intern("to_f"), 0));
115
+ }
116
+ else if(rb_respond_to(structure, rb_intern("to_int"))){
117
+ return rbcf_number_convert_to_cf(rb_funcall(structure, rb_intern("to_i"), 0));
118
+ }
119
+ else if(rb_respond_to(structure, rb_intern("to_str"))){
120
+ return rbcf_string_convert_to_cf(rb_funcall(structure, rb_intern("to_s"), 0));
121
+ }
122
+ else {
123
+ return NULL;
124
+ }
125
+ }
126
+
127
+
128
+ VALUE rbcf_plist_parse(VALUE self, VALUE data) {
129
+ CFPropertyListFormat format; // the format of the plist
130
+ CFStringRef errorString; // Parsing error string
131
+
132
+ if(rb_obj_is_kind_of(data, rb_cString) == Qtrue){
133
+ CFReadStreamRef stream = CFReadStreamCreateWithBytesNoCopy(NULL, (UInt8 *)RSTRING(data)->ptr, RSTRING(data)->len, kCFAllocatorNull);
134
+
135
+ if(CFReadStreamOpen(stream)){
136
+ CFPropertyListRef plist = CFPropertyListCreateFromStream(NULL, stream, 0, kCFPropertyListImmutable, &format, &errorString);
137
+ CFReadStreamClose(stream);
138
+ CFRelease(stream);
139
+ if(plist){
140
+ VALUE plist_value = rbcf_plist_convert_to_ruby(plist);
141
+ CFRelease(plist);
142
+ rbcf_reset_release_pool();
143
+ return plist_value;
144
+ }
145
+
146
+ }
147
+ }
148
+
149
+ rbcf_reset_release_pool();
150
+ return Qnil;
151
+ }
152
+
153
+
154
+ VALUE rbcf_plist_encode(int argc, VALUE *argv, VALUE self) {
155
+ VALUE structure, encoding;
156
+ rb_scan_args(argc, argv, "11", &structure, &encoding);
157
+
158
+ CFPropertyListFormat format = kCFPropertyListBinaryFormat_v1_0; // the format of the plist
159
+ CFStringRef errorString; // Parsing error string
160
+
161
+ CFPropertyListRef cf_structure = rbcf_plist_convert_to_cf(structure);
162
+ CFWriteStreamRef stream = CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorDefault, kCFAllocatorDefault);
163
+ if(CFWriteStreamOpen(stream)){
164
+ CFIndex num_bytes = CFPropertyListWriteToStream(cf_structure, stream, format, &errorString);
165
+ if(num_bytes > 0){
166
+ CFTypeRef data = CFWriteStreamCopyProperty(stream, kCFStreamPropertyDataWritten);
167
+ rbcf_register_for_release(data);
168
+ CFRelease(stream);
169
+ if(data && CFGetTypeID(data) == CFDataGetTypeID()){
170
+ VALUE out_string = rb_str_new((char *)CFDataGetBytePtr(data), CFDataGetLength(data));
171
+ rbcf_reset_release_pool();
172
+ return out_string;
173
+ }
174
+ }
175
+ }
176
+
177
+ rbcf_reset_release_pool();
178
+ return Qnil;
179
+ }
180
+
data/lib/plist.h ADDED
@@ -0,0 +1,12 @@
1
+ #include <ruby.h>
2
+ #include <CoreFoundation/CFPropertyList.h>
3
+
4
+ RUBY_EXTERN VALUE rb_cCFData;
5
+
6
+ VALUE rbcf_plist_parse(VALUE self, VALUE data);
7
+ VALUE rbcf_plist_encode(int argc, VALUE *argv, VALUE self);
8
+
9
+ VALUE rbcf_plist_convert_to_ruby(CFPropertyListRef plist);
10
+ CFPropertyListRef rbcf_plist_convert_to_cf(VALUE structure);
11
+
12
+ void rbcf_register_for_release(CFTypeRef obj);
data/lib/rubycf.c ADDED
@@ -0,0 +1,27 @@
1
+ /*
2
+ * rubycf.c
3
+ * rubycf
4
+ *
5
+ * Created by Dave Grijalva on 12/22/08.
6
+ * Copyright 2008 __MyCompanyName__. All rights reserved.
7
+ *
8
+ */
9
+
10
+ #include <ruby.h>
11
+ #include <CoreFoundation/CoreFoundation.h>
12
+ #include "plist.h"
13
+
14
+ static VALUE rb_mRubyCF;
15
+ static VALUE rb_cPlist;
16
+
17
+ void Init_rubycf (void)
18
+ {
19
+ // Add the initialization code of your module here.
20
+ rb_mRubyCF = rb_define_module("RubyCF");
21
+
22
+ rb_cPlist = rb_define_class_under(rb_mRubyCF, "PList", rb_cObject);
23
+ rb_define_module_function(rb_cPlist, "parse", rbcf_plist_parse, 1);
24
+ rb_define_module_function(rb_cPlist, "encode", rbcf_plist_encode, -1);
25
+
26
+ rb_require("rubycf_extensions.rb");
27
+ }
@@ -0,0 +1,59 @@
1
+ # Extensions to the build in C functions
2
+
3
+ module RubyCF
4
+ class PList
5
+ class << self
6
+ alias decode parse
7
+ end
8
+
9
+ def self.parse_file file
10
+ self.parse(file.is_a?(File) ? file.read : File.read(file))
11
+ end
12
+ end
13
+
14
+ # CF handles raw data different from strings. Ruby treats them the same.
15
+ # use RubyCF::Data objects to tell the plist encoder to treat the objects
16
+ # as data.
17
+ class Data
18
+ attr_reader :data
19
+
20
+ def self.from_file file
21
+ Data.new(file.is_a?(File) ? file.read : File.read(file))
22
+ end
23
+
24
+ def initialize string
25
+ self.data = string
26
+ end
27
+
28
+ def inspect
29
+ "RubyCF::Data #{@data.size} bytes"
30
+ end
31
+
32
+ def == other
33
+ if(other.is_a?(RubyCF::Data))
34
+ return other.data == @data
35
+ else
36
+ return other == @data
37
+ end
38
+ end
39
+
40
+ def data= string
41
+ @data = string.to_s
42
+ end
43
+
44
+ end
45
+ end
46
+
47
+ class Object
48
+ def to_plist
49
+ # supported types
50
+ # [Integer, Float, String, Array, Hash, RubyCF::Data].each do |klass|
51
+ return RubyCF::PList.encode(self) #if self.is_a? klass
52
+ # end
53
+ #
54
+ # if self.resond_to? :to_hash
55
+ # elsif self.resond_to? :to_a
56
+ # elsif self.resond_to?
57
+ #
58
+ end
59
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubycf
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Dave Grijalva
8
+ autorequire: rubycf
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-11-02 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: dgrijalva@ngmoco.com
18
+ executables: []
19
+
20
+ extensions:
21
+ - extconf.rb
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - lib/cfarray.c
26
+ - lib/cfarray.h
27
+ - lib/cfdata.c
28
+ - lib/cfdata.h
29
+ - lib/cfdate.c
30
+ - lib/cfdate.h
31
+ - lib/cfdictionary.c
32
+ - lib/cfdictionary.h
33
+ - lib/cfnumber.c
34
+ - lib/cfnumber.h
35
+ - lib/cfstring.c
36
+ - lib/cfstring.h
37
+ - lib/plist.c
38
+ - lib/plist.h
39
+ - lib/rubycf.c
40
+ - lib/rubycf_extensions.rb
41
+ - README
42
+ has_rdoc: true
43
+ homepage: http://ngmoco.com/
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ requirements: []
64
+
65
+ rubyforge_project:
66
+ rubygems_version: 1.3.5
67
+ signing_key:
68
+ specification_version: 3
69
+ summary: Bindings for Apple Core Foundation
70
+ test_files: []
71
+