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 d9ccd2923be628ac85e8a8da45090d981f0585cd Author: Andrew Stitcher <[email protected]> AuthorDate: Wed Jun 1 19:25:58 2022 -0400 PROTON-2557: Introduce pn_tostring in place of pn_inspect Introduce and use a new API pn_tostring which produces a string representation of a Proton object in a char* string. It allocates this string with malloc and the application must free it. This replaces pn_inspect which requires the application to use the pn_string_t type purely to receive the string output. But we really don't want or need to expose this type outside the library itself. --- c/benchmarks/connection-driver.cpp | 18 +++++++++--------- c/benchmarks/message-encoding_list.cpp | 24 ++++++++++++------------ c/benchmarks/message-encoding_map.cpp | 31 +++++++++++++++---------------- c/examples/direct.c | 7 +++---- c/examples/receive.c | 7 +++---- c/include/proton/object.h | 1 + c/src/core/object/object.c | 16 +++++++++++++++- c/tests/fuzz/fuzz-connection-driver.c | 7 +++---- c/tests/fuzz/fuzz-proactor-receive.c | 8 ++++---- c/tests/object_test.cpp | 11 +++++------ c/tests/pn_test.cpp | 7 ++++--- c/tests/pn_test.hpp | 4 ---- cpp/src/object.cpp | 7 +++---- cpp/src/proton_bits.cpp | 7 +++---- 14 files changed, 80 insertions(+), 75 deletions(-) diff --git a/c/benchmarks/connection-driver.cpp b/c/benchmarks/connection-driver.cpp index e2fdad16e..f3bef928a 100644 --- a/c/benchmarks/connection-driver.cpp +++ b/c/benchmarks/connection-driver.cpp @@ -19,24 +19,25 @@ * */ -#include <unistd.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> #include <wait.h> #include <benchmark/benchmark.h> #include "proton/connection_driver.h" #include "proton/engine.h" +#include "proton/listener.h" #include "proton/log.h" #include "proton/message.h" +#include "proton/netaddr.h" +#include "proton/object.h" +#include "proton/proactor.h" +#include "proton/sasl.h" #include "proton/transport.h" -#include <proton/listener.h> -#include <proton/netaddr.h> -#include <proton/proactor.h> -#include <proton/sasl.h> // variant of the receive.c proactor example @@ -475,11 +476,10 @@ static void decode_message(pn_delivery_t *dlv) { // decode it into a proton message pn_message_t *m = pn_message(); if (PN_OK == pn_message_decode(m, buffer, len)) { - pn_string_t *s = pn_string(NULL); - pn_inspect(pn_message_body(m), s); + char *s = pn_tostring(pn_message_body(m)); if (VERBOSE) - printf("%s\n", pn_string_get(s)); - pn_free(s); + printf("%s\n", s); + free(s); } pn_message_free(m); } diff --git a/c/benchmarks/message-encoding_list.cpp b/c/benchmarks/message-encoding_list.cpp index 51e8cebd0..1b4954fa1 100644 --- a/c/benchmarks/message-encoding_list.cpp +++ b/c/benchmarks/message-encoding_list.cpp @@ -18,24 +18,25 @@ * under the License. * */ -#include <unistd.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <wait.h> + +#include <benchmark/benchmark.h> #include "proton/connection_driver.h" #include "proton/engine.h" +#include "proton/listener.h" #include "proton/log.h" #include "proton/message.h" - -#include <benchmark/benchmark.h> -#include <proton/listener.h> -#include <proton/netaddr.h> -#include <proton/proactor.h> -#include <proton/sasl.h> -#include <wait.h> +#include "proton/netaddr.h" +#include "proton/object.h" +#include "proton/proactor.h" +#include "proton/sasl.h" const bool VERBOSE = false; const bool ERRORS = true; @@ -45,13 +46,12 @@ static void decode_message_buffer(pn_rwbytes_t data) { int err = pn_message_decode(m, data.start, data.size); if (!err) { /* Print the decoded message */ - pn_string_t *s = pn_string(NULL); - pn_inspect(pn_message_body(m), s); + char *s = pn_tostring(pn_message_body(m)); if (VERBOSE) { - printf("%s\n", pn_string_get(s)); + printf("%s\n", s); fflush(stdout); } - pn_free(s); + free(s); pn_message_free(m); free(data.start); } else { diff --git a/c/benchmarks/message-encoding_map.cpp b/c/benchmarks/message-encoding_map.cpp index 86f8e1deb..d58746c73 100644 --- a/c/benchmarks/message-encoding_map.cpp +++ b/c/benchmarks/message-encoding_map.cpp @@ -18,24 +18,25 @@ * under the License. * */ -#include <unistd.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> +#include <wait.h> + +#include <benchmark/benchmark.h> #include "proton/connection_driver.h" #include "proton/engine.h" +#include "proton/listener.h" #include "proton/log.h" #include "proton/message.h" - -#include <benchmark/benchmark.h> -#include <proton/listener.h> -#include <proton/netaddr.h> -#include <proton/proactor.h> -#include <proton/sasl.h> -#include <wait.h> +#include "proton/netaddr.h" +#include "proton/object.h" +#include "proton/proactor.h" +#include "proton/sasl.h" #define MAX_SIZE 1024 @@ -49,13 +50,12 @@ static void decode_message_buffer(pn_rwbytes_t data) { int err = pn_message_decode(m, data.start, data.size); if (!err) { /* Print the decoded message */ - pn_string_t *s = pn_string(NULL); - pn_inspect(pn_message_body(m), s); + char *s = pn_tostring(pn_message_body(m)); if (VERBOSE) { - printf("%s\n", pn_string_get(s)); + printf("%s\n", s); fflush(stdout); } - pn_free(s); + free(s); pn_message_free(m); free(data.start); } else { @@ -152,11 +152,10 @@ static void decode_message(pn_delivery_t *dlv) { // decode it into a proton message pn_message_t *m = pn_message(); if (PN_OK == pn_message_decode(m, buffer, len)) { - pn_string_t *s = pn_string(NULL); - pn_inspect(pn_message_body(m), s); + char *s = pn_tostring(pn_message_body(m)); if (VERBOSE) - printf("%s\n", pn_string_get(s)); - pn_free(s); + printf("%s\n", s); + free(s); } pn_message_free(m); } diff --git a/c/examples/direct.c b/c/examples/direct.c index ceaaf2379..977b85c8d 100644 --- a/c/examples/direct.c +++ b/c/examples/direct.c @@ -98,11 +98,10 @@ static void decode_message(pn_rwbytes_t data) { int err = pn_message_decode(m, data.start, data.size); if (!err) { /* Print the decoded message */ - pn_string_t *s = pn_string(NULL); - pn_inspect(pn_message_body(m), s); - printf("%s\n", pn_string_get(s)); + char *s = pn_tostring(pn_message_body(m)); + printf("%s\n", s); fflush(stdout); - pn_free(s); + free(s); pn_message_free(m); free(data.start); } else { diff --git a/c/examples/receive.c b/c/examples/receive.c index c70e0d8e3..c6f31f433 100644 --- a/c/examples/receive.c +++ b/c/examples/receive.c @@ -61,10 +61,9 @@ static void decode_message(pn_rwbytes_t data) { int err = pn_message_decode(m, data.start, data.size); if (!err) { /* Print the decoded message */ - pn_string_t *s = pn_string(NULL); - pn_inspect(pn_message_body(m), s); - printf("%s\n", pn_string_get(s)); - pn_free(s); + char *s = pn_tostring(pn_message_body(m)); + printf("%s\n", s); + free(s); pn_message_free(m); free(data.start); } else { diff --git a/c/include/proton/object.h b/c/include/proton/object.h index 3db656406..ce76c6941 100644 --- a/c/include/proton/object.h +++ b/c/include/proton/object.h @@ -156,6 +156,7 @@ PN_EXTERN uintptr_t pn_hashcode(void *object); PN_EXTERN intptr_t pn_compare(void *a, void *b); PN_EXTERN bool pn_equals(void *a, void *b); PN_EXTERN int pn_inspect(void *object, pn_string_t *dst); +PN_EXTERN char *pn_tostring(void *object); PN_EXTERN pn_list_t *pn_list(const pn_class_t *clazz, size_t capacity); PN_EXTERN size_t pn_list_size(pn_list_t *list); diff --git a/c/src/core/object/object.c b/c/src/core/object/object.c index 318b3d95f..a3ee2cbfd 100644 --- a/c/src/core/object/object.c +++ b/c/src/core/object/object.c @@ -23,8 +23,9 @@ #include "core/memory.h" -#include <stdlib.h> #include <assert.h> +#include <stdlib.h> +#include <string.h> #define CID_pn_default CID_pn_object #define pn_default_initialize NULL @@ -369,6 +370,19 @@ int pn_inspect(void *object, pn_string_t *dst) return pn_string_addf(dst, "%s<%p>", name, object); } +char *pn_tostring(void *object) +{ + pn_string_t *s = pn_string(NULL); + pn_inspect(object, s); + + const char *sc = pn_string_get(s); + int l = pn_string_size(s)+1; // include final null + char *r = malloc(l); + strncpy(r, sc, l); + pn_decref(s); + return r; +} + #define pn_weakref_new NULL #define pn_weakref_initialize NULL #define pn_weakref_finalize NULL diff --git a/c/tests/fuzz/fuzz-connection-driver.c b/c/tests/fuzz/fuzz-connection-driver.c index ba0650896..8f8459fac 100644 --- a/c/tests/fuzz/fuzz-connection-driver.c +++ b/c/tests/fuzz/fuzz-connection-driver.c @@ -181,11 +181,10 @@ static void decode_message(pn_delivery_t *dlv) { // decode it into a proton message pn_message_t *m = pn_message(); if (PN_OK == pn_message_decode(m, buffer, len)) { - pn_string_t *s = pn_string(NULL); - pn_inspect(pn_message_body(m), s); + char *s = pn_tostring(pn_message_body(m)); if (ERRORS) - printf("%s\n", pn_string_get(s)); - pn_free(s); + printf("%s\n", s); + free(s); } pn_message_free(m); } diff --git a/c/tests/fuzz/fuzz-proactor-receive.c b/c/tests/fuzz/fuzz-proactor-receive.c index 499c439c2..b81160424 100644 --- a/c/tests/fuzz/fuzz-proactor-receive.c +++ b/c/tests/fuzz/fuzz-proactor-receive.c @@ -26,6 +26,7 @@ #include <proton/delivery.h> #include <proton/link.h> #include <proton/message.h> +#include <proton/object.h> #include <proton/proactor.h> #include <proton/session.h> #include <proton/transport.h> @@ -91,10 +92,9 @@ static void decode_message(pn_delivery_t *dlv) { // decode it into a proton message pn_message_t *m = pn_message(); if (PN_OK == pn_message_decode(m, buffer, len)) { - pn_string_t *s = pn_string(NULL); - pn_inspect(pn_message_body(m), s); - printf("%s\n", pn_string_get(s)); - pn_free(s); + char *s = pn_tostring(pn_message_body(m)); + printf("%s\n", s); + free(s); } pn_message_free(m); } diff --git a/c/tests/object_test.cpp b/c/tests/object_test.cpp index c5a30237e..bd9d27eeb 100644 --- a/c/tests/object_test.cpp +++ b/c/tests/object_test.cpp @@ -714,12 +714,11 @@ TEST_CASE("map_iteration") { pn_decref(pairs); } -#define test_inspect(o, expected) \ - do { \ - pn_string_t *dst = pn_string(NULL); \ - pn_inspect(o, dst); \ - CHECK_THAT(expected, Equals(pn_string_get(dst))); \ - pn_free(dst); \ +#define test_inspect(o, expected) \ + do { \ + char *dst = pn_tostring(o); \ + CHECK_THAT(expected, Equals(dst)); \ + free(dst); \ } while (0) TEST_CASE("list_inspect") { diff --git a/c/tests/pn_test.cpp b/c/tests/pn_test.cpp index 37e5199dc..03a2526d5 100644 --- a/c/tests/pn_test.cpp +++ b/c/tests/pn_test.cpp @@ -60,9 +60,10 @@ std::ostream &operator<<(std::ostream &o, const pn_error_t &const_err) { namespace pn_test { std::string inspect(void *obj) { - auto_free<pn_string_t, pn_string_free> s(pn_string(NULL)); - pn_inspect(obj, s); - return pn_string_get(s); + char* s = pn_tostring(obj); + std::string r(s); + free(s); + return r; } etypes make_etypes_(int first, ...) { diff --git a/c/tests/pn_test.hpp b/c/tests/pn_test.hpp index 249451ba7..c3dcf0176 100644 --- a/c/tests/pn_test.hpp +++ b/c/tests/pn_test.hpp @@ -56,10 +56,6 @@ public: operator T *() const { return ptr_; } // not marking explicit for convenience }; -// pn_free() works for some, but not all pn_xxx_t* types. -// Add typed pn_string_free() so we can be consistent and safe. -inline void pn_string_free(pn_string_t *s) { pn_free(s); } - // Call pn_inspect(), return std::string std::string inspect(void *); diff --git a/cpp/src/object.cpp b/cpp/src/object.cpp index 2732d5d0e..b3c82cc31 100644 --- a/cpp/src/object.cpp +++ b/cpp/src/object.cpp @@ -33,10 +33,9 @@ void pn_ptr_base::decref(void *p) { std::string pn_ptr_base::inspect(void* p) { if (!p) return std::string(); - ::pn_string_t* s = ::pn_string(NULL); - (void) ::pn_inspect(p, s); - std::string tmp = std::string(pn_string_get(s)); - pn_free(s); + char* s = ::pn_tostring(p); + std::string tmp(s); + free(s); return tmp; } }} diff --git a/cpp/src/proton_bits.cpp b/cpp/src/proton_bits.cpp index 3e1b27f7e..517f7456d 100644 --- a/cpp/src/proton_bits.cpp +++ b/cpp/src/proton_bits.cpp @@ -54,10 +54,9 @@ std::string error_str(pn_error_t* err, long code) { } std::ostream& operator<<(std::ostream& o, const inspectable& object) { - pn_string_t* str = pn_string(""); - pn_inspect(object.value, str); - o << pn_string_get(str); - pn_free(str); + char* str = pn_tostring(object.value); + o << str; + free(str); return o; } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
