[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