Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2011-11-15 13:12:10 +0400
committerCampbell Barton <ideasman42@gmail.com>2011-11-15 13:12:10 +0400
commit2ab17326135e666dd31bb0695ebc2ef426615fae (patch)
tree57fb344834d44580aa45e1c82be56115116aec48 /source/blender
parentae046bc0eba28acb4101215e7dae411f99214ea1 (diff)
support for non-null terminated byte strings in id properties (as a subtype of IDP_STRING types)
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/blenkernel/BKE_idprop.h6
-rw-r--r--source/blender/blenkernel/intern/idprop.c55
-rw-r--r--source/blender/makesdna/DNA_ID.h7
-rw-r--r--source/blender/makesrna/intern/rna_access.c30
-rw-r--r--source/blender/python/generic/IDProp.c32
5 files changed, 101 insertions, 29 deletions
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 10c02f54b2e..ef760277f56 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -40,7 +40,11 @@ typedef union IDPropertyTemplate {
int i;
float f;
double d;
- char *str;
+ struct {
+ char *str;
+ short len;
+ char subtype;
+ } string;
struct ID *id;
struct {
short type;
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index ac4b936cb41..07057e4ee32 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -349,17 +349,20 @@ static IDProperty *IDP_CopyString(IDProperty *prop)
void IDP_AssignString(IDProperty *prop, const char *st, int maxlen)
{
- int stlen;
-
- stlen = strlen(st);
+ int 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,18 +706,36 @@ IDProperty *IDP_New(int type, IDPropertyTemplate val, const char *name)
}
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;
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index c135254b11b..97ea7592d04 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -80,6 +80,13 @@ typedef struct IDProperty {
#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. */
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 6f9c7a8f19b..47a7420cb7f 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -2271,12 +2271,23 @@ void RNA_property_string_get(PointerRNA *ptr, PropertyRNA *prop, char *value)
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 @@ int RNA_property_string_length(PointerRNA *ptr, PropertyRNA *prop)
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 @@ void RNA_property_string_set(PointerRNA *ptr, PropertyRNA *prop, const char *val
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 */
diff --git a/source/blender/python/generic/IDProp.c b/source/blender/python/generic/IDProp.c
index 6d869a7eb1f..d0759a69d8f 100644
--- a/source/blender/python/generic/IDProp.c
+++ b/source/blender/python/generic/IDProp.c
@@ -64,11 +64,18 @@ PyObject *BPy_IDGroup_WrapData( ID *id, IDProperty *prop )
{
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 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
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 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty
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 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
{
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));