rubycf 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+