key-data.[ch] (key_copydata): New function copies filtered key data.
authorMark Wooding <mdw@distorted.org.uk>
Sun, 22 Jan 2012 12:57:45 +0000 (12:57 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sun, 22 Jan 2012 13:08:53 +0000 (13:08 +0000)
key-data.c
key-data.h

index c77b6a4..43ad901 100644 (file)
@@ -410,4 +410,59 @@ int key_do(key_data *k, const key_filter *kf, dstr *d,
   }
 }
 
+/* --- @key_copydata@ --- *
+ *
+ * Arguments:  @key_data *k@ = key data to copy
+ *             @const key_filter *kf@ = pointer to filter block
+ *
+ * Returns:    Pointer to a copy of the data, or null if the root subkey
+ *             didn't match the filter.
+ *
+ * Use:                Copies a chunk of key data.  Subkeys, whether they're
+ *             structured or leaves, which don't match the filter aren't
+ *             copied.  The copy may or may not have structure in common
+ *             with the original.
+ */
+
+static int structmatchp(key_data *k, const key_filter *kf)
+{
+  key_subkeyiter i;
+
+  if (!KEY_MATCH(k, kf)) return (0);
+  else if ((k->e & KF_ENCMASK) == KENC_STRUCT) return (1);
+  else {
+    for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, 0, &k); )
+      if (!structmatchp(k, kf)) return (0);
+    return (1);
+  }
+}
+
+key_data *key_copydata(key_data *k, const key_filter *kf)
+{
+  key_subkeyiter i;
+  const char *tag;
+  key_data *kd, *kkd;
+
+  /* --- Trivial cases --- */
+
+  if (!KEY_MATCH(k, kf))
+    return (0);
+  else if (structmatchp(k, kf)) {
+    key_incref(k);
+    return (k);
+  }
+
+  /* --- Copy a structured key recursively --- */
+
+  kkd = key_newstruct();
+  for (key_mksubkeyiter(&i, k); key_nextsubkey(&i, &tag, &kd); ) {
+    if ((kd = key_copydata(kd, kf)) != 0)
+      key_structsteal(kkd, tag, kd);
+  }
+
+  /* --- Done --- */
+
+  return (kkd);
+}
+
 /*----- That's all, folks -------------------------------------------------*/
index e216bc0..e37c381 100644 (file)
@@ -414,6 +414,22 @@ extern int key_do(key_data */*k*/, const key_filter */*kf*/, dstr */*d*/,
                                  dstr */*d*/, void */*p*/),
                  void */*p*/);
 
+/* --- @key_copydata@ --- *
+ *
+ * Arguments:  @key_data *k@ = key data to copy
+ *             @const key_filter *kf@ = pointer to filter block
+ *
+ * Returns:    Pointer to a copy of the data, or null if the root subkey
+ *             didn't match the filter.
+ *
+ * Use:                Copies a chunk of key data.  Subkeys, whether they're
+ *             structured or leaves, which don't match the filter aren't
+ *             copied.  The copy may or may not have structure in common
+ *             with the original.
+ */
+
+extern key_data *key_copydata(key_data */*k*/, const key_filter */*kf*/);
+
 /*----- Textual encoding --------------------------------------------------*/
 
 /* --- @key_read@ --- *