in bundles/remote_services/discovery_common/src/endpoint_descriptor_reader.c [93:268]
celix_status_t endpointDescriptorReader_parseDocument(endpoint_descriptor_reader_t *reader, char *document, celix_array_list_t** endpoints) {
celix_status_t status = CELIX_SUCCESS;
reader->reader = xmlReaderForMemory(document, (int) strlen(document), NULL, "UTF-8", 0);
if (reader->reader == NULL) {
status = CELIX_BUNDLE_EXCEPTION;
} else {
bool inProperty = false;
bool inXml = false;
bool inArray = false;
bool inList = false;
bool inSet = false;
bool inValue = false;
const xmlChar *propertyName = NULL;
const xmlChar *propertyValue = NULL;
valueType propertyType = VALUE_TYPE_STRING;
xmlChar *valueBuffer = xmlMalloc(256);
valueBuffer[0] = '\0';
celix_array_list_t* propertyValues = celix_arrayList_create();
celix_array_list_t* endpointDescriptions = NULL;
if (*endpoints) {
// use the given arraylist...
endpointDescriptions = *endpoints;
} else {
endpointDescriptions = celix_arrayList_create();
// return the read endpoints...
*endpoints = endpointDescriptions;
}
celix_properties_t *endpointProperties = NULL;
int read = xmlTextReaderRead(reader->reader);
while (read == XML_TEXTREADER_MODE_INTERACTIVE) {
int type = xmlTextReaderNodeType(reader->reader);
if (type == XML_READER_TYPE_ELEMENT) {
const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
if (inXml) {
valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "<");
valueBuffer = xmlStrcat(valueBuffer, localname);
int i = xmlTextReaderMoveToFirstAttribute(reader->reader);
while (i == 1) {
const xmlChar *name = xmlTextReaderConstName(reader->reader);
const xmlChar *value = xmlTextReaderConstValue(reader->reader);
valueBuffer = xmlStrcat(valueBuffer, BAD_CAST " ");
valueBuffer = xmlStrcat(valueBuffer, name);
valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "=\"");
valueBuffer = xmlStrcat(valueBuffer, BAD_CAST value);
valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "\"");
i = xmlTextReaderMoveToNextAttribute(reader->reader);
}
valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
} else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
if (endpointProperties != NULL)
celix_properties_destroy(endpointProperties);
endpointProperties = celix_properties_create();
} else if (xmlStrcmp(localname, PROPERTY) == 0) {
inProperty = true;
propertyName = xmlTextReaderGetAttribute(reader->reader, NAME);
propertyValue = xmlTextReaderGetAttribute(reader->reader, VALUE);
xmlChar *vtype = xmlTextReaderGetAttribute(reader->reader, VALUE_TYPE);
propertyType = valueTypeFromString((char*) vtype);
celix_arrayList_clear(propertyValues);
if (xmlTextReaderIsEmptyElement(reader->reader)) {
inProperty = false;
if (propertyValue != NULL) {
endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
}
xmlFree((void *) propertyName);
xmlFree((void *) propertyValue);
xmlFree((void *) vtype);
}
} else {
valueBuffer[0] = 0;
inArray |= inProperty && xmlStrcmp(localname, ARRAY) == 0;
inList |= inProperty && xmlStrcmp(localname, LIST) == 0;
inSet |= inProperty && xmlStrcmp(localname, SET) == 0;
inXml |= inProperty && xmlStrcmp(localname, XML) == 0;
inValue |= inProperty && xmlStrcmp(localname, VALUE) == 0;
}
} else if (type == XML_READER_TYPE_END_ELEMENT) {
const xmlChar *localname = xmlTextReaderConstLocalName(reader->reader);
if (inXml) {
if (xmlStrcmp(localname, XML) != 0) {
valueBuffer = xmlStrcat(valueBuffer, BAD_CAST "</");
valueBuffer = xmlStrcat(valueBuffer, localname);
valueBuffer = xmlStrcat(valueBuffer, BAD_CAST ">");
}
else {
inXml = false;
}
} else if (xmlStrcmp(localname, ENDPOINT_DESCRIPTION) == 0) {
endpoint_description_t *endpointDescription = NULL;
// Completely parsed endpoint description, add it to our list of results...
if(endpointDescription_create(endpointProperties, &endpointDescription) == CELIX_SUCCESS){
celix_arrayList_add(endpointDescriptions, endpointDescription);
}
endpointProperties = celix_properties_create();
} else if (xmlStrcmp(localname, PROPERTY) == 0) {
inProperty = false;
if (inArray || inList || inSet) {
endpointDescriptorReader_addMultiValuedProperty(endpointProperties, propertyName, propertyValues);
}
else if (propertyValue != NULL) {
if (propertyType != VALUE_TYPE_STRING) {
celix_logHelper_warning(*reader->loghelper, "ENDPOINT_DESCRIPTOR_READER: Only string support for %s\n", propertyName);
}
endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, propertyValue);
xmlFree((void *) propertyValue);
}
else {
endpointDescriptorReader_addSingleValuedProperty(endpointProperties, propertyName, valueBuffer);
}
xmlFree((void *) propertyName);
unsigned int k=0;
for(;k<celix_arrayList_size(propertyValues);k++){
free(celix_arrayList_get(propertyValues,k));
}
celix_arrayList_clear(propertyValues);
propertyType = VALUE_TYPE_STRING;
inArray = false;
inList = false;
inSet = false;
inXml = false;
} else if (xmlStrcmp(localname, VALUE) == 0) {
celix_arrayList_add(propertyValues, strdup((char*) valueBuffer));
valueBuffer[0] = 0;
inValue = false;
}
} else if (type == XML_READER_TYPE_TEXT) {
if (inValue || inXml) {
const xmlChar *value = xmlTextReaderValue(reader->reader);
valueBuffer = xmlStrcat(valueBuffer, value);
xmlFree((void *)value);
}
}
read = xmlTextReaderRead(reader->reader);
}
if(endpointProperties!=NULL){
celix_properties_destroy(endpointProperties);
}
unsigned int k=0;
for(;k<celix_arrayList_size(propertyValues);k++){
free(celix_arrayList_get(propertyValues,k));
}
celix_arrayList_destroy(propertyValues);
xmlFree(valueBuffer);
xmlFreeTextReader(reader->reader);
}
return status;
}