Author: rhs
Date: Fri Aug 23 11:55:09 2013
New Revision: 1516825

URL: http://svn.apache.org/r1516825
Log:
added list/map inspect and list compare

Modified:
    qpid/proton/trunk/proton-c/include/proton/object.h
    qpid/proton/trunk/proton-c/src/object/object.c
    qpid/proton/trunk/proton-c/src/tests/object.c

Modified: qpid/proton/trunk/proton-c/include/proton/object.h
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/object.h?rev=1516825&r1=1516824&r2=1516825&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/object.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/object.h Fri Aug 23 11:55:09 2013
@@ -52,6 +52,13 @@ typedef struct {
   int (*inspect)(void *, pn_string_t *);
 } pn_class_t;
 
+#define PN_CLASS(PREFIX) {                      \
+    PREFIX ## _finalize,                        \
+    PREFIX ## _hashcode,                        \
+    PREFIX ## _compare,                         \
+    PREFIX ## _inspect                          \
+}
+
 PN_EXTERN void *pn_new(size_t size, pn_class_t *clazz);
 PN_EXTERN void *pn_incref(void *object);
 PN_EXTERN void pn_decref(void *object);

Modified: qpid/proton/trunk/proton-c/src/object/object.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/object/object.c?rev=1516825&r1=1516824&r2=1516825&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/object/object.c (original)
+++ qpid/proton/trunk/proton-c/src/object/object.c Fri Aug 23 11:55:09 2013
@@ -269,9 +269,47 @@ static uintptr_t pn_list_hashcode(void *
   return hash;
 }
 
