You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2016/11/14 18:28:29 UTC

[08/20] qpid-proton git commit: PROTON-1350 PROTON-1351: Introduce proton-c core library - Created new core proton library qpid-proton-core which only contains protocol processsing and no IO. - Rearranged source tree to separate core protocol code and

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/object/object.c
----------------------------------------------------------------------
diff --git a/proton-c/src/object/object.c b/proton-c/src/object/object.c
deleted file mode 100644
index b0c1b33..0000000
--- a/proton-c/src/object/object.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- *
- * 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/object.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#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) a - (intptr_t) b; }
-
-const pn_class_t PN_OBJECT[] = {PN_CLASS(pn_object)};
-
-#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) a - (intptr_t) b; }
-int pn_void_inspect(void *object, pn_string_t *dst) { return pn_string_addf(dst, "%p", object); }
-
-const pn_class_t PN_VOID[] = {PN_METACLASS(pn_void)};
-
-const char *pn_class_name(const pn_class_t *clazz)
-{
-  return clazz->name;
-}
-
-pn_cid_t pn_class_id(const pn_class_t *clazz)
-{
-  return clazz->cid;
-}
-
-void *pn_class_new(const pn_class_t *clazz, size_t size)
-{
-  assert(clazz);
-  void *object = clazz->newinst(clazz, size);
-  if (clazz->initialize) {
-    clazz->initialize(object);
-  }
-  return object;
-}
-
-void *pn_class_incref(const pn_class_t *clazz, void *object)
-{
-  assert(clazz);
-  if (object) {
-    clazz = clazz->reify(object);
-    clazz->incref(object);
-  }
-  return object;
-}
-
-int pn_class_refcount(const pn_class_t *clazz, void *object)
-{
-  assert(clazz);
-  clazz = clazz->reify(object);
-  return clazz->refcount(object);
-}
-
-int pn_class_decref(const pn_class_t *clazz, void *object)
-{
-  assert(clazz);
-
-  if (object) {
-    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);
-      }
-      if (rc == 0) {
-        clazz->free(object);
-        return 0;
-      }
-    } else {
-      return rc;
-    }
-  }
-
-  return 0;
-}
-
-void pn_class_free(const pn_class_t *clazz, void *object)
-{
-  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 {
-      if (clazz->finalize) {
-        clazz->finalize(object);
-      }
-      clazz->free(object);
-    }
-  }
-}
-
-const pn_class_t *pn_class_reify(const pn_class_t *clazz, void *object)
-{
-  assert(clazz);
-  return clazz->reify(object);
-}
-
-uintptr_t pn_class_hashcode(const pn_class_t *clazz, void *object)
-{
-  assert(clazz);
-
-  if (!object) return 0;
-
-  clazz = clazz->reify(object);
-
-  if (clazz->hashcode) {
-    return clazz->hashcode(object);
-  } else {
-    return (uintptr_t) object;
-  }
-}
-
-intptr_t pn_class_compare(const pn_class_t *clazz, void *a, void *b)
-{
-  assert(clazz);
-
-  if (a == b) return 0;
-
-  clazz = clazz->reify(a);
-
-  if (a && b && clazz->compare) {
-    return clazz->compare(a, b);
-  } else {
-    return (intptr_t) a - (intptr_t) b;
-  }
-}
-
-bool pn_class_equals(const pn_class_t *clazz, void *a, void *b)
-{
-  return pn_class_compare(clazz, a, b) == 0;
-}
-
-int pn_class_inspect(const pn_class_t *clazz, void *object, pn_string_t *dst)
-{
-  assert(clazz);
-
-  clazz = clazz->reify(object);
-
-  if (!pn_string_get(dst)) {
-    pn_string_set(dst, "");
-  }
-
-  if (object && clazz->inspect) {
-    return clazz->inspect(object, dst);
-  }
-
-  const char *name = clazz->name ? clazz->name : "<anon>";
-
-  return pn_string_addf(dst, "%s<%p>", name, object);
-}
-
-typedef struct {
-  const pn_class_t *clazz;
-  int refcount;
-} pni_head_t;
-
-#define pni_head(PTR) \
-  (((pni_head_t *) (PTR)) - 1)
-
-void *pn_object_new(const pn_class_t *clazz, size_t size)
-{
-  void *object = NULL;
-  pni_head_t *head = (pni_head_t *) malloc(sizeof(pni_head_t) + size);
-  if (head != NULL) {
-    object = head + 1;
-    head->clazz = clazz;
-    head->refcount = 1;
-  }
-  return object;
-}
-
-const pn_class_t *pn_object_reify(void *object)
-{
-  if (object) {
-    return pni_head(object)->clazz;
-  } else {
-    return PN_OBJECT;
-  }
-}
-
-void pn_object_incref(void *object)
-{
-  if (object) {
-    pni_head(object)->refcount++;
-  }
-}
-
-int pn_object_refcount(void *object)
-{
-  assert(object);
-  return pni_head(object)->refcount;
-}
-
-void pn_object_decref(void *object)
-{
-  pni_head_t *head = pni_head(object);
-  assert(head->refcount > 0);
-  head->refcount--;
-}
-
-void pn_object_free(void *object)
-{
-  pni_head_t *head = pni_head(object);
-  free(head);
-}
-
-void *pn_incref(void *object)
-{
-  return pn_class_incref(PN_OBJECT, object);
-}
-
-int pn_decref(void *object)
-{
-  return pn_class_decref(PN_OBJECT, object);
-}
-
-int pn_refcount(void *object)
-{
-  return pn_class_refcount(PN_OBJECT, object);
-}
-
-void pn_free(void *object)
-{
-  pn_class_free(PN_OBJECT, object);
-}
-
-const pn_class_t *pn_class(void *object)
-{
-  return pn_class_reify(PN_OBJECT, object);
-}
-
-uintptr_t pn_hashcode(void *object)
-{
-  return pn_class_hashcode(PN_OBJECT, object);
-}
-
-intptr_t pn_compare(void *a, void *b)
-{
-  return pn_class_compare(PN_OBJECT, a, b);
-}
-
-bool pn_equals(void *a, void *b)
-{
-  return !pn_compare(a, b);
-}
-
-int pn_inspect(void *object, pn_string_t *dst)
-{
-  return pn_class_inspect(PN_OBJECT, object, dst);
-}
-
-#define pn_weakref_new NULL
-#define pn_weakref_initialize NULL
-#define pn_weakref_finalize NULL
-#define pn_weakref_free 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 uintptr_t pn_weakref_hashcode(void *object) {
-  return pn_hashcode(object);
-}
-static intptr_t pn_weakref_compare(void *a, void *b) {
-  return pn_compare(a, b);
-}
-static int pn_weakref_inspect(void *object, pn_string_t *dst) {
-  return pn_inspect(object, dst);
-}
-
-const pn_class_t PN_WEAKREF[] = {PN_METACLASS(pn_weakref)};

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/object/record.c
----------------------------------------------------------------------
diff --git a/proton-c/src/object/record.c b/proton-c/src/object/record.c
deleted file mode 100644
index 6f4fe0a..0000000
--- a/proton-c/src/object/record.c
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- *
- * 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/object.h>
-#include <stdlib.h>
-#include <assert.h>
-
-typedef struct {
-  pn_handle_t key;
-  const pn_class_t *clazz;
-  void *value;
-} pni_field_t;
-
-struct pn_record_t {
-  size_t size;
-  size_t capacity;
-  pni_field_t *fields;
-};
-
-static void pn_record_initialize(void *object)
-{
-  pn_record_t *record = (pn_record_t *) object;
-  record->size = 0;
-  record->capacity = 0;
-  record->fields = NULL;
-}
-
-static void pn_record_finalize(void *object)
-{
-  pn_record_t *record = (pn_record_t *) object;
-  for (size_t i = 0; i < record->size; i++) {
-    pni_field_t *v = &record->fields[i];
-    pn_class_decref(v->clazz, v->value);
-  }
-  free(record->fields);
-}
-
-#define pn_record_hashcode NULL
-#define pn_record_compare NULL
-#define pn_record_inspect NULL
-
-pn_record_t *pn_record(void)
-{
-  static const pn_class_t clazz = PN_CLASS(pn_record);
-  pn_record_t *record = (pn_record_t *) pn_class_new(&clazz, sizeof(pn_record_t));
-  pn_record_def(record, PN_LEGCTX, PN_VOID);
-  return record;
-}
-
-static pni_field_t *pni_record_find(pn_record_t *record, pn_handle_t key) {
-  for (size_t i = 0; i < record->size; i++) {
-    pni_field_t *field = &record->fields[i];
-    if (field->key == key) {
-      return field;
-    }
-  }
-  return NULL;
-}
-
-static pni_field_t *pni_record_create(pn_record_t *record) {
-  record->size++;
-  if (record->size > record->capacity) {
-    record->fields = (pni_field_t *) realloc(record->fields, record->size * sizeof(pni_field_t));
-    record->capacity = record->size;
-  }
-  pni_field_t *field = &record->fields[record->size - 1];
-  field->key = 0;
-  field->clazz = NULL;
-  field->value = NULL;
-  return field;
-}
-
-void pn_record_def(pn_record_t *record, pn_handle_t key, const pn_class_t *clazz)
-{
-  assert(record);
-  assert(clazz);
-
-  pni_field_t *field = pni_record_find(record, key);
-  if (field) {
-    assert(field->clazz == clazz);
-  } else {
-    field = pni_record_create(record);
-    field->key = key;
-    field->clazz = clazz;
-  }
-}
-
-bool pn_record_has(pn_record_t *record, pn_handle_t key)
-{
-  assert(record);
-  pni_field_t *field = pni_record_find(record, key);
-  if (field) {
-    return true;
-  } else {
-    return false;
-  }
-}
-
-void *pn_record_get(pn_record_t *record, pn_handle_t key)
-{
-  assert(record);
-  pni_field_t *field = pni_record_find(record, key);
-  if (field) {
-    return field->value;
-  } else {
-    return NULL;
-  }
-}
-
-void pn_record_set(pn_record_t *record, pn_handle_t key, void *value)
-{
-  assert(record);
-
-  pni_field_t *field = pni_record_find(record, key);
-  if (field) {
-    void *old = field->value;
-    field->value = value;
-    pn_class_incref(field->clazz, value);
-    pn_class_decref(field->clazz, old);
-  }
-}
-
-void pn_record_clear(pn_record_t *record)
-{
-  assert(record);
-  for (size_t i = 0; i < record->size; i++) {
-    pni_field_t *field = &record->fields[i];
-    pn_class_decref(field->clazz, field->value);
-    field->key = 0;
-    field->clazz = NULL;
-    field->value = NULL;
-  }
-  record->size = 0;
-  pn_record_def(record, PN_LEGCTX, PN_VOID);
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/object/string.c
----------------------------------------------------------------------
diff --git a/proton-c/src/object/string.c b/proton-c/src/object/string.c
deleted file mode 100644
index 7b900ca..0000000
--- a/proton-c/src/object/string.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- *
- * 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));
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/parser.c
----------------------------------------------------------------------
diff --git a/proton-c/src/parser.c b/proton-c/src/parser.c
deleted file mode 100644
index 87cb758..0000000
--- a/proton-c/src/parser.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- *
- * 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/parser.h>
-#include <proton/scanner.h>
-#include <proton/error.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include "platform.h"
-
-struct pn_parser_t {
-  pn_scanner_t *scanner;
-  char *atoms;
-  size_t size;
-  size_t capacity;
-  int error_code;
-};
-
-pn_parser_t *pn_parser()
-{
-  pn_parser_t *parser = (pn_parser_t *) malloc(sizeof(pn_parser_t));
-  if (parser != NULL) {
-    parser->scanner = pn_scanner();
-    parser->atoms = NULL;
-    parser->size = 0;
-    parser->capacity = 0;
-  }
-  return parser;
-}
-
-static void pni_parser_ensure(pn_parser_t *parser, size_t size)
-{
-  while (parser->capacity - parser->size < size) {
-    parser->capacity = parser->capacity ? 2 * parser->capacity : 1024;
-    parser->atoms = (char *) realloc(parser->atoms, parser->capacity);
-  }
-}
-
-int pn_parser_err(pn_parser_t *parser, int code, const char *fmt, ...)
-{
-  va_list ap;
-  va_start(ap, fmt);
-  int err = pn_scanner_verr(parser->scanner, code, fmt, ap);
-  va_end(ap);
-  return err;
-}
-
-int pn_parser_errno(pn_parser_t *parser)
-{
-  return pn_scanner_errno(parser->scanner);
-}
-
-const char *pn_parser_error(pn_parser_t *parser)
-{
-  return pn_scanner_error(parser->scanner);
-}
-
-void pn_parser_free(pn_parser_t *parser)
-{
-  if (parser) {
-    pn_scanner_free(parser->scanner);
-    free(parser->atoms);
-    free(parser);
-  }
-}
-
-static int pni_parser_shift(pn_parser_t *parser)
-{
-  return pn_scanner_shift(parser->scanner);
-}
-
-static pn_token_t pni_parser_token(pn_parser_t *parser)
-{
-  return pn_scanner_token(parser->scanner);
-}
-
-static int pni_parser_value(pn_parser_t *parser, pn_data_t *data);
-
-static int pni_parser_descriptor(pn_parser_t *parser, pn_data_t *data)
-{
-  if (pni_parser_token(parser).type == PN_TOK_AT) {
-    int err = pni_parser_shift(parser);
-    if (err) return err;
-
-    err = pn_data_put_described(data);
-    if (err) return pn_parser_err(parser, err, "error writing described");
-    pn_data_enter(data);
-    for (int i = 0; i < 2; i++) {
-      err = pni_parser_value(parser, data);
-      if (err) return err;
-    }
-    pn_data_exit(data);
-    return 0;
-  } else {
-    return pn_parser_err(parser, PN_ERR, "expecting '@'");
-  }
-}
-
-static int pni_parser_map(pn_parser_t *parser, pn_data_t *data)
-{
-  if (pni_parser_token(parser).type == PN_TOK_LBRACE) {
-    int err = pni_parser_shift(parser);
-    if (err) return err;
-
-    err = pn_data_put_map(data);
-    if (err) return pn_parser_err(parser, err, "error writing map");
-
-    pn_data_enter(data);
-
-    if (pni_parser_token(parser).type != PN_TOK_RBRACE) {
-      while (true) {
-        err = pni_parser_value(parser, data);
-        if (err) return err;
-
-        if (pni_parser_token(parser).type == PN_TOK_EQUAL) {
-          err = pni_parser_shift(parser);
-          if (err) return err;
-        } else {
-          return pn_parser_err(parser, PN_ERR, "expecting '='");
-        }
-
-        err = pni_parser_value(parser, data);
-        if (err) return err;
-
-        if (pni_parser_token(parser).type == PN_TOK_COMMA) {
-          err = pni_parser_shift(parser);
-          if (err) return err;
-        } else {
-          break;
-        }
-      }
-    }
-
-    pn_data_exit(data);
-
-    if (pni_parser_token(parser).type == PN_TOK_RBRACE) {
-      return pni_parser_shift(parser);
-    } else {
-      return pn_parser_err(parser, PN_ERR, "expecting '}'");
-    }
-  } else {
-    return pn_parser_err(parser, PN_ERR, "expecting '{'");
-  }
-}
-
-static int pni_parser_list(pn_parser_t *parser, pn_data_t *data)
-{
-  int err;
-
-  if (pni_parser_token(parser).type == PN_TOK_LBRACKET) {
-    err = pni_parser_shift(parser);
-    if (err) return err;
-
-    err = pn_data_put_list(data);
-    if (err) return pn_parser_err(parser, err, "error writing list");
-
-    pn_data_enter(data);
-
-    if (pni_parser_token(parser).type != PN_TOK_RBRACKET) {
-      while (true) {
-        err = pni_parser_value(parser, data);
-        if (err) return err;
-
-        if (pni_parser_token(parser).type == PN_TOK_COMMA) {
-          err = pni_parser_shift(parser);
-          if (err) return err;
-        } else {
-          break;
-        }
-      }
-    }
-
-    pn_data_exit(data);
-
-    if (pni_parser_token(parser).type == PN_TOK_RBRACKET) {
-      return pni_parser_shift(parser);
-    } else {
-      return pn_parser_err(parser, PN_ERR, "expecting ']'");
-    }
-  } else {
-    return pn_parser_err(parser, PN_ERR, "expecting '['");
-  }
-}
-
-static void pni_parser_append_tok(pn_parser_t *parser, char *dst, int *idx)
-{
-  memcpy(dst + *idx, pni_parser_token(parser).start, pni_parser_token(parser).size);
-  *idx += pni_parser_token(parser).size;
-}
-
-static int pni_parser_number(pn_parser_t *parser, pn_data_t *data)
-{
-  bool dbl = false;
-  char number[1024];
-  int idx = 0;
-  int err;
-
-  bool negate = false;
-
-  if (pni_parser_token(parser).type == PN_TOK_NEG || pni_parser_token(parser).type == PN_TOK_POS) {
-    if (pni_parser_token(parser).type == PN_TOK_NEG)
-      negate = !negate;
-    err = pni_parser_shift(parser);
-    if (err) return err;
-  }
-
-  if (pni_parser_token(parser).type == PN_TOK_FLOAT || pni_parser_token(parser).type == PN_TOK_INT) {
-    dbl = pni_parser_token(parser).type == PN_TOK_FLOAT;
-    pni_parser_append_tok(parser, number, &idx);
-    err = pni_parser_shift(parser);
-    if (err) return err;
-  } else {
-    return pn_parser_err(parser, PN_ERR, "expecting FLOAT or INT");
-  }
-
-  number[idx] = '\0';
-
-  if (dbl) {
-    double value = atof(number);
-    if (negate) {
-      value = -value;
-    }
-    err = pn_data_put_double(data, value);
-    if (err) return pn_parser_err(parser, err, "error writing double");
-  } else {
-    int64_t value = pn_i_atoll(number);
-    if (negate) {
-      value = -value;
-    }
-    err = pn_data_put_long(data, value);
-    if (err) return pn_parser_err(parser, err, "error writing long");
-  }
-
-  return 0;
-}
-
-static int pni_parser_unquote(pn_parser_t *parser, char *dst, const char *src, size_t *n)
-{
-  size_t idx = 0;
-  bool escape = false;
-  int start, end;
-  if (src[0] != '"') {
-    if (src[1] == '"') {
-      start = 2;
-      end = *n - 1;
-    } else {
-      start = 1;
-      end = *n;
-    }
-  } else {
-    start = 1;
-    end = *n - 1;
-  }
-  for (int i = start; i < end; i++)
-  {
-    char c = src[i];
-    if (escape) {
-      switch (c) {
-      case '"':
-      case '\\':
-      case '/':
-        dst[idx++] = c;
-        escape = false;
-        break;
-      case 'b':
-        dst[idx++] = '\b';
-        break;
-      case 'f':
-        dst[idx++] = '\f';
-        break;
-      case 'n':
-        dst[idx++] = '\n';
-        break;
-      case 'r':
-        dst[idx++] = '\r';
-        break;
-      case 't':
-        dst[idx++] = '\t';
-        break;
-      case 'x':
-        {
-          char n1 = toupper(src[i+1]);
-          char n2 = n1 ? toupper(src[i+2]) : 0;
-          if (!n2) {
-            return pn_parser_err(parser, PN_ERR, "truncated escape code");
-          }
-          int d1 = isdigit(n1) ? n1 - '0' : n1 - 'A' + 10;
-          int d2 = isdigit(n2) ? n2 - '0' : n2 - 'A' + 10;
-          dst[idx++] = d1*16 + d2;
-          i += 2;
-        }
-        break;
-      // XXX: need to handle unicode escapes: 'u'
-      default:
-        return pn_parser_err(parser, PN_ERR, "unrecognized escape code");
-      }
-      escape = false;
-    } else {
-      switch (c)
-      {
-      case '\\':
-        escape = true;
-        break;
-      default:
-        dst[idx++] = c;
-        break;
-      }
-    }
-  }
-  dst[idx++] = '\0';
-  *n = idx;
-  return 0;
-}
-
-static int pni_parser_value(pn_parser_t *parser, pn_data_t *data)
-{
-  int err;
-  size_t n;
-  char *dst;
-
-  pn_token_t tok = pni_parser_token(parser);
-
-  switch (tok.type)
-  {
-  case PN_TOK_AT:
-    return pni_parser_descriptor(parser, data);
-  case PN_TOK_LBRACE:
-    return pni_parser_map(parser, data);
-  case PN_TOK_LBRACKET:
-    return pni_parser_list(parser, data);
-  case PN_TOK_BINARY:
-  case PN_TOK_SYMBOL:
-  case PN_TOK_STRING:
-    n = tok.size;
-    pni_parser_ensure(parser, n);
-    dst = parser->atoms + parser->size;
-    err = pni_parser_unquote(parser, dst, tok.start, &n);
-    if (err) return err;
-    parser->size += n;
-    switch (tok.type) {
-    case PN_TOK_BINARY:
-      err = pn_data_put_binary(data, pn_bytes(n - 1, dst));
-      break;
-    case PN_TOK_STRING:
-      err = pn_data_put_string(data, pn_bytes(n - 1, dst));
-      break;
-    case PN_TOK_SYMBOL:
-      err = pn_data_put_symbol(data, pn_bytes(n - 1, dst));
-      break;
-    default:
-      return pn_parser_err(parser, PN_ERR, "internal error");
-    }
-    if (err) return pn_parser_err(parser, err, "error writing string/binary/symbol");
-    return pni_parser_shift(parser);
-  case PN_TOK_POS:
-  case PN_TOK_NEG:
-  case PN_TOK_FLOAT:
-  case PN_TOK_INT:
-    return pni_parser_number(parser, data);
-  case PN_TOK_TRUE:
-    err = pn_data_put_bool(data, true);
-    if (err) return pn_parser_err(parser, err, "error writing boolean");
-    return pni_parser_shift(parser);
-  case PN_TOK_FALSE:
-    err = pn_data_put_bool(data, false);
-    if (err) return pn_parser_err(parser, err, "error writing boolean");
-    return pni_parser_shift(parser);
-  case PN_TOK_NULL:
-    err = pn_data_put_null(data);
-    if (err) return pn_parser_err(parser, err, "error writing null");
-    return pni_parser_shift(parser);
-  default:
-    return pn_parser_err(parser, PN_ERR, "expecting one of '[', '{', STRING, "
-                         "SYMBOL, BINARY, true, false, null, NUMBER");
-  }
-}
-
-static int pni_parser_parse_r(pn_parser_t *parser, pn_data_t *data)
-{
-  while (true) {
-    int err;
-    switch (pni_parser_token(parser).type)
-    {
-    case PN_TOK_EOS:
-      return 0;
-    case PN_TOK_ERR:
-      return PN_ERR;
-    default:
-      err = pni_parser_value(parser, data);
-      if (err) return err;
-    }
-  }
-}
-
-int pn_parser_parse(pn_parser_t *parser, const char *str, pn_data_t *data)
-{
-  int err = pn_scanner_start(parser->scanner, str);
-  if (err) return err;
-  parser->size = 0;
-  return pni_parser_parse_r(parser, data);
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/platform.c
----------------------------------------------------------------------
diff --git a/proton-c/src/platform.c b/proton-c/src/platform.c
deleted file mode 100644
index 3a8cade..0000000
--- a/proton-c/src/platform.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *
- * 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 "util.h"
-
-#ifdef PN_WINAPI
-#include <windows.h>
-int pn_i_getpid() {
-  return (int) GetCurrentProcessId();
-}
-#else
-#include <unistd.h>
-int pn_i_getpid() {
-  return (int) getpid();
-}
-#endif
-
-/* Allow for systems that do not implement clock_gettime()*/
-#ifdef USE_CLOCK_GETTIME
-#include <time.h>
-pn_timestamp_t pn_i_now(void)
-{
-  struct timespec now;
-  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)
-#include <windows.h>
-pn_timestamp_t pn_i_now(void)
-{
-  FILETIME now;
-  GetSystemTimeAsFileTime(&now);
-  ULARGE_INTEGER t;
-  t.u.HighPart = now.dwHighDateTime;
-  t.u.LowPart = now.dwLowDateTime;
-  // Convert to milliseconds and adjust base epoch
-  return t.QuadPart / 10000 - 11644473600000;
-}
-#else
-#include <sys/time.h>
-pn_timestamp_t pn_i_now(void)
-{
-  struct timeval now;
-  if (gettimeofday(&now, NULL)) pni_fatal("gettimeofday failed\n");
-  return ((pn_timestamp_t)now.tv_sec) * 1000 + (now.tv_usec / 1000);
-}
-#endif
-
-#include <string.h>
-#include <stdio.h>
-static void pn_i_strerror(int errnum, char *buf, size_t buflen)
-{
-  // PROTON-1029 provide a simple default in case strerror fails
-  snprintf(buf, buflen, "errno: %d", errnum);
-#ifdef USE_STRERROR_R
-  strerror_r(errnum, buf, buflen);
-#elif USE_STRERROR_S
-  strerror_s(buf, buflen, errnum);
-#elif USE_OLD_STRERROR
-  strncpy(buf, strerror(errnum), buflen);
-#endif
-}
-
-int pn_i_error_from_errno(pn_error_t *error, const char *msg)
-{
-  char err[1024];
-  pn_i_strerror(errno, err, 1024);
-  int code = PN_ERR;
-  if (errno == EINTR)
-      code = PN_INTR;
-  return pn_error_format(error, code, "%s: %s", msg, err);
-}
-
-#ifdef USE_ATOLL
-#include <stdlib.h>
-int64_t pn_i_atoll(const char* num) {
-  return atoll(num);
-}
-#elif USE_ATOI64
-#include <stdlib.h>
-int64_t pn_i_atoll(const char* num) {
-  return _atoi64(num);
-}
-#else
-#error "Don't know how to convert int64_t values on this platform"
-#endif
-
-#ifdef _MSC_VER
-// [v]snprintf on Windows only matches C99 when no errors or overflow.
-int pn_i_vsnprintf(char *buf, size_t count, const char *fmt, va_list ap) {
-  if (fmt == NULL)
-    return -1;
-  if ((buf == NULL) && (count > 0))
-    return -1;
-  if (count > 0) {
-    int n = vsnprintf_s(buf, count, _TRUNCATE, fmt, ap);
-    if (n >= 0)  // no overflow
-      return n;  // same as C99
-    buf[count-1] = '\0';
-  }
-  // separate call to get needed buffer size on overflow
-  int n = _vscprintf(fmt, ap);
-  if (n >= (int) count)
-    return n;
-  return -1;
-}
-
-int pn_i_snprintf(char *buf, size_t count, const char *fmt, ...) {
-  va_list ap;
-  va_start(ap, fmt);
-  int n = pn_i_vsnprintf(buf, count, fmt, ap);
-  va_end(ap);
-  return n;
-}
-#endif

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/platform.h
----------------------------------------------------------------------
diff --git a/proton-c/src/platform.h b/proton-c/src/platform.h
deleted file mode 100644
index 6a0bbc1..0000000
--- a/proton-c/src/platform.h
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef PROTON_PLATFORM_H
-#define PROTON_PLATFORM_H 1
-
-/*
- *
- * 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/types.h"
-#include "proton/error.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Get the current PID
- *
- * @return process id
- * @internal
- */
-int pn_i_getpid(void);
-
-
-/** Get the current time in pn_timestamp_t format.
- *
- * Returns current time in milliseconds since Unix Epoch,
- * as defined by AMQP 1.0
- *
- * @return current time
- * @internal
- */
-pn_timestamp_t pn_i_now(void);
-
-/** Generate system error message.
- *
- * Populate the proton error structure based on the last system error
- * code.
- *
- * @param[in] error the proton error structure
- * @param[in] msg the descriptive context message
- * @return error->code
- *
- * @internal
- */
-int pn_i_error_from_errno(pn_error_t *error, const char *msg);
-
-/** Provide C99 atoll functinality.
- *
- * @param[in] num the string representation of the number.
- * @return the integer value.
- *
- * @internal
- */
-int64_t pn_i_atoll(const char* num);
-
-#ifdef _MSC_VER
-/** Windows snprintf and vsnprintf substitutes.
- *
- * Provide the expected C99 behavior for these functions.
- */
-#include <stdio.h>
-
-#define snprintf pn_i_snprintf
-#define vsnprintf pn_i_vsnprintf
-
-int pn_i_snprintf(char *buf, size_t count, const char *fmt, ...);
-int pn_i_vsnprintf(char *buf, size_t count, const char *fmt, va_list ap);
-
-#if !defined(S_ISDIR)
-# define S_ISDIR(X) ((X) & _S_IFDIR)
-#endif
-
-#endif
-
-#if defined _MSC_VER || defined _OPENVMS
-#if !defined(va_copy)
-#define va_copy(d,s) ((d) = (s))
-#endif
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* platform.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/platform/platform.c
----------------------------------------------------------------------
diff --git a/proton-c/src/platform/platform.c b/proton-c/src/platform/platform.c
new file mode 100644
index 0000000..393f75c
--- /dev/null
+++ b/proton-c/src/platform/platform.c
@@ -0,0 +1,122 @@
+/*
+ *
+ * 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 <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef PN_WINAPI
+#include <windows.h>
+int pn_i_getpid() {
+  return (int) GetCurrentProcessId();
+}
+#else
+#include <unistd.h>
+int pn_i_getpid() {
+  return (int) getpid();
+}
+#endif
+
+void pni_vfatal(const char *fmt, va_list ap)
+{
+  vfprintf(stderr, fmt, ap);
+  abort();
+}
+
+void pni_fatal(const char *fmt, ...)
+{
+  va_list ap;
+  va_start(ap, fmt);
+  pni_vfatal(fmt, ap);
+  va_end(ap);
+}
+
+/* Allow for systems that do not implement clock_gettime()*/
+#ifdef USE_CLOCK_GETTIME
+#include <time.h>
+pn_timestamp_t pn_i_now(void)
+{
+  struct timespec now;
+  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)
+#include <windows.h>
+pn_timestamp_t pn_i_now(void)
+{
+  FILETIME now;
+  GetSystemTimeAsFileTime(&now);
+  ULARGE_INTEGER t;
+  t.u.HighPart = now.dwHighDateTime;
+  t.u.LowPart = now.dwLowDateTime;
+  // Convert to milliseconds and adjust base epoch
+  return t.QuadPart / 10000 - 11644473600000;
+}
+#else
+#include <sys/time.h>
+pn_timestamp_t pn_i_now(void)
+{
+  struct timeval now;
+  if (gettimeofday(&now, NULL)) pni_fatal("gettimeofday failed\n");
+  return ((pn_timestamp_t)now.tv_sec) * 1000 + (now.tv_usec / 1000);
+}
+#endif
+
+#include <string.h>
+#include <stdio.h>
+static void pn_i_strerror(int errnum, char *buf, size_t buflen)
+{
+  // PROTON-1029 provide a simple default in case strerror fails
+  pni_snprintf(buf, buflen, "errno: %d", errnum);
+#ifdef USE_STRERROR_R
+  strerror_r(errnum, buf, buflen);
+#elif USE_STRERROR_S
+  strerror_s(buf, buflen, errnum);
+#elif USE_OLD_STRERROR
+  strncpy(buf, strerror(errnum), buflen);
+#endif
+}
+
+int pn_i_error_from_errno(pn_error_t *error, const char *msg)
+{
+  char err[1024];
+  pn_i_strerror(errno, err, 1024);
+  int code = PN_ERR;
+  if (errno == EINTR)
+      code = PN_INTR;
+  return pn_error_format(error, code, "%s: %s", msg, err);
+}
+
+#ifdef USE_ATOLL
+#include <stdlib.h>
+int64_t pn_i_atoll(const char* num) {
+  return atoll(num);
+}
+#elif USE_ATOI64
+#include <stdlib.h>
+int64_t pn_i_atoll(const char* num) {
+  return _atoi64(num);
+}
+#else
+#error "Don't know how to convert int64_t values on this platform"
+#endif

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/platform/platform.h
----------------------------------------------------------------------
diff --git a/proton-c/src/platform/platform.h b/proton-c/src/platform/platform.h
new file mode 100644
index 0000000..d846cda
--- /dev/null
+++ b/proton-c/src/platform/platform.h
@@ -0,0 +1,93 @@
+#ifndef PROTON_PLATFORM_H
+#define PROTON_PLATFORM_H 1
+
+/*
+ *
+ * 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/types.h"
+#include "proton/error.h"
+
+/** Get the current PID
+ *
+ * @return process id
+ * @internal
+ */
+int pn_i_getpid(void);
+
+
+/** Get the current time in pn_timestamp_t format.
+ *
+ * Returns current time in milliseconds since Unix Epoch,
+ * as defined by AMQP 1.0
+ *
+ * @return current time
+ * @internal
+ */
+pn_timestamp_t pn_i_now(void);
+
+/** Generate system error message.
+ *
+ * Populate the proton error structure based on the last system error
+ * code.
+ *
+ * @param[in] error the proton error structure
+ * @param[in] msg the descriptive context message
+ * @return error->code
+ *
+ * @internal
+ */
+int pn_i_error_from_errno(pn_error_t *error, const char *msg);
+
+/** Provide C99 atoll functinality.
+ *
+ * @param[in] num the string representation of the number.
+ * @return the integer value.
+ *
+ * @internal
+ */
+int64_t pn_i_atoll(const char* num);
+
+int pni_snprintf(char *buf, size_t count, const char *fmt, ...);
+int pni_vsnprintf(char *buf, size_t count, const char *fmt, va_list ap);
+
+#ifndef _MSC_VER
+
+#define pni_snprintf snprintf
+#define pni_vsnprintf vsnprintf
+
+#else
+
+#if !defined(S_ISDIR)
+# define S_ISDIR(X) ((X) & _S_IFDIR)
+#endif
+
+#endif
+
+#if defined _MSC_VER || defined _OPENVMS
+#if !defined(va_copy)
+#define va_copy(d,s) ((d) = (s))
+#endif
+#endif
+
+// Low level pretty rubbish URL parser
+void pni_parse_url(char *url, char **scheme, char **user, char **pass, char **host, char **port, char **path);
+
+#endif /* platform.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/platform/platform_fmt.h
----------------------------------------------------------------------
diff --git a/proton-c/src/platform/platform_fmt.h b/proton-c/src/platform/platform_fmt.h
new file mode 100644
index 0000000..17f95f3
--- /dev/null
+++ b/proton-c/src/platform/platform_fmt.h
@@ -0,0 +1,85 @@
+#ifndef _PROTON_SRC_PLATFORM_FMT_H
+#define _PROTON_SRC_PLATFORM_FMT_H 1
+
+/*
+ *
+ * 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.
+ *
+ */
+
+/*
+ * Platform dependent type-specific format specifiers for PRIx and %z
+ * for use with printf.  PRIx defs are normally available in
+ * inttypes.h (C99), but extra steps are required for C++, and they
+ * are not available in Visual Studio at all.
+ * Visual studio uses "%I" for size_t instead of "%z".
+ */
+
+#ifndef __cplusplus
+
+// normal case
+#include <inttypes.h>
+#define PN_ZI "zi"
+#define PN_ZU "zu"
+
+#ifdef _OPENVMS
+
+#undef PN_ZI
+#undef PN_ZU
+#define PN_ZI "i"
+#define PN_ZU "u"
+#define PRIu64 "llu"
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "llu"
+
+#define PRIi8 "i"
+#define PRIi16 "i"
+#define PRIi32 "i"
+#define PRIi64 "lli"
+
+#endif /* _OPENVMS */
+
+#else
+
+#ifdef _MSC_VER
+#define PRIu8 "u"
+#define PRIu16 "u"
+#define PRIu32 "u"
+#define PRIu64 "I64u"
+
+#define PRIi8 "i"
+#define PRIi16 "i"
+#define PRIi32 "i"
+#define PRIi64 "I64i"
+
+#define PN_ZI "Ii"
+#define PN_ZU "Iu"
+#else
+// Normal C++
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#define PN_ZI "zi"
+#define PN_ZU "zu"
+
+#endif /* _MSC_VER */
+
+#endif /* __cplusplus */
+
+#endif /* platform_fmt.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/platform_fmt.h
----------------------------------------------------------------------
diff --git a/proton-c/src/platform_fmt.h b/proton-c/src/platform_fmt.h
deleted file mode 100644
index 17f95f3..0000000
--- a/proton-c/src/platform_fmt.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef _PROTON_SRC_PLATFORM_FMT_H
-#define _PROTON_SRC_PLATFORM_FMT_H 1
-
-/*
- *
- * 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.
- *
- */
-
-/*
- * Platform dependent type-specific format specifiers for PRIx and %z
- * for use with printf.  PRIx defs are normally available in
- * inttypes.h (C99), but extra steps are required for C++, and they
- * are not available in Visual Studio at all.
- * Visual studio uses "%I" for size_t instead of "%z".
- */
-
-#ifndef __cplusplus
-
-// normal case
-#include <inttypes.h>
-#define PN_ZI "zi"
-#define PN_ZU "zu"
-
-#ifdef _OPENVMS
-
-#undef PN_ZI
-#undef PN_ZU
-#define PN_ZI "i"
-#define PN_ZU "u"
-#define PRIu64 "llu"
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "llu"
-
-#define PRIi8 "i"
-#define PRIi16 "i"
-#define PRIi32 "i"
-#define PRIi64 "lli"
-
-#endif /* _OPENVMS */
-
-#else
-
-#ifdef _MSC_VER
-#define PRIu8 "u"
-#define PRIu16 "u"
-#define PRIu32 "u"
-#define PRIu64 "I64u"
-
-#define PRIi8 "i"
-#define PRIi16 "i"
-#define PRIi32 "i"
-#define PRIi64 "I64i"
-
-#define PN_ZI "Ii"
-#define PN_ZU "Iu"
-#else
-// Normal C++
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-#define PN_ZI "zi"
-#define PN_ZU "zu"
-
-#endif /* _MSC_VER */
-
-#endif /* __cplusplus */
-
-#endif /* platform_fmt.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/posix/io.c
----------------------------------------------------------------------
diff --git a/proton-c/src/posix/io.c b/proton-c/src/posix/io.c
deleted file mode 100644
index 27d1a35..0000000
--- a/proton-c/src/posix/io.c
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- *
- * 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/io.h>
-#include <proton/object.h>
-#include <proton/selector.h>
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <netdb.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <assert.h>
-
-#include "platform.h"
-
-#define MAX_HOST (1024)
-#define MAX_SERV (64)
-
-struct pn_io_t {
-  char host[MAX_HOST];
-  char serv[MAX_SERV];
-  pn_error_t *error;
-  pn_selector_t *selector;
-  bool wouldblock;
-};
-
-void pn_io_initialize(void *obj)
-{
-  pn_io_t *io = (pn_io_t *) obj;
-  io->error = pn_error();
-  io->wouldblock = false;
-  io->selector = NULL;
-}
-
-void pn_io_finalize(void *obj)
-{
-  pn_io_t *io = (pn_io_t *) obj;
-  pn_error_free(io->error);
-}
-
-#define pn_io_hashcode NULL
-#define pn_io_compare NULL
-#define pn_io_inspect NULL
-
-pn_io_t *pn_io(void)
-{
-  static const pn_class_t clazz = PN_CLASS(pn_io);
-  pn_io_t *io = (pn_io_t *) pn_class_new(&clazz, sizeof(pn_io_t));
-  return io;
-}
-
-void pn_io_free(pn_io_t *io)
-{
-  pn_free(io);
-}
-
-pn_error_t *pn_io_error(pn_io_t *io)
-{
-  assert(io);
-  return io->error;
-}
-
-int pn_pipe(pn_io_t *io, pn_socket_t *dest)
-{
-  int n = pipe(dest);
-  if (n) {
-    pn_i_error_from_errno(io->error, "pipe");
-  }
-
-  return n;
-}
-
-static void pn_configure_sock(pn_io_t *io, pn_socket_t sock) {
-  // this would be nice, but doesn't appear to exist on linux
-  /*
-  int set = 1;
-  if (!setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int))) {
-    pn_i_error_from_errno(io->error, "setsockopt");
-  };
-  */
-
-  int flags = fcntl(sock, F_GETFL);
-  flags |= O_NONBLOCK;
-
-  if (fcntl(sock, F_SETFL, flags) < 0) {
-    pn_i_error_from_errno(io->error, "fcntl");
-  }
-
-  //
-  // Disable the Nagle algorithm on TCP connections.
-  //
-  // Note:  It would be more correct for the "level" argument to be SOL_TCP.  However, there
-  //        are portability issues with this macro so we use IPPROTO_TCP instead.
-  //
-  int tcp_nodelay = 1;
-  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*) &tcp_nodelay, sizeof(tcp_nodelay)) < 0) {
-    pn_i_error_from_errno(io->error, "setsockopt");
-  }
-}
-
-static inline int pn_create_socket(int af, int protocol);
-
-pn_socket_t pn_listen(pn_io_t *io, const char *host, const char *port)
-{
-  struct addrinfo *addr;
-  struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM};
-  int code = getaddrinfo(host, port, &hints, &addr);
-  if (code) {
-    pn_error_format(io->error, PN_ERR, "getaddrinfo(%s, %s): %s\n", host, port, gai_strerror(code));
-    return PN_INVALID_SOCKET;
-  }
-
-  pn_socket_t sock = pn_create_socket(addr->ai_family, addr->ai_protocol);
-  if (sock == PN_INVALID_SOCKET) {
-    freeaddrinfo(addr);
-    pn_i_error_from_errno(io->error, "pn_create_socket");
-    return PN_INVALID_SOCKET;
-  }
-
-  int optval = 1;
-  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) {
-    pn_i_error_from_errno(io->error, "setsockopt");
-    freeaddrinfo(addr);
-    close(sock);
-    return PN_INVALID_SOCKET;
-  }
-
-  if (bind(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
-    pn_i_error_from_errno(io->error, "bind");
-    freeaddrinfo(addr);
-    close(sock);
-    return PN_INVALID_SOCKET;
-  }
-
-  freeaddrinfo(addr);
-
-  if (listen(sock, 50) == -1) {
-    pn_i_error_from_errno(io->error, "listen");
-    close(sock);
-    return PN_INVALID_SOCKET;
-  }
-
-  return sock;
-}
-
-pn_socket_t pn_connect(pn_io_t *io, const char *host, const char *port)
-{
-  struct addrinfo *addr;
-  struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM};
-  int code = getaddrinfo(host, port, &hints, &addr);
-  if (code) {
-    pn_error_format(io->error, PN_ERR, "getaddrinfo(%s, %s): %s", host, port, gai_strerror(code));
-    return PN_INVALID_SOCKET;
-  }
-
-  pn_socket_t sock = pn_create_socket(addr->ai_family, addr->ai_protocol);
-  if (sock == PN_INVALID_SOCKET) {
-    pn_i_error_from_errno(io->error, "pn_create_socket");
-    freeaddrinfo(addr);
-    return PN_INVALID_SOCKET;
-  }
-
-  pn_configure_sock(io, sock);
-
-  if (connect(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
-    if (errno != EINPROGRESS) {
-      pn_i_error_from_errno(io->error, "connect");
-      freeaddrinfo(addr);
-      close(sock);
-      return PN_INVALID_SOCKET;
-    }
-  }
-
-  freeaddrinfo(addr);
-
-  return sock;
-}
-
-pn_socket_t pn_accept(pn_io_t *io, pn_socket_t socket, char *name, size_t size)
-{
-  struct sockaddr_storage addr;
-  socklen_t addrlen = sizeof(addr);
-  *name = '\0';
-  pn_socket_t sock = accept(socket, (struct sockaddr *) &addr, &addrlen);
-  if (sock == PN_INVALID_SOCKET) {
-    pn_i_error_from_errno(io->error, "accept");
-    return sock;
-  } else {
-    int code;
-    if ((code = getnameinfo((struct sockaddr *) &addr, addrlen, io->host, MAX_HOST, io->serv, MAX_SERV, 0))) {
-      pn_error_format(io->error, PN_ERR, "getnameinfo: %s\n", gai_strerror(code));
-      if (close(sock) == -1)
-        pn_i_error_from_errno(io->error, "close");
-      return PN_INVALID_SOCKET;
-    } else {
-      pn_configure_sock(io, sock);
-      snprintf(name, size, "%s:%s", io->host, io->serv);
-      return sock;
-    }
-  }
-}
-
-/* Abstract away turning off SIGPIPE */
-#ifdef MSG_NOSIGNAL
-ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t len) {
-  ssize_t count = send(socket, buf, len, MSG_NOSIGNAL);
-  io->wouldblock = (errno == EAGAIN || errno == EWOULDBLOCK);
-  if (count < 0) { pn_i_error_from_errno(io->error, "send"); }
-  return count;
-}
-
-static inline int pn_create_socket(int af, int protocol) {
-  return socket(af, SOCK_STREAM, protocol);
-}
-#elif defined(SO_NOSIGPIPE)
-ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t size) {
-  ssize_t count = send(socket, buf, size, 0);
-  io->wouldblock = (errno == EAGAIN || errno == EWOULDBLOCK);
-  if (count < 0) { pn_i_error_from_errno(io->error, "send"); }
-  return count;
-}
-
-static inline int pn_create_socket(int af, int protocol) {
-  int sock;
-  sock = socket(af, SOCK_STREAM, protocol);
-  if (sock == -1) return sock;
-
-  int optval = 1;
-  if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) == -1) {
-    close(sock);
-    return -1;
-  }
-  return sock;
-}
-#else
-
-#include <signal.h>
-
-static inline int pn_create_socket(int af, int protocol) {
-  return socket(af, SOCK_STREAM, protocol);
-}
-
-static ssize_t nosigpipe_send(int fd, const void *buffer, size_t size) {
-  sigset_t pendingSignals, oldSignals, newSignals;
-  ssize_t count;
-  int sendErrno, sigmaskErr;
-
-  sigpending(&pendingSignals);
-  int sigpipeIsPending = sigismember(&pendingSignals, SIGPIPE);
-  if (!sigpipeIsPending) {
-    sigemptyset(&newSignals);
-    sigaddset(&newSignals, SIGPIPE);
-    if (sigmaskErr = pthread_sigmask(SIG_BLOCK, (const sigset_t *)&newSignals, (sigset_t *)&oldSignals))
-    {
-      errno = sigmaskErr;
-      return -1;
-    }
-  }
-
-  count = send(fd, buffer, size, 0);
-  if (!sigpipeIsPending) {
-    sendErrno = errno;
-    if (count == -1 && errno == EPIPE) {
-      while (-1 == sigtimedwait(&newSignals, NULL, &(struct timespec){ 0, 0 }) && errno == EINTR)
-        ; //do nothing
-    }
-    if (sigmaskErr = pthread_sigmask(SIG_SETMASK, (const sigset_t *)&oldSignals, (sigset_t *)NULL))
-    {
-      errno = sigmaskErr;
-      return -1;
-    }
-    errno = sendErrno;
-  }
-  return count;
-}
-
-ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t size) {
-  ssize_t count = nosigpipe_send(socket, buf, size);
-  io->wouldblock = (errno == EAGAIN || errno == EWOULDBLOCK);
-  if (count < 0) { pn_i_error_from_errno(io->error, "send"); }
-  return count;
-}
-#endif
-
-ssize_t pn_recv(pn_io_t *io, pn_socket_t socket, void *buf, size_t size)
-{
-  ssize_t count = recv(socket, buf, size, 0);
-  io->wouldblock = count < 0 && (errno == EAGAIN || errno == EWOULDBLOCK);
-  if (count < 0) { pn_i_error_from_errno(io->error, "recv"); }
-  return count;
-}
-
-ssize_t pn_write(pn_io_t *io, pn_socket_t socket, const void *buf, size_t size)
-{
-  return write(socket, buf, size);
-}
-
-ssize_t pn_read(pn_io_t *io, pn_socket_t socket, void *buf, size_t size)
-{
-  return read(socket, buf, size);
-}
-
-void pn_close(pn_io_t *io, pn_socket_t socket)
-{
-  close(socket);
-}
-
-bool pn_wouldblock(pn_io_t *io)
-{
-  return io->wouldblock;
-}
-
-pn_selector_t *pn_io_selector(pn_io_t *io)
-{
-  if (io->selector == NULL)
-    io->selector = pni_selector();
-  return io->selector;
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/posix/selector.c
----------------------------------------------------------------------
diff --git a/proton-c/src/posix/selector.c b/proton-c/src/posix/selector.c
deleted file mode 100644
index 7f72c84..0000000
--- a/proton-c/src/posix/selector.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- *
- * 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/selector.h>
-#include <proton/error.h>
-#include <poll.h>
-#include <stdlib.h>
-#include <assert.h>
-#include "platform.h"
-#include "selectable.h"
-#include "util.h"
-
-struct pn_selector_t {
-  struct pollfd *fds;
-  pn_timestamp_t *deadlines;
-  size_t capacity;
-  pn_list_t *selectables;
-  size_t current;
-  pn_timestamp_t awoken;
-  pn_error_t *error;
-};
-
-void pn_selector_initialize(void *obj)
-{
-  pn_selector_t *selector = (pn_selector_t *) obj;
-  selector->fds = NULL;
-  selector->deadlines = NULL;
-  selector->capacity = 0;
-  selector->selectables = pn_list(PN_WEAKREF, 0);
-  selector->current = 0;
-  selector->awoken = 0;
-  selector->error = pn_error();
-}
-
-void pn_selector_finalize(void *obj)
-{
-  pn_selector_t *selector = (pn_selector_t *) obj;
-  free(selector->fds);
-  free(selector->deadlines);
-  pn_free(selector->selectables);
-  pn_error_free(selector->error);
-}
-
-#define pn_selector_hashcode NULL
-#define pn_selector_compare NULL
-#define pn_selector_inspect NULL
-
-pn_selector_t *pni_selector(void)
-{
-  static const pn_class_t clazz = PN_CLASS(pn_selector);
-  pn_selector_t *selector = (pn_selector_t *) pn_class_new(&clazz, sizeof(pn_selector_t));
-  return selector;
-}
-
-void pn_selector_add(pn_selector_t *selector, pn_selectable_t *selectable)
-{
-  assert(selector);
-  assert(selectable);
-  assert(pni_selectable_get_index(selectable) < 0);
-
-  if (pni_selectable_get_index(selectable) < 0) {
-    pn_list_add(selector->selectables, selectable);
-    size_t size = pn_list_size(selector->selectables);
-
-    if (selector->capacity < size) {
-      selector->fds = (struct pollfd *) realloc(selector->fds, size*sizeof(struct pollfd));
-      selector->deadlines = (pn_timestamp_t *) realloc(selector->deadlines, size*sizeof(pn_timestamp_t));
-      selector->capacity = size;
-    }
-
-    pni_selectable_set_index(selectable, size - 1);
-  }
-
-  pn_selector_update(selector, selectable);
-}
-
-void pn_selector_update(pn_selector_t *selector, pn_selectable_t *selectable)
-{
-  int idx = pni_selectable_get_index(selectable);
-  assert(idx >= 0);
-  selector->fds[idx].fd = pn_selectable_get_fd(selectable);
-  selector->fds[idx].events = 0;
-  selector->fds[idx].revents = 0;
-  if (pn_selectable_is_reading(selectable)) {
-    selector->fds[idx].events |= POLLIN;
-  }
-  if (pn_selectable_is_writing(selectable)) {
-    selector->fds[idx].events |= POLLOUT;
-  }
-  selector->deadlines[idx] = pn_selectable_get_deadline(selectable);
-}
-
-void pn_selector_remove(pn_selector_t *selector, pn_selectable_t *selectable)
-{
-  assert(selector);
-  assert(selectable);
-
-  int idx = pni_selectable_get_index(selectable);
-  assert(idx >= 0);
-  pn_list_del(selector->selectables, idx, 1);
-  size_t size = pn_list_size(selector->selectables);
-  for (size_t i = idx; i < size; i++) {
-    pn_selectable_t *sel = (pn_selectable_t *) pn_list_get(selector->selectables, i);
-    pni_selectable_set_index(sel, i);
-    selector->fds[i] = selector->fds[i + 1];
-  }
-
-  pni_selectable_set_index(selectable, -1);
-
-  if (selector->current >= (size_t) idx) {
-    selector->current--;
-  }
-}
-
-size_t pn_selector_size(pn_selector_t *selector) {
-  assert(selector);
-  return pn_list_size(selector->selectables);
-}
-
-int pn_selector_select(pn_selector_t *selector, int timeout)
-{
-  assert(selector);
-
-  size_t size = pn_list_size(selector->selectables);
-
-  if (timeout) {
-    pn_timestamp_t deadline = 0;
-    for (size_t i = 0; i < size; i++) {
-      pn_timestamp_t d = selector->deadlines[i];
-      if (d)
-        deadline = (deadline == 0) ? d : pn_min(deadline, d);
-    }
-
-    if (deadline) {
-      pn_timestamp_t now = pn_i_now();
-      int64_t delta = deadline - now;
-      if (delta < 0) {
-        timeout = 0;
-      } else if (delta < timeout) {
-        timeout = delta;
-      }
-    }
-  }
-
-  int error = 0;
-  int result = poll(selector->fds, size, timeout);
-  if (result == -1) {
-    error = pn_i_error_from_errno(selector->error, "poll");
-  } else {
-    selector->current = 0;
-    selector->awoken = pn_i_now();
-  }
-
-  return error;
-}
-
-pn_selectable_t *pn_selector_next(pn_selector_t *selector, int *events)
-{
-  pn_list_t *l = selector->selectables;
-  size_t size = pn_list_size(l);
-  while (selector->current < size) {
-    pn_selectable_t *sel = (pn_selectable_t *) pn_list_get(l, selector->current);
-    struct pollfd *pfd = &selector->fds[selector->current];
-    pn_timestamp_t deadline = selector->deadlines[selector->current];
-    int ev = 0;
-    if (pfd->revents & POLLIN) {
-      ev |= PN_READABLE;
-    }
-    if ((pfd->revents & POLLERR) ||
-        (pfd->revents & POLLHUP) ||
-        (pfd->revents & POLLNVAL)) {
-      ev |= PN_ERROR;
-    }
-    if (pfd->revents & POLLOUT) {
-      ev |= PN_WRITABLE;
-    }
-    if (deadline && selector->awoken >= deadline) {
-      ev |= PN_EXPIRED;
-    }
-    selector->current++;
-    if (ev) {
-      *events = ev;
-      return sel;
-    }
-  }
-  return NULL;
-}
-
-void pn_selector_free(pn_selector_t *selector)
-{
-  assert(selector);
-  pn_free(selector);
-}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/reactor/acceptor.c
----------------------------------------------------------------------
diff --git a/proton-c/src/reactor/acceptor.c b/proton-c/src/reactor/acceptor.c
index f56f7bd..a044748 100644
--- a/proton-c/src/reactor/acceptor.c
+++ b/proton-c/src/reactor/acceptor.c
@@ -19,13 +19,14 @@
  *
  */
 
-#include <proton/io.h>
 #include <proton/sasl.h>
-#include <proton/selector.h>
 #include <proton/transport.h>
 #include <proton/connection.h>
+
+#include "io.h"
 #include "reactor.h"
 #include "selectable.h"
+#include "selector.h"
 
 #include <string.h>
 
@@ -38,7 +39,7 @@ PN_HANDLE(PNI_ACCEPTOR_CONNECTION)
 void pni_acceptor_readable(pn_selectable_t *sel) {
   pn_reactor_t *reactor = (pn_reactor_t *) pni_selectable_get_context(sel);
   char name[1024];
-  pn_socket_t sock = pn_accept(pn_reactor_io(reactor), pn_selectable_get_fd(sel), name, 1024);
+  pn_socket_t sock = pn_accept(pni_reactor_io(reactor), pn_selectable_get_fd(sel), name, 1024);
   pn_handler_t *handler = (pn_handler_t *) pn_record_get(pn_selectable_attachments(sel), PNI_ACCEPTOR_HANDLER);
   if (!handler) { handler = pn_reactor_get_handler(reactor); }
   pn_record_t *record = pn_selectable_attachments(sel);
@@ -67,12 +68,12 @@ void pni_acceptor_readable(pn_selectable_t *sel) {
 void pni_acceptor_finalize(pn_selectable_t *sel) {
   pn_reactor_t *reactor = (pn_reactor_t *) pni_selectable_get_context(sel);
   if (pn_selectable_get_fd(sel) != PN_INVALID_SOCKET) {
-    pn_close(pn_reactor_io(reactor), pn_selectable_get_fd(sel));
+    pn_close(pni_reactor_io(reactor), pn_selectable_get_fd(sel));
   }
 }
 
 pn_acceptor_t *pn_reactor_acceptor(pn_reactor_t *reactor, const char *host, const char *port, pn_handler_t *handler) {
-  pn_socket_t socket = pn_listen(pn_reactor_io(reactor), host, port);
+  pn_socket_t socket = pn_listen(pni_reactor_io(reactor), host, port);
   if (socket == PN_INVALID_SOCKET) {
     return NULL;
   }
@@ -94,7 +95,7 @@ void pn_acceptor_close(pn_acceptor_t *acceptor) {
   if (!pn_selectable_is_terminal(sel)) {
     pn_reactor_t *reactor = (pn_reactor_t *) pni_selectable_get_context(sel);
     pn_socket_t socket = pn_selectable_get_fd(sel);
-    pn_close(pn_reactor_io(reactor), socket);
+    pn_close(pni_reactor_io(reactor), socket);
     pn_selectable_set_fd(sel, PN_INVALID_SOCKET);
     pn_selectable_terminate(sel);
     pn_reactor_update(reactor, sel);

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/reactor/connection.c
----------------------------------------------------------------------
diff --git a/proton-c/src/reactor/connection.c b/proton-c/src/reactor/connection.c
index d73e386..4bc8b8d 100644
--- a/proton-c/src/reactor/connection.c
+++ b/proton-c/src/reactor/connection.c
@@ -28,6 +28,7 @@
 #include <assert.h>
 #include <stdio.h>
 #include <string.h>
+#include "io.h"
 #include "selectable.h"
 #include "reactor.h"
 
@@ -187,12 +188,12 @@ void pni_handle_bound(pn_reactor_t *reactor, pn_event_t *event) {
       pn_transport_close_tail(transport);
       pn_transport_close_head(transport);
   } else {
-      pn_socket_t sock = pn_connect(pn_reactor_io(reactor), host, port);
+      pn_socket_t sock = pn_connect(pni_reactor_io(reactor), host, port);
       // invalid sockets are ignored by poll, so we need to do this manualy
       if (sock == PN_INVALID_SOCKET) {
           pn_condition_t *cond = pn_transport_condition(transport);
           pn_condition_set_name(cond, "proton:io");
-          pn_condition_set_description(cond, pn_error_text(pn_io_error(pn_reactor_io(reactor))));
+          pn_condition_set_description(cond, pn_error_text(pn_reactor_error(reactor)));
           pn_transport_close_tail(transport);
           pn_transport_close_head(transport);
       } else {
@@ -215,14 +216,14 @@ static void pni_connection_readable(pn_selectable_t *sel)
   pn_transport_t *transport = pni_transport(sel);
   ssize_t capacity = pn_transport_capacity(transport);
   if (capacity > 0) {
-    ssize_t n = pn_recv(pn_reactor_io(reactor), pn_selectable_get_fd(sel),
+    ssize_t n = pn_recv(pni_reactor_io(reactor), pn_selectable_get_fd(sel),
                         pn_transport_tail(transport), capacity);
     if (n <= 0) {
-      if (n == 0 || !pn_wouldblock(pn_reactor_io(reactor))) {
+      if (n == 0 || !pn_wouldblock(pni_reactor_io(reactor))) {
         if (n < 0) {
           pn_condition_t *cond = pn_transport_condition(transport);
           pn_condition_set_name(cond, "proton:io");
-          pn_condition_set_description(cond, pn_error_text(pn_io_error(pn_reactor_io(reactor))));
+          pn_condition_set_description(cond, pn_error_text(pn_reactor_error(reactor)));
         }
         pn_transport_close_tail(transport);
       }
@@ -246,14 +247,14 @@ static void pni_connection_writable(pn_selectable_t *sel)
   pn_transport_t *transport = pni_transport(sel);
   ssize_t pending = pn_transport_pending(transport);
   if (pending > 0) {
-    ssize_t n = pn_send(pn_reactor_io(reactor), pn_selectable_get_fd(sel),
+    ssize_t n = pn_send(pni_reactor_io(reactor), pn_selectable_get_fd(sel),
                         pn_transport_head(transport), pending);
     if (n < 0) {
-      if (!pn_wouldblock(pn_reactor_io(reactor))) {
+      if (!pn_wouldblock(pni_reactor_io(reactor))) {
         pn_condition_t *cond = pn_transport_condition(transport);
         if (!pn_condition_is_set(cond)) {
           pn_condition_set_name(cond, "proton:io");
-          pn_condition_set_description(cond, pn_error_text(pn_io_error(pn_reactor_io(reactor))));
+          pn_condition_set_description(cond, pn_error_text(pn_reactor_error(reactor)));
         }
         pn_transport_close_head(transport);
       }
@@ -296,7 +297,7 @@ static void pni_connection_finalize(pn_selectable_t *sel) {
   pn_record_t *record = pn_transport_attachments(transport);
   pn_record_set(record, PN_TRANCTX, NULL);
   pn_socket_t fd = pn_selectable_get_fd(sel);
-  pn_close(pn_reactor_io(reactor), fd);
+  pn_close(pni_reactor_io(reactor), fd);
 }
 
 pn_selectable_t *pn_reactor_selectable_transport(pn_reactor_t *reactor, pn_socket_t sock, pn_transport_t *transport) {

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/reactor/io.h
----------------------------------------------------------------------
diff --git a/proton-c/src/reactor/io.h b/proton-c/src/reactor/io.h
new file mode 100644
index 0000000..24596ec
--- /dev/null
+++ b/proton-c/src/reactor/io.h
@@ -0,0 +1,70 @@
+#ifndef PROTON_IO_H
+#define PROTON_IO_H 1
+
+/*
+ *
+ * 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 "selector.h"
+
+#include <proton/import_export.h>
+#include <proton/error.h>
+#include <proton/type_compat.h>
+#include <stddef.h>
+
+/**
+ * A ::pn_io_t manages IO for a group of pn_socket_t handles.  A
+ * pn_io_t object may have zero or one pn_selector_t selectors
+ * associated with it (see ::pn_io_selector()).  If one is associated,
+ * all the pn_socket_t handles managed by a pn_io_t must use that
+ * pn_selector_t instance.
+ *
+ * The pn_io_t interface is single-threaded. All methods are intended
+ * to be used by one thread at a time, except that multiple threads
+ * may use:
+ *
+ *   ::pn_write()
+ *   ::pn_send()
+ *   ::pn_recv()
+ *   ::pn_close()
+ *   ::pn_selector_select()
+ *
+ * provided at most one thread is calling ::pn_selector_select() and
+ * the other threads are operating on separate pn_socket_t handles.
+ */
+typedef struct pn_io_t pn_io_t;
+
+pn_io_t *pn_io(void);
+void pn_io_free(pn_io_t *io);
+pn_error_t *pn_io_error(pn_io_t *io);
+pn_socket_t pn_connect(pn_io_t *io, const char *host, const char *port);
+pn_socket_t pn_listen(pn_io_t *io, const char *host, const char *port);
+
+pn_socket_t pn_accept(pn_io_t *io, pn_socket_t socket, char *name, size_t size);
+void pn_close(pn_io_t *io, pn_socket_t socket);
+ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t size);
+ssize_t pn_recv(pn_io_t *io, pn_socket_t socket, void *buf, size_t size);
+int pn_pipe(pn_io_t *io, pn_socket_t *dest);
+ssize_t pn_read(pn_io_t *io, pn_socket_t socket, void *buf, size_t size);
+ssize_t pn_write(pn_io_t *io, pn_socket_t socket, const void *buf, size_t size);
+bool pn_wouldblock(pn_io_t *io);
+pn_selector_t *pn_io_selector(pn_io_t *io);
+
+#endif /* io.h */

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/reactor/io/posix/io.c
----------------------------------------------------------------------
diff --git a/proton-c/src/reactor/io/posix/io.c b/proton-c/src/reactor/io/posix/io.c
new file mode 100644
index 0000000..5a0de3b
--- /dev/null
+++ b/proton-c/src/reactor/io/posix/io.c
@@ -0,0 +1,342 @@
+/*
+ *
+ * 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 "reactor/io.h"
+#include "reactor/selector.h"
+#include "platform/platform.h" // pn_i_error_from_errno
+
+#include <proton/object.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+
+#define MAX_HOST (1024)
+#define MAX_SERV (64)
+
+struct pn_io_t {
+  char host[MAX_HOST];
+  char serv[MAX_SERV];
+  pn_error_t *error;
+  pn_selector_t *selector;
+  bool wouldblock;
+};
+
+void pn_io_initialize(void *obj)
+{
+  pn_io_t *io = (pn_io_t *) obj;
+  io->error = pn_error();
+  io->wouldblock = false;
+  io->selector = NULL;
+}
+
+void pn_io_finalize(void *obj)
+{
+  pn_io_t *io = (pn_io_t *) obj;
+  pn_error_free(io->error);
+}
+
+#define pn_io_hashcode NULL
+#define pn_io_compare NULL
+#define pn_io_inspect NULL
+
+pn_io_t *pn_io(void)
+{
+  static const pn_class_t clazz = PN_CLASS(pn_io);
+  pn_io_t *io = (pn_io_t *) pn_class_new(&clazz, sizeof(pn_io_t));
+  return io;
+}
+
+void pn_io_free(pn_io_t *io)
+{
+  pn_free(io);
+}
+
+pn_error_t *pn_io_error(pn_io_t *io)
+{
+  assert(io);
+  return io->error;
+}
+
+int pn_pipe(pn_io_t *io, pn_socket_t *dest)
+{
+  int n = pipe(dest);
+  if (n) {
+    pn_i_error_from_errno(io->error, "pipe");
+  }
+
+  return n;
+}
+
+static void pn_configure_sock(pn_io_t *io, pn_socket_t sock) {
+  // this would be nice, but doesn't appear to exist on linux
+  /*
+  int set = 1;
+  if (!setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int))) {
+    pn_i_error_from_errno(io->error, "setsockopt");
+  };
+  */
+
+  int flags = fcntl(sock, F_GETFL);
+  flags |= O_NONBLOCK;
+
+  if (fcntl(sock, F_SETFL, flags) < 0) {
+    pn_i_error_from_errno(io->error, "fcntl");
+  }
+
+  //
+  // Disable the Nagle algorithm on TCP connections.
+  //
+  // Note:  It would be more correct for the "level" argument to be SOL_TCP.  However, there
+  //        are portability issues with this macro so we use IPPROTO_TCP instead.
+  //
+  int tcp_nodelay = 1;
+  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*) &tcp_nodelay, sizeof(tcp_nodelay)) < 0) {
+    pn_i_error_from_errno(io->error, "setsockopt");
+  }
+}
+
+static inline int pn_create_socket(int af, int protocol);
+
+pn_socket_t pn_listen(pn_io_t *io, const char *host, const char *port)
+{
+  struct addrinfo *addr;
+  struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM};
+  int code = getaddrinfo(host, port, &hints, &addr);
+  if (code) {
+    pn_error_format(io->error, PN_ERR, "getaddrinfo(%s, %s): %s\n", host, port, gai_strerror(code));
+    return PN_INVALID_SOCKET;
+  }
+
+  pn_socket_t sock = pn_create_socket(addr->ai_family, addr->ai_protocol);
+  if (sock == PN_INVALID_SOCKET) {
+    freeaddrinfo(addr);
+    pn_i_error_from_errno(io->error, "pn_create_socket");
+    return PN_INVALID_SOCKET;
+  }
+
+  int optval = 1;
+  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) {
+    pn_i_error_from_errno(io->error, "setsockopt");
+    freeaddrinfo(addr);
+    close(sock);
+    return PN_INVALID_SOCKET;
+  }
+
+  if (bind(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
+    pn_i_error_from_errno(io->error, "bind");
+    freeaddrinfo(addr);
+    close(sock);
+    return PN_INVALID_SOCKET;
+  }
+
+  freeaddrinfo(addr);
+
+  if (listen(sock, 50) == -1) {
+    pn_i_error_from_errno(io->error, "listen");
+    close(sock);
+    return PN_INVALID_SOCKET;
+  }
+
+  return sock;
+}
+
+pn_socket_t pn_connect(pn_io_t *io, const char *host, const char *port)
+{
+  struct addrinfo *addr;
+  struct addrinfo hints = {0, AF_UNSPEC, SOCK_STREAM};
+  int code = getaddrinfo(host, port, &hints, &addr);
+  if (code) {
+    pn_error_format(io->error, PN_ERR, "getaddrinfo(%s, %s): %s", host, port, gai_strerror(code));
+    return PN_INVALID_SOCKET;
+  }
+
+  pn_socket_t sock = pn_create_socket(addr->ai_family, addr->ai_protocol);
+  if (sock == PN_INVALID_SOCKET) {
+    pn_i_error_from_errno(io->error, "pn_create_socket");
+    freeaddrinfo(addr);
+    return PN_INVALID_SOCKET;
+  }
+
+  pn_configure_sock(io, sock);
+
+  if (connect(sock, addr->ai_addr, addr->ai_addrlen) == -1) {
+    if (errno != EINPROGRESS) {
+      pn_i_error_from_errno(io->error, "connect");
+      freeaddrinfo(addr);
+      close(sock);
+      return PN_INVALID_SOCKET;
+    }
+  }
+
+  freeaddrinfo(addr);
+
+  return sock;
+}
+
+pn_socket_t pn_accept(pn_io_t *io, pn_socket_t socket, char *name, size_t size)
+{
+  struct sockaddr_storage addr;
+  socklen_t addrlen = sizeof(addr);
+  *name = '\0';
+  pn_socket_t sock = accept(socket, (struct sockaddr *) &addr, &addrlen);
+  if (sock == PN_INVALID_SOCKET) {
+    pn_i_error_from_errno(io->error, "accept");
+    return sock;
+  } else {
+    int code;
+    if ((code = getnameinfo((struct sockaddr *) &addr, addrlen, io->host, MAX_HOST, io->serv, MAX_SERV, 0))) {
+      pn_error_format(io->error, PN_ERR, "getnameinfo: %s\n", gai_strerror(code));
+      if (close(sock) == -1)
+        pn_i_error_from_errno(io->error, "close");
+      return PN_INVALID_SOCKET;
+    } else {
+      pn_configure_sock(io, sock);
+      pni_snprintf(name, size, "%s:%s", io->host, io->serv);
+      return sock;
+    }
+  }
+}
+
+/* Abstract away turning off SIGPIPE */
+#ifdef MSG_NOSIGNAL
+ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t len) {
+  ssize_t count = send(socket, buf, len, MSG_NOSIGNAL);
+  io->wouldblock = (errno == EAGAIN || errno == EWOULDBLOCK);
+  if (count < 0) { pn_i_error_from_errno(io->error, "send"); }
+  return count;
+}
+
+static inline int pn_create_socket(int af, int protocol) {
+  return socket(af, SOCK_STREAM, protocol);
+}
+#elif defined(SO_NOSIGPIPE)
+ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t size) {
+  ssize_t count = send(socket, buf, size, 0);
+  io->wouldblock = (errno == EAGAIN || errno == EWOULDBLOCK);
+  if (count < 0) { pn_i_error_from_errno(io->error, "send"); }
+  return count;
+}
+
+static inline int pn_create_socket(int af, int protocol) {
+  int sock;
+  sock = socket(af, SOCK_STREAM, protocol);
+  if (sock == -1) return sock;
+
+  int optval = 1;
+  if (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) == -1) {
+    close(sock);
+    return -1;
+  }
+  return sock;
+}
+#else
+
+#include <signal.h>
+
+static inline int pn_create_socket(int af, int protocol) {
+  return socket(af, SOCK_STREAM, protocol);
+}
+
+static ssize_t nosigpipe_send(int fd, const void *buffer, size_t size) {
+  sigset_t pendingSignals, oldSignals, newSignals;
+  ssize_t count;
+  int sendErrno, sigmaskErr;
+
+  sigpending(&pendingSignals);
+  int sigpipeIsPending = sigismember(&pendingSignals, SIGPIPE);
+  if (!sigpipeIsPending) {
+    sigemptyset(&newSignals);
+    sigaddset(&newSignals, SIGPIPE);
+    if (sigmaskErr = pthread_sigmask(SIG_BLOCK, (const sigset_t *)&newSignals, (sigset_t *)&oldSignals))
+    {
+      errno = sigmaskErr;
+      return -1;
+    }
+  }
+
+  count = send(fd, buffer, size, 0);
+  if (!sigpipeIsPending) {
+    sendErrno = errno;
+    if (count == -1 && errno == EPIPE) {
+      while (-1 == sigtimedwait(&newSignals, NULL, &(struct timespec){ 0, 0 }) && errno == EINTR)
+        ; //do nothing
+    }
+    if (sigmaskErr = pthread_sigmask(SIG_SETMASK, (const sigset_t *)&oldSignals, (sigset_t *)NULL))
+    {
+      errno = sigmaskErr;
+      return -1;
+    }
+    errno = sendErrno;
+  }
+  return count;
+}
+
+ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t size) {
+  ssize_t count = nosigpipe_send(socket, buf, size);
+  io->wouldblock = (errno == EAGAIN || errno == EWOULDBLOCK);
+  if (count < 0) { pn_i_error_from_errno(io->error, "send"); }
+  return count;
+}
+#endif
+
+ssize_t pn_recv(pn_io_t *io, pn_socket_t socket, void *buf, size_t size)
+{
+  ssize_t count = recv(socket, buf, size, 0);
+  io->wouldblock = count < 0 && (errno == EAGAIN || errno == EWOULDBLOCK);
+  if (count < 0) { pn_i_error_from_errno(io->error, "recv"); }
+  return count;
+}
+
+ssize_t pn_write(pn_io_t *io, pn_socket_t socket, const void *buf, size_t size)
+{
+  return write(socket, buf, size);
+}
+
+ssize_t pn_read(pn_io_t *io, pn_socket_t socket, void *buf, size_t size)
+{
+  return read(socket, buf, size);
+}
+
+void pn_close(pn_io_t *io, pn_socket_t socket)
+{
+  close(socket);
+}
+
+bool pn_wouldblock(pn_io_t *io)
+{
+  return io->wouldblock;
+}
+
+pn_selector_t *pn_io_selector(pn_io_t *io)
+{
+  if (io->selector == NULL)
+    io->selector = pni_selector();
+  return io->selector;
+}

http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/a5850716/proton-c/src/reactor/io/posix/selector.c
----------------------------------------------------------------------
diff --git a/proton-c/src/reactor/io/posix/selector.c b/proton-c/src/reactor/io/posix/selector.c
new file mode 100644
index 0000000..bf6882a
--- /dev/null
+++ b/proton-c/src/reactor/io/posix/selector.c
@@ -0,0 +1,214 @@
+/*
+ *
+ * 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 "core/util.h"
+#include "platform/platform.h" // pn_i_now, pn_i_error_from_errno
+#include "reactor/io.h"
+#include "reactor/selector.h"
+#include "reactor/selectable.h"
+
+#include <proton/error.h>
+
+#include <poll.h>
+#include <stdlib.h>
+#include <assert.h>
+
+struct pn_selector_t {
+  struct pollfd *fds;
+  pn_timestamp_t *deadlines;
+  size_t capacity;
+  pn_list_t *selectables;
+  size_t current;
+  pn_timestamp_t awoken;
+  pn_error_t *error;
+};
+
+void pn_selector_initialize(void *obj)
+{
+  pn_selector_t *selector = (pn_selector_t *) obj;
+  selector->fds = NULL;
+  selector->deadlines = NULL;
+  selector->capacity = 0;
+  selector->selectables = pn_list(PN_WEAKREF, 0);
+  selector->current = 0;
+  selector->awoken = 0;
+  selector->error = pn_error();
+}
+
+void pn_selector_finalize(void *obj)
+{
+  pn_selector_t *selector = (pn_selector_t *) obj;
+  free(selector->fds);
+  free(selector->deadlines);
+  pn_free(selector->selectables);
+  pn_error_free(selector->error);
+}
+
+#define pn_selector_hashcode NULL
+#define pn_selector_compare NULL
+#define pn_selector_inspect NULL
+
+pn_selector_t *pni_selector(void)
+{
+  static const pn_class_t clazz = PN_CLASS(pn_selector);
+  pn_selector_t *selector = (pn_selector_t *) pn_class_new(&clazz, sizeof(pn_selector_t));
+  return selector;
+}
+
+void pn_selector_add(pn_selector_t *selector, pn_selectable_t *selectable)
+{
+  assert(selector);
+  assert(selectable);
+  assert(pni_selectable_get_index(selectable) < 0);
+
+  if (pni_selectable_get_index(selectable) < 0) {
+    pn_list_add(selector->selectables, selectable);
+    size_t size = pn_list_size(selector->selectables);
+
+    if (selector->capacity < size) {
+      selector->fds = (struct pollfd *) realloc(selector->fds, size*sizeof(struct pollfd));
+      selector->deadlines = (pn_timestamp_t *) realloc(selector->deadlines, size*sizeof(pn_timestamp_t));
+      selector->capacity = size;
+    }
+
+    pni_selectable_set_index(selectable, size - 1);
+  }
+
+  pn_selector_update(selector, selectable);
+}
+
+void pn_selector_update(pn_selector_t *selector, pn_selectable_t *selectable)
+{
+  int idx = pni_selectable_get_index(selectable);
+  assert(idx >= 0);
+  selector->fds[idx].fd = pn_selectable_get_fd(selectable);
+  selector->fds[idx].events = 0;
+  selector->fds[idx].revents = 0;
+  if (pn_selectable_is_reading(selectable)) {
+    selector->fds[idx].events |= POLLIN;
+  }
+  if (pn_selectable_is_writing(selectable)) {
+    selector->fds[idx].events |= POLLOUT;
+  }
+  selector->deadlines[idx] = pn_selectable_get_deadline(selectable);
+}
+
+void pn_selector_remove(pn_selector_t *selector, pn_selectable_t *selectable)
+{
+  assert(selector);
+  assert(selectable);
+
+  int idx = pni_selectable_get_index(selectable);
+  assert(idx >= 0);
+  pn_list_del(selector->selectables, idx, 1);
+  size_t size = pn_list_size(selector->selectables);
+  for (size_t i = idx; i < size; i++) {
+    pn_selectable_t *sel = (pn_selectable_t *) pn_list_get(selector->selectables, i);
+    pni_selectable_set_index(sel, i);
+    selector->fds[i] = selector->fds[i + 1];
+  }
+
+  pni_selectable_set_index(selectable, -1);
+
+  if (selector->current >= (size_t) idx) {
+    selector->current--;
+  }
+}
+
+size_t pn_selector_size(pn_selector_t *selector) {
+  assert(selector);
+  return pn_list_size(selector->selectables);
+}
+
+int pn_selector_select(pn_selector_t *selector, int timeout)
+{
+  assert(selector);
+
+  size_t size = pn_list_size(selector->selectables);
+
+  if (timeout) {
+    pn_timestamp_t deadline = 0;
+    for (size_t i = 0; i < size; i++) {
+      pn_timestamp_t d = selector->deadlines[i];
+      if (d)
+        deadline = (deadline == 0) ? d : pn_min(deadline, d);
+    }
+
+    if (deadline) {
+      pn_timestamp_t now = pn_i_now();
+      int64_t delta = deadline - now;
+      if (delta < 0) {
+        timeout = 0;
+      } else if (delta < timeout) {
+        timeout = delta;
+      }
+    }
+  }
+
+  int error = 0;
+  int result = poll(selector->fds, size, timeout);
+  if (result == -1) {
+    error = pn_i_error_from_errno(selector->error, "poll");
+  } else {
+    selector->current = 0;
+    selector->awoken = pn_i_now();
+  }
+
+  return error;
+}
+
+pn_selectable_t *pn_selector_next(pn_selector_t *selector, int *events)
+{
+  pn_list_t *l = selector->selectables;
+  size_t size = pn_list_size(l);
+  while (selector->current < size) {
+    pn_selectable_t *sel = (pn_selectable_t *) pn_list_get(l, selector->current);
+    struct pollfd *pfd = &selector->fds[selector->current];
+    pn_timestamp_t deadline = selector->deadlines[selector->current];
+    int ev = 0;
+    if (pfd->revents & POLLIN) {
+      ev |= PN_READABLE;
+    }
+    if ((pfd->revents & POLLERR) ||
+        (pfd->revents & POLLHUP) ||
+        (pfd->revents & POLLNVAL)) {
+      ev |= PN_ERROR;
+    }
+    if (pfd->revents & POLLOUT) {
+      ev |= PN_WRITABLE;
+    }
+    if (deadline && selector->awoken >= deadline) {
+      ev |= PN_EXPIRED;
+    }
+    selector->current++;
+    if (ev) {
+      *events = ev;
+      return sel;
+    }
+  }
+  return NULL;
+}
+
+void pn_selector_free(pn_selector_t *selector)
+{
+  assert(selector);
+  pn_free(selector);
+}


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