Revision: 41861
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=41861
Author:   campbellbarton
Date:     2011-11-15 09:12:10 +0000 (Tue, 15 Nov 2011)
Log Message:
-----------
support for non-null terminated byte strings in id properties (as a subtype of 
IDP_STRING types)

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_idprop.h
    trunk/blender/source/blender/blenkernel/intern/idprop.c
    trunk/blender/source/blender/makesdna/DNA_ID.h
    trunk/blender/source/blender/makesrna/intern/rna_access.c
    trunk/blender/source/blender/python/generic/IDProp.c

Modified: trunk/blender/source/blender/blenkernel/BKE_idprop.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_idprop.h        2011-11-15 
08:43:28 UTC (rev 41860)
+++ trunk/blender/source/blender/blenkernel/BKE_idprop.h        2011-11-15 
09:12:10 UTC (rev 41861)
@@ -40,7 +40,11 @@
        int i;
        float f;
        double d;
-       char *str;
+       struct {
+               char *str;
+               short len;
+               char subtype;
+       } string;
        struct ID *id;
        struct {
                short type;

Modified: trunk/blender/source/blender/blenkernel/intern/idprop.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/idprop.c     2011-11-15 
08:43:28 UTC (rev 41860)
+++ trunk/blender/source/blender/blenkernel/intern/idprop.c     2011-11-15 
09:12:10 UTC (rev 41861)
@@ -349,17 +349,20 @@
 
 void IDP_AssignString(IDProperty *prop, const char *st, int maxlen)
 {
-       int stlen;
+       int stlen = strlen(st);
 
-       stlen = strlen(st);
-
        if(maxlen > 0 && maxlen < stlen)
                stlen= maxlen;
 
-       stlen++; /* make room for null byte */
-
-       IDP_ResizeArray(prop, stlen);
-       BLI_strncpy(prop->data.pointer, st, stlen);
+       if (prop->subtype == IDP_STRING_SUB_BYTE) {
+               IDP_ResizeArray(prop, stlen);
+               memcpy(prop->data.pointer, st, stlen);
+       }
+       else {
+               stlen++; /* make room for null byte */
+               IDP_ResizeArray(prop, stlen);
+               BLI_strncpy(prop->data.pointer, st, stlen);
+       }
 }
 
 void IDP_ConcatStringC(IDProperty *prop, const char *st)
@@ -703,19 +706,37 @@
                }
                case IDP_STRING:
                {
-                       char *st = val.str;
+                       const char *st = val.string.str;
 
                        prop = MEM_callocN(sizeof(IDProperty), "IDProperty 
string");
-                       if (st == NULL) {
-                               prop->data.pointer = 
MEM_callocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1");
-                               prop->totallen = DEFAULT_ALLOC_FOR_NULL_STRINGS;
-                               prop->len = 1; /*NULL string, has len of 1 to 
account for null byte.*/
-                       } else {
-                               int stlen = strlen(st) + 1;
-                               prop->data.pointer = MEM_mallocN(stlen, "id 
property string 2");
-                               prop->len = prop->totallen = stlen;
-                               memcpy(prop->data.pointer, st, stlen);
+                       if (val.string.subtype == IDP_STRING_SUB_BYTE) {
+                               /* note, intentionally not null terminated */
+                               if (st == NULL) {
+                                       prop->data.pointer = 
MEM_callocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1");
+                                       prop->totallen = 
DEFAULT_ALLOC_FOR_NULL_STRINGS;
+                                       prop->len = 0;
+                               }
+                               else {
+                                       prop->data.pointer = 
MEM_mallocN(val.string.len, "id property string 2");
+                                       prop->len = prop->totallen = 
val.string.len;
+                                       memcpy(prop->data.pointer, st, 
val.string.len);
+                               }
+                               prop->subtype= IDP_STRING_SUB_BYTE;
                        }
+                       else {
+                               if (st == NULL) {
+                                       prop->data.pointer = 
MEM_callocN(DEFAULT_ALLOC_FOR_NULL_STRINGS, "id property string 1");
+                                       prop->totallen = 
DEFAULT_ALLOC_FOR_NULL_STRINGS;
+                                       prop->len = 1; /*NULL string, has len 
of 1 to account for null byte.*/
+                               }
+                               else {
+                                       int stlen = strlen(st) + 1;
+                                       prop->data.pointer = MEM_mallocN(stlen, 
"id property string 3");
+                                       prop->len = prop->totallen = stlen;
+                                       memcpy(prop->data.pointer, st, stlen);
+                               }
+                               prop->subtype= IDP_STRING_SUB_UTF8;
+                       }
                        break;
                }
                case IDP_GROUP:

Modified: trunk/blender/source/blender/makesdna/DNA_ID.h
===================================================================
--- trunk/blender/source/blender/makesdna/DNA_ID.h      2011-11-15 08:43:28 UTC 
(rev 41860)
+++ trunk/blender/source/blender/makesdna/DNA_ID.h      2011-11-15 09:12:10 UTC 
(rev 41861)
@@ -80,6 +80,13 @@
 #define IDP_IDPARRAY   9
 #define IDP_NUMTYPES   10
 
+/*->subtype */
+
+/* IDP_STRING */
+#define IDP_STRING_SUB_UTF8  0 /* default */
+#define IDP_STRING_SUB_BYTE  1 /* arbitrary byte array, _not_ null terminated 
*/
+
+
 /* add any future new id property types here.*/
 
 /* watch it: Sequence has identical beginning. */

Modified: trunk/blender/source/blender/makesrna/intern/rna_access.c
===================================================================
--- trunk/blender/source/blender/makesrna/intern/rna_access.c   2011-11-15 
08:43:28 UTC (rev 41860)
+++ trunk/blender/source/blender/makesrna/intern/rna_access.c   2011-11-15 
09:12:10 UTC (rev 41861)
@@ -2271,12 +2271,23 @@
 
        BLI_assert(RNA_property_type(prop) == PROP_STRING);
 
-       if((idprop=rna_idproperty_check(&prop, ptr)))
-               strcpy(value, IDP_String(idprop));
-       else if(sprop->get)
+       if((idprop=rna_idproperty_check(&prop, ptr))) {
+               /* editing bytes is not 100% supported
+                * since they can contain NIL chars */
+               if (idprop->subtype == IDP_STRING_SUB_BYTE) {
+                       memcpy(value, IDP_String(idprop), idprop->len + 1);
+                       value[idprop->len]= '\0';
+               }
+               else {
+                       strcpy(value, IDP_String(idprop));
+               }
+       }
+       else if(sprop->get) {
                sprop->get(ptr, value);
-       else
+       }
+       else {
                strcpy(value, sprop->defaultvalue);
+       }
 }
 
 char *RNA_property_string_get_alloc(PointerRNA *ptr, PropertyRNA *prop,
@@ -2320,8 +2331,14 @@
 
        BLI_assert(RNA_property_type(prop) == PROP_STRING);
 
-       if((idprop=rna_idproperty_check(&prop, ptr)))
-               return strlen(IDP_String(idprop));
+       if((idprop=rna_idproperty_check(&prop, ptr))) {
+               if (idprop->subtype == IDP_STRING_SUB_BYTE) {
+                       return idprop->len;
+               }
+               else {
+                       return strlen(IDP_String(idprop));
+               }
+       }
        else if(sprop->length)
                return sprop->length(ptr);
        else
@@ -2336,6 +2353,7 @@
        BLI_assert(RNA_property_type(prop) == PROP_STRING);
 
        if((idprop=rna_idproperty_check(&prop, ptr)))
+               /* both IDP_STRING_SUB_BYTE / IDP_STRING_SUB_UTF8 */
                IDP_AssignString(idprop, value, 
RNA_property_string_maxlength(prop) - 1);
        else if(sprop->set)
                sprop->set(ptr, value); /* set function needs to clamp its self 
*/

Modified: trunk/blender/source/blender/python/generic/IDProp.c
===================================================================
--- trunk/blender/source/blender/python/generic/IDProp.c        2011-11-15 
08:43:28 UTC (rev 41860)
+++ trunk/blender/source/blender/python/generic/IDProp.c        2011-11-15 
09:12:10 UTC (rev 41861)
@@ -64,11 +64,18 @@
 {
        switch ( prop->type ) {
                case IDP_STRING:
+
+               if (prop->subtype == IDP_STRING_SUB_BYTE) {
+                       return PyBytes_FromStringAndSize(IDP_Array(prop), 
prop->len);
+               }
+               else {
 #ifdef USE_STRING_COERCE
-            return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1);
+                       return PyC_UnicodeFromByteAndSize(IDP_Array(prop), 
prop->len - 1);
 #else
-            return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len - 1);
+                       return PyUnicode_FromStringAndSize(IDP_Array(prop), 
prop->len - 1);
 #endif
+               }
+
                case IDP_INT:
                        return PyLong_FromLong( (long)prop->data.val );
                case IDP_FLOAT:
@@ -332,7 +339,8 @@
        else if (PyUnicode_Check(ob)) {
 #ifdef USE_STRING_COERCE
                PyObject *value_coerce= NULL;
-               val.str = (char *)PyC_UnicodeAsByte(ob, &value_coerce);
+               val.string.str = (char *)PyC_UnicodeAsByte(ob, &value_coerce);
+               val.string.subtype = IDP_STRING_SUB_UTF8;
                prop = IDP_New(IDP_STRING, val, name);
                Py_XDECREF(value_coerce);
 #else
@@ -340,6 +348,15 @@
                prop = IDP_New(IDP_STRING, val, name);
 #endif
        }
+       else if (PyBytes_Check(ob)) {
+               val.string.str= PyBytes_AS_STRING(ob);
+               val.string.len= PyBytes_GET_SIZE(ob);
+               val.string.subtype= IDP_STRING_SUB_BYTE;
+
+               prop = IDP_New(IDP_STRING, val, name);
+               //prop = IDP_NewString(PyBytes_AS_STRING(ob), name, 
PyBytes_GET_SIZE(ob));
+               //prop->subtype= IDP_STRING_SUB_BYTE;
+       }
        else if (PySequence_Check(ob)) {
                PyObject *item;
                int i;
@@ -493,11 +510,16 @@
 {
        switch (prop->type) {
                case IDP_STRING:
+                       if (prop->subtype == IDP_STRING_SUB_BYTE) {
+                               return 
PyBytes_FromStringAndSize(IDP_Array(prop), prop->len);
+                       }
+                       else {
 #ifdef USE_STRING_COERCE
-            return PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1);
+                               return 
PyC_UnicodeFromByteAndSize(IDP_Array(prop), prop->len - 1);
 #else
-            return PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len - 1);
+                               return 
PyUnicode_FromStringAndSize(IDP_Array(prop), prop->len - 1);
 #endif
+                       }
                        break;
                case IDP_FLOAT:
                        return PyFloat_FromDouble(*((float*)&prop->data.val));

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to