0
static VALUE id_binary;
0
static VALUE id_openstep;
0
VALUE convertPropertyListRef(CFPropertyListRef plist);
0
VALUE convertStringRef(CFStringRef plist);
0
VALUE convertDictionaryRef(CFDictionaryRef plist);
0
int count = rb_scan_args(argc, argv, "11", &io, &retFormat);
0
if (count < 2) retFormat = Qfalse;
0
- //if (RTEST(rb_obj_is_kind_of(io, rb_cIO))) {
0
if (RTEST(rb_respond_to(io, id_read))) {
0
buffer = rb_funcall(io, id_read, 0);
0
- CFReadStreamRef readStream = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8*)RSTRING(buffer)->ptr, RSTRING(buffer)->len, kCFAllocatorNull);
0
+ // For some reason, the CFReadStream version doesn't work with input < 6 characters
0
+ // but the CFDataRef version doesn't return format
0
+ // So lets use the CFDataRef version unless format is requested
0
CFStringRef error = NULL;
0
+ CFPropertyListRef plist;
0
CFPropertyListFormat format;
0
- CFReadStreamOpen(readStream);
0
- CFPropertyListRef plist = CFPropertyListCreateFromStream(kCFAllocatorDefault, readStream, 0, kCFPropertyListImmutable, &format, &error);
0
- CFReadStreamClose(readStream);
0
- CFRelease(readStream);
0
+ if (RTEST(retFormat)) {
0
+ // Format was requested
0
+ // now just in case, if the input is < 6 characters, we will pad it out with newlines
0
+ // we could do this in all cases, but I don't think it will work with binary
0
+ // even though binary shouldn't be < 6 characters
0
+ if (RSTRING(buffer)->len < 6) {
0
+ bytes = ALLOC_N(UInt8, 6);
0
+ memset(bytes, '\n', 6);
0
+ MEMCPY(bytes, RSTRING(buffer)->ptr, UInt8, RSTRING(buffer)->len);
0
+ bytes = (UInt8 *)RSTRING(buffer)->ptr;
0
+ len = RSTRING(buffer)->len;
0
+ CFReadStreamRef readStream = CFReadStreamCreateWithBytesNoCopy(kCFAllocatorDefault, bytes, len, kCFAllocatorNull);
0
+ CFReadStreamOpen(readStream);
0
+ plist = CFPropertyListCreateFromStream(kCFAllocatorDefault, readStream, 0, kCFPropertyListImmutable, &format, &error);
0
+ CFReadStreamClose(readStream);
0
+ CFRelease(readStream);
0
+ // Format wasn't requested
0
+ CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8*)RSTRING(buffer)->ptr, RSTRING(buffer)->len, kCFAllocatorNull);
0
+ plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, data, kCFPropertyListImmutable, &error);
0
VALUE obj = convertPropertyListRef(plist);
0
if (RTEST(retFormat)) {
0
VALUE ary = rb_ary_new();
0
- double num = NUM2DBL(obj);
0
- type = kCFNumberDoubleType;
0
+ double num = NUM2DBL(obj);
0
+ type = kCFNumberDoubleType;
0
- int num = NUM2INT(obj);
0
- type = kCFNumberIntType;
0
+ int num = NUM2INT(obj);
0
+ type = kCFNumberIntType;
0
- long long num = NUM2LL(obj);
0
- type = kCFNumberLongLongType;
0
+ long long num = NUM2LL(obj);
0
+ type = kCFNumberLongLongType;
0
- long num = NUM2LONG(obj);
0
- type = kCFNumberLongType;
0
+ long num = NUM2LONG(obj);
0
+ type = kCFNumberLongType;
0
- rb_raise(rb_eStandardError, "ERROR: Wrong object type passed to convertNumber");
0
+ rb_raise(rb_eStandardError, "ERROR: Wrong object type passed to convertNumber");
0
CFNumberRef number = CFNumberCreate(kCFAllocatorDefault, type, valuePtr);
0
VALUE str_blob(VALUE self) {
0
- VALUE blob = rb_
iv_get(self, "@blob");
0
+ VALUE blob = rb_
attr_get(self, id_blob);
0
VALUE str_setBlob(VALUE self, VALUE b) {
0
if (TYPE(b) == T_TRUE || TYPE(b) == T_FALSE) {
0
- return rb_iv
_set(self, "@blob", b);
0
+ return rb_iv
ar_set(self, id_blob, b);
0
rb_raise(rb_eArgError, "Argument 1 must be true or false");
0
id_xml = rb_intern("xml1");
0
id_binary = rb_intern("binary1");
0
id_openstep = rb_intern("openstep");
0
+ id_blob = rb_intern("@blob");
Comments
No one has commented yet.