You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by fa...@apache.org on 2014/09/27 16:23:02 UTC

svn commit: r1627970 [3/6] - in /qpid/proton/branches/fadams-javascript-binding: ./ contrib/proton-jms/src/main/java/org/apache/qpid/proton/jms/ examples/include/pncompat/ proton-c/ proton-c/bindings/javascript/ proton-c/bindings/perl/ proton-c/binding...

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/object.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/object.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/object.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/object.c Sat Sep 27 14:23:00 2014
@@ -19,1031 +19,294 @@
  *
  */
 
-#include "../platform.h"
-#include <proton/error.h>
 #include <proton/object.h>
-#include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 #include <assert.h>
-#include <ctype.h>
 
-typedef struct {
-  const pn_class_t *clazz;
-  int refcount;
-} pni_head_t;
+#define pn_object_initialize NULL
+#define pn_object_finalize NULL
+#define pn_object_inspect NULL
+uintptr_t pn_object_hashcode(void *object) { return (uintptr_t) object; }
+intptr_t pn_object_compare(void *a, void *b) { return (intptr_t) b - (intptr_t) a; }
 
-#define pni_head(PTR) \
-  (((pni_head_t *) (PTR)) - 1)
+const pn_class_t PNI_OBJECT = PN_CLASS(pn_object);
+const pn_class_t *PN_OBJECT = &PNI_OBJECT;
 
-void *pn_new(size_t size, const pn_class_t *clazz)
+#define pn_void_initialize NULL
+static void *pn_void_new(const pn_class_t *clazz, size_t size) { return malloc(size); }
+static void pn_void_incref(void *object) {}
+static void pn_void_decref(void *object) {}
+static int pn_void_refcount(void *object) { return -1; }
+#define pn_void_finalize NULL
+static void pn_void_free(void *object) { free(object); }
+static const pn_class_t *pn_void_reify(void *object) { return PN_VOID; }
+uintptr_t pn_void_hashcode(void *object) { return (uintptr_t) object; }
+intptr_t pn_void_compare(void *a, void *b) { return (intptr_t) b - (intptr_t) a; }
+int pn_void_inspect(void *object, pn_string_t *dst) { return pn_string_addf(dst, "%p", object); }
+
+const pn_class_t PNI_VOID = PN_METACLASS(pn_void);
+const pn_class_t *PN_VOID = &PNI_VOID;
+
+const char *pn_class_name(const pn_class_t *clazz)
 {
-  return pn_new2(size, clazz, NULL);
+  return clazz->name;
 }
 
-void *pn_new2(size_t size, const pn_class_t *clazz, void *from)
+pn_cid_t pn_class_id(const pn_class_t *clazz)
 {
-  pni_head_t *head = (pni_head_t *) malloc(sizeof(pni_head_t) + size);
-  void *object = head + 1;
-  pn_initialize(object, clazz);
-  return object;
+  return clazz->cid;
 }
 
-void pn_initialize(void *object, const pn_class_t *clazz)
+void *pn_class_new(const pn_class_t *clazz, size_t size)
 {
-  pni_head_t *head = pni_head(object);
-  head->clazz = clazz;
-  head->refcount = 1;
-  if (clazz && clazz->initialize) {
+  assert(clazz);
+  void *object = clazz->newinst(clazz, size);
+  if (clazz->initialize) {
     clazz->initialize(object);
   }
-}
-
-void *pn_incref(void *object) {
-  return pn_incref2(object, NULL);
-}
-
-void *pn_incref2(void *object, void *from) {
-  if (object) {
-    pni_head(object)->refcount++;
-  }
   return object;
 }
 
-void pn_decref(void *object) {
-  pn_decref2(object, NULL);
-}
-
-void pn_decref2(void *object, void *from)
+void *pn_class_incref(const pn_class_t *clazz, void *object)
 {
+  assert(clazz);
   if (object) {
-    pni_head_t *head = pni_head(object);
-    assert(head->refcount > 0);
-    head->refcount--;
-    if (!head->refcount) {
-      pn_finalize(object);
-      // Check the refcount again in case finalize created a new
-      // reference.
-      if (!head->refcount) {
-        free(head);
-      }
-    }
+    clazz = clazz->reify(object);
+    clazz->incref(object);
   }
+  return object;
 }
 
-void pn_finalize(void *object)
+int pn_class_refcount(const pn_class_t *clazz, void *object)
 {
-  if (object) {
-    pni_head_t *head = pni_head(object);
-    assert(head->refcount == 0);
-    if (head->clazz && head->clazz->finalize) {
-      head->clazz->finalize(object);
-    }
-  }
+  assert(clazz);
+  clazz = clazz->reify(object);
+  return clazz->refcount(object);
 }
 
-int pn_refcount(void *object)
+int pn_class_decref(const pn_class_t *clazz, void *object)
 {
-  assert(object);
-  return pni_head(object)->refcount;
-}
+  assert(clazz);
 
-void pn_free(void *object)
-{
   if (object) {
-    assert(pn_refcount(object) == 1);
-    pn_decref(object);
-  }
-}
-
-const pn_class_t *pn_class(void *object)
-{
-  assert(object);
-  return pni_head(object)->clazz;
-}
-
-uintptr_t pn_hashcode(void *object)
-{
-  if (!object) return 0;
-
-  pni_head_t *head = pni_head(object);
-  if (head->clazz && head->clazz->hashcode) {
-    return head->clazz->hashcode(object);
-  } else {
-    return (uintptr_t) head;
-  }
-}
-
-intptr_t pn_compare(void *a, void *b)
-{
-  if (a == b) return 0;
-  if (a && b) {
-    pni_head_t *ha = pni_head(a);
-    pni_head_t *hb = pni_head(b);
-
-    if (ha->clazz && hb->clazz && ha->clazz == hb->clazz) {
-      const pn_class_t *clazz = ha->clazz;
-      if (clazz->compare) {
-        return clazz->compare(a, b);
+    clazz = clazz->reify(object);
+    clazz->decref(object);
+    int rc = clazz->refcount(object);
+    if (rc == 0) {
+      if (clazz->finalize) {
+        clazz->finalize(object);
+        // check the refcount again in case the finalizer created a
+        // new reference
+        rc = clazz->refcount(object);
       }
-    }
-  }
-
-  return (intptr_t) b - (intptr_t) a;
-}
-
-bool pn_equals(void *a, void *b)
-{
-  return !pn_compare(a, b);
-}
-
-int pn_inspect(void *object, pn_string_t *dst)
-{
-  if (!pn_string_get(dst)) {
-    pn_string_set(dst, "");
-  }
-
-  if (object) {
-    pni_head_t *head = pni_head(object);
-    const char *name;
-    if (head->clazz) {
-      const pn_class_t *clazz = head->clazz;
-      if (clazz->inspect) {
-        return clazz->inspect(object, dst);
-      } else if (clazz->name) {
-        name = clazz->name;
-      } else {
-        name = "object";
+      if (rc == 0) {
+        clazz->free(object);
+        return 0;
       }
     } else {
-      name = "object";
+      return rc;
     }
-    return pn_string_addf(dst, "%s<%p>", name, object);
-  } else {
-    return pn_string_addf(dst, "(null)");
-  }
-}
-
-struct pn_list_t {
-  size_t capacity;
-  size_t size;
-  void **elements;
-  int options;
-};
-
-size_t pn_list_size(pn_list_t *list)
-{
-  assert(list);
-  return list->size;
-}
-
-void *pn_list_get(pn_list_t *list, int index)
-{
-  assert(list); assert(list->size);
-  return list->elements[index % list->size];
-}
-
-void pn_list_set(pn_list_t *list, int index, void *value)
-{
-  assert(list); assert(list->size);
-  void *old = list->elements[index % list->size];
-  if (list->options & PN_REFCOUNT) pn_decref2(old, list);
-  list->elements[index % list->size] = value;
-  if (list->options & PN_REFCOUNT) pn_incref2(value, list);
-}
-
-void pn_list_ensure(pn_list_t *list, size_t capacity)
-{
-  assert(list);
-  if (list->capacity < capacity) {
-    size_t newcap = list->capacity;
-    while (newcap < capacity) { newcap *= 2; }
-    list->elements = (void **) realloc(list->elements, newcap * sizeof(void *));
-    assert(list->elements);
-    list->capacity = newcap;
   }
-}
 
-int pn_list_add(pn_list_t *list, void *value)
-{
-  assert(list);
-  pn_list_ensure(list, list->size + 1);
-  list->elements[list->size++] = value;
-  if (list->options & PN_REFCOUNT) pn_incref2(value, list);
   return 0;
 }
 
-ssize_t pn_list_index(pn_list_t *list, void *value)
+void pn_class_free(const pn_class_t *clazz, void *object)
 {
-  for (size_t i = 0; i < list->size; i++) {
-    if (pn_equals(list->elements[i], value)) {
-      return i;
-    }
-  }
-
-  return -1;
-}
-
-bool pn_list_remove(pn_list_t *list, void *value)
-{
-  assert(list);
-  ssize_t idx = pn_list_index(list, value);
-  if (idx < 0) {
-    return false;
-  } else {
-    pn_list_del(list, idx, 1);
-  }
-
-  return true;
-}
-
-void pn_list_del(pn_list_t *list, int index, int n)
-{
-  assert(list);
-  index %= list->size;
-
-  if (list->options & PN_REFCOUNT) {
-    for (int i = 0; i < n; i++) {
-      pn_decref2(list->elements[index + i], list);
-    }
-  }
-
-  size_t slide = list->size - (index + n);
-  for (size_t i = 0; i < slide; i++) {
-    list->elements[index + i] = list->elements[index + n + i];
-  }
-
-  list->size -= n;
-}
-
-void pn_list_clear(pn_list_t *list)
-{
-  assert(list);
-  pn_list_del(list, 0, list->size);
-}
-
-void pn_list_fill(pn_list_t *list, void *value, int n)
-{
-  for (int i = 0; i < n; i++) {
-    pn_list_add(list, value);
-  }
-}
-
-typedef struct {
-  pn_list_t *list;
-  size_t index;
-} pni_list_iter_t;
-
-static void *pni_list_next(void *ctx)
-{
-  pni_list_iter_t *iter = (pni_list_iter_t *) ctx;
-  if (iter->index < pn_list_size(iter->list)) {
-    return pn_list_get(iter->list, iter->index++);
-  } else {
-    return NULL;
-  }
-}
-
-void pn_list_iterator(pn_list_t *list, pn_iterator_t *iter)
-{
-  pni_list_iter_t *liter = (pni_list_iter_t *) pn_iterator_start(iter, pni_list_next, sizeof(pni_list_iter_t));
-  liter->list = list;
-  liter->index = 0;
-}
-
-static void pn_list_finalize(void *object)
-{
-  assert(object);
-  pn_list_t *list = (pn_list_t *) object;
-  for (size_t i = 0; i < list->size; i++) {
-    if (list->options & PN_REFCOUNT) pn_decref2(pn_list_get(list, i), list);
-  }
-  free(list->elements);
-}
-
-static uintptr_t pn_list_hashcode(void *object)
-{
-  assert(object);
-  pn_list_t *list = (pn_list_t *) object;
-  uintptr_t hash = 1;
-
-  for (size_t i = 0; i < list->size; i++) {
-    hash = hash * 31 + pn_hashcode(pn_list_get(list, i));
-  }
-
-  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, "]");
-}
-
-#define pn_list_initialize NULL
-
-pn_list_t *pn_list(size_t capacity, int options)
-{
-  static const 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;
-  list->elements = (void **) malloc(list->capacity * sizeof(void *));
-  list->size = 0;
-  list->options = options;
-  return list;
-}
-
-#define PNI_ENTRY_FREE (0)
-#define PNI_ENTRY_LINK (1)
-#define PNI_ENTRY_TAIL (2)
-
-typedef struct {
-  void *key;
-  void *value;
-  size_t next;
-  uint8_t state;
-} pni_entry_t;
-
-struct pn_map_t {
-  pni_entry_t *entries;
-  size_t capacity;
-  size_t addressable;
-  size_t size;
-  uintptr_t (*hashcode)(void *key);
-  bool (*equals)(void *a, void *b);
-  float load_factor;
-  bool count_keys;
-  bool count_values;
-  bool inspect_keys;
-};
-
-static void pn_map_finalize(void *object)
-{
-  pn_map_t *map = (pn_map_t *) object;
-
-  if (map->count_keys || map->count_values) {
-    for (size_t i = 0; i < map->capacity; i++) {
-      if (map->entries[i].state != PNI_ENTRY_FREE) {
-        if (map->count_keys) pn_decref2(map->entries[i].key, map);
-        if (map->count_values) pn_decref2(map->entries[i].value, map);
-      }
-    }
-  }
-
-  free(map->entries);
-}
-
-static uintptr_t pn_map_hashcode(void *object)
-{
-  pn_map_t *map = (pn_map_t *) object;
-
-  uintptr_t hashcode = 0;
-
-  for (size_t i = 0; i < map->capacity; i++) {
-    if (map->entries[i].state != PNI_ENTRY_FREE) {
-      void *key = map->entries[i].key;
-      void *value = map->entries[i].value;
-      hashcode += pn_hashcode(key) ^ pn_hashcode(value);
-    }
-  }
-
-  return hashcode;
-}
-
-static void pni_map_allocate(pn_map_t *map)
-{
-  map->entries = (pni_entry_t *) malloc(map->capacity * sizeof (pni_entry_t));
-  for (size_t i = 0; i < map->capacity; i++) {
-    map->entries[i].key = NULL;
-    map->entries[i].value = NULL;
-    map->entries[i].next = 0;
-    map->entries[i].state = PNI_ENTRY_FREE;
-  }
-  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;
-    }
-    if (map->inspect_keys) {
-      err = pn_inspect(pn_map_key(map, entry), dst);
+  assert(clazz);
+  if (object) {
+    clazz = clazz->reify(object);
+    int rc = clazz->refcount(object);
+    assert(rc == 1 || rc == -1);
+    if (rc == 1) {
+      rc = pn_class_decref(clazz, object);
+      assert(rc == 0);
     } else {
-      err = pn_string_addf(dst, "%p", pn_map_key(map, entry));
+      if (clazz->finalize) {
+        clazz->finalize(object);
+      }
+      clazz->free(object);
     }
-    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_initialize NULL
-#define pn_map_compare NULL
-
-pn_map_t *pn_map(size_t capacity, float load_factor, int options)
-{
-  static const 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;
-  map->addressable = (size_t) (map->capacity * 0.86);
-  if (!map->addressable) map->addressable = map->capacity;
-  map->load_factor = load_factor;
-  map->hashcode = pn_hashcode;
-  map->equals = pn_equals;
-  map->count_keys = (options & PN_REFCOUNT) || (options & PN_REFCOUNT_KEY);
-  map->count_values = (options & PN_REFCOUNT) || (options & PN_REFCOUNT_VALUE);
-  map->inspect_keys = true;
-  pni_map_allocate(map);
-  return map;
 }
 
-size_t pn_map_size(pn_map_t *map)
+const pn_class_t *pn_class_reify(const pn_class_t *clazz, void *object)
 {
-  assert(map);
-  return map->size;
+  assert(clazz);
+  return clazz->reify(object);
 }
 
-static float pni_map_load(pn_map_t *map)
+uintptr_t pn_class_hashcode(const pn_class_t *clazz, void *object)
 {
-  return ((float) map->size) / ((float) map->addressable);
-}
-
-static bool pni_map_ensure(pn_map_t *map, size_t capacity)
-{
-  float load = pni_map_load(map);
-  if (capacity <= map->capacity && load <= map->load_factor) {
-    return false;
-  }
-
-  size_t oldcap = map->capacity;
+  assert(clazz);
 
-  while (map->capacity < capacity || pni_map_load(map) > map->load_factor) {
-    map->capacity *= 2;
-    map->addressable = (size_t) (0.86 * map->capacity);
-  }
-
-  pni_entry_t *entries = map->entries;
-  pni_map_allocate(map);
-
-  for (size_t i = 0; i < oldcap; i++) {
-    if (entries[i].state != PNI_ENTRY_FREE) {
-      void *key = entries[i].key;
-      void *value = entries[i].value;
-      pn_map_put(map, key, value);
-      if (map->count_keys) pn_decref2(key, map);
-      if (map->count_values) pn_decref2(value, map);
-    }
-  }
-
-  free(entries);
-  return true;
-}
-
-static pni_entry_t *pni_map_entry(pn_map_t *map, void *key, pni_entry_t **pprev, bool create)
-{
-  uintptr_t hashcode = map->hashcode(key);
-
-  pni_entry_t *entry = &map->entries[hashcode % map->addressable];
-  pni_entry_t *prev = NULL;
-
-  if (entry->state == PNI_ENTRY_FREE) {
-    if (create) {
-      entry->state = PNI_ENTRY_TAIL;
-      entry->key = key;
-      if (map->count_keys) pn_incref2(key, map);
-      map->size++;
-      return entry;
-    } else {
-      return NULL;
-    }
-  }
-
-  while (true) {
-    if (map->equals(entry->key, key)) {
-      if (pprev) *pprev = prev;
-      return entry;
-    }
-
-    if (entry->state == PNI_ENTRY_TAIL) {
-      break;
-    } else {
-      prev = entry;
-      entry = &map->entries[entry->next];
-    }
-  }
+  if (!object) return 0;
 
-  if (create) {
-    if (pni_map_ensure(map, map->size + 1)) {
-      // if we had to grow the table we need to start over
-      return pni_map_entry(map, key, pprev, create);
-    }
+  clazz = clazz->reify(object);
 
-    size_t empty = 0;
-    for (size_t i = 0; i < map->capacity; i++) {
-      size_t idx = map->capacity - i - 1;
-      if (map->entries[idx].state == PNI_ENTRY_FREE) {
-        empty = idx;
-        break;
-      }
-    }
-    entry->next = empty;
-    entry->state = PNI_ENTRY_LINK;
-    map->entries[empty].state = PNI_ENTRY_TAIL;
-    map->entries[empty].key = key;
-    if (map->count_keys) pn_incref2(key, map);
-    if (pprev) *pprev = entry;
-    map->size++;
-    return &map->entries[empty];
+  if (clazz->hashcode) {
+    return clazz->hashcode(object);
   } else {
-    return NULL;
+    return (uintptr_t) object;
   }
 }
 
-int pn_map_put(pn_map_t *map, void *key, void *value)
+intptr_t pn_class_compare(const pn_class_t *clazz, void *a, void *b)
 {
-  assert(map);
-  pni_entry_t *entry = pni_map_entry(map, key, NULL, true);
-  if (map->count_values) pn_decref2(entry->value, map);
-  entry->value = value;
-  if (map->count_values) pn_incref2(value, map);
-  return 0;
-}
+  assert(clazz);
 
-void *pn_map_get(pn_map_t *map, void *key)
-{
-  assert(map);
-  pni_entry_t *entry = pni_map_entry(map, key, NULL, false);
-  return entry ? entry->value : NULL;
-}
-
-void pn_map_del(pn_map_t *map, void *key)
-{
-  assert(map);
-  pni_entry_t *prev = NULL;
-  pni_entry_t *entry = pni_map_entry(map, key, &prev, false);
-  if (entry) {
-    void *dref_key = (map->count_keys) ? entry->key : NULL;
-    void *dref_value = (map->count_values) ? entry->value : NULL;
-    if (prev) {
-      prev->next = entry->next;
-      prev->state = entry->state;
-    } else if (entry->next) {
-      assert(entry->state == PNI_ENTRY_LINK);
-      pni_entry_t *next = &map->entries[entry->next];
-      *entry = *next;
-      entry = next;
-    }
-    entry->state = PNI_ENTRY_FREE;
-    entry->next = 0;
-    entry->key = NULL;
-    entry->value = NULL;
-    map->size--;
-    if (dref_key) pn_decref2(dref_key, map);
-    if (dref_value) pn_decref2(dref_value, map);
-  }
-}
-
-pn_handle_t pn_map_head(pn_map_t *map)
-{
-  assert(map);
-  for (size_t i = 0; i < map->capacity; i++)
-  {
-    if (map->entries[i].state != PNI_ENTRY_FREE) {
-      return i + 1;
-    }
-  }
+  if (a == b) return 0;
 
-  return 0;
-}
+  clazz = clazz->reify(a);
 
-pn_handle_t pn_map_next(pn_map_t *map, pn_handle_t entry)
-{
-  for (size_t i = entry; i < map->capacity; i++) {
-    if (map->entries[i].state != PNI_ENTRY_FREE) {
-      return i + 1;
-    }
+  if (a && b && clazz->compare) {
+    return clazz->compare(a, b);
+  } else {
+    return (intptr_t) b - (intptr_t) a;
   }
-
-  return 0;
-}
-
-void *pn_map_key(pn_map_t *map, pn_handle_t entry)
-{
-  assert(map);
-  assert(entry);
-  return map->entries[entry - 1].key;
 }
 
-void *pn_map_value(pn_map_t *map, pn_handle_t entry)
+bool pn_class_equals(const pn_class_t *clazz, void *a, void *b)
 {
-  assert(map);
-  assert(entry);
-  return map->entries[entry - 1].value;
+  return pn_class_compare(clazz, a, b) == 0;
 }
 
-struct pn_hash_t {
-  pn_map_t map;
-};
-
-static uintptr_t pni_identity_hashcode(void *obj)
+int pn_class_inspect(const pn_class_t *clazz, void *object, pn_string_t *dst)
 {
-  return (uintptr_t ) obj;
-}
-
-static bool pni_identity_equals(void *a, void *b)
-{
-  return a == b;
-}
-
-pn_hash_t *pn_hash(size_t capacity, float load_factor, int options)
-{
-  pn_hash_t *hash = (pn_hash_t *) pn_map(capacity, load_factor, 0);
-  hash->map.hashcode = pni_identity_hashcode;
-  hash->map.equals = pni_identity_equals;
-  hash->map.count_keys = false;
-  hash->map.count_values = options & PN_REFCOUNT;
-  hash->map.inspect_keys = false;
-  return hash;
-}
-
-size_t pn_hash_size(pn_hash_t *hash)
-{
-  return pn_map_size(&hash->map);
-}
-
-int pn_hash_put(pn_hash_t *hash, uintptr_t key, void *value)
-{
-  return pn_map_put(&hash->map, (void *) key, value);
-}
-
-void *pn_hash_get(pn_hash_t *hash, uintptr_t key)
-{
-  return pn_map_get(&hash->map, (void *) key);
-}
-
-void pn_hash_del(pn_hash_t *hash, uintptr_t key)
-{
-  pn_map_del(&hash->map, (void *) key);
-}
-
-pn_handle_t pn_hash_head(pn_hash_t *hash)
-{
-  return pn_map_head(&hash->map);
-}
-
-pn_handle_t pn_hash_next(pn_hash_t *hash, pn_handle_t entry)
-{
-  return pn_map_next(&hash->map, entry);
-}
-
-uintptr_t pn_hash_key(pn_hash_t *hash, pn_handle_t entry)
-{
-  return (uintptr_t) pn_map_key(&hash->map, entry);
-}
-
-void *pn_hash_value(pn_hash_t *hash, pn_handle_t entry)
-{
-  return pn_map_value(&hash->map, entry);
-}
-
-
-#define PNI_NULL_SIZE (-1)
+  assert(clazz);
 
-struct pn_string_t {
-  char *bytes;
-  ssize_t size;       // PNI_NULL_SIZE (-1) means null
-  size_t capacity;
-};
+  clazz = clazz->reify(object);
 
-static void pn_string_finalize(void *object)
-{
-  pn_string_t *string = (pn_string_t *) object;
-  free(string->bytes);
-}
-
-static uintptr_t pn_string_hashcode(void *object)
-{
-  pn_string_t *string = (pn_string_t *) object;
-  if (string->size == PNI_NULL_SIZE) {
-    return 0;
-  }
-
-  uintptr_t hashcode = 1;
-  for (ssize_t i = 0; i < string->size; i++) {
-    hashcode = hashcode * 31 + string->bytes[i];
-  }
-  return hashcode;
-}
-
-static intptr_t pn_string_compare(void *oa, void *ob)
-{
-  pn_string_t *a = (pn_string_t *) oa;
-  pn_string_t *b = (pn_string_t *) ob;
-  if (a->size != b->size) {
-    return b->size - a->size;
-  }
-
-  if (a->size == PNI_NULL_SIZE) {
-    return 0;
-  } else {
-    return memcmp(a->bytes, b->bytes, a->size);
+  if (!pn_string_get(dst)) {
+    pn_string_set(dst, "");
   }
-}
 
-static int pn_string_inspect(void *obj, pn_string_t *dst)
-{
-  pn_string_t *str = (pn_string_t *) obj;
-  if (str->size == PNI_NULL_SIZE) {
-    return pn_string_addf(dst, "null");
+  if (object && clazz->inspect) {
+    return clazz->inspect(object, dst);
   }
 
-  int err = pn_string_addf(dst, "\"");
+  const char *name = clazz->name ? clazz->name : "<anon>";
 
-  for (int i = 0; i < str->size; i++) {
-    uint8_t c = str->bytes[i];
-    if (isprint(c)) {
-      err = pn_string_addf(dst, "%c", c);
-      if (err) return err;
-    } else {
-      err = pn_string_addf(dst, "\\x%.2x", c);
-      if (err) return err;
-    }
-  }
-
-  return pn_string_addf(dst, "\"");
+  return pn_string_addf(dst, "%s<%p>", name, object);
 }
 
-pn_string_t *pn_string(const char *bytes)
-{
-  return pn_stringn(bytes, bytes ? strlen(bytes) : 0);
-}
-
-#define pn_string_initialize NULL
+typedef struct {
+  const pn_class_t *clazz;
+  int refcount;
+} pni_head_t;
 
+#define pni_head(PTR) \
+  (((pni_head_t *) (PTR)) - 1)
 
-pn_string_t *pn_stringn(const char *bytes, size_t n)
+void *pn_object_new(const pn_class_t *clazz, size_t size)
 {
-  static const pn_class_t clazz = PN_CLASS(pn_string);
-  pn_string_t *string = (pn_string_t *) pn_new(sizeof(pn_string_t), &clazz);
-  string->capacity = n ? n * sizeof(char) : 16;
-  string->bytes = (char *) malloc(string->capacity);
-  pn_string_setn(string, bytes, n);
-  return string;
+  pni_head_t *head = (pni_head_t *) malloc(sizeof(pni_head_t) + size);
+  void *object = head + 1;
+  head->clazz = clazz;
+  head->refcount = 1;
+  return object;
 }
 
-const char *pn_string_get(pn_string_t *string)
+const pn_class_t *pn_object_reify(void *object)
 {
-  assert(string);
-  if (string->size == PNI_NULL_SIZE) {
-    return NULL;
+  if (object) {
+    return pni_head(object)->clazz;
   } else {
-    return string->bytes;
+    return PN_OBJECT;
   }
 }
 
-size_t pn_string_size(pn_string_t *string)
+void pn_object_incref(void *object)
 {
-  assert(string);
-  if (string->size == PNI_NULL_SIZE) {
-    return 0;
-  } else {
-    return string->size;
+  if (object) {
+    pni_head(object)->refcount++;
   }
 }
 
-int pn_string_set(pn_string_t *string, const char *bytes)
+int pn_object_refcount(void *object)
 {
-  return pn_string_setn(string, bytes, bytes ? strlen(bytes) : 0);
-}
-
-int pn_string_grow(pn_string_t *string, size_t capacity)
-{
-  bool grow = false;
-  while (string->capacity < (capacity*sizeof(char) + 1)) {
-    string->capacity *= 2;
-    grow = true;
-  }
-
-  if (grow) {
-    char *growed = (char *) realloc(string->bytes, string->capacity);
-    if (growed) {
-      string->bytes = growed;
-    } else {
-      return PN_ERR;
-    }
-  }
-
-  return 0;
+  assert(object);
+  return pni_head(object)->refcount;
 }
 
-int pn_string_setn(pn_string_t *string, const char *bytes, size_t n)
+void pn_object_decref(void *object)
 {
-  int err = pn_string_grow(string, n);
-  if (err) return err;
-
-  if (bytes) {
-    memcpy(string->bytes, bytes, n*sizeof(char));
-    string->bytes[n] = '\0';
-    string->size = n;
-  } else {
-    string->size = PNI_NULL_SIZE;
-  }
-
-  return 0;
+  pni_head_t *head = pni_head(object);
+  assert(head->refcount > 0);
+  head->refcount--;
 }
 
-ssize_t pn_string_put(pn_string_t *string, char *dst)
+void pn_object_free(void *object)
 {
-  assert(string);
-  assert(dst);
-
-  if (string->size != PNI_NULL_SIZE) {
-    memcpy(dst, string->bytes, string->size + 1);
-  }
-
-  return string->size;
+  pni_head_t *head = pni_head(object);
+  free(head);
 }
 
-void pn_string_clear(pn_string_t *string)
+void *pn_incref(void *object)
 {
-  pn_string_set(string, NULL);
+  return pn_class_incref(PN_OBJECT, object);
 }
 
-int pn_string_format(pn_string_t *string, const char *format, ...)
+int pn_decref(void *object)
 {
-  va_list ap;
-
-  va_start(ap, format);
-  int err = pn_string_vformat(string, format, ap);
-  va_end(ap);
-  return err;
+  return pn_class_decref(PN_OBJECT, object);
 }
 
-int pn_string_vformat(pn_string_t *string, const char *format, va_list ap)
+int pn_refcount(void *object)
 {
-  pn_string_set(string, "");
-  return pn_string_vaddf(string, format, ap);
+  return pn_class_refcount(PN_OBJECT, object);
 }
 
-int pn_string_addf(pn_string_t *string, const char *format, ...)
+void pn_free(void *object)
 {
-  va_list ap;
-
-  va_start(ap, format);
-  int err = pn_string_vaddf(string, format, ap);
-  va_end(ap);
-  return err;
+  pn_class_free(PN_OBJECT, object);
 }
 
-int pn_string_vaddf(pn_string_t *string, const char *format, va_list ap)
+const pn_class_t *pn_class(void *object)
 {
-  va_list copy;
-
-  if (string->size == PNI_NULL_SIZE) {
-    return PN_ERR;
-  }
-
-  while (true) {
-    va_copy(copy, ap);
-    int err = vsnprintf(string->bytes + string->size, string->capacity - string->size, format, copy);
-    va_end(copy);
-    if (err < 0) {
-      return err;
-    } else if ((size_t) err >= string->capacity - string->size) {
-      pn_string_grow(string, string->size + err);
-    } else {
-      string->size += err;
-      return 0;
-    }
-  }
+  return pn_class_reify(PN_OBJECT, object);
 }
 
-char *pn_string_buffer(pn_string_t *string)
+uintptr_t pn_hashcode(void *object)
 {
-  assert(string);
-  return string->bytes;
+  return pn_class_hashcode(PN_OBJECT, object);
 }
 
-size_t pn_string_capacity(pn_string_t *string)
+intptr_t pn_compare(void *a, void *b)
 {
-  assert(string);
-  return string->capacity - 1;
+  return pn_class_compare(PN_OBJECT, a, b);
 }
 
-int pn_string_resize(pn_string_t *string, size_t size)
+bool pn_equals(void *a, void *b)
 {
-  assert(string);
-  int err = pn_string_grow(string, size);
-  if (err) return err;
-  string->size = size;
-  string->bytes[size] = '\0';
-  return 0;
+  return !pn_compare(a, b);
 }
 
-int pn_string_copy(pn_string_t *string, pn_string_t *src)
+int pn_inspect(void *object, pn_string_t *dst)
 {
-  assert(string);
-  return pn_string_setn(string, pn_string_get(src), pn_string_size(src));
+  return pn_class_inspect(PN_OBJECT, object, dst);
 }
 
-struct pn_iterator_t {
-  pn_iterator_next_t next;
-  size_t size;
-  void *state;
-};
+#define pn_weakref_new NULL
+#define pn_weakref_initialize NULL
+#define pn_weakref_finalize NULL
+#define pn_weakref_free NULL
 
-static void pn_iterator_initialize(void *object)
-{
-  pn_iterator_t *it = (pn_iterator_t *) object;
-  it->next = NULL;
-  it->size = 0;
-  it->state = NULL;
+static void pn_weakref_incref(void *object) {}
+static void pn_weakref_decref(void *object) {}
+static int pn_weakref_refcount(void *object) { return -1; }
+static const pn_class_t *pn_weakref_reify(void *object) {
+  return PN_WEAKREF;
 }
-
-static void pn_iterator_finalize(void *object)
-{
-  pn_iterator_t *it = (pn_iterator_t *) object;
-  free(it->state);
+static uintptr_t pn_weakref_hashcode(void *object) {
+  return pn_hashcode(object);
 }
-
-#define pn_iterator_hashcode NULL
-#define pn_iterator_compare NULL
-#define pn_iterator_inspect NULL
-
-pn_iterator_t *pn_iterator()
-{
-  static const pn_class_t clazz = PN_CLASS(pn_iterator);
-  pn_iterator_t *it = (pn_iterator_t *) pn_new(sizeof(pn_iterator_t), &clazz);
-  return it;
+static intptr_t pn_weakref_compare(void *a, void *b) {
+  return pn_compare(a, b);
 }
-
-void  *pn_iterator_start(pn_iterator_t *iterator, pn_iterator_next_t next,
-                         size_t size) {
-  assert(iterator);
-  assert(next);
-  iterator->next = next;
-  if (iterator->size < size) {
-    iterator->state = realloc(iterator->state, size);
-  }
-  return iterator->state;
+static int pn_weakref_inspect(void *object, pn_string_t *dst) {
+  return pn_inspect(object, dst);
 }
 
-void *pn_iterator_next(pn_iterator_t *iterator) {
-  assert(iterator);
-  if (iterator->next) {
-    void *result = iterator->next(iterator->state);
-    if (!result) iterator->next = NULL;
-    return result;
-  } else {
-    return NULL;
-  }
-}
+const pn_class_t PNI_WEAKREF = PN_METACLASS(pn_weakref);
+const pn_class_t *PN_WEAKREF = &PNI_WEAKREF;

Added: qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/string.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/string.c?rev=1627970&view=auto
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/string.c (added)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/string.c Sat Sep 27 14:23:00 2014
@@ -0,0 +1,270 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "platform.h"
+
+#include <proton/error.h>
+#include <proton/object.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <ctype.h>
+
+#define PNI_NULL_SIZE (-1)
+
+struct pn_string_t {
+  char *bytes;
+  ssize_t size;       // PNI_NULL_SIZE (-1) means null
+  size_t capacity;
+};
+
+static void pn_string_finalize(void *object)
+{
+  pn_string_t *string = (pn_string_t *) object;
+  free(string->bytes);
+}
+
+static uintptr_t pn_string_hashcode(void *object)
+{
+  pn_string_t *string = (pn_string_t *) object;
+  if (string->size == PNI_NULL_SIZE) {
+    return 0;
+  }
+
+  uintptr_t hashcode = 1;
+  for (ssize_t i = 0; i < string->size; i++) {
+    hashcode = hashcode * 31 + string->bytes[i];
+  }
+  return hashcode;
+}
+
+static intptr_t pn_string_compare(void *oa, void *ob)
+{
+  pn_string_t *a = (pn_string_t *) oa;
+  pn_string_t *b = (pn_string_t *) ob;
+  if (a->size != b->size) {
+    return b->size - a->size;
+  }
+
+  if (a->size == PNI_NULL_SIZE) {
+    return 0;
+  } else {
+    return memcmp(a->bytes, b->bytes, a->size);
+  }
+}
+
+static int pn_string_inspect(void *obj, pn_string_t *dst)
+{
+  pn_string_t *str = (pn_string_t *) obj;
+  if (str->size == PNI_NULL_SIZE) {
+    return pn_string_addf(dst, "null");
+  }
+
+  int err = pn_string_addf(dst, "\"");
+
+  for (int i = 0; i < str->size; i++) {
+    uint8_t c = str->bytes[i];
+    if (isprint(c)) {
+      err = pn_string_addf(dst, "%c", c);
+      if (err) return err;
+    } else {
+      err = pn_string_addf(dst, "\\x%.2x", c);
+      if (err) return err;
+    }
+  }
+
+  return pn_string_addf(dst, "\"");
+}
+
+pn_string_t *pn_string(const char *bytes)
+{
+  return pn_stringn(bytes, bytes ? strlen(bytes) : 0);
+}
+
+#define pn_string_initialize NULL
+
+
+pn_string_t *pn_stringn(const char *bytes, size_t n)
+{
+  static const pn_class_t clazz = PN_CLASS(pn_string);
+  pn_string_t *string = (pn_string_t *) pn_class_new(&clazz, sizeof(pn_string_t));
+  string->capacity = n ? n * sizeof(char) : 16;
+  string->bytes = (char *) malloc(string->capacity);
+  pn_string_setn(string, bytes, n);
+  return string;
+}
+
+const char *pn_string_get(pn_string_t *string)
+{
+  assert(string);
+  if (string->size == PNI_NULL_SIZE) {
+    return NULL;
+  } else {
+    return string->bytes;
+  }
+}
+
+size_t pn_string_size(pn_string_t *string)
+{
+  assert(string);
+  if (string->size == PNI_NULL_SIZE) {
+    return 0;
+  } else {
+    return string->size;
+  }
+}
+
+int pn_string_set(pn_string_t *string, const char *bytes)
+{
+  return pn_string_setn(string, bytes, bytes ? strlen(bytes) : 0);
+}
+
+int pn_string_grow(pn_string_t *string, size_t capacity)
+{
+  bool grow = false;
+  while (string->capacity < (capacity*sizeof(char) + 1)) {
+    string->capacity *= 2;
+    grow = true;
+  }
+
+  if (grow) {
+    char *growed = (char *) realloc(string->bytes, string->capacity);
+    if (growed) {
+      string->bytes = growed;
+    } else {
+      return PN_ERR;
+    }
+  }
+
+  return 0;
+}
+
+int pn_string_setn(pn_string_t *string, const char *bytes, size_t n)
+{
+  int err = pn_string_grow(string, n);
+  if (err) return err;
+
+  if (bytes) {
+    memcpy(string->bytes, bytes, n*sizeof(char));
+    string->bytes[n] = '\0';
+    string->size = n;
+  } else {
+    string->size = PNI_NULL_SIZE;
+  }
+
+  return 0;
+}
+
+ssize_t pn_string_put(pn_string_t *string, char *dst)
+{
+  assert(string);
+  assert(dst);
+
+  if (string->size != PNI_NULL_SIZE) {
+    memcpy(dst, string->bytes, string->size + 1);
+  }
+
+  return string->size;
+}
+
+void pn_string_clear(pn_string_t *string)
+{
+  pn_string_set(string, NULL);
+}
+
+int pn_string_format(pn_string_t *string, const char *format, ...)
+{
+  va_list ap;
+
+  va_start(ap, format);
+  int err = pn_string_vformat(string, format, ap);
+  va_end(ap);
+  return err;
+}
+
+int pn_string_vformat(pn_string_t *string, const char *format, va_list ap)
+{
+  pn_string_set(string, "");
+  return pn_string_vaddf(string, format, ap);
+}
+
+int pn_string_addf(pn_string_t *string, const char *format, ...)
+{
+  va_list ap;
+
+  va_start(ap, format);
+  int err = pn_string_vaddf(string, format, ap);
+  va_end(ap);
+  return err;
+}
+
+int pn_string_vaddf(pn_string_t *string, const char *format, va_list ap)
+{
+  va_list copy;
+
+  if (string->size == PNI_NULL_SIZE) {
+    return PN_ERR;
+  }
+
+  while (true) {
+    va_copy(copy, ap);
+    int err = vsnprintf(string->bytes + string->size, string->capacity - string->size, format, copy);
+    va_end(copy);
+    if (err < 0) {
+      return err;
+    } else if ((size_t) err >= string->capacity - string->size) {
+      pn_string_grow(string, string->size + err);
+    } else {
+      string->size += err;
+      return 0;
+    }
+  }
+}
+
+char *pn_string_buffer(pn_string_t *string)
+{
+  assert(string);
+  return string->bytes;
+}
+
+size_t pn_string_capacity(pn_string_t *string)
+{
+  assert(string);
+  return string->capacity - 1;
+}
+
+int pn_string_resize(pn_string_t *string, size_t size)
+{
+  assert(string);
+  int err = pn_string_grow(string, size);
+  if (err) return err;
+  string->size = size;
+  string->bytes[size] = '\0';
+  return 0;
+}
+
+int pn_string_copy(pn_string_t *string, pn_string_t *src)
+{
+  assert(string);
+  return pn_string_setn(string, pn_string_get(src), pn_string_size(src));
+}

Propchange: qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/string.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/proton/branches/fadams-javascript-binding/proton-c/src/object/string.c
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/platform.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/platform.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/platform.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/platform.c Sat Sep 27 14:23:00 2014
@@ -21,7 +21,6 @@
 
 #include "platform.h"
 #include "util.h"
-#include "proton/util.h" // for pn_fatal() ?should pn_fatal() be public?
 
 /* Allow for systems that do not implement clock_gettime()*/
 #ifdef USE_CLOCK_GETTIME
@@ -29,7 +28,7 @@
 pn_timestamp_t pn_i_now(void)
 {
   struct timespec now;
-  if (clock_gettime(CLOCK_REALTIME, &now)) pn_fatal("clock_gettime() failed\n");
+  if (clock_gettime(CLOCK_REALTIME, &now)) pni_fatal("clock_gettime() failed\n");
   return ((pn_timestamp_t)now.tv_sec) * 1000 + (now.tv_nsec / 1000000);
 }
 #elif defined(USE_WIN_FILETIME)
@@ -49,7 +48,7 @@ pn_timestamp_t pn_i_now(void)
 pn_timestamp_t pn_i_now(void)
 {
   struct timeval now;
-  if (gettimeofday(&now, NULL)) pn_fatal("gettimeofday failed\n");
+  if (gettimeofday(&now, NULL)) pni_fatal("gettimeofday failed\n");
   return ((pn_timestamp_t)now.tv_sec) * 1000 + (now.tv_usec / 1000);
 }
 #endif
@@ -93,12 +92,12 @@ char* pn_i_genuuid(void) {
 #ifdef USE_STRERROR_R
 #include <string.h>
 static void pn_i_strerror(int errnum, char *buf, size_t buflen) {
-  if (strerror_r(errnum, buf, buflen) != 0) pn_fatal("strerror_r() failed\n");
+  if (strerror_r(errnum, buf, buflen) != 0) pni_fatal("strerror_r() failed\n");
 }
 #elif USE_STRERROR_S
 #include <string.h>
 static void pn_i_strerror(int errnum, char *buf, size_t buflen) {
-  if (strerror_s(buf, buflen, errnum) != 0) pn_fatal("strerror_s() failed\n");
+  if (strerror_s(buf, buflen, errnum) != 0) pni_fatal("strerror_s() failed\n");
 }
 #elif USE_OLD_STRERROR
 // This is thread safe on some platforms, and the only option on others

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/driver.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/driver.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/driver.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/driver.c Sat Sep 27 14:23:00 2014
@@ -37,11 +37,9 @@
 #include <proton/io.h>
 #include <proton/sasl.h>
 #include <proton/ssl.h>
-#include <proton/util.h>
 #include <proton/object.h>
-#include "../util.h"
-#include "../platform.h"
-#include "../ssl/ssl-internal.h"
+#include "util.h"
+#include "platform.h"
 
 /* Decls */
 
@@ -342,12 +340,12 @@ void pn_connector_set_connection(pn_conn
 {
   if (!ctor) return;
   if (ctor->connection) {
-    pn_decref(ctor->connection);
+    pn_class_decref(PN_OBJECT, ctor->connection);
     pn_transport_unbind(ctor->transport);
   }
   ctor->connection = connection;
   if (ctor->connection) {
-    pn_incref(ctor->connection);
+    pn_class_incref(PN_OBJECT, ctor->connection);
     pn_transport_bind(ctor->transport, connection);
   }
   if (ctor->transport) pn_transport_trace(ctor->transport, ctor->trace);
@@ -404,7 +402,7 @@ void pn_connector_free(pn_connector_t *c
   if (ctor->driver) pn_driver_remove_connector(ctor->driver, ctor);
   pn_transport_free(ctor->transport);
   ctor->transport = NULL;
-  if (ctor->connection) pn_decref(ctor->connection);
+  if (ctor->connection) pn_class_decref(PN_OBJECT, ctor->connection);
   ctor->connection = NULL;
   free(ctor);
 }

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/io.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/io.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/io.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/io.c Sat Sep 27 14:23:00 2014
@@ -35,7 +35,7 @@
 #include <fcntl.h>
 #include <assert.h>
 
-#include "../platform.h"
+#include "platform.h"
 
 #define MAX_HOST (1024)
 #define MAX_SERV (64)
@@ -69,7 +69,7 @@ void pn_io_finalize(void *obj)
 pn_io_t *pn_io(void)
 {
   static const pn_class_t clazz = PN_CLASS(pn_io);
-  pn_io_t *io = (pn_io_t *) pn_new(sizeof(pn_io_t), &clazz);
+  pn_io_t *io = (pn_io_t *) pn_class_new(&clazz, sizeof(pn_io_t));
   return io;
 }
 

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/selector.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/selector.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/selector.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/posix/selector.c Sat Sep 27 14:23:00 2014
@@ -24,9 +24,9 @@
 #include <poll.h>
 #include <stdlib.h>
 #include <assert.h>
-#include "../platform.h"
-#include "../selectable.h"
-#include "../util.h"
+#include "platform.h"
+#include "selectable.h"
+#include "util.h"
 
 struct pn_selector_t {
   struct pollfd *fds;
@@ -45,7 +45,7 @@ void pn_selector_initialize(void *obj)
   selector->fds = NULL;
   selector->deadlines = NULL;
   selector->capacity = 0;
-  selector->selectables = pn_list(0, 0);
+  selector->selectables = pn_list(PN_WEAKREF, 0);
   selector->deadline = 0;
   selector->current = 0;
   selector->awoken = 0;
@@ -68,7 +68,7 @@ void pn_selector_finalize(void *obj)
 pn_selector_t *pni_selector(void)
 {
   static const pn_class_t clazz = PN_CLASS(pn_selector);
-  pn_selector_t *selector = (pn_selector_t *) pn_new(sizeof(pn_selector_t), &clazz);
+  pn_selector_t *selector = (pn_selector_t *) pn_class_new(&clazz, sizeof(pn_selector_t));
   return selector;
 }
 

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/proton.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/proton.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/proton.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/proton.c Sat Sep 27 14:23:00 2014
@@ -29,16 +29,18 @@
 #include "pncompat/misc_funcs.inc"
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <proton/driver.h>
-#include <proton/message.h>
-#include <proton/util.h>
+
+#include "proton/buffer.h"
+#include "proton/codec.h"
+#include "proton/driver.h"
+#include "proton/engine.h"
+#include "proton/message.h"
+#include "proton/version.h"
 #include "util.h"
-#include <proton/version.h>
-#include <proton/codec.h>
-#include <proton/buffer.h>
-#include <proton/parser.h>
 #include "platform_fmt.h"
+
 #include "protocol.h"
 
 void error_exit(const char* fmt, ...)

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/sasl/sasl.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/sasl/sasl.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/sasl/sasl.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/sasl/sasl.c Sat Sep 27 14:23:00 2014
@@ -25,13 +25,13 @@
 #include <string.h>
 #include <proton/buffer.h>
 #include <proton/framing.h>
-#include <proton/engine.h> // XXX: just needed for PN_EOS
+#include <proton/error.h>
 #include <proton/sasl.h>
 #include "protocol.h"
 #include "dispatch_actions.h"
-#include "../dispatcher/dispatcher.h"
-#include "../engine/engine-internal.h"
-#include "../util.h"
+#include "engine/engine-internal.h"
+#include "dispatcher/dispatcher.h"
+#include "util.h"
 
 
 struct pn_sasl_t {

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/selectable.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/selectable.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/selectable.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/selectable.c Sat Sep 27 14:23:00 2014
@@ -91,7 +91,7 @@ pn_selectable_t *pni_selectable(ssize_t 
                                 void (*finalize)(pn_selectable_t *))
 {
   static const pn_class_t clazz = PN_CLASS(pn_selectable);
-  pn_selectable_t *selectable = (pn_selectable_t *) pn_new(sizeof(pn_selectable_t), &clazz);
+  pn_selectable_t *selectable = (pn_selectable_t *) pn_class_new(&clazz, sizeof(pn_selectable_t));
   selectable->capacity = capacity;
   selectable->pending = pending;
   selectable->readable = readable;

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/ssl/openssl.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/ssl/openssl.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/ssl/openssl.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/ssl/openssl.c Sat Sep 27 14:23:00 2014
@@ -20,11 +20,10 @@
  */
 
 #include <proton/ssl.h>
-#include "./ssl-internal.h"
 #include <proton/engine.h>
-#include "../engine/engine-internal.h"
-#include "../platform.h"
-#include "../util.h"
+#include "engine/engine-internal.h"
+#include "platform.h"
+#include "util.h"
 
 #include <openssl/ssl.h>
 #include <openssl/dh.h>
@@ -197,7 +196,7 @@ static int ssl_failed(pn_ssl_t *ssl)
     ERR_error_string_n( ssl_err, buf, sizeof(buf) );
   }
   _log_ssl_error(NULL);    // spit out any remaining errors to the log file
-  ssl->transport->tail_closed = true;
+  pni_close_tail(ssl->transport);
   pn_do_error(ssl->transport, "amqp:connection:framing-error", "SSL Failure: %s", buf);
   return PN_EOS;
 }

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/ssl/ssl_stub.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/ssl/ssl_stub.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/ssl/ssl_stub.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/ssl/ssl_stub.c Sat Sep 27 14:23:00 2014
@@ -20,6 +20,8 @@
  */
 
 #include <proton/ssl.h>
+#include <proton/error.h>
+#include <proton/transport.h>
 
 
 /** @file

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/tests/object.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/tests/object.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/tests/object.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/tests/object.c Sat Sep 27 14:23:00 2014
@@ -30,12 +30,12 @@
 static char mem;
 static void *END = &mem;
 
-static pn_list_t *build_list(size_t capacity, int options, ...)
+static pn_list_t *build_list(size_t capacity, ...)
 {
-  pn_list_t *result = pn_list(capacity, options);
+  pn_list_t *result = pn_list(PN_OBJECT, capacity);
   va_list ap;
 
-  va_start(ap, options);
+  va_start(ap, capacity);
   while (true) {
     void *arg = va_arg(ap, void *);
     if (arg == END) {
@@ -43,23 +43,21 @@ static pn_list_t *build_list(size_t capa
     }
 
     pn_list_add(result, arg);
-    if (PN_REFCOUNT & options) {
-      pn_decref(arg);
-    }
+    pn_class_decref(PN_OBJECT, arg);
   }
   va_end(ap);
 
   return result;
 }
 
-static pn_map_t *build_map(size_t capacity, float load_factor, int options, ...)
+static pn_map_t *build_map(size_t capacity, float load_factor, ...)
 {
-  pn_map_t *result = pn_map(capacity, load_factor, options);
+  pn_map_t *result = pn_map(PN_OBJECT, PN_OBJECT, capacity, load_factor);
   va_list ap;
 
   void *prev = NULL;
 
-  va_start(ap, options);
+  va_start(ap, load_factor);
   int count = 0;
   while (true) {
     void *arg = va_arg(ap, void *);
@@ -70,10 +68,8 @@ static pn_map_t *build_map(size_t capaci
 
     if (count % 2) {
       pn_map_put(result, prev, arg);
-      if (PN_REFCOUNT & options) {
-        pn_decref(prev);
-        pn_decref(arg);
-      }
+      pn_class_decref(PN_OBJECT, prev);
+      pn_class_decref(PN_OBJECT, arg);
     } else {
       prev = arg;
     }
@@ -93,15 +89,51 @@ static void noop(void *o) {}
 static uintptr_t zero(void *o) { return 0; }
 static intptr_t delta(void *a, void *b) { return (uintptr_t) b - (uintptr_t) a; }
 
-static pn_class_t null_class = {0};
+#define CID_noop CID_pn_object
+#define noop_initialize noop
+#define noop_finalize noop
+#define noop_hashcode zero
+#define noop_compare delta
+#define noop_inspect NULL
 
-static pn_class_t noop_class = {NULL, noop, noop, zero, delta};
+static const pn_class_t noop_class = PN_CLASS(noop);
 
-static void test_new(size_t size, pn_class_t *clazz)
+static void test_class(const pn_class_t *clazz, size_t size)
 {
-  void *obj = pn_new(size, clazz);
+  void *a = pn_class_new(clazz, size);
+  void *b = pn_class_new(clazz, size);
+
+  assert(!pn_class_equals(clazz, a, b));
+  assert(pn_class_equals(clazz, a, a));
+  assert(pn_class_equals(clazz, b, b));
+  assert(!pn_class_equals(clazz, a, NULL));
+  assert(!pn_class_equals(clazz, NULL, a));
+
+  int rca = pn_class_refcount(clazz, a);
+  int rcb = pn_class_refcount(clazz, b);
+
+  assert(rca == -1 || rca == 1);
+  assert(rcb == -1 || rcb == 1);
+
+  pn_class_incref(clazz, a);
+
+  rca = pn_class_refcount(clazz, a);
+  assert(rca == -1 || rca == 2);
+
+  pn_class_decref(clazz, a);
+
+  rca = pn_class_refcount(clazz, a);
+  assert(rca == -1 || rca == 1);
+
+  pn_class_free(clazz, a);
+  pn_class_free(clazz, b);
+}
+
+static void test_new(size_t size, const pn_class_t *clazz)
+{
+  void *obj = pn_class_new(clazz, size);
   assert(obj);
-  assert(pn_refcount(obj) == 1);
+  assert(pn_class_refcount(PN_OBJECT, obj) == 1);
   assert(pn_class(obj) == clazz);
   char *bytes = (char *) obj;
   for (size_t i = 0; i < size; i++) {
@@ -117,11 +149,18 @@ static void finalizer(void *object)
   (**called)++;
 }
 
+#define CID_finalizer CID_pn_object
+#define finalizer_initialize NULL
+#define finalizer_finalize finalizer
+#define finalizer_hashcode NULL
+#define finalizer_compare NULL
+#define finalizer_inspect NULL
+
 static void test_finalize(void)
 {
-  static pn_class_t clazz = {NULL, NULL, finalizer};
+  static pn_class_t clazz = PN_CLASS(finalizer);
 
-  int **obj = (int **) pn_new(sizeof(int **), &clazz);
+  int **obj = (int **) pn_class_new(&clazz, sizeof(int **));
   assert(obj);
 
   int called = 0;
@@ -139,23 +178,37 @@ static void test_free(void)
 
 static uintptr_t hashcode(void *obj) { return (uintptr_t) obj; }
 
+#define CID_hashcode CID_pn_object
+#define hashcode_initialize NULL
+#define hashcode_finalize NULL
+#define hashcode_compare NULL
+#define hashcode_hashcode hashcode
+#define hashcode_inspect NULL
+
 static void test_hashcode(void)
 {
-  static pn_class_t clazz = {NULL, NULL, NULL, hashcode};
-  void *obj = pn_new(0, &clazz);
+  static pn_class_t clazz = PN_CLASS(hashcode);
+  void *obj = pn_class_new(&clazz, 0);
   assert(obj);
   assert(pn_hashcode(obj) == (uintptr_t) obj);
   assert(pn_hashcode(NULL) == 0);
   pn_free(obj);
 }
 
+#define CID_compare CID_pn_object
+#define compare_initialize NULL
+#define compare_finalize NULL
+#define compare_compare delta
+#define compare_hashcode NULL
+#define compare_inspect NULL
+
 static void test_compare(void)
 {
-  static pn_class_t clazz = {NULL, NULL, NULL, NULL, delta};
+  static pn_class_t clazz = PN_CLASS(compare);
 
-  void *a = pn_new(0, &clazz);
+  void *a = pn_class_new(&clazz, 0);
   assert(a);
-  void *b = pn_new(0, &clazz);
+  void *b = pn_class_new(&clazz, 0);
   assert(b);
 
   assert(pn_compare(a, b));
@@ -181,7 +234,7 @@ static void test_compare(void)
 
 static void test_refcounting(int refs)
 {
-  void *obj = pn_new(0, NULL);
+  void *obj = pn_class_new(PN_OBJECT, 0);
 
   assert(pn_refcount(obj) == 1);
 
@@ -204,7 +257,7 @@ static void test_refcounting(int refs)
 
 static void test_list(size_t capacity)
 {
-  pn_list_t *list = pn_list(0, 0);
+  pn_list_t *list = pn_list(PN_WEAKREF, 0);
   assert(pn_list_size(list) == 0);
   assert(!pn_list_add(list, (void *) 0));
   assert(!pn_list_add(list, (void *) 1));
@@ -224,12 +277,12 @@ static void test_list(size_t capacity)
 
 static void test_list_refcount(size_t capacity)
 {
-  void *one = pn_new(0, NULL);
-  void *two = pn_new(0, NULL);
-  void *three = pn_new(0, NULL);
-  void *four = pn_new(0, NULL);
+  void *one = pn_class_new(PN_OBJECT, 0);
+  void *two = pn_class_new(PN_OBJECT, 0);
+  void *three = pn_class_new(PN_OBJECT, 0);
+  void *four = pn_class_new(PN_OBJECT, 0);
 
-  pn_list_t *list = pn_list(0, PN_REFCOUNT);
+  pn_list_t *list = pn_list(PN_OBJECT, 0);
   assert(!pn_list_add(list, one));
   assert(!pn_list_add(list, two));
   assert(!pn_list_add(list, three));
@@ -281,7 +334,7 @@ static void check_list_index(pn_list_t *
 
 static void test_list_index(void)
 {
-  pn_list_t *l = pn_list(0, 0);
+  pn_list_t *l = pn_list(PN_WEAKREF, 0);
   void *one = pn_string("one");
   void *two = pn_string("two");
   void *three = pn_string("three");
@@ -324,7 +377,7 @@ static bool pn_strequals(const char *a, 
 
 static void test_build_list(void)
 {
-  pn_list_t *l = build_list(0, PN_REFCOUNT,
+  pn_list_t *l = build_list(0,
                             pn_string("one"),
                             pn_string("two"),
                             pn_string("three"),
@@ -344,7 +397,7 @@ static void test_build_list(void)
 
 static void test_build_map(void)
 {
-  pn_map_t *m = build_map(0, 0.75, PN_REFCOUNT,
+  pn_map_t *m = build_map(0, 0.75,
                           pn_string("key"),
                           pn_string("value"),
                           pn_string("key2"),
@@ -368,7 +421,7 @@ static void test_build_map(void)
 
 static void test_build_map_odd(void)
 {
-  pn_map_t *m = build_map(0, 0.75, PN_REFCOUNT,
+  pn_map_t *m = build_map(0, 0.75,
                           pn_string("key"),
                           pn_string("value"),
                           pn_string("key2"),
@@ -395,11 +448,11 @@ static void test_build_map_odd(void)
 
 static void test_map(void)
 {
-  void *one = pn_new(0, NULL);
-  void *two = pn_new(0, NULL);
-  void *three = pn_new(0, NULL);
+  void *one = pn_class_new(PN_OBJECT, 0);
+  void *two = pn_class_new(PN_OBJECT, 0);
+  void *three = pn_class_new(PN_OBJECT, 0);
 
-  pn_map_t *map = pn_map(4, 0.75, PN_REFCOUNT);
+  pn_map_t *map = pn_map(PN_OBJECT, PN_OBJECT, 4, 0.75);
   assert(pn_map_size(map) == 0);
 
   pn_string_t *key = pn_string("key");
@@ -458,11 +511,11 @@ static void test_map(void)
 
 static void test_hash(void)
 {
-  void *one = pn_new(0, NULL);
-  void *two = pn_new(0, NULL);
-  void *three = pn_new(0, NULL);
+  void *one = pn_class_new(PN_OBJECT, 0);
+  void *two = pn_class_new(PN_OBJECT, 0);
+  void *three = pn_class_new(PN_OBJECT, 0);
 
-  pn_hash_t *hash = pn_hash(4, 0.75, PN_REFCOUNT);
+  pn_hash_t *hash = pn_hash(PN_OBJECT, 4, 0.75);
   pn_hash_put(hash, 0, NULL);
   pn_hash_put(hash, 1, one);
   pn_hash_put(hash, 2, two);
@@ -512,6 +565,7 @@ static uintptr_t collider_hashcode(void 
   return 23;
 }
 
+#define CID_collider CID_pn_object
 #define collider_initialize NULL
 #define collider_finalize NULL
 #define collider_inspect NULL
@@ -521,12 +575,12 @@ static void test_map_links(void)
   const pn_class_t collider_clazz = PN_CLASS(collider);
   void *keys[3];
   for (int i = 0; i < 3; i++)
-    keys[i] = pn_new(0, &collider_clazz);
+    keys[i] = pn_class_new(&collider_clazz, 0);
 
   // test deleting a head, middle link, tail
 
   for (int delete_idx=0; delete_idx < 3; delete_idx++) {
-    pn_map_t *map = pn_map(0, 0.75, 0);
+    pn_map_t *map = pn_map(PN_WEAKREF, PN_WEAKREF, 0, 0.75);
     // create a chain of entries that have same head (from identical key hashcode)
     for (int i = 0; i < 3; i++) {
       pn_map_put(map, keys[i], keys[i]);
@@ -637,17 +691,17 @@ static void test_string_addf(void)
 
 static void test_map_iteration(int n)
 {
-  pn_list_t *pairs = pn_list(2*n, PN_REFCOUNT);
+  pn_list_t *pairs = pn_list(PN_OBJECT, 2*n);
   for (int i = 0; i < n; i++) {
-    void *key = pn_new(0, NULL);
-    void *value = pn_new(0, NULL);
+    void *key = pn_class_new(PN_OBJECT, 0);
+    void *value = pn_class_new(PN_OBJECT, 0);
     pn_list_add(pairs, key);
     pn_list_add(pairs, value);
     pn_decref(key);
     pn_decref(value);
   }
 
-  pn_map_t *map = pn_map(0, 0.75, PN_REFCOUNT);
+  pn_map_t *map = pn_map(PN_OBJECT, PN_OBJECT, 0, 0.75);
 
   assert(pn_map_head(map) == 0);
 
@@ -684,22 +738,22 @@ void test_inspect(void *o, const char *e
 
 void test_list_inspect(void)
 {
-  pn_list_t *l = build_list(0, PN_REFCOUNT, END);
+  pn_list_t *l = build_list(0, END);
   test_inspect(l, "[]");
   pn_free(l);
 
-  l = build_list(0, PN_REFCOUNT, pn_string("one"), END);
+  l = build_list(0, pn_string("one"), END);
   test_inspect(l, "[\"one\"]");
   pn_free(l);
 
-  l = build_list(0, PN_REFCOUNT,
+  l = build_list(0,
                  pn_string("one"),
                  pn_string("two"),
                  END);
   test_inspect(l, "[\"one\", \"two\"]");
   pn_free(l);
 
-  l = build_list(0, PN_REFCOUNT,
+  l = build_list(0,
                  pn_string("one"),
                  pn_string("two"),
                  pn_string("three"),
@@ -713,24 +767,24 @@ void test_map_inspect(void)
   // 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);
+  pn_map_t *m = build_map(0, 0.75, END);
   test_inspect(m, "{}");
   pn_free(m);
 
-  m = build_map(0, 0.75, PN_REFCOUNT,
+  m = build_map(0, 0.75,
                 pn_string("key"), pn_string("value"),
                 END);
   test_inspect(m, "{\"key\": \"value\"}");
   pn_free(m);
 
-  m = build_map(0, 0.75, PN_REFCOUNT,
+  m = build_map(0, 0.75,
                 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,
+  m = build_map(0, 0.75,
                 pn_string("k1"), pn_string("v1"),
                 pn_string("k2"), pn_string("v2"),
                 pn_string("k3"), pn_string("v3"),
@@ -741,14 +795,14 @@ void test_map_inspect(void)
 
 void test_list_compare(void)
 {
-  pn_list_t *a = pn_list(0, PN_REFCOUNT);
-  pn_list_t *b = pn_list(0, PN_REFCOUNT);
+  pn_list_t *a = pn_list(PN_OBJECT, 0);
+  pn_list_t *b = pn_list(PN_OBJECT, 0);
 
   assert(pn_equals(a, b));
 
-  void *one = pn_new(0, NULL);
-  void *two = pn_new(0, NULL);
-  void *three = pn_new(0, NULL);
+  void *one = pn_class_new(PN_OBJECT, 0);
+  void *two = pn_class_new(PN_OBJECT, 0);
+  void *three = pn_class_new(PN_OBJECT, 0);
 
   pn_list_add(a, one);
   assert(!pn_equals(a, b));
@@ -785,7 +839,7 @@ static void *pn_it_next(void *state) {
 
 void test_iterator(void)
 {
-  pn_list_t *list = build_list(0, PN_REFCOUNT,
+  pn_list_t *list = build_list(0,
                                pn_string("one"),
                                pn_string("two"),
                                pn_string("three"),
@@ -811,8 +865,13 @@ void test_iterator(void)
 int main(int argc, char **argv)
 {
   for (size_t i = 0; i < 128; i++) {
-    test_new(i, NULL);
-    test_new(i, &null_class);
+    test_class(PN_OBJECT, i);
+    test_class(PN_VOID, i);
+    test_class(&noop_class, i);
+  }
+
+  for (size_t i = 0; i < 128; i++) {
+    test_new(i, PN_OBJECT);
     test_new(i, &noop_class);
   }
 

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/tests/parse-url.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/tests/parse-url.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/tests/parse-url.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/tests/parse-url.c Sat Sep 27 14:23:00 2014
@@ -20,7 +20,6 @@
  */
 
 #include <stdarg.h>
-#include <proton/type_compat.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -29,8 +28,9 @@
 #undef NDEBUG
 #include <assert.h>
 
-#include <proton/error.h>
-#include <proton/util.h>
+#include "proton/type_compat.h"
+#include "proton/error.h"
+#include "util.h"
 
 static inline bool equalStrP(const char* s1, const char* s2)
 {

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/transport/transport.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/transport/transport.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/transport/transport.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/transport/transport.c Sat Sep 27 14:23:00 2014
@@ -19,7 +19,7 @@
  *
  */
 
-#include "../engine/engine-internal.h"
+#include "engine/engine-internal.h"
 #include <stdlib.h>
 #include <string.h>
 #include <proton/framing.h>
@@ -30,12 +30,10 @@
 #include <stdarg.h>
 #include <stdio.h>
 
-#include "../engine/event.h"
-
-#include "../sasl/sasl-internal.h"
-#include "../ssl/ssl-internal.h"
-#include "../platform.h"
-#include "../platform_fmt.h"
+#include "sasl/sasl-internal.h"
+#include "ssl/ssl-internal.h"
+#include "platform.h"
+#include "platform_fmt.h"
 
 static ssize_t transport_consume(pn_transport_t *transport);
 
@@ -43,7 +41,7 @@ static ssize_t transport_consume(pn_tran
 
 void pn_delivery_map_init(pn_delivery_map_t *db, pn_sequence_t next)
 {
-  db->deliveries = pn_hash(0, 0.75, PN_REFCOUNT);
+  db->deliveries = pn_hash(PN_OBJECT, 0, 0.75);
   db->next = next;
 }
 
@@ -91,6 +89,7 @@ void pn_delivery_map_clear(pn_delivery_m
     pn_delivery_t *dlv = (pn_delivery_t *) pn_hash_value(hash, entry);
     pn_delivery_map_del(dm, dlv);
   }
+  dm->next = 0;
 }
 
 static ssize_t pn_input_read_amqp_header(pn_io_layer_t *io_layer, const char *bytes, size_t available);
@@ -164,9 +163,10 @@ static void pn_transport_initialize(void
   transport->remote_properties = pn_data(0);
   transport->disp_data = pn_data(0);
   pn_condition_init(&transport->remote_condition);
+  pn_condition_init(&transport->condition);
 
-  transport->local_channels = pn_hash(0, 0.75, PN_REFCOUNT);
-  transport->remote_channels = pn_hash(0, 0.75, PN_REFCOUNT);
+  transport->local_channels = pn_hash(PN_OBJECT, 0, 0.75);
+  transport->remote_channels = pn_hash(PN_OBJECT, 0, 0.75);
 
   transport->bytes_input = 0;
   transport->bytes_output = 0;
@@ -175,6 +175,9 @@ static void pn_transport_initialize(void
   transport->output_pending = 0;
 
   transport->done_processing = false;
+
+  transport->posted_head_closed = false;
+  transport->posted_tail_closed = false;
 }
 
 pn_session_t *pn_channel_state(pn_transport_t *transport, uint16_t channel)
@@ -189,12 +192,12 @@ static void pni_map_remote_channel(pn_se
   session->state.remote_channel = channel;
 }
 
-void pni_transport_unbind_handles(pn_hash_t *handles);
+void pni_transport_unbind_handles(pn_hash_t *handles, bool reset_state);
 
 static void pni_unmap_remote_channel(pn_session_t *ssn)
 {
   // XXX: should really update link state also
-  pni_transport_unbind_handles(ssn->state.remote_handles);
+  pni_transport_unbind_handles(ssn->state.remote_handles, false);
   pn_transport_t *transport = ssn->connection->transport;
   uint16_t channel = ssn->state.remote_channel;
   ssn->state.remote_channel = -2;
@@ -211,8 +214,8 @@ static void pn_transport_finalize(void *
 pn_transport_t *pn_transport()
 {
   static const pn_class_t clazz = PN_CLASS(pn_transport);
-  pn_transport_t *transport = (pn_transport_t *) pn_new(sizeof(pn_transport_t),
-                                                        &clazz);
+  pn_transport_t *transport =
+    (pn_transport_t *) pn_class_new(&clazz, sizeof(pn_transport_t));
   if (!transport) return NULL;
 
   transport->output_buf = (char *) malloc(transport->output_size);
@@ -254,6 +257,7 @@ static void pn_transport_finalize(void *
   pn_free(transport->remote_properties);
   pn_free(transport->disp_data);
   pn_condition_tini(&transport->remote_condition);
+  pn_condition_tini(&transport->condition);
   pn_free(transport->local_channels);
   pn_free(transport->remote_channels);
   if (transport->input_buf) free(transport->input_buf);
@@ -263,25 +267,36 @@ static void pn_transport_finalize(void *
 
 int pn_transport_bind(pn_transport_t *transport, pn_connection_t *connection)
 {
-  if (!transport) return PN_ARG_ERR;
+  assert(transport);
+  assert(connection);
+
   if (transport->connection) return PN_STATE_ERR;
   if (connection->transport) return PN_STATE_ERR;
+
   transport->connection = connection;
   connection->transport = transport;
-  pn_incref2(connection, transport);
+
+  pn_collector_put(connection->collector, PN_OBJECT, connection, PN_CONNECTION_BOUND);
+
+  pn_incref(connection);
   if (transport->open_rcvd) {
     PN_SET_REMOTE(connection->endpoint.state, PN_REMOTE_ACTIVE);
-    pn_collector_put(connection->collector, PN_CONNECTION_REMOTE_OPEN, connection);
+    pn_collector_put(connection->collector, PN_OBJECT, connection, PN_CONNECTION_REMOTE_OPEN);
     transport->disp->halt = false;
     transport_consume(transport);        // blech - testBindAfterOpen
   }
+
   return 0;
 }
 
-void pni_transport_unbind_handles(pn_hash_t *handles)
+void pni_transport_unbind_handles(pn_hash_t *handles, bool reset_state)
 {
   for (pn_handle_t h = pn_hash_head(handles); h; h = pn_hash_next(handles, h)) {
     uintptr_t key = pn_hash_key(handles, h);
+    if (reset_state) {
+      pn_link_t *link = (pn_link_t *) pn_hash_value(handles, h);
+      pn_link_unbound(link);
+    }
     pn_hash_del(handles, key);
   }
 }
@@ -291,8 +306,9 @@ void pni_transport_unbind_channels(pn_ha
   for (pn_handle_t h = pn_hash_head(channels); h; h = pn_hash_next(channels, h)) {
     uintptr_t key = pn_hash_key(channels, h);
     pn_session_t *ssn = (pn_session_t *) pn_hash_value(channels, h);
-    pni_transport_unbind_handles(ssn->state.local_handles);
-    pni_transport_unbind_handles(ssn->state.remote_handles);
+    pni_transport_unbind_handles(ssn->state.local_handles, true);
+    pni_transport_unbind_handles(ssn->state.remote_handles, true);
+    pn_session_unbound(ssn);
     pn_hash_del(channels, key);
   }
 }
@@ -302,9 +318,12 @@ int pn_transport_unbind(pn_transport_t *
   assert(transport);
   if (!transport->connection) return 0;
 
+
   pn_connection_t *conn = transport->connection;
   transport->connection = NULL;
 
+  pn_collector_put(conn->collector, PN_OBJECT, conn, PN_CONNECTION_UNBOUND);
+
   // XXX: what happens if the endpoints are freed before we get here?
   pn_session_t *ssn = pn_session_head(conn, 0);
   while (ssn) {
@@ -324,7 +343,7 @@ int pn_transport_unbind(pn_transport_t *
   pni_transport_unbind_channels(transport->remote_channels);
 
   pn_connection_unbound(conn);
-  pn_decref2(conn, transport);
+  pn_decref(conn);
   return 0;
 }
 
@@ -333,6 +352,12 @@ pn_error_t *pn_transport_error(pn_transp
   return NULL;
 }
 
+pn_condition_t *pn_transport_condition(pn_transport_t *transport)
+{
+  assert(transport);
+  return &transport->condition;
+}
+
 static void pni_map_remote_handle(pn_link_t *link, uint32_t handle)
 {
   link->state.remote_handle = handle;
@@ -413,6 +438,15 @@ int pn_post_close(pn_transport_t *transp
                        (bool) condition, ERROR, condition, description, info);
 }
 
+static pn_collector_t *pni_transport_collector(pn_transport_t *transport)
+{
+  if (transport->connection && transport->connection->collector) {
+    return transport->connection->collector;
+  } else {
+    return NULL;
+  }
+}
+
 int pn_do_error(pn_transport_t *transport, const char *condition, const char *fmt, ...)
 {
   va_list ap;
@@ -430,6 +464,10 @@ int pn_do_error(pn_transport_t *transpor
     transport->close_sent = true;
   }
   transport->disp->halt = true;
+  pn_condition_set_name(&transport->condition, condition);
+  pn_condition_set_description(&transport->condition, buf);
+  pn_collector_t *collector = pni_transport_collector(transport);
+  pn_collector_put(collector, PN_OBJECT, transport, PN_TRANSPORT_ERROR);
   pn_transport_logf(transport, "ERROR %s %s", condition, buf);
   return PN_ERR;
 }
@@ -479,7 +517,7 @@ int pn_do_open(pn_dispatcher_t *disp)
 
   if (conn) {
     PN_SET_REMOTE(conn->endpoint.state, PN_REMOTE_ACTIVE);
-    pn_collector_put(conn->collector, PN_CONNECTION_REMOTE_OPEN, conn);
+    pn_collector_put(conn->collector, PN_OBJECT, conn, PN_CONNECTION_REMOTE_OPEN);
   } else {
     transport->disp->halt = true;
   }
@@ -508,7 +546,7 @@ int pn_do_begin(pn_dispatcher_t *disp)
   ssn->state.incoming_transfer_count = next;
   pni_map_remote_channel(ssn, disp->channel);
   PN_SET_REMOTE(ssn->endpoint.state, PN_REMOTE_ACTIVE);
-  pn_collector_put(transport->connection->collector, PN_SESSION_REMOTE_OPEN, ssn);
+  pn_collector_put(transport->connection->collector, PN_OBJECT, ssn, PN_SESSION_REMOTE_OPEN);
   return 0;
 }
 
@@ -682,7 +720,7 @@ int pn_do_attach(pn_dispatcher_t *disp)
     link->state.delivery_count = idc;
   }
 
-  pn_collector_put(transport->connection->collector, PN_LINK_REMOTE_OPEN, link);
+  pn_collector_put(transport->connection->collector, PN_OBJECT, link, PN_LINK_REMOTE_OPEN);
   return 0;
 }
 
@@ -763,7 +801,7 @@ int pn_do_transfer(pn_dispatcher_t *disp
     pn_post_flow(transport, ssn, link);
   }
 
-  pn_collector_put(transport->connection->collector, PN_DELIVERY, delivery);
+  pn_collector_put(transport->connection->collector, PN_OBJECT, delivery, PN_DELIVERY);
   return 0;
 }
 
@@ -813,7 +851,7 @@ int pn_do_flow(pn_dispatcher_t *disp)
       }
     }
 
-    pn_collector_put(transport->connection->collector, PN_LINK_FLOW, link);
+    pn_collector_put(transport->connection->collector, PN_OBJECT, link, PN_LINK_FLOW);
   }
 
   return 0;
@@ -908,7 +946,7 @@ int pn_do_disposition(pn_dispatcher_t *d
       delivery->updated = true;
       pn_work_update(transport->connection, delivery);
 
-      pn_collector_put(transport->connection->collector, PN_DELIVERY, delivery);
+      pn_collector_put(transport->connection->collector, PN_OBJECT, delivery, PN_DELIVERY);
     }
   }
 
@@ -938,9 +976,9 @@ int pn_do_detach(pn_dispatcher_t *disp)
   if (closed)
   {
     PN_SET_REMOTE(link->endpoint.state, PN_REMOTE_CLOSED);
-    pn_collector_put(transport->connection->collector, PN_LINK_REMOTE_CLOSE, link);
+    pn_collector_put(transport->connection->collector, PN_OBJECT, link, PN_LINK_REMOTE_CLOSE);
   } else {
-    // TODO: implement
+    pn_collector_put(transport->connection->collector, PN_OBJECT, link, PN_LINK_REMOTE_DETACH);
   }
 
   pni_unmap_remote_handle(link);
@@ -954,7 +992,7 @@ int pn_do_end(pn_dispatcher_t *disp)
   int err = pn_scan_error(disp->args, &ssn->endpoint.remote_condition, SCAN_ERROR_DEFAULT);
   if (err) return err;
   PN_SET_REMOTE(ssn->endpoint.state, PN_REMOTE_CLOSED);
-  pn_collector_put(transport->connection->collector, PN_SESSION_REMOTE_CLOSE, ssn);
+  pn_collector_put(transport->connection->collector, PN_OBJECT, ssn, PN_SESSION_REMOTE_CLOSE);
   pni_unmap_remote_channel(ssn);
   return 0;
 }
@@ -967,7 +1005,7 @@ int pn_do_close(pn_dispatcher_t *disp)
   if (err) return err;
   transport->close_rcvd = true;
   PN_SET_REMOTE(conn->endpoint.state, PN_REMOTE_CLOSED);
-  pn_collector_put(transport->connection->collector, PN_CONNECTION_REMOTE_CLOSE, conn);
+  pn_collector_put(transport->connection->collector, PN_OBJECT, conn, PN_CONNECTION_REMOTE_CLOSE);
   return 0;
 }
 
@@ -997,6 +1035,14 @@ ssize_t pn_transport_input(pn_transport_
   return original - available;
 }
 
+static void pni_maybe_post_closed(pn_transport_t *transport)
+{
+  pn_collector_t *collector = pni_transport_collector(transport);
+  if (transport->posted_head_closed && transport->posted_tail_closed) {
+    pn_collector_put(collector, PN_OBJECT, transport, PN_TRANSPORT_CLOSED);
+  }
+}
+
 // process pending input until none remaining or EOS
 static ssize_t transport_consume(pn_transport_t *transport)
 {
@@ -1018,6 +1064,12 @@ static ssize_t transport_consume(pn_tran
       if (transport->disp->trace & (PN_TRACE_RAW | PN_TRACE_FRM))
         pn_transport_log(transport, "  <- EOS");
       transport->input_pending = 0;  // XXX ???
+      if (!transport->posted_tail_closed) {
+        pn_collector_t *collector = pni_transport_collector(transport);
+        pn_collector_put(collector, PN_OBJECT, transport, PN_TRANSPORT_TAIL_CLOSED);
+        transport->posted_tail_closed = true;
+        pni_maybe_post_closed(transport);
+      }
       return n;
     }
   }
@@ -1445,7 +1497,7 @@ int pn_process_tpwork_sender(pn_transpor
         link->session->outgoing_deliveries--;
       }
 
-      pn_collector_put(transport->connection->collector, PN_LINK_FLOW, link);
+      pn_collector_put(transport->connection->collector, PN_OBJECT, link, PN_LINK_FLOW);
     }
   }
 
@@ -1571,7 +1623,7 @@ int pn_process_link_teardown(pn_transpor
     pn_session_t *session = link->session;
     pn_session_state_t *ssn_state = &session->state;
     pn_link_state_t *state = &link->state;
-    if (endpoint->state & PN_LOCAL_CLOSED && (int32_t) state->local_handle >= 0 &&
+    if (((endpoint->state & PN_LOCAL_CLOSED) || link->detached) && (int32_t) state->local_handle >= 0 &&
         (int16_t) ssn_state->local_channel >= 0 && !transport->close_sent) {
       if (pn_link_is_sender(link) && pn_link_queued(link) &&
           (int32_t) state->remote_handle != -2 &&
@@ -1588,8 +1640,10 @@ int pn_process_link_teardown(pn_transpor
         info = pn_condition_info(&endpoint->condition);
       }
 
-      int err = pn_post_frame(transport->disp, ssn_state->local_channel, "DL[Io?DL[sSC]]", DETACH,
-                              state->local_handle, true, (bool) name, ERROR, name, description, info);
+      int err =
+          pn_post_frame(transport->disp, ssn_state->local_channel,
+                        "DL[Io?DL[sSC]]", DETACH, state->local_handle, !link->detached,
+                        (bool)name, ERROR, name, description, info);
       if (err) return err;
       pni_unmap_local_handle(link);
     }
@@ -1625,7 +1679,7 @@ bool pn_pointful_buffering(pn_transport_
 
 static void pni_unmap_local_channel(pn_session_t *ssn) {
   // XXX: should really update link state also
-  pni_transport_unbind_handles(ssn->state.local_handles);
+  pni_transport_unbind_handles(ssn->state.local_handles, false);
   pn_transport_t *transport = ssn->connection->transport;
   pn_session_state_t *state = &ssn->state;
   uintptr_t channel = state->local_channel;
@@ -2039,6 +2093,13 @@ ssize_t pn_transport_push(pn_transport_t
   }
 }
 
+void pni_close_tail(pn_transport_t *transport)
+{
+  if (!transport->tail_closed) {
+    transport->tail_closed = true;
+  }
+}
+
 int pn_transport_process(pn_transport_t *transport, size_t size)
 {
   assert(transport);
@@ -2048,7 +2109,7 @@ int pn_transport_process(pn_transport_t 
 
   ssize_t n = transport_consume( transport );
   if (n == PN_EOS) {
-    transport->tail_closed = true;
+    pni_close_tail(transport);
   }
 
   if (n < 0 && n != PN_EOS) return n;
@@ -2058,7 +2119,7 @@ int pn_transport_process(pn_transport_t 
 // input stream has closed
 int pn_transport_close_tail(pn_transport_t *transport)
 {
-  transport->tail_closed = true;
+  pni_close_tail(transport);
   transport_consume( transport );
   return 0;
   // XXX: what if not all input processed at this point?  do we care???
@@ -2110,6 +2171,14 @@ void pn_transport_pop(pn_transport_t *tr
       memmove( transport->output_buf,  &transport->output_buf[size],
                transport->output_pending );
     }
+
+    if (!transport->output_pending && pn_transport_pending(transport) < 0 &&
+        !transport->posted_head_closed) {
+      pn_collector_t *collector = pni_transport_collector(transport);
+      pn_collector_put(collector, PN_OBJECT, transport, PN_TRANSPORT_HEAD_CLOSED);
+      transport->posted_head_closed = true;
+      pni_maybe_post_closed(transport);
+    }
   }
 }
 
@@ -2143,3 +2212,9 @@ bool pn_transport_closed(pn_transport_t 
   ssize_t pending = pn_transport_pending(transport);
   return capacity < 0 && pending < 0;
 }
+
+pn_connection_t *pn_transport_connection(pn_transport_t *transport)
+{
+  assert(transport);
+  return transport->connection;
+}

Added: qpid/proton/branches/fadams-javascript-binding/proton-c/src/url.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/url.c?rev=1627970&view=auto
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/url.c (added)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/url.c Sat Sep 27 14:23:00 2014
@@ -0,0 +1,168 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+#include "proton/url.h"
+#include "proton/object.h"
+#include "util.h"
+#include "platform.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+static char* copy(const char* str) {
+    if (str ==  NULL) return NULL;
+    char *str2 = (char*)malloc(strlen(str)+1);
+    if (str2) strcpy(str2, str);
+    return str2;
+}
+
+struct pn_url_t {
+    char *scheme;
+    char *username;
+    char *password;
+    char *host;
+    char *port;
+    char *path;
+    pn_string_t *str;
+};
+
+/** Internal use only, returns the pn_string_t. Public function is pn_url_str() */
+static pn_string_t *pn_url_string(pn_url_t* url)
+{
+    pn_url_str(url);               /* Make sure str is up to date */
+    return url->str;
+}
+
+static void pn_url_finalize(void *object)
+{
+    pn_url_t *url = (pn_url_t *) object;
+    pn_url_clear(url);
+    pn_free(url->str);
+}
+
+static uintptr_t pn_url_hashcode(void *object)
+{
+    pn_url_t *url = (pn_url_t *) object;
+    return pn_hashcode(pn_url_string(url));
+}
+
+static intptr_t pn_url_compare(void *oa, void *ob)
+{
+    pn_url_t *a = (pn_url_t *) oa;
+    pn_url_t *b = (pn_url_t *) ob;
+    return pn_compare(pn_url_string(a), pn_url_string(b));
+}
+
+
+static int pn_url_inspect(void *obj, pn_string_t *dst)
+{
+    pn_url_t *url = (pn_url_t *) obj;
+    int err = 0;
+    err = pn_string_addf(dst, "Url("); if (err) return err;
+    err = pn_inspect(pn_url_string(url), dst); if (err) return err;
+    return pn_string_addf(dst, ")");
+}
+
+#define pn_url_initialize NULL
+
+
+PN_EXTERN pn_url_t *pn_url() {
+    static const pn_class_t clazz = PN_CLASS(pn_url);
+    pn_url_t *url = (pn_url_t*) pn_class_new(&clazz, sizeof(pn_url_t));
+    if (!url) return NULL;
+    memset(url, 0, sizeof(*url));
+    url->str = pn_string(NULL);
+    return url;
+}
+
+/** Parse a string URL as a pn_url_t.
+ *@param[in] url A URL string.
+ *@return The parsed pn_url_t or NULL if url is not a valid URL string.
+ */
+PN_EXTERN pn_url_t *pn_url_parse(const char *str) {
+    if (!str || !*str)          /* Empty string or NULL is illegal. */
+        return NULL;
+
+    pn_url_t *url = pn_url();
+    char *str2 = copy(str);
+    pni_parse_url(str2, &url->scheme, &url->username, &url->password, &url->host, &url->port, &url->path);
+    url->scheme = copy(url->scheme);
+    url->username = copy(url->username);
+    url->password = copy(url->password);
+    url->host = (url->host && !*url->host) ? NULL : copy(url->host);
+    url->port = copy(url->port);
+    url->path = copy(url->path);
+
+    free(str2);
+    return url;
+}
+
+/** Free a URL */
+PN_EXTERN void pn_url_free(pn_url_t *url) { pn_free(url); }
+
+/** Clear the contents of the URL. */
+PN_EXTERN void pn_url_clear(pn_url_t *url) {
+    pn_url_set_scheme(url, NULL);
+    pn_url_set_username(url, NULL);
+    pn_url_set_password(url, NULL);
+    pn_url_set_host(url, NULL);
+    pn_url_set_port(url, NULL);
+    pn_url_set_path(url, NULL);
+    pn_string_clear(url->str);
+}
+
+static inline int len(const char *str) { return str ? strlen(str) : 0; }
+
+/** Return the string form of a URL. */
+PN_EXTERN const char *pn_url_str(pn_url_t *url) {
+    if (pn_string_get(url->str) == NULL) {
+        pn_string_set(url->str, "");
+        if (url->scheme) pn_string_addf(url->str, "%s://", url->scheme);
+        if (url->username) pn_string_addf(url->str, "%s", url->username);
+        if (url->password) pn_string_addf(url->str, ":%s", url->password);
+        if (url->username || url->password) pn_string_addf(url->str, "@");
+        if (url->host) {
+            if (strchr(url->host, ':')) pn_string_addf(url->str, "[%s]", url->host);
+            else pn_string_addf(url->str, "%s", url->host);
+        }
+        if (url->port) pn_string_addf(url->str, ":%s", url->port);
+        if (url->path) pn_string_addf(url->str, "/%s", url->path);
+    }
+    return pn_string_get(url->str);
+}
+
+PN_EXTERN const char *pn_url_get_scheme(pn_url_t *url) { return url->scheme; }
+PN_EXTERN const char *pn_url_get_username(pn_url_t *url) { return url->username; }
+PN_EXTERN const char *pn_url_get_password(pn_url_t *url) { return url->password; }
+PN_EXTERN const char *pn_url_get_host(pn_url_t *url) { return url->host; }
+PN_EXTERN const char *pn_url_get_port(pn_url_t *url) { return url->port; }
+PN_EXTERN const char *pn_url_get_path(pn_url_t *url) { return url->path; }
+
+#define SET(part) free(url->part); url->part = copy(part); pn_string_clear(url->str)
+PN_EXTERN void pn_url_set_scheme(pn_url_t *url, const char *scheme) { SET(scheme); }
+PN_EXTERN void pn_url_set_username(pn_url_t *url, const char *username) { SET(username); }
+PN_EXTERN void pn_url_set_password(pn_url_t *url, const char *password) { SET(password); }
+PN_EXTERN void pn_url_set_host(pn_url_t *url, const char *host) { SET(host); }
+PN_EXTERN void pn_url_set_port(pn_url_t *url, const char *port) { SET(port); }
+PN_EXTERN void pn_url_set_path(pn_url_t *url, const char *path) { SET(path); }
+
+

Propchange: qpid/proton/branches/fadams-javascript-binding/proton-c/src/url.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: qpid/proton/branches/fadams-javascript-binding/proton-c/src/url.c
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/util.c
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/util.c?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/util.c (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/util.c Sat Sep 27 14:23:00 2014
@@ -27,7 +27,6 @@
 #include <ctype.h>
 #include <string.h>
 #include <proton/error.h>
-#include <proton/util.h>
 #include <proton/types.h>
 #include "util.h"
 
@@ -200,17 +199,17 @@ void pni_parse_url(char *url, char **sch
   if (*pass) pni_urldecode(*pass, *pass);
 }
 
-void pn_vfatal(const char *fmt, va_list ap)
+void pni_vfatal(const char *fmt, va_list ap)
 {
   vfprintf(stderr, fmt, ap);
   abort();
 }
 
-void pn_fatal(const char *fmt, ...)
+void pni_fatal(const char *fmt, ...)
 {
   va_list ap;
   va_start(ap, fmt);
-  pn_vfatal(fmt, ap);
+  pni_vfatal(fmt, ap);
   va_end(ap);
 }
 

Modified: qpid/proton/branches/fadams-javascript-binding/proton-c/src/util.h
URL: http://svn.apache.org/viewvc/qpid/proton/branches/fadams-javascript-binding/proton-c/src/util.h?rev=1627970&r1=1627969&r2=1627970&view=diff
==============================================================================
--- qpid/proton/branches/fadams-javascript-binding/proton-c/src/util.h (original)
+++ qpid/proton/branches/fadams-javascript-binding/proton-c/src/util.h Sat Sep 27 14:23:00 2014
@@ -33,6 +33,9 @@
 #include <proton/types.h>
 #include <proton/object.h>
 
+PN_EXTERN void pni_parse_url(char *url, char **scheme, char **user, char **pass, char **host, char **port, char **path);
+void pni_fatal(const char *fmt, ...);
+void pni_vfatal(const char *fmt, va_list ap);
 PN_EXTERN ssize_t pn_quote_data(char *dst, size_t capacity, const char *src, size_t size);
 int pn_quote(pn_string_t *dst, const char *src, size_t size);
 PN_EXTERN void pn_fprint_data(FILE *stream, const char *bytes, size_t size);



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org