+static intptr_t pn_list_compare(void *oa, void *ob)
+{
+  assert(oa); assert(ob);
+  pn_list_t *a = (pn_list_t *) oa;
+  pn_list_t *b = (pn_list_t *) ob;
+
+  size_t na = pn_list_size(a);
+  size_t nb = pn_list_size(b);
+  if (na != nb) {
+    return nb - na;
+  } else {
+    for (size_t i = 0; i < na; i++) {
+      intptr_t delta = pn_compare(pn_list_get(a, i), pn_list_get(b, i));
+      if (delta) return delta;
+    }
+  }
+
+  return 0;
+}
+
+static int pn_list_inspect(void *obj, pn_string_t *dst)
+{
+  assert(obj);
+  pn_list_t *list = (pn_list_t *) obj;
+  int err = pn_string_addf(dst, "[");
+  if (err) return err;
+  size_t n = pn_list_size(list);
+  for (size_t i = 0; i < n; i++) {
+    if (i > 0) {
+      err = pn_string_addf(dst, ", ");
+      if (err) return err;
+    }
+    err = pn_inspect(pn_list_get(list, i), dst);
+    if (err) return err;
+  }
+  return pn_string_addf(dst, "]");
+}
+
 pn_list_t *pn_list(size_t capacity, int options)
 {
-  static pn_class_t clazz = {pn_list_finalize, pn_list_hashcode};
+  static pn_class_t clazz = PN_CLASS(pn_list);
 
   pn_list_t *list = (pn_list_t *) pn_new(sizeof(pn_list_t), &clazz);
   list->capacity = capacity ? capacity : 16;
@@ -349,9 +387,37 @@ static void pni_map_allocate(pn_map_t *m
   map->size = 0;
 }
 
+static int pn_map_inspect(void *obj, pn_string_t *dst)
+{
+  assert(obj);
+  pn_map_t *map = (pn_map_t *) obj;
+  int err = pn_string_addf(dst, "{");
+  if (err) return err;
+  pn_handle_t entry = pn_map_head(map);
+  bool first = true;
+  while (entry) {
+    if (first) {
+      first = false;
+    } else {
+      err = pn_string_addf(dst, ", ");
+      if (err) return err;
+    }
+    err = pn_inspect(pn_map_key(map, entry), dst);
+    if (err) return err;
+    err = pn_string_addf(dst, ": ");
+    if (err) return err;
+    err = pn_inspect(pn_map_value(map, entry), dst);
+    if (err) return err;
+    entry = pn_map_next(map, entry);
+  }
+  return pn_string_addf(dst, "}");
+}
+
+#define pn_map_compare NULL
+
 pn_map_t *pn_map(size_t capacity, float load_factor, int options)
 {
-  static pn_class_t clazz = {pn_map_finalize, pn_map_hashcode, NULL};
+  static pn_class_t clazz = PN_CLASS(pn_map);
 
   pn_map_t *map = (pn_map_t *) pn_new(sizeof(pn_map_t), &clazz);
   map->capacity = capacity ? capacity : 16;
@@ -675,8 +741,7 @@ pn_string_t *pn_string(const char *bytes
   return pn_stringn(bytes, bytes ? strlen(bytes) : 0);
 }
 
-static pn_class_t clazz = {pn_string_finalize, pn_string_hashcode,
-                           pn_string_compare, pn_string_inspect};
+static pn_class_t clazz = PN_CLASS(pn_string);
 
 pn_string_t *pn_stringn(const char *bytes, size_t n)
 {

Modified: qpid/proton/trunk/proton-c/src/tests/object.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/tests/object.c?rev=1516825&r1=1516824&r2=1516825&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/tests/object.c (original)
+++ qpid/proton/trunk/proton-c/src/tests/object.c Fri Aug 23 11:55:09 2013
@@ -630,6 +630,101 @@ static void test_map_iteration(int n)
   pn_decref(pairs);
 }
 
+void test_inspect(void *o, const char *expected)
+{
+  pn_string_t *dst = pn_string(NULL);
+  pn_inspect(o, dst);
+  assert(pn_strequals(pn_string_get(dst), expected));
+  pn_free(dst);
+}
+
+void test_list_inspect()
+{
+  pn_list_t *l = build_list(0, PN_REFCOUNT, END);
+  test_inspect(l, "[]");
+  pn_free(l);
+
+  l = build_list(0, PN_REFCOUNT, pn_string("one"), END);
+  test_inspect(l, "[\"one\"]");
+  pn_free(l);
+
+  l = build_list(0, PN_REFCOUNT,
+                 pn_string("one"),
+                 pn_string("two"),
+                 END);
+  test_inspect(l, "[\"one\", \"two\"]");
+  pn_free(l);
+
+  l = build_list(0, PN_REFCOUNT,
+                 pn_string("one"),
+                 pn_string("two"),
+                 pn_string("three"),
+                 END);
+  test_inspect(l, "[\"one\", \"two\", \"three\"]");
+  pn_free(l);
+}
+
+void test_map_inspect()
+{
+  // note that when there is more than one entry in a map, the order
+  // of the entries is dependent on the hashes involved, it will be
+  // deterministic though
+  pn_map_t *m = build_map(0, 0.75, PN_REFCOUNT, END);
+  test_inspect(m, "{}");
+  pn_free(m);
+
+  m = build_map(0, 0.75, PN_REFCOUNT,
+                pn_string("key"), pn_string("value"),
+                END);
+  test_inspect(m, "{\"key\": \"value\"}");
+  pn_free(m);
+
+  m = build_map(0, 0.75, PN_REFCOUNT,
+                pn_string("k1"), pn_string("v1"),
+                pn_string("k2"), pn_string("v2"),
+                END);
+  test_inspect(m, "{\"k1\": \"v1\", \"k2\": \"v2\"}");
+  pn_free(m);
+
+  m = build_map(0, 0.75, PN_REFCOUNT,
+                pn_string("k1"), pn_string("v1"),
+                pn_string("k2"), pn_string("v2"),
+                pn_string("k3"), pn_string("v3"),
+                END);
+  test_inspect(m, "{\"k3\": \"v3\", \"k1\": \"v1\", \"k2\": \"v2\"}");
+  pn_free(m);
+}
+
+void test_list_compare()
+{
+  pn_list_t *a = pn_list(0, PN_REFCOUNT);
+  pn_list_t *b = pn_list(0, PN_REFCOUNT);
+
+  assert(pn_equals(a, b));
+
+  void *one = pn_new(0, NULL);
+  void *two = pn_new(0, NULL);
+  void *three = pn_new(0, NULL);
+
+  pn_list_add(a, one);
+  assert(!pn_equals(a, b));
+  pn_list_add(b, one);
+  assert(pn_equals(a, b));
+
+  pn_list_add(b, two);
+  assert(!pn_equals(a, b));
+  pn_list_add(a, two);
+  assert(pn_equals(a, b));
+
+  pn_list_add(a, three);
+  assert(!pn_equals(a, b));
+  pn_list_add(b, three);
+  assert(pn_equals(a, b));
+
+  pn_free(a); pn_free(b);
+  pn_free(one); pn_free(two); pn_free(three);
+}
+
 int main(int argc, char **argv)
 {
   for (size_t i = 0; i < 128; i++) {
@@ -681,5 +776,9 @@ int main(int argc, char **argv)
     test_map_iteration(i);
   }
 
+  test_list_inspect();
+  test_map_inspect();
+  test_list_compare();
+
   return 0;
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to