|
@@ -250,3 +250,130 @@ void bmx_map_ptrmap_copy(struct tree_root ** dst_root, struct tree_root * src_ro
|
|
|
bmx_map_ptrmap_insert(src_node->key, src_node->value, dst_root);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+/* +++++++++++++++++++++++++++++++++++++++++++++++++++++ */
|
|
|
+
|
|
|
+struct stringmap_node {
|
|
|
+ struct tree_root link;
|
|
|
+ BBString * key;
|
|
|
+ BBOBJECT value;
|
|
|
+};
|
|
|
+
|
|
|
+static int compare_stringmap_nodes(const void *x, const void *y) {
|
|
|
+ struct stringmap_node * node_x = (struct stringmap_node *)x;
|
|
|
+ struct stringmap_node * node_y = (struct stringmap_node *)y;
|
|
|
+
|
|
|
+ return bbStringCompare(node_x->key, node_y->key);
|
|
|
+}
|
|
|
+
|
|
|
+void bmx_map_stringmap_clear(struct tree_root ** root) {
|
|
|
+ struct stringmap_node *node;
|
|
|
+ struct stringmap_node *tmp;
|
|
|
+ tree_for_each_entry_safe(node, tmp, *root, link) {
|
|
|
+ BBRELEASE(node->key);
|
|
|
+ BBRELEASE(node->value);
|
|
|
+ tree_del(&node->link, root);
|
|
|
+ free(node);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int bmx_map_stringmap_isempty(struct tree_root ** root) {
|
|
|
+ return *root == 0;
|
|
|
+}
|
|
|
+
|
|
|
+void bmx_map_stringmap_insert( BBString * key, BBObject *value, struct tree_root ** root) {
|
|
|
+ struct stringmap_node * node = (struct stringmap_node *)malloc(sizeof(struct stringmap_node));
|
|
|
+ node->key = key;
|
|
|
+ BBRETAIN(key);
|
|
|
+ node->value = value;
|
|
|
+ BBRETAIN(value);
|
|
|
+
|
|
|
+ struct stringmap_node * old_node = (struct stringmap_node *)tree_map(&node->link, compare_intmap_nodes, root);
|
|
|
+
|
|
|
+ if (&node->link != &old_node->link) {
|
|
|
+ BBRELEASE(old_node->key);
|
|
|
+ BBRELEASE(old_node->value);
|
|
|
+ // key already exists. Store the value in this node.
|
|
|
+ old_node->value = value;
|
|
|
+ // delete the new node, since we don't need it
|
|
|
+ free(node);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+int bmx_map_stringmap_contains(BBString * key, struct tree_root ** root) {
|
|
|
+ struct stringmap_node node;
|
|
|
+ node.key = key;
|
|
|
+
|
|
|
+ struct stringmap_node * found = (struct stringmap_node *)tree_search(&node, compare_intmap_nodes, *root);
|
|
|
+ if (found) {
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+BBObject * bmx_map_stringmap_valueforkey(int key, struct tree_root ** root) {
|
|
|
+ struct stringmap_node node;
|
|
|
+ node.key = key;
|
|
|
+
|
|
|
+ struct stringmap_node * found = (struct stringmap_node *)tree_search(&node, compare_intmap_nodes, *root);
|
|
|
+
|
|
|
+ if (found) {
|
|
|
+ return found->value;
|
|
|
+ }
|
|
|
+
|
|
|
+ return &bbNullObject;
|
|
|
+}
|
|
|
+
|
|
|
+int bmx_map_stringmap_remove(int key, struct tree_root ** root) {
|
|
|
+ struct stringmap_node node;
|
|
|
+ node.key = key;
|
|
|
+
|
|
|
+ struct stringmap_node * found = (struct stringmap_node *)tree_search(&node, compare_intmap_nodes, *root);
|
|
|
+
|
|
|
+ if (found) {
|
|
|
+ BBRELEASE(found->key);
|
|
|
+ BBRELEASE(found->value);
|
|
|
+ tree_del(&found->link, root);
|
|
|
+ free(found);
|
|
|
+ return 1;
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+struct stringmap_node * bmx_map_stringmap_nextnode(struct stringmap_node * node) {
|
|
|
+ return tree_successor(node);
|
|
|
+}
|
|
|
+
|
|
|
+struct stringmap_node * bmx_map_stringmap_firstnode(struct tree_root * root) {
|
|
|
+ return tree_min(root);
|
|
|
+}
|
|
|
+
|
|
|
+BBString * bmx_map_stringmap_key(struct stringmap_node * node) {
|
|
|
+ return node->key;
|
|
|
+}
|
|
|
+
|
|
|
+BBObject * bmx_map_stringmap_value(struct stringmap_node * node) {
|
|
|
+ return node->value;
|
|
|
+}
|
|
|
+
|
|
|
+int bmx_map_stringmap_hasnext(struct stringmap_node * node, struct tree_root * root) {
|
|
|
+ if (!root) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!node) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ return (tree_successor(node) != 0) ? 1 : 0;
|
|
|
+}
|
|
|
+
|
|
|
+void bmx_map_stringmap_copy(struct tree_root ** dst_root, struct tree_root * src_root) {
|
|
|
+ struct stringmap_node *src_node;
|
|
|
+ struct stringmap_node *tmp;
|
|
|
+ tree_for_each_entry_safe(src_node, tmp, src_root, link) {
|
|
|
+ bmx_map_stringmap_insert(src_node->key, src_node->value, dst_root);
|
|
|
+ }
|
|
|
+}
|