[Pyobjc-dev] OC_PythonString implementation
Brought to you by:
ronaldoussoren
From: <bb...@ma...> - 2003-02-07 22:03:57
|
Posting a patch for comment -- all unit tests continue to work as expected (and the ones that break still break). It eliminates some duplication of the string's data. If I could figure out how to determine the encoding of a Unicode object, I could eliminate the rest of the duplication. It currently may be slower overall simply because the various string extension methods haven't been implemented yet. The implementation should also eliminate the creation of a new PythonString or Unicode object on the way from ObjC back to Python (as the implementation of -__pyobjc_PythonObject__ in OC_PythonString class will override the category of NSString that implements the same). This would seem to have similar reference counting issues as does OC_PythonDictionary and friends. This implementation would also seem to be consistent with OC_PythonDictionary and friends. Index: Modules/objc/OC_PythonString.h =================================================================== RCS file: /cvsroot/pyobjc/pyobjc/Modules/objc/OC_PythonString.h,v retrieving revision 1.3 diff -c -r1.3 OC_PythonString.h *** Modules/objc/OC_PythonString.h 18 Oct 2002 10:03:14 -0000 1.3 --- Modules/objc/OC_PythonString.h 7 Feb 2003 21:51:13 -0000 *************** *** 1,44 **** ! /* Copyright (c) 1996,97 by Lele Gaifax. All Rights Reserved ! * ! * This software may be used and distributed freely for any purpose ! * provided that this notice is included unchanged on any and all ! * copies. The author does not warrant or guarantee this software in ! * any way. ! * ! * This file is part of the PyObjC package. ! * ! * RCSfile: OC_PythonString.h,v ! * Revision: 1.8 ! * Date: 1998/01/04 17:59:21 ! * ! * Created Thu Sep 5 19:46:45 1996. ! */ ! #ifndef _OC_PythonString_H ! #define _OC_PythonString_H ! #include "OC_PythonObject.h" ! /*#C This class wraps a PyString object, making it easier to handle this ! kind of objects from Objective-C. */ ! @interface OC_PythonString : OC_PythonObject { } ! /*#M Returns a new autoreleased PyString object with @var{str} of ! length @var{size} as contents. */ ! + (id <PythonObject>) fromString:(char *) str andSize:(int) size; ! ! //#M Returns a new autoreleased PyString object with @var{str} as contents. ! + (id <PythonObject>) fromString:(char *) str; ! ! //#M Returns the size of the string. ! - (int) size; ! ! //#M Returns the ``C'' equivalent. ! - (char *) asString; ! ! @end /* OC_PythonString class interface */ ! ! ! #endif /* _OC_PythonString_H */ --- 1,29 ---- ! #ifndef OC_PythonString_h ! #define OC_PythonString_h ! #import <CoreFoundation/CoreFoundation.h> ! #import <Foundation/NSString.h> ! #include "Python.h" ! /* ! * OC_PythonString - Objective-C proxy class for Python strings ! * ! * Instances of this class are used as proxies for Python strings ! * when these are passed to Objective-C code. Because this class is ! * a subclass of NSString Python sequences can be used everywhere ! * where NSString is used. Python strings are immutable. ! */ ! @interface OC_PythonString:NSString { + PyObject* value; + PyObject* _internalRep; + CFStringRef stringValue; } ! +newWithPythonObject:(PyObject*)value; ! -initWithPythonObject:(PyObject*)value; ! -(void)dealloc; ! -(PyObject*)__pyobjc_PythonObject__; ! @end ! #endif Index: Modules/objc/OC_PythonString.m =================================================================== RCS file: /cvsroot/pyobjc/pyobjc/Modules/objc/OC_PythonString.m,v retrieving revision 1.4 diff -c -r1.4 OC_PythonString.m *** Modules/objc/OC_PythonString.m 5 Feb 2003 21:08:51 -0000 1.4 --- Modules/objc/OC_PythonString.m 7 Feb 2003 21:51:13 -0000 *************** *** 1,49 **** - /* Copyright (c) 1996,97 by Lele Gaifax. All Rights Reserved - * - * This software may be used and distributed freely for any purpose - * provided that this notice is included unchanged on any and all - * copies. The author does not warrant or guarantee this software in - * any way. - * - * This file is part of the PyObjC package. - * - * RCSfile: OC_PythonString.m,v - * Revision: 1.9 - * Date: 1998/01/04 17:59:22 - * - * Created Thu Sep 5 19:49:36 1996. - */ - #include "OC_PythonString.h" @implementation OC_PythonString ! + (id <PythonObject>) fromString:(char *) str andSize:(int) size { ! PyObject *pystr = PyString_FromStringAndSize (str, size); ! id <PythonObject> result = [self newWithObject:pystr]; ! Py_DECREF(pystr); ! return result; } ! + (id <PythonObject>) fromString:(char *) str { ! PyObject *pystr = PyString_FromString(str); ! id <PythonObject> result = [self newWithObject:pystr]; ! ! Py_DECREF(pystr); ! return result; } ! - (int) size { ! return PyString_Size([self pyObject]); } ! - (char *) asString { ! return PyString_AsString([self pyObject]); } ! @end /* OC_PythonString class implementation */ --- 1,84 ---- #include "OC_PythonString.h" + #include "pyobjc.h" + #include "objc_support.h" @implementation OC_PythonString + +newWithPythonObject:(PyObject*)v; + { + OC_PythonString* res = [[OC_PythonString alloc] initWithPythonObject:v]; + [res autorelease]; + return res; + } ! -initWithPythonObject:(PyObject*)v; { ! value = v; ! if (PyString_Check(value)) { ! char *buffer; ! int length; ! int result; ! ! result = PyString_AsStringAndSize(value, &buffer, &length); ! if(result == -1) { ! ObjCErr_ToObjC(); ! [self release]; ! return nil; // not reached ! } ! stringValue = CFStringCreateWithCStringNoCopy(NULL, ! buffer, ! kCFStringEncodingUTF8, ! kCFAllocatorNull); ! _internalRep = NULL; ! } else if (PyUnicode_Check(value)) { ! char *buffer; ! int length; ! int result; ! #warning Is there a way to determine what the encoding of value is and instantiate a CFString directly? ! _internalRep = PyUnicode_AsUTF8String(value); ! result = PyString_AsStringAndSize(_internalRep, &buffer, &length); ! if(result == -1) { ! ObjCErr_ToObjC(); ! [self release]; ! return nil; ! } ! ! stringValue = CFStringCreateWithCStringNoCopy(NULL, ! buffer, ! kCFStringEncodingUTF8, ! kCFAllocatorNull); ! } ! ! Py_INCREF(value); ! ! return self; } ! -(PyObject*)__pyobjc_PythonObject__ { ! Py_INCREF(value); ! return value; } ! -(void)dealloc { ! CFRelease(stringValue); ! Py_XDECREF(value); ! Py_XDECREF(_internalRep); ! [super dealloc]; } ! - (unsigned int)length; { ! int result; ! result = CFStringGetLength(stringValue); ! return result; } ! - (unichar)characterAtIndex:(unsigned)index; ! { ! UniChar result; ! result = CFStringGetCharacterAtIndex(stringValue, index); ! return result; ! } ! @end Index: Modules/objc/objc_support.m =================================================================== RCS file: /cvsroot/pyobjc/pyobjc/Modules/objc/objc_support.m,v retrieving revision 1.22 diff -c -r1.22 objc_support.m *** Modules/objc/objc_support.m 6 Feb 2003 21:01:05 -0000 1.22 --- Modules/objc/objc_support.m 7 Feb 2003 21:51:13 -0000 *************** *** 843,881 **** *(id *) datum = (id)ObjCClass_GetClass(argument); else if (ObjCObject_Check (argument)) { *(id *) datum = ObjCObject_GetObject(argument); ! } else if (PyString_Check (argument)) ! { ! /* We should probably translate to unicode using the default python ! * encoding (which is ASCII and may be different from the NSString ! * default encoding) ! */ ! unsigned char* strval = (unsigned char*)PyString_AS_STRING(argument); ! int len = PyString_GET_SIZE(argument); ! int i; ! ! for (i = 0; i < len; i++) { ! if (strval[i] >= 128) { ! error = "string with ordinals in range(128)"; ! return error; ! } ! } ! ! *(id *) datum = [NSString ! stringWithCString:PyString_AS_STRING(argument) ! length:PyString_GET_SIZE(argument)]; ! } ! else if (PyUnicode_Check(argument)) ! { ! PyObject* utf8 = PyUnicode_AsUTF8String(argument); ! ! if (utf8) { ! *(id *) datum = [NSString ! stringWithUTF8String:PyString_AS_STRING(utf8)]; ! Py_DECREF(utf8); ! } else { ! error = "Cannot convert Unicode string"; ! } ! } else if (PyInt_Check (argument)) *(id *) datum = [NSNumber numberWithLong:PyInt_AS_LONG (argument)]; else if (PyFloat_Check (argument)) --- 843,850 ---- *(id *) datum = (id)ObjCClass_GetClass(argument); else if (ObjCObject_Check (argument)) { *(id *) datum = ObjCObject_GetObject(argument); ! } else if ( (PyString_Check (argument)) || (PyUnicode_Check(argument)) ) ! *(id *) datum = [OC_PythonString newWithPythonObject:argument]; else if (PyInt_Check (argument)) *(id *) datum = [NSNumber numberWithLong:PyInt_AS_LONG (argument)]; else if (PyFloat_Check (argument)) Index: Modules/objc/pyobjc.h =================================================================== RCS file: /cvsroot/pyobjc/pyobjc/Modules/objc/pyobjc.h,v retrieving revision 1.19 diff -c -r1.19 pyobjc.h *** Modules/objc/pyobjc.h 5 Feb 2003 21:08:53 -0000 1.19 --- Modules/objc/pyobjc.h 7 Feb 2003 21:51:13 -0000 *************** *** 12,17 **** --- 12,18 ---- #include "OC_PythonObject.h" #include "OC_PythonArray.h" #include "OC_PythonDictionary.h" + #include "OC_PythonString.h" #include "super-call.h" /* |