* xmlHashScanFull3: * @hash: hash table * @key: first string key or NULL * @key2: second string key or NULL * @key3: third string key or NULL * @scan: scanner function for items in the hash * @data: extra data passed to @scan * * Scan the hash @table and apply @scan to each value matching * (@key, @key2, @key3) tuple. If one of the keys is null, * the comparison is considered to match.
| 1085 | * the comparison is considered to match. |
| 1086 | */ |
| 1087 | void |
| 1088 | xmlHashScanFull3(xmlHashTablePtr hash, const xmlChar *key, |
| 1089 | const xmlChar *key2, const xmlChar *key3, |
| 1090 | xmlHashScannerFull scan, void *data) { |
| 1091 | const xmlHashEntry *entry, *end; |
| 1092 | xmlHashEntry old; |
| 1093 | unsigned i; |
| 1094 | |
| 1095 | if ((hash == NULL) || (hash->size == 0) || (scan == NULL)) |
| 1096 | return; |
| 1097 | |
| 1098 | /* |
| 1099 | * We must handle the case that a scanned entry is removed when executing |
| 1100 | * the callback (xmlCleanSpecialAttr and possibly other places). |
| 1101 | * |
| 1102 | * Find the start of a probe sequence to avoid scanning entries twice if |
| 1103 | * a deletion happens. |
| 1104 | */ |
| 1105 | entry = hash->table; |
| 1106 | end = &hash->table[hash->size]; |
| 1107 | while (entry->hashValue != 0) { |
| 1108 | if (++entry >= end) |
| 1109 | entry = hash->table; |
| 1110 | } |
| 1111 | |
| 1112 | for (i = 0; i < hash->size; i++) { |
| 1113 | if ((entry->hashValue != 0) && (entry->payload != NULL)) { |
| 1114 | /* |
| 1115 | * Make sure to rescan after a possible deletion. |
| 1116 | */ |
| 1117 | do { |
| 1118 | if (((key != NULL) && (strcmp((const char *) key, |
| 1119 | (const char *) entry->key) != 0)) || |
| 1120 | ((key2 != NULL) && (!xmlFastStrEqual(key2, entry->key2))) || |
| 1121 | ((key3 != NULL) && (!xmlFastStrEqual(key3, entry->key3)))) |
| 1122 | break; |
| 1123 | old = *entry; |
| 1124 | scan(entry->payload, data, entry->key, entry->key2, entry->key3); |
| 1125 | } while ((entry->hashValue != 0) && |
| 1126 | (entry->payload != NULL) && |
| 1127 | ((entry->key != old.key) || |
| 1128 | (entry->key2 != old.key2) || |
| 1129 | (entry->key3 != old.key3))); |
| 1130 | } |
| 1131 | if (++entry >= end) |
| 1132 | entry = hash->table; |
| 1133 | } |
| 1134 | } |
| 1135 | |
| 1136 | /* |
| 1137 | * xmlHashCopySafe: |
no test coverage detected