static stKVDatabaseConf *constructFromString(const char *xmlString) { stHash *hash = hackParseXmlString(xmlString); stKVDatabaseConf *databaseConf = NULL; const char *type = getXmlValueRequired(hash, "conf_type"); const char *dbTag = getXmlValueRequired(hash, "db_tag"); if (!stString_eq(type, dbTag)) { stThrowNew(ST_KV_DATABASE_EXCEPTION_ID, "Database XML tag \"%s\" did not match st_kv_database_conf type attribute", dbTag, type); } if (stString_eq(type, "tokyo_cabinet")) { databaseConf = stKVDatabaseConf_constructTokyoCabinet(getXmlValueRequired(hash, "database_dir")); } else if (stString_eq(type, "kyoto_tycoon")) { databaseConf = stKVDatabaseConf_constructKyotoTycoon(getXmlValueRequired(hash, "host"), getXmlPort(hash), getXmlTimeout(hash), getXMLMaxKTRecordSize(hash), getXMLMaxKTBulkSetSize(hash), getXMLMaxKTBulkSetNumRecords(hash), getXmlValueRequired(hash, "database_dir"), stHash_search(hash, "database_name")); } else if (stString_eq(type, "mysql")) { databaseConf = stKVDatabaseConf_constructMySql(getXmlValueRequired(hash, "host"), getXmlPort(hash), getXmlValueRequired(hash, "user"), getXmlValueRequired(hash, "password"), getXmlValueRequired(hash, "database_name"), getXmlValueRequired(hash, "table_name")); } else { stThrowNew(ST_KV_DATABASE_EXCEPTION_ID, "invalid database type \"%s\"", type); } stHash_destruct(hash); return databaseConf; }
/* Parse XML string into a hash. This parses all attributes of all tags * into values. st_kv_database_conf type is stored as conf_type, * database tag is stores as db_tag. This does minimal error checking * and is really lame. */ static stHash *hackParseXmlString(const char *xmlString) { stHash *hash = stHash_construct3(stHash_stringKey, stHash_stringEqualKey, free, free); char *toReplace[5] = { "</", "<", "/>", ">", "=" }; char *cA = stString_replace(xmlString, toReplace[0], " "), *cA2; for (int64_t i = 1; i < 5; i++) { cA2 = stString_replace(cA, toReplace[i], " "); free(cA); cA = cA2; } getExpectedToken(&cA2, "st_kv_database_conf"); stHash_insert(hash, stString_copy("conf_type"), getKeyValue(&cA2, "type")); stHash_insert(hash, stString_copy("db_tag"), getNextToken(&cA2)); char *key; while (((key = getNextToken(&cA2)) != NULL) && !stString_eq(key, "st_kv_database_conf")) { char *value = getNextToken(&cA2); if (value == NULL) { stThrowNew(ST_KV_DATABASE_EXCEPTION_ID, "failed to to get value for key \"%s\"", key); } if (stHash_search(hash, key) != NULL) { stThrowNew(ST_KV_DATABASE_EXCEPTION_ID, "got a duplicate entry in the database conf string \"%s\"", key); } stHash_insert(hash, key, value); } if(!stString_eq(key, "st_kv_database_conf")) { stThrowNew(ST_KV_DATABASE_EXCEPTION_ID, "got an unexpected final entry \"%s\"", key); } free(key); free(cA); return hash; }
/* assert sanity of nodeCompLink */ void mafTreeNodeCompLink_assert(struct mafTreeNodeCompLink *ncLink) { #ifndef NDEBUG if (ncLink != NULL) { assert(stString_eq(stTree_getLabel(ncLink->node), ncLink->comp->seq->orgSeqName)); } #endif }
static void getExpectedToken(char **tokenStream, const char *expected) { char *cA = getNextToken(tokenStream); if (!stString_eq(cA, expected)) { stThrowNew(ST_KV_DATABASE_EXCEPTION_ID, "BUG: expected the token: %s in database XML string, but I got: %s from the stream %s", expected, cA, *tokenStream); } free(cA); }
bool stTree_equals(stTree *tree1, stTree *tree2) { if (stTree_getBranchLength(tree1) != stTree_getBranchLength(tree2)) { return false; } if (!stString_eq(stTree_getLabel(tree1), stTree_getLabel(tree2))) { return false; } int numChildren = stTree_getChildNumber(tree1); if (stTree_getChildNumber(tree2) != numChildren) { return false; } for (int i = 0; i < numChildren; i++) { if (!stTree_equals(stTree_getChild(tree1, i), stTree_getChild(tree2, i))) { return false; } } return true; }