[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [41861] trunk/blender/source/blender: support for non-null terminated byte strings in id properties ( as a subtype of IDP_STRING types)
Campbell Barton
ideasman42 at gmail.com
Tue Nov 15 10:12:11 CET 2011
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));
More information about the Bf-blender-cvs
mailing list