static c_array createKeyList( c_type instanceType, c_array keyList) { c_ulong size, i; c_array newKeyList = NULL; assert(instanceType); if (keyList) { size = c_arraySize(keyList); newKeyList = c_arrayNew(c_field_t(c_getBase(instanceType)), size); if (newKeyList) { for(i = 0; i<size; i++){ c_field f = c_fieldNew(instanceType, PREFIX); assert(f); if (f) { newKeyList[i] = c_fieldConcat(f, keyList[i]); c_free(f); } else { OS_REPORT(OS_CRITICAL, "createKeyList", V_RESULT_INTERNAL_ERROR, "Could not create c_field"); } } } else { OS_REPORT(OS_FATAL, "createKeyList", V_RESULT_INTERNAL_ERROR, "Could not create array"); } } return newKeyList; }
c_field c_fieldConcat ( c_field head, c_field tail) { c_base base; c_long i, len1, len2, totlen; c_field field; base = c__getBase(head); len1 = c_arraySize(head->path); len2 = c_arraySize(tail->path); field = c_new(c_field_t(base)); if (field) { field->type = c_keep(tail->type); field->kind = tail->kind; field->path = c_newArray(c_fieldPath_t(base),len1 + len2); for (i=0;i<len1;i++) { field->path[i] = c_keep(head->path[i]); } for (i=0;i<len2;i++) { field->path[i+len1] = c_keep(tail->path[i]); } len1 = c_arraySize(head->refs); len2 = c_arraySize(tail->refs); totlen = len1 + len2; if (totlen > 0) { field->offset = 0; field->refs = c_newArray(c_fieldRefs_t(base),totlen); if (len1) { for (i=0;i<len1;i++) { field->refs[i] = head->refs[i]; } } else { tail->refs[0] = (c_voidp)head->offset; len1 = 1; } for (i=0;i<len2;i++) { field->refs[i+len1] = tail->refs[i]; } } else { field->offset = head->offset + tail->offset; field->refs = NULL; } len1 = strlen(head->name); len2 = strlen(tail->name); field->name = c_stringMalloc(base,len1+len2+2); os_sprintf(field->name,"%s.%s",head->name,tail->name); } else { OS_REPORT(OS_ERROR, "database::c_fieldConcat",0, "Failed to allocate c_field object."); } return field; }
c_field c_fieldNew ( c_type type, const c_char *fieldName) { c_array path; c_field field; c_metaObject o; c_long n,length; c_address offset; c_iter nameList, refsList; c_string name; c_base base; if ((fieldName == NULL) || (type == NULL)) { OS_REPORT(OS_ERROR, "c_fieldNew failed",0, "illegal parameter"); return NULL; } base = c__getBase(type); if (base == NULL) { OS_REPORT(OS_ERROR, "c_fieldNew failed",0, "failed to retreive base"); return NULL; } nameList = c_splitString(fieldName,"."); length = c_iterLength(nameList); field = NULL; if (length > 0) { o = NULL; offset = 0; refsList = NULL; path = c_newArray(c_fieldPath_t(base),length); if (path) { for (n=0;n<length;n++) { name = c_iterTakeFirst(nameList); o = c_metaResolve(c_metaObject(type),name); os_free(name); if (o == NULL) { c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL); c_iterFree(nameList); c_iterFree(refsList); c_free(path); return NULL; } path[n] = o; switch (c_baseObject(o)->kind) { case M_ATTRIBUTE: case M_RELATION: type = c_property(o)->type; offset += c_property(o)->offset; break; case M_MEMBER: type = c_specifier(o)->type; offset += c_member(o)->offset; break; default: c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL); c_iterFree(nameList); c_iterFree(refsList); c_free(path); return NULL; } switch (c_baseObject(type)->kind) { case M_INTERFACE: case M_CLASS: case M_COLLECTION: /*Longs are inserted in an iterator? Explanation please...*/ refsList = c_iterInsert(refsList,(c_voidp)offset); offset = 0; break; default: break; } } if (offset > 0) { refsList = c_iterInsert(refsList,(c_voidp)offset); } field = c_new(c_field_t(base)); field->name = c_stringNew(base,fieldName); field->path = path; field->type = c_keep(type); field->kind = c_metaValueKind(o); field->refs = NULL; if (refsList) { length = c_iterLength(refsList); field->offset = 0; if (length > 0) { field->refs = c_newArray(c_fieldRefs_t(base),length); if (field->refs) { for (n=(length-1);n>=0;n--) { field->refs[n] = c_iterTakeFirst(refsList); } } else { OS_REPORT(OS_ERROR, "c_fieldNew failed",0, "failed to allocate field->refs array"); c_free(field); field = NULL; } } c_iterFree(refsList); } else { field->offset = offset; } } else { OS_REPORT(OS_ERROR, "c_fieldNew failed",0, "failed to allocate field->path array"); c_iterWalk(nameList,(c_iterWalkAction)os_free,NULL); c_iterFree(nameList); } c_iterFree(nameList); } else { OS_REPORT_1(OS_ERROR, "c_fieldNew failed",0, "failed to process field name <%s>", fieldName); } return field; }
static c_bool createMessageKeyList( c_type messageType, const c_char *topicKeyExpr, c_array *keyListRef) { c_array keyList; c_type fieldType; c_field field; c_iter splitNames, newNames; c_char *name, *newName; c_long i,length,sres; assert(keyListRef != NULL); *keyListRef = NULL; if (topicKeyExpr == NULL) { return TRUE; } newNames = NULL; splitNames = c_splitString(topicKeyExpr,", \t"); while ((name = c_iterTakeFirst(splitNames)) != NULL) { #define PATH_SEPARATOR "." #define PREFIX "userData" length = strlen(PREFIX) + sizeof(PATH_SEPARATOR) + strlen(name); newName = (char *)os_malloc(length); sres = snprintf(newName,length,"%s"PATH_SEPARATOR"%s",PREFIX, name); assert(sres == (length-1)); #undef PREFIX #undef PATH_SEPARATOR os_free(name); newNames = c_iterAppend(newNames,newName); } c_iterFree(splitNames); length = c_iterLength(newNames); if (length == 0) { return TRUE; } fieldType = c_field_t(c_getBase(messageType)); keyList = c_arrayNew(fieldType,length); c_free(fieldType); i=0; while ((name = c_iterTakeFirst(newNames)) != NULL) { field = c_fieldNew(messageType,name); if (field == NULL) { OS_REPORT_1(OS_API_INFO, "create message key list failed", 21, "specified key field name %s not found", name); os_free(name); c_iterFree(newNames); c_free(keyList); return FALSE; } keyList[i++] = field; os_free(name); } c_iterFree(newNames); *keyListRef = keyList; return TRUE; }