This is an automated email from the ASF dual-hosted git repository.

astitcher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git

commit 0836fabc397dbf253578d8ca37f120704f3a8fda
Author: Andrew Stitcher <[email protected]>
AuthorDate: Wed Jun 29 13:11:59 2022 +0100

    PROTON-2559: Modify pn_object inspect operation to use pn_fixed_string_t
    
    This now allows us to inspect objects without potentially allocating
    an indefinite amount of memory.
    
    Renamed the new operation pn_finspect() and created a compatible
    pn_inspect for any current users (none known)
---
 c/src/core/buffer.h         |   3 +-
 c/src/core/codec.c          | 181 +++++++++++++++++++++++---------------------
 c/src/core/data.h           |   3 +-
 c/src/core/engine.c         |  18 ++---
 c/src/core/event.c          |  35 ++++-----
 c/src/core/fixed_string.h   |   3 +
 c/src/core/message.c        | 167 ++++++++++++++--------------------------
 c/src/core/object/list.c    |  17 ++---
 c/src/core/object/map.c     |  23 +++---
 c/src/core/object/object.c  |  54 +++++++++----
 c/src/core/object/string.c  |  18 ++---
 c/src/core/object_private.h |   6 +-
 c/src/core/util.h           |   8 +-
 c/src/core/value_dump.h     |   2 -
 c/src/extra/url.c           |  11 +--
 c/src/reactor/reactor.c     |  10 ++-
 16 files changed, 268 insertions(+), 291 deletions(-)

diff --git a/c/src/core/buffer.h b/c/src/core/buffer.h
index 0b3f8fa77..e205c9b55 100644
--- a/c/src/core/buffer.h
+++ b/c/src/core/buffer.h
@@ -48,7 +48,8 @@ int pn_buffer_defrag(pn_buffer_t *buf);
 pn_bytes_t pn_buffer_bytes(pn_buffer_t *buf);
 pn_rwbytes_t pn_buffer_memory(pn_buffer_t *buf);
 pn_rwbytes_t pn_buffer_free_memory(pn_buffer_t *buf);
-int pn_buffer_quote(pn_buffer_t *buf, pn_string_t *string, size_t n);
+struct pn_string_t;
+int pn_buffer_quote(pn_buffer_t *buf, struct pn_string_t *string, size_t n);
 
 #ifdef __cplusplus
 }
diff --git a/c/src/core/codec.c b/c/src/core/codec.c
index a3047f057..513a994cc 100644
--- a/c/src/core/codec.c
+++ b/c/src/core/codec.c
@@ -36,6 +36,7 @@
 #include "decoder.h"
 #include "encoder.h"
 #include "data.h"
+#include "fixed_string.h"
 #include "logger_private.h"
 #include "memory.h"
 
@@ -109,43 +110,59 @@ static const pn_fields_t *pni_node_fields(pn_data_t 
*data, pni_node_t *node)
   }
 }
 
-int pni_inspect_atom(pn_atom_t *atom, pn_string_t *str)
+void pni_inspect_atom(pn_atom_t *atom, pn_fixed_string_t *str)
 {
   switch (atom->type) {
   case PN_NULL:
-    return pn_string_addf(str, "null");
+    pn_fixed_string_addf(str, "null");
+    return;
   case PN_BOOL:
-    return pn_string_addf(str, atom->u.as_bool ? "true" : "false");
+    pn_fixed_string_addf(str, atom->u.as_bool ? "true" : "false");
+    return;
   case PN_UBYTE:
-    return pn_string_addf(str, "%" PRIu8, atom->u.as_ubyte);
+    pn_fixed_string_addf(str, "%" PRIu8, atom->u.as_ubyte);
+    return;
   case PN_BYTE:
-    return pn_string_addf(str, "%" PRIi8, atom->u.as_byte);
+    pn_fixed_string_addf(str, "%" PRIi8, atom->u.as_byte);
+    return;
   case PN_USHORT:
-    return pn_string_addf(str, "%" PRIu16, atom->u.as_ushort);
+    pn_fixed_string_addf(str, "%" PRIu16, atom->u.as_ushort);
+    return;
   case PN_SHORT:
-    return pn_string_addf(str, "%" PRIi16, atom->u.as_short);
+    pn_fixed_string_addf(str, "%" PRIi16, atom->u.as_short);
+    return;
   case PN_UINT:
-    return pn_string_addf(str, "%" PRIu32, atom->u.as_uint);
+    pn_fixed_string_addf(str, "%" PRIu32, atom->u.as_uint);
+    return;
   case PN_INT:
-    return pn_string_addf(str, "%" PRIi32, atom->u.as_int);
+    pn_fixed_string_addf(str, "%" PRIi32, atom->u.as_int);
+    return;
   case PN_CHAR:
-    return pn_string_addf(str, "%c",  atom->u.as_char);
+    pn_fixed_string_addf(str, "%c",  atom->u.as_char);
+    return;
   case PN_ULONG:
-    return pn_string_addf(str, "%" PRIu64, atom->u.as_ulong);
+    pn_fixed_string_addf(str, "%" PRIu64, atom->u.as_ulong);
+    return;
   case PN_LONG:
-    return pn_string_addf(str, "%" PRIi64, atom->u.as_long);
+    pn_fixed_string_addf(str, "%" PRIi64, atom->u.as_long);
+    return;
   case PN_TIMESTAMP:
-    return pn_string_addf(str, "%" PRIi64, atom->u.as_timestamp);
+    pn_fixed_string_addf(str, "%" PRIi64, atom->u.as_timestamp);
+    return;
   case PN_FLOAT:
-    return pn_string_addf(str, "%g", atom->u.as_float);
+    pn_fixed_string_addf(str, "%g", atom->u.as_float);
+    return;
   case PN_DOUBLE:
-    return pn_string_addf(str, "%g", atom->u.as_double);
+    pn_fixed_string_addf(str, "%g", atom->u.as_double);
+    return;
   case PN_DECIMAL32:
-    return pn_string_addf(str, "D32(%" PRIu32 ")", atom->u.as_decimal32);
+    pn_fixed_string_addf(str, "D32(%" PRIu32 ")", atom->u.as_decimal32);
+    return;
   case PN_DECIMAL64:
-    return pn_string_addf(str, "D64(%" PRIu64 ")", atom->u.as_decimal64);
+    pn_fixed_string_addf(str, "D64(%" PRIu64 ")", atom->u.as_decimal64);
+    return;
   case PN_DECIMAL128:
-    return pn_string_addf(str, "D128(%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
+    pn_fixed_string_addf(str, "D128(%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
                           "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
                           "%02hhx%02hhx)",
                           atom->u.as_decimal128.bytes[0],
@@ -164,8 +181,9 @@ int pni_inspect_atom(pn_atom_t *atom, pn_string_t *str)
                           atom->u.as_decimal128.bytes[13],
                           atom->u.as_decimal128.bytes[14],
                           atom->u.as_decimal128.bytes[15]);
+    return;
   case PN_UUID:
-    return pn_string_addf(str, "UUID(%02hhx%02hhx%02hhx%02hhx-"
+    pn_fixed_string_addf(str, "UUID(%02hhx%02hhx%02hhx%02hhx-"
                           "%02hhx%02hhx-%02hhx%02hhx-%02hhx%02hhx-"
                           "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx)",
                           atom->u.as_uuid.bytes[0],
@@ -184,11 +202,11 @@ int pni_inspect_atom(pn_atom_t *atom, pn_string_t *str)
                           atom->u.as_uuid.bytes[13],
                           atom->u.as_uuid.bytes[14],
                           atom->u.as_uuid.bytes[15]);
+    return;
   case PN_BINARY:
   case PN_STRING:
   case PN_SYMBOL:
     {
-      int err;
       const char *pfx;
       pn_bytes_t bin = atom->u.as_bytes;
       bool quote;
@@ -213,25 +231,30 @@ int pni_inspect_atom(pn_atom_t *atom, pn_string_t *str)
         break;
       default:
         assert(false);
-        return PN_ERR;
+        return;
       }
 
-      if ((err = pn_string_addf(str, "%s", pfx))) return err;
-      if (quote) if ((err = pn_string_addf(str, "\""))) return err;
-      if ((err = pn_quote(str, bin.start, bin.size))) return err;
-      if (quote) if ((err = pn_string_addf(str, "\""))) return err;
-      return 0;
+      pn_fixed_string_addf(str, "%s", pfx);
+      if (quote) pn_fixed_string_addf(str, "\"");
+      pn_fixed_string_quote(str, bin.start, bin.size);
+      if (quote) pn_fixed_string_addf(str, "\"");
+      return;
     }
   case PN_LIST:
-    return pn_string_addf(str, "<list>");
+    pn_fixed_string_addf(str, "<list>");
+    return;
   case PN_MAP:
-    return pn_string_addf(str, "<map>");
+    pn_fixed_string_addf(str, "<map>");
+    return;
   case PN_ARRAY:
-    return pn_string_addf(str, "<array>");
+    pn_fixed_string_addf(str, "<array>");
+    return;
   case PN_DESCRIBED:
-    return pn_string_addf(str, "<described>");
+    pn_fixed_string_addf(str, "<described>");
+    return;
   default:
-    return pn_string_addf(str, "<undefined: %i>", atom->type);
+    pn_fixed_string_addf(str, "<undefined: %i>", atom->type);
+    return;
   }
 }
 
@@ -248,7 +271,7 @@ static int pni_node_lindex(pn_data_t *data, pni_node_t 
*node)
 
 int pni_inspect_enter(void *ctx, pn_data_t *data, pni_node_t *node)
 {
-  pn_string_t *str = (pn_string_t *) ctx;
+  pn_fixed_string_t *str = (pn_fixed_string_t *) ctx;
   pn_atom_t *atom = (pn_atom_t *) &node->atom;
 
   pni_node_t *parent = pn_data_node(data, node->parent);
@@ -256,8 +279,6 @@ int pni_inspect_enter(void *ctx, pn_data_t *data, 
pni_node_t *node)
   pni_node_t *grandparent = parent ? pn_data_node(data, parent->parent) : NULL;
   const pn_fields_t *grandfields = pni_node_fields(data, grandparent);
 
-  int err;
-
   if (grandfields) {
     if (atom->type == PN_NULL) {
       return 0;
@@ -267,32 +288,34 @@ int pni_inspect_enter(void *ctx, pn_data_t *data, 
pni_node_t *node)
         ? (const 
char*)FIELD_STRINGPOOL.STRING0+FIELD_FIELDS[grandfields->first_field_index+lindex]
         : NULL;
     if (name) {
-      err = pn_string_addf(str, "%s=", name);
-      if (err) return err;
+      pn_fixed_string_addf(str, "%s=", name);
     }
   }
 
   switch (atom->type) {
   case PN_DESCRIBED:
-    return pn_string_addf(str, "@");
+    pn_fixed_string_addf(str, "@");
+    return 0;
   case PN_ARRAY:
     // XXX: need to fix for described arrays
-    return pn_string_addf(str, "@%s[", pn_type_name(node->type));
+    pn_fixed_string_addf(str, "@%s[", pn_type_name(node->type));
+    return 0;
   case PN_LIST:
-    return pn_string_addf(str, "[");
+    pn_fixed_string_addf(str, "[");
+    return 0;
   case PN_MAP:
-    return pn_string_addf(str, "{");
+    pn_fixed_string_addf(str, "{");
+    return 0;
   default:
     if (fields && node->prev == 0) {
-      err = pn_string_addf(str, "%s", (const char 
*)FIELD_STRINGPOOL.STRING0+FIELD_NAME[fields->name_index]);
-      if (err) return err;
-      err = pn_string_addf(str, "(");
-      if (err) return err;
-      err = pni_inspect_atom(atom, str);
-      if (err) return err;
-      return pn_string_addf(str, ")");
+      pn_fixed_string_addf(str, "%s", (const char 
*)FIELD_STRINGPOOL.STRING0+FIELD_NAME[fields->name_index]);
+      pn_fixed_string_addf(str, "(");
+      pni_inspect_atom(atom, str);
+      pn_fixed_string_addf(str, ")");
+      return 0;
     } else {
-      return pni_inspect_atom(atom, str);
+      pni_inspect_atom(atom, str);
+      return 0;
     }
   }
 }
@@ -311,18 +334,15 @@ pni_node_t *pni_next_nonnull(pn_data_t *data, pni_node_t 
*node)
 
 int pni_inspect_exit(void *ctx, pn_data_t *data, pni_node_t *node)
 {
-  pn_string_t *str = (pn_string_t *) ctx;
-  int err;
+  pn_fixed_string_t *str = (pn_fixed_string_t *) ctx;
 
   switch (node->atom.type) {
   case PN_ARRAY:
   case PN_LIST:
-    err = pn_string_addf(str, "]");
-    if (err) return err;
+    pn_fixed_string_addf(str, "]");
     break;
   case PN_MAP:
-    err = pn_string_addf(str, "}");
-    if (err) return err;
+    pn_fixed_string_addf(str, "}");
     break;
   default:
     break;
@@ -334,15 +354,12 @@ int pni_inspect_exit(void *ctx, pn_data_t *data, 
pni_node_t *node)
   if (!grandfields || node->atom.type != PN_NULL) {
     if (node->next) {
       if (parent && parent->atom.type == PN_MAP && (pni_node_lindex(data, 
node) % 2) == 0) {
-        err = pn_string_addf(str, "=");
-        if (err) return err;
+        pn_fixed_string_addf(str, "=");
       } else if (parent && parent->atom.type == PN_DESCRIBED && node->prev == 
0) {
-        err = pn_string_addf(str, " ");
-        if (err) return err;
+        pn_fixed_string_addf(str, " ");
       } else {
         if (!grandfields || pni_next_nonnull(data, node)) {
-          err = pn_string_addf(str, ", ");
-          if (err) return err;
+          pn_fixed_string_addf(str, ", ");
         }
       }
     }
@@ -351,11 +368,11 @@ int pni_inspect_exit(void *ctx, pn_data_t *data, 
pni_node_t *node)
   return 0;
 }
 
-static int pn_data_inspect(void *obj, pn_string_t *dst)
+static void pn_data_inspect(void *obj, pn_fixed_string_t *dst)
 {
   pn_data_t *data = (pn_data_t *) obj;
 
-  return pni_data_traverse(data, pni_inspect_enter, pni_inspect_exit, dst);
+  pni_data_traverse(data, pni_inspect_enter, pni_inspect_exit, dst);
 }
 
 #define pn_data_initialize NULL
@@ -1221,31 +1238,21 @@ int pn_data_scan(pn_data_t *data, const char *fmt, ...)
 
 int pn_data_print(pn_data_t *data)
 {
-  pn_string_t *str = pn_string("");
-  int err = pn_data_inspect(data, str);
-  if (err) {
-    pn_free(str);
-    return err;
-  }
-  printf("%s", pn_string_get(str));
-  pn_free(str);
+  char buf[1024];
+  pn_fixed_string_t str = pn_fixed_string(buf, sizeof(buf));
+  pn_data_inspect(data, &str);
+  pn_fixed_string_terminate(&str);
+  printf("%s", buf);
   return 0;
 }
 
 int pn_data_format(pn_data_t *data, char *bytes, size_t *size)
 {
-  pn_string_t *str = pn_string("");
-  int err = pn_data_inspect(data, str);
-  if (err) return err;
-  if (pn_string_size(str) >= *size) {
-    pn_free(str);
-    return PN_OVERFLOW;
-  } else {
-    pn_string_put(str, bytes);
-    *size = pn_string_size(str);
-    pn_free(str);
-    return 0;
-  }
+  pn_fixed_string_t str = pn_fixed_string(bytes, *size);
+  pn_data_inspect(data, &str);
+  pn_fixed_string_terminate(&str);
+  *size = str.position;
+  return 0;
 }
 
 static size_t pni_data_id(pn_data_t *data, pni_node_t *node)
@@ -1483,13 +1490,14 @@ bool pn_data_lookup(pn_data_t *data, const char *name)
 
 void pn_data_dump(pn_data_t *data)
 {
-  pn_string_t *str = pn_string(0);
   printf("{current=%" PN_ZI ", parent=%" PN_ZI "}\n", (size_t) data->current, 
(size_t) data->parent);
+  char buf[256];
   for (unsigned i = 0; i < data->size; i++)
   {
     pni_node_t *node = &data->nodes[i];
-    pn_string_setn(str, "", 0);
-    pni_inspect_atom((pn_atom_t *) &node->atom, str);
+    pn_fixed_string_t str = pn_fixed_string(buf, sizeof(buf));
+    pni_inspect_atom((pn_atom_t *) &node->atom, &str);
+    pn_fixed_string_terminate(&str);
     printf("Node %i: prev=%" PN_ZI ", next=%" PN_ZI ", parent=%" PN_ZI ", 
down=%" PN_ZI 
            ", children=%" PN_ZI ", type=%s (%s)\n",
            i + 1, (size_t) node->prev,
@@ -1497,9 +1505,8 @@ void pn_data_dump(pn_data_t *data)
            (size_t) node->parent,
            (size_t) node->down,
            (size_t) node->children,
-           pn_type_name(node->atom.type), pn_string_get(str));
+           pn_type_name(node->atom.type), buf);
   }
-  pn_free(str);
 }
 
 static pni_node_t *pni_data_add(pn_data_t *data)
diff --git a/c/src/core/data.h b/c/src/core/data.h
index e90e4f29b..97315b495 100644
--- a/c/src/core/data.h
+++ b/c/src/core/data.h
@@ -70,6 +70,7 @@ int pni_data_traverse(pn_data_t *data,
                       int (*exit)(void *ctx, pn_data_t *data, pni_node_t 
*node),
                       void *ctx);
 
-int pni_inspect_atom(pn_atom_t *atom, pn_string_t *str);
+struct pn_fixed_string_t;
+void pni_inspect_atom(pn_atom_t *atom, struct pn_fixed_string_t *str);
 
 #endif /* data.h */
diff --git a/c/src/core/engine.c b/c/src/core/engine.c
index 3e4385532..aa90a4b31 100644
--- a/c/src/core/engine.c
+++ b/c/src/core/engine.c
@@ -24,6 +24,7 @@
 
 #include "engine-internal.h"
 
+#include "fixed_string.h"
 #include "framing.h"
 #include "memory.h"
 #include "platform/platform.h"
@@ -50,7 +51,7 @@ static void pn_delivery_finalize(void *object);
 #define pn_delivery_initialize NULL
 #define pn_delivery_hashcode NULL
 #define pn_delivery_compare NULL
-static int pn_delivery_inspect(void *obj, pn_string_t *dst);
+static void pn_delivery_inspect(void *obj, pn_fixed_string_t *dst);
 static const pn_class_t PN_CLASSCLASS(pn_delivery) = PN_METACLASS(pn_delivery);
 
 // endpoints
@@ -1518,17 +1519,16 @@ static void pn_disposition_clear(pn_disposition_t *ds)
   pn_condition_clear(&ds->condition);
 }
 
-int pn_delivery_inspect(void *obj, pn_string_t *dst) {
+void pn_delivery_inspect(void *obj, pn_fixed_string_t *dst) {
   pn_delivery_t *d = (pn_delivery_t*)obj;
   const char* dir = pn_link_is_sender(d->link) ? "sending" : "receiving";
   pn_bytes_t bytes = pn_buffer_bytes(d->tag);
-  int err =
-    pn_string_addf(dst, "pn_delivery<%p>{%s, tag=b\"", obj, dir) ||
-    pn_quote(dst, bytes.start, bytes.size) ||
-    pn_string_addf(dst, "\", local=%s, remote=%s}",
-                   pn_disposition_type_name(d->local.type),
-                   pn_disposition_type_name(d->remote.type));
-  return err;
+  pn_fixed_string_addf(dst, "pn_delivery<%p>{%s, tag=b\"", obj, dir);
+  pn_fixed_string_quote(dst, bytes.start, bytes.size);
+  pn_fixed_string_addf(dst, "\", local=%s, remote=%s}",
+                       pn_disposition_type_name(d->local.type),
+                       pn_disposition_type_name(d->remote.type));
+  return;
 }
 
 pn_delivery_tag_t pn_dtag(const char *bytes, size_t size) {
diff --git a/c/src/core/event.c b/c/src/core/event.c
index 13eefdd41..5736b5c03 100644
--- a/c/src/core/event.c
+++ b/c/src/core/event.c
@@ -22,6 +22,7 @@
 #include <proton/object.h>
 #include <proton/event.h>
 
+#include "core/fixed_string.h"
 #include "core/object_private.h"
 
 #include <assert.h>
@@ -46,7 +47,7 @@ struct pn_event_t {
 
 static void pn_event_initialize(void *object);
 static void pn_event_finalize(void *object);
-static int pn_event_inspect(void *object, pn_string_t *string);
+static void pn_event_inspect(void *object, pn_fixed_string_t *string);
 #define pn_event_hashcode NULL
 #define pn_event_compare NULL
 
@@ -84,26 +85,25 @@ static void pn_collector_finalize(void *object)
   pn_decref(collector->pool);
 }
 
-static int pn_collector_inspect(void *object, pn_string_t *dst)
+static void pn_collector_inspect(void *object, pn_fixed_string_t *dst)
 {
   pn_collector_t *collector = (pn_collector_t *)object;
   assert(collector);
-  int err = pn_string_addf(dst, "EVENTS[");
-  if (err) return err;
+  pn_fixed_string_addf(dst, "EVENTS[");
   pn_event_t *event = collector->head;
   bool first = true;
   while (event) {
     if (first) {
       first = false;
     } else {
-      err = pn_string_addf(dst, ", ");
-      if (err) return err;
+      pn_fixed_string_addf(dst, ", ");
     }
-    err = pn_inspect(event, dst);
-    if (err) return err;
+
+      pn_finspect(event, dst);
     event = event->next;
   }
-  return pn_string_addf(dst, "]");
+  pn_fixed_string_addf(dst, "]");
+  return;
 }
 
 #define pn_collector_hashcode NULL
@@ -262,27 +262,24 @@ static void pn_event_finalize(void *object) {
   pn_decref(pool);
 }
 
-static int pn_event_inspect(void *object, pn_string_t *dst)
+static void pn_event_inspect(void *object, pn_fixed_string_t *dst)
 {
   pn_event_t *event = (pn_event_t *)object;
   assert(event);
   assert(dst);
   const char *name = pn_event_type_name(event->type);
-  int err;
   if (name) {
-    err = pn_string_addf(dst, "(%s", pn_event_type_name(event->type));
+    pn_fixed_string_addf(dst, "(%s", pn_event_type_name(event->type));
   } else {
-    err = pn_string_addf(dst, "(<%u>", (unsigned int) event->type);
+    pn_fixed_string_addf(dst, "(<%u>", (unsigned int) event->type);
   }
-  if (err) return err;
   if (event->context) {
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
-    err = pn_class_inspect(event->clazz, event->context, dst);
-    if (err) return err;
+    pn_fixed_string_addf(dst, ", ");
+    pn_class_inspect(event->clazz, event->context, dst);
   }
 
-  return pn_string_addf(dst, ")");
+  pn_fixed_string_addf(dst, ")");
+  return;
 }
 
 pn_event_t *pn_event(void)
diff --git a/c/src/core/fixed_string.h b/c/src/core/fixed_string.h
index fc36ee866..6df7be761 100644
--- a/c/src/core/fixed_string.h
+++ b/c/src/core/fixed_string.h
@@ -25,6 +25,9 @@
 #include "util.h"
 
 #include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
 
 typedef struct pn_fixed_string_t {
   char    *bytes;
diff --git a/c/src/core/message.c b/c/src/core/message.c
index 9f0d7e5c0..5a6849e15 100644
--- a/c/src/core/message.c
+++ b/c/src/core/message.c
@@ -27,6 +27,7 @@
 #include "protocol.h"
 #include "util.h"
 
+#include "core/fixed_string.h"
 #include "core/frame_generators.h"
 #include "core/frame_consumers.h"
 
@@ -157,216 +158,164 @@ void pn_message_finalize(void *obj)
   pn_error_free(msg->error);
 }
 
-int pn_message_inspect(void *obj, pn_string_t *dst)
+void pn_message_inspect(void *obj, pn_fixed_string_t *dst)
 {
   pn_message_t *msg = (pn_message_t *) obj;
-  int err = pn_string_addf(dst, "Message{");
-  if (err) return err;
+  pn_fixed_string_addf(dst, "Message{");
 
   bool comma = false;
 
   if (pn_string_get(msg->address)) {
-    err = pn_string_addf(dst, "address=");
-    if (err) return err;
-    err = pn_inspect(msg->address, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "address=");
+    pn_finspect(msg->address, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (msg->durable) {
-    err = pn_string_addf(dst, "durable=%i, ", msg->durable);
-    if (err) return err;
+    pn_fixed_string_addf(dst, "durable=%i, ", msg->durable);
     comma = true;
   }
 
   if (msg->priority != HEADER_PRIORITY_DEFAULT) {
-    err = pn_string_addf(dst, "priority=%i, ", msg->priority);
-    if (err) return err;
+    pn_fixed_string_addf(dst, "priority=%i, ", msg->priority);
     comma = true;
   }
 
   if (msg->ttl) {
-    err = pn_string_addf(dst, "ttl=%" PRIu32 ", ", msg->ttl);
-    if (err) return err;
+    pn_fixed_string_addf(dst, "ttl=%" PRIu32 ", ", msg->ttl);
     comma = true;
   }
 
   if (msg->first_acquirer) {
-    err = pn_string_addf(dst, "first_acquirer=%i, ", msg->first_acquirer);
-    if (err) return err;
+    pn_fixed_string_addf(dst, "first_acquirer=%i, ", msg->first_acquirer);
     comma = true;
   }
 
   if (msg->delivery_count) {
-    err = pn_string_addf(dst, "delivery_count=%" PRIu32 ", ", 
msg->delivery_count);
-    if (err) return err;
+    pn_fixed_string_addf(dst, "delivery_count=%" PRIu32 ", ", 
msg->delivery_count);
     comma = true;
   }
 
   pn_atom_t id = pn_message_get_id(msg);
   if (id.type!=PN_NULL) {
-    err = pn_string_addf(dst, "id=");
-    if (err) return err;
-    err = pni_inspect_atom(&id, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "id=");
+    pni_inspect_atom(&id, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (pn_string_get(msg->user_id)) {
-    err = pn_string_addf(dst, "user_id=");
-    if (err) return err;
-    err = pn_inspect(msg->user_id, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "user_id=");
+    pn_finspect(msg->user_id, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (pn_string_get(msg->subject)) {
-    err = pn_string_addf(dst, "subject=");
-    if (err) return err;
-    err = pn_inspect(msg->subject, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "subject=");
+    pn_finspect(msg->subject, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (pn_string_get(msg->reply_to)) {
-    err = pn_string_addf(dst, "reply_to=");
-    if (err) return err;
-    err = pn_inspect(msg->reply_to, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "reply_to=");
+    pn_finspect(msg->reply_to, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   pn_atom_t correlation_id = pn_message_get_correlation_id(msg);
   if (correlation_id.type!=PN_NULL) {
-    err = pn_string_addf(dst, "correlation_id=");
-    if (err) return err;
-    err = pni_inspect_atom(&correlation_id, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "correlation_id=");
+    pni_inspect_atom(&correlation_id, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (pn_string_get(msg->content_type)) {
-    err = pn_string_addf(dst, "content_type=");
-    if (err) return err;
-    err = pn_inspect(msg->content_type, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "content_type=");
+    pn_finspect(msg->content_type, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (pn_string_get(msg->content_encoding)) {
-    err = pn_string_addf(dst, "content_encoding=");
-    if (err) return err;
-    err = pn_inspect(msg->content_encoding, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "content_encoding=");
+    pn_finspect(msg->content_encoding, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (msg->expiry_time) {
-    err = pn_string_addf(dst, "expiry_time=%" PRIi64 ", ", msg->expiry_time);
-    if (err) return err;
+    pn_fixed_string_addf(dst, "expiry_time=%" PRIi64 ", ", msg->expiry_time);
     comma = true;
   }
 
   if (msg->creation_time) {
-    err = pn_string_addf(dst, "creation_time=%" PRIi64 ", ", 
msg->creation_time);
-    if (err) return err;
+    pn_fixed_string_addf(dst, "creation_time=%" PRIi64 ", ", 
msg->creation_time);
     comma = true;
   }
 
   if (pn_string_get(msg->group_id)) {
-    err = pn_string_addf(dst, "group_id=");
-    if (err) return err;
-    err = pn_inspect(msg->group_id, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "group_id=");
+    pn_finspect(msg->group_id, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (msg->group_sequence) {
-    err = pn_string_addf(dst, "group_sequence=%" PRIi32 ", ", 
msg->group_sequence);
-    if (err) return err;
+    pn_fixed_string_addf(dst, "group_sequence=%" PRIi32 ", ", 
msg->group_sequence);
     comma = true;
   }
 
   if (pn_string_get(msg->reply_to_group_id)) {
-    err = pn_string_addf(dst, "reply_to_group_id=");
-    if (err) return err;
-    err = pn_inspect(msg->reply_to_group_id, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "reply_to_group_id=");
+    pn_finspect(msg->reply_to_group_id, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (msg->inferred) {
-    err = pn_string_addf(dst, "inferred=%i, ", msg->inferred);
-    if (err) return err;
+    pn_fixed_string_addf(dst, "inferred=%i, ", msg->inferred);
     comma = true;
   }
 
   if (pn_data_size(msg->instructions)) {
-    err = pn_string_addf(dst, "instructions=");
-    if (err) return err;
-    err = pn_inspect(msg->instructions, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "instructions=");
+    pn_finspect(msg->instructions, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (pn_data_size(msg->annotations)) {
-    err = pn_string_addf(dst, "annotations=");
-    if (err) return err;
-    err = pn_inspect(msg->annotations, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "annotations=");
+    pn_finspect(msg->annotations, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (pn_data_size(msg->properties)) {
-    err = pn_string_addf(dst, "properties=");
-    if (err) return err;
-    err = pn_inspect(msg->properties, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "properties=");
+    pn_finspect(msg->properties, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (pn_data_size(msg->body)) {
-    err = pn_string_addf(dst, "body=");
-    if (err) return err;
-    err = pn_inspect(msg->body, dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ", ");
-    if (err) return err;
+    pn_fixed_string_addf(dst, "body=");
+    pn_finspect(msg->body, dst);
+    pn_fixed_string_addf(dst, ", ");
     comma = true;
   }
 
   if (comma) {
-    int err = pn_string_resize(dst, pn_string_size(dst) - 2);
-    if (err) return err;
-  }
+    dst->position = dst->position - 2;
+ }
 
-  return pn_string_addf(dst, "}");
+  pn_fixed_string_addf(dst, "}");
+  return;
 }
 
 #define pn_message_initialize NULL
diff --git a/c/src/core/object/list.c b/c/src/core/object/list.c
index 3d2bc0f6e..72fd799fd 100644
--- a/c/src/core/object/list.c
+++ b/c/src/core/object/list.c
@@ -19,8 +19,7 @@
  *
  */
 
-#include <proton/object.h>
-
+#include "core/fixed_string.h"
 #include "core/memory.h"
 
 #include <stddef.h>
@@ -236,22 +235,20 @@ static intptr_t pn_list_compare(void *oa, void *ob)
   return 0;
 }
 
-static int pn_list_inspect(void *obj, pn_string_t *dst)
+static void pn_list_inspect(void *obj, pn_fixed_string_t *dst)
 {
   assert(obj);
   pn_list_t *list = (pn_list_t *) obj;
-  int err = pn_string_addf(dst, "[");
-  if (err) return err;
+  pn_fixed_string_addf(dst, "[");
   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;
+      pn_fixed_string_addf(dst, ", ");
     }
-    err = pn_class_inspect(list->clazz, pn_list_get(list, i), dst);
-    if (err) return err;
+    pn_class_inspect(list->clazz, pn_list_get(list, i), dst);
   }
-  return pn_string_addf(dst, "]");
+  pn_fixed_string_addf(dst, "]");
+  return;
 }
 
 #define pn_list_initialize NULL
diff --git a/c/src/core/object/map.c b/c/src/core/object/map.c
index 9ee154c8f..faf4b9ada 100644
--- a/c/src/core/object/map.c
+++ b/c/src/core/object/map.c
@@ -19,9 +19,8 @@
  *
  */
 
-#include <proton/object.h>
-
 #include "core/memory.h"
+#include "core/fixed_string.h"
 
 #include <stddef.h>
 #include <assert.h>
@@ -94,30 +93,26 @@ static void pni_map_allocate(pn_map_t *map)
   map->size = 0;
 }
 
-static int pn_map_inspect(void *obj, pn_string_t *dst)
+static void pn_map_inspect(void *obj, pn_fixed_string_t *dst)
 {
   assert(obj);
   pn_map_t *map = (pn_map_t *) obj;
-  int err = pn_string_addf(dst, "{");
-  if (err) return err;
+  pn_fixed_string_addf(dst, "{");
   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;
+      pn_fixed_string_addf(dst, ", ");
     }
-    err = pn_class_inspect(map->key, pn_map_key(map, entry), dst);
-    if (err) return err;
-    err = pn_string_addf(dst, ": ");
-    if (err) return err;
-    err = pn_class_inspect(map->value, pn_map_value(map, entry), dst);
-    if (err) return err;
+    pn_class_inspect(map->key, pn_map_key(map, entry), dst);
+    pn_fixed_string_addf(dst, ": ");
+    pn_class_inspect(map->value, pn_map_value(map, entry), dst);
     entry = pn_map_next(map, entry);
   }
-  return pn_string_addf(dst, "}");
+  pn_fixed_string_addf(dst, "}");
+  return;
 }
 
 #define pn_map_initialize NULL
diff --git a/c/src/core/object/object.c b/c/src/core/object/object.c
index 2b2eadf23..2db97c907 100644
--- a/c/src/core/object/object.c
+++ b/c/src/core/object/object.c
@@ -22,6 +22,8 @@
 #include <proton/object.h>
 
 #include "core/memory.h"
+#include "core/fixed_string.h"
+#include "core/object_private.h"
 
 #include <assert.h>
 #include <stdlib.h>
@@ -252,19 +254,17 @@ 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)
+void pn_class_inspect(const pn_class_t *clazz, void *object, pn_fixed_string_t 
*dst)
 {
-  if (!pn_string_get(dst)) {
-    pn_string_set(dst, "");
-  }
-
   if (object && clazz->inspect) {
-    return clazz->inspect(object, dst);
+    clazz->inspect(object, dst);
+    return;
   }
 
   const char *name = clazz->name ? clazz->name : "<anon>";
 
-  return pn_string_addf(dst, "%s<%p>", name, object);
+  pn_fixed_string_addf(dst, "%s<%p>", name, object);
+  return;
 }
 
 void *pn_incref(void *object)
@@ -384,23 +384,45 @@ int pn_inspect(void *object, pn_string_t *dst)
   const pn_class_t *clazz = pni_head(object)->clazz;
 
   if (clazz->inspect) {
-    return clazz->inspect(object, dst);
+    char buf[1024];
+    pn_fixed_string_t str = pn_fixed_string(buf, sizeof(buf));
+    clazz->inspect(object, &str);
+    return pn_string_setn(dst, buf, str.position);
   }
 
   const char *name = clazz->name ? clazz->name : "<anon>";
   return pn_string_addf(dst, "%s<%p>", name, object);
 }
 
+void pn_finspect(void *object, pn_fixed_string_t *dst)
+{
+  if (!object) {
+    pn_fixed_string_addf(dst, "pn_object<%p>", object);
+    return;
+  }
+
+  const pn_class_t *clazz = pni_head(object)->clazz;
+
+  if (clazz->inspect) {
+    clazz->inspect(object, dst);
+    return;
+  }
+
+  const char *name = clazz->name ? clazz->name : "<anon>";
+  pn_fixed_string_addf(dst, "%s<%p>", name, object);
+  return;
+}
+
 char *pn_tostring(void *object)
 {
-  pn_string_t *s = pn_string(NULL);
-  pn_inspect(object, s);
+  char buf[1024];
+  pn_fixed_string_t s = pn_fixed_string(buf, sizeof(buf));
+  pn_finspect(object, &s);
+  pn_fixed_string_terminate(&s);
 
-  const char *sc = pn_string_get(s);
-  int l = pn_string_size(s)+1; // include final null
+  int l = s.position+1; // include final null
   char *r = malloc(l);
-  strncpy(r, sc, l);
-  pn_decref(s);
+  strncpy(r, buf, l);
   return r;
 }
 
@@ -415,7 +437,7 @@ char *pn_tostring(void *object)
 
 #define pn_weakref_hashcode pn_hashcode
 #define pn_weakref_compare pn_compare
-#define pn_weakref_inspect pn_inspect
+#define pn_weakref_inspect pn_finspect
 
 const pn_class_t PN_WEAKREF[] = {PN_METACLASS(pn_weakref)};
 
@@ -460,7 +482,7 @@ int pn_strongref_refcount(void *object)
 
 #define pn_strongref_hashcode pn_hashcode
 #define pn_strongref_compare pn_compare
-#define pn_strongref_inspect pn_inspect
+#define pn_strongref_inspect pn_finspect
 
 static const pn_class_t PN_OBJECT_S = PN_METACLASS(pn_strongref);
 const pn_class_t *PN_OBJECT = &PN_OBJECT_S;
diff --git a/c/src/core/object/string.c b/c/src/core/object/string.c
index b50530674..efcb642f3 100644
--- a/c/src/core/object/string.c
+++ b/c/src/core/object/string.c
@@ -23,6 +23,7 @@
 #include <proton/error.h>
 #include <proton/object.h>
 
+#include "core/fixed_string.h"
 #include "core/memory.h"
 
 #include <stdio.h>
@@ -74,28 +75,27 @@ static intptr_t pn_string_compare(void *oa, void *ob)
   }
 }
 
-static int pn_string_inspect(void *obj, pn_string_t *dst)
+static void pn_string_inspect(void *obj, pn_fixed_string_t *dst)
 {
   pn_string_t *str = (pn_string_t *) obj;
   if (str->size == PNI_NULL_SIZE) {
-    return pn_string_addf(dst, "null");
+    pn_fixed_string_addf(dst, "null");
+    return;
   }
 
-  int err = pn_string_addf(dst, "\"");
-  if (err) return err;
+  pn_fixed_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;
+      pn_fixed_string_addf(dst, "%c", c);
     } else {
-      err = pn_string_addf(dst, "\\x%.2x", c);
-      if (err) return err;
+      pn_fixed_string_addf(dst, "\\x%.2x", c);
     }
   }
 
-  return pn_string_addf(dst, "\"");
+  pn_fixed_string_addf(dst, "\"");
+  return;
 }
 
 pn_string_t *pn_string(const char *bytes)
diff --git a/c/src/core/object_private.h b/c/src/core/object_private.h
index 9b277c28a..12a784506 100644
--- a/c/src/core/object_private.h
+++ b/c/src/core/object_private.h
@@ -47,6 +47,7 @@ typedef struct pn_hash_t pn_hash_t;
 typedef void *(*pn_iterator_next_t)(void *state);
 typedef struct pn_iterator_t pn_iterator_t;
 
+struct pn_fixed_string_t;
 struct pn_class_t {
     const char *name;
     pn_cid_t cid;
@@ -59,7 +60,7 @@ struct pn_class_t {
     void (*free)(void *);
     uintptr_t (*hashcode)(void *);
     intptr_t (*compare)(void *, void *);
-    int (*inspect)(void *, pn_string_t *);
+    void (*inspect)(void *, struct pn_fixed_string_t*);
 };
 
 #define PN_CLASS(PREFIX) {                      \
@@ -124,7 +125,7 @@ PN_EXTERN void pn_class_free(const pn_class_t *clazz, void 
*object);
 
 PN_EXTERN intptr_t pn_class_compare(const pn_class_t *clazz, void *a, void *b);
 PN_EXTERN bool pn_class_equals(const pn_class_t *clazz, void *a, void *b);
-PN_EXTERN int pn_class_inspect(const pn_class_t *clazz, void *object, 
pn_string_t *dst);
+PN_EXTERN void pn_class_inspect(const pn_class_t *clazz, void *object, struct 
pn_fixed_string_t *dst);
 
 PN_EXTERN void pn_object_incref(void *object);
 
@@ -133,6 +134,7 @@ PN_EXTERN void pn_void_incref(void *object);
 PN_EXTERN void pn_void_decref(void *object);
 PN_EXTERN int pn_void_refcount(void *object);
 
+void pn_finspect(void *object, struct pn_fixed_string_t *dst);
 PN_EXTERN int pn_inspect(void *object, pn_string_t *dst);
 PN_EXTERN uintptr_t pn_hashcode(void *object);
 PN_EXTERN intptr_t pn_compare(void *a, void *b);
diff --git a/c/src/core/util.h b/c/src/core/util.h
index 7895f9e84..692f8fdb6 100644
--- a/c/src/core/util.h
+++ b/c/src/core/util.h
@@ -32,14 +32,16 @@
 #include <stdlib.h>
 #include <string.h>
 #include <proton/types.h>
-#include <proton/object.h>
+
+#include "object_private.h"
 
 #if __cplusplus
 extern "C" {
 #endif
 
 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);
+struct pn_string_t;
+int pn_quote(struct pn_string_t *dst, const char *src, size_t size);
 bool pn_env_bool(const char *name);
 pn_timestamp_t pn_timestamp_min(pn_timestamp_t a, pn_timestamp_t b);
 
@@ -54,7 +56,7 @@ static inline bool pn_bytes_equal(const pn_bytes_t a, const 
pn_bytes_t b) {
   return (a.size == b.size && !memcmp(a.start, b.start, a.size));
 }
 
-static inline pn_bytes_t pn_string_bytes(pn_string_t *s) {
+static inline pn_bytes_t pn_string_bytes(struct pn_string_t *s) {
   return pn_bytes(pn_string_size(s), pn_string_get(s));
 }
 
diff --git a/c/src/core/value_dump.h b/c/src/core/value_dump.h
index 3da41249c..0f6418f5a 100644
--- a/c/src/core/value_dump.h
+++ b/c/src/core/value_dump.h
@@ -24,8 +24,6 @@
 
 #include "proton/types.h"
 
-#include "core/object_private.h"
-
 struct pn_fixed_string_t;
 size_t pni_value_dump(pn_bytes_t frame, struct pn_fixed_string_t *output);
 
diff --git a/c/src/extra/url.c b/c/src/extra/url.c
index 9652f82a2..5e71b6234 100644
--- a/c/src/extra/url.c
+++ b/c/src/extra/url.c
@@ -21,6 +21,7 @@
 
 #define PN_USE_DEPRECATED_API 1
 
+#include "core/fixed_string.h"
 #include "core/util.h"
 #include "proton/url.h"
 #include "proton/object.h"
@@ -176,13 +177,13 @@ static intptr_t pn_url_compare(void *oa, void *ob)
 }
 
 
-static int pn_url_inspect(void *obj, pn_string_t *dst)
+static void pn_url_inspect(void *obj, pn_fixed_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, ")");
+    pn_fixed_string_addf(dst, "Url(");
+    pn_finspect(pn_url_string(url), dst);
+    pn_fixed_string_addf(dst, ")");
+    return;
 }
 
 #define pn_url_initialize NULL
diff --git a/c/src/reactor/reactor.c b/c/src/reactor/reactor.c
index dbb9e8e26..340ee7c6b 100644
--- a/c/src/reactor/reactor.c
+++ b/c/src/reactor/reactor.c
@@ -19,6 +19,7 @@
  *
  */
 
+#include "core/fixed_string.h"
 #include "core/object_private.h"
 #include "io.h"
 #include "reactor.h"
@@ -364,10 +365,11 @@ pn_task_t *pn_reactor_schedule(pn_reactor_t *reactor, int 
delay, pn_handler_t *h
 }
 
 void pni_event_print(pn_event_t *event) {
-  pn_string_t *str = pn_string(NULL);
-  pn_inspect(event, str);
-  printf("%s\n", pn_string_get(str));
-  pn_free(str);
+  char buf[256];
+  pn_fixed_string_t str = pn_fixed_string(buf, sizeof(buf));
+  pn_finspect(event, &str);
+  pn_fixed_string_terminate(&str);
+  printf("%s\n", buf);
 }
 
 bool pni_reactor_more(pn_reactor_t *reactor) {


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

Reply via email to