diff --git a/properties.h b/properties.h index 069e206..33db750 100644 --- a/properties.h +++ b/properties.h @@ -122,6 +122,25 @@ struct objc_property_list struct objc_property properties[]; }; +/** + * Structure used for copying property attributes. + */ +struct objc_property_attribute +{ + /** + * Name of the attribute. + */ + const char *name; + /** + * Value of the attribute. + */ + const char *value; + /** + * Length of value string. + */ + size_t length; +}; + PRIVATE BOOL initPropertyFromAttributesList(struct objc_property *property, const char *name, const objc_property_attribute_t *attributes, diff --git a/properties.m b/properties.m index 2c28971..a5b69d3 100644 --- a/properties.m +++ b/properties.m @@ -367,80 +367,111 @@ const char *property_getAttributes(objc_property_t property) objc_property_attribute_t *property_copyAttributeList(objc_property_t property, unsigned int *outCount) { - if (NULL == property) { return NULL; } - objc_property_attribute_t attrs[10]; - int count = 0; + if (NULL == property) { if (outCount) *outCount = 0; return NULL; } + struct objc_property_attribute attrs[10]; + size_t attrcount = 0; + size_t stringslen = 0; if (property->type_encoding != NULL) { - attrs[count].name = "T"; - attrs[count].value = property->type_encoding; - count++; + attrs[attrcount].name = "T"; + attrs[attrcount].value = property->type_encoding; + attrs[attrcount].length = strlen(property->type_encoding); + stringslen += attrs[attrcount].length + 3; + attrcount++; } if ((property->attributes & OBJC_PR_readonly) == OBJC_PR_readonly) { - attrs[count].name = "R"; - attrs[count].value = ""; - count++; + attrs[attrcount].name = "R"; + attrs[attrcount].value = ""; + attrs[attrcount].length = 0; + stringslen += 3; + attrcount++; } - else + if ((property->attributes & OBJC_PR_retain) == OBJC_PR_retain + || (property->attributes & OBJC_PR_strong) == OBJC_PR_strong) { - if ((property->attributes & OBJC_PR_retain) == OBJC_PR_retain - || (property->attributes & OBJC_PR_strong) == OBJC_PR_strong) - { - attrs[count].name = "&"; - attrs[count].value = ""; - count++; - } - else if ((property->attributes & OBJC_PR_copy) == OBJC_PR_copy) - { - attrs[count].name = "C"; - attrs[count].value = ""; - count++; - } - else if ((property->attributes & OBJC_PR_weak) == OBJC_PR_weak) - { - attrs[count].name = "W"; - attrs[count].value = ""; - count++; - } + attrs[attrcount].name = "&"; + attrs[attrcount].value = ""; + attrs[attrcount].length = 0; + stringslen += 3; + attrcount++; + } + if ((property->attributes & OBJC_PR_copy) == OBJC_PR_copy) + { + attrs[attrcount].name = "C"; + attrs[attrcount].value = ""; + attrs[attrcount].length = 0; + stringslen += 3; + attrcount++; + } + if ((property->attributes & OBJC_PR_weak) == OBJC_PR_weak) + { + attrs[attrcount].name = "W"; + attrs[attrcount].value = ""; + attrs[attrcount].length = 0; + stringslen += 3; + attrcount++; } if ((property->attributes & OBJC_PR_dynamic) == OBJC_PR_dynamic) { - attrs[count].name = "D"; - attrs[count].value = ""; - count++; + attrs[attrcount].name = "D"; + attrs[attrcount].value = ""; + attrs[attrcount].length = 0; + stringslen += 3; + attrcount++; } if ((property->attributes & OBJC_PR_nonatomic) == OBJC_PR_nonatomic) { - attrs[count].name = "N"; - attrs[count].value = ""; - count++; + attrs[attrcount].name = "N"; + attrs[attrcount].value = ""; + attrs[attrcount].length = 0; + stringslen += 3; + attrcount++; } - if ((property->attributes & OBJC_PR_getter) == OBJC_PR_getter) + if (property->getter_name != NULL) { - attrs[count].name = "G"; - attrs[count].value = property->getter_name; - count++; + attrs[attrcount].name = "G"; + attrs[attrcount].value = property->getter_name; + attrs[attrcount].length = strlen(property->getter_name); + stringslen += attrs[attrcount].length + 3; + attrcount++; } - if ((property->attributes & OBJC_PR_setter) == OBJC_PR_setter) + if (property->setter_name != NULL) { - attrs[count].name = "S"; - attrs[count].value = property->setter_name; - count++; + attrs[attrcount].name = "S"; + attrs[attrcount].value = property->setter_name; + attrs[attrcount].length = strlen(property->setter_name); + stringslen += attrs[attrcount].length + 3; + attrcount++; } if (property->ivar_name != NULL) { - attrs[count].name = "V"; - attrs[count].value = property->ivar_name; - count++; + attrs[attrcount].name = "V"; + attrs[attrcount].value = property->ivar_name; + attrs[attrcount].length = strlen(property->ivar_name); + stringslen += attrs[attrcount].length + 3; + attrcount++; } - objc_property_attribute_t *propAttrs = calloc(sizeof(objc_property_attribute_t), count); - memcpy(propAttrs, attrs, count * sizeof(objc_property_attribute_t)); + if (attrcount == 0) { if (outCount) *outCount = 0; return NULL; } + + objc_property_attribute_t *propAttrs = calloc(1, (attrcount+1) * sizeof(objc_property_attribute_t) + stringslen); + objc_property_attribute_t *ra = propAttrs; + char *rs = (char *)(ra+attrcount+1); + for (size_t a = 0; a < attrcount; a++) + { + ra->name = rs; + memcpy(rs, attrs[a].name, 2); + rs += 2; + ra->value = rs; + memcpy(rs, attrs[a].value, attrs[a].length + 1); + rs += attrs[a].length + 1; + ra ++; + } if (NULL != outCount) { - *outCount = count; + *outCount = attrcount; } return propAttrs; } @@ -570,21 +601,18 @@ BOOL initPropertyFromAttributesList(struct objc_property *p, { s = stpcpy(s, "R,"); } - else + if ((p->attributes & OBJC_PR_retain) == OBJC_PR_retain + || (p->attributes & OBJC_PR_strong) == OBJC_PR_strong) { - if ((p->attributes & OBJC_PR_retain) == OBJC_PR_retain - || (p->attributes & OBJC_PR_strong) == OBJC_PR_strong) - { - s = stpcpy(s, "&,"); - } - else if ((p->attributes & OBJC_PR_copy) == OBJC_PR_copy) - { - s = stpcpy(s, "C,"); - } - else if ((p->attributes & OBJC_PR_weak) == OBJC_PR_weak) - { - s = stpcpy(s, "W,"); - } + s = stpcpy(s, "&,"); + } + if ((p->attributes & OBJC_PR_copy) == OBJC_PR_copy) + { + s = stpcpy(s, "C,"); + } + if ((p->attributes & OBJC_PR_weak) == OBJC_PR_weak) + { + s = stpcpy(s, "W,"); } if ((p->attributes & OBJC_PR_dynamic) == OBJC_PR_dynamic) {