Author: rhs
Date: Thu May  9 12:30:27 2013
New Revision: 1480604

URL: http://svn.apache.org/r1480604
Log:
prep for QPID-229: added tests for pn_string_t; made pn_string_t handle NULL 
properly; switched message implementation to use new string API

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

Modified: qpid/proton/trunk/proton-c/include/proton/object.h
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/include/proton/object.h?rev=1480604&r1=1480603&r2=1480604&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/include/proton/object.h (original)
+++ qpid/proton/trunk/proton-c/include/proton/object.h Thu May  9 12:30:27 2013
@@ -86,6 +86,7 @@ PN_EXTERN const char *pn_string_get(pn_s
 PN_EXTERN size_t pn_string_size(pn_string_t *string);
 PN_EXTERN int pn_string_set(pn_string_t *string, const char *bytes);
 PN_EXTERN int pn_string_setn(pn_string_t *string, const char *bytes, size_t n);
+PN_EXTERN void pn_string_clear(pn_string_t *string);
 
 #ifdef __cplusplus
 }

Modified: qpid/proton/trunk/proton-c/src/message/message.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/message/message.c?rev=1480604&r1=1480603&r2=1480604&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/message/message.c (original)
+++ qpid/proton/trunk/proton-c/src/message/message.c Thu May  9 12:30:27 2013
@@ -20,13 +20,14 @@
  */
 
 #include <proton/message.h>
-#include <proton/buffer.h>
+#include <proton/object.h>
 #include <proton/codec.h>
 #include <proton/error.h>
 #include <proton/parser.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <assert.h>
 #include "protocol.h"
 #include "../util.h"
 
@@ -53,18 +54,18 @@ struct pn_message_t {
   bool first_acquirer;
   uint32_t delivery_count;
   pn_data_t *id;
-  pn_buffer_t *user_id;
-  pn_buffer_t *address;
-  pn_buffer_t *subject;
-  pn_buffer_t *reply_to;
+  pn_string_t *user_id;
+  pn_string_t *address;
+  pn_string_t *subject;
+  pn_string_t *reply_to;
   pn_data_t *correlation_id;
-  pn_buffer_t *content_type;
-  pn_buffer_t *content_encoding;
+  pn_string_t *content_type;
+  pn_string_t *content_encoding;
   pn_timestamp_t expiry_time;
   pn_timestamp_t creation_time;
-  pn_buffer_t *group_id;
+  pn_string_t *group_id;
   pn_sequence_t group_sequence;
-  pn_buffer_t *reply_to_group_id;
+  pn_string_t *reply_to_group_id;
 
   bool inferred;
   pn_data_t *data;
@@ -87,18 +88,18 @@ pn_message_t *pn_message()
   msg->first_acquirer = false;
   msg->delivery_count = 0;
   msg->id = pn_data(1);
-  msg->user_id = NULL;
-  msg->address = NULL;
-  msg->subject = NULL;
-  msg->reply_to = NULL;
+  msg->user_id = pn_string(NULL);
+  msg->address = pn_string(NULL);
+  msg->subject = pn_string(NULL);
+  msg->reply_to = pn_string(NULL);
   msg->correlation_id = pn_data(1);
-  msg->content_type = NULL;
-  msg->content_encoding = NULL;
+  msg->content_type = pn_string(NULL);
+  msg->content_encoding = pn_string(NULL);
   msg->expiry_time = 0;
   msg->creation_time = 0;
-  msg->group_id = NULL;
+  msg->group_id = pn_string(NULL);
   msg->group_sequence = 0;
-  msg->reply_to_group_id = NULL;
+  msg->reply_to_group_id = pn_string(NULL);
 
   msg->inferred = false;
   msg->data = pn_data(16);
@@ -116,14 +117,14 @@ pn_message_t *pn_message()
 void pn_message_free(pn_message_t *msg)
 {
   if (msg) {
-    pn_buffer_free(msg->user_id);
-    pn_buffer_free(msg->address);
-    pn_buffer_free(msg->subject);
-    pn_buffer_free(msg->reply_to);
-    pn_buffer_free(msg->content_type);
-    pn_buffer_free(msg->content_encoding);
-    pn_buffer_free(msg->group_id);
-    pn_buffer_free(msg->reply_to_group_id);
+    pn_free(msg->user_id);
+    pn_free(msg->address);
+    pn_free(msg->subject);
+    pn_free(msg->reply_to);
+    pn_free(msg->content_type);
+    pn_free(msg->content_encoding);
+    pn_free(msg->group_id);
+    pn_free(msg->reply_to_group_id);
     pn_data_free(msg->id);
     pn_data_free(msg->correlation_id);
     pn_data_free(msg->data);
@@ -145,18 +146,18 @@ void pn_message_clear(pn_message_t *msg)
   msg->first_acquirer = false;
   msg->delivery_count = 0;
   pn_data_clear(msg->id);
-  if (msg->user_id) pn_buffer_clear(msg->user_id);
-  if (msg->address) pn_buffer_clear(msg->address);
-  if (msg->subject) pn_buffer_clear(msg->subject);
-  if (msg->reply_to) pn_buffer_clear(msg->reply_to);
+  pn_string_clear(msg->user_id);
+  pn_string_clear(msg->address);
+  pn_string_clear(msg->subject);
+  pn_string_clear(msg->reply_to);
   pn_data_clear(msg->correlation_id);
-  if (msg->content_type) pn_buffer_clear(msg->content_type);
-  if (msg->content_encoding) pn_buffer_clear(msg->content_encoding);
+  pn_string_clear(msg->content_type);
+  pn_string_clear(msg->content_encoding);
   msg->expiry_time = 0;
   msg->creation_time = 0;
-  if (msg->group_id) pn_buffer_clear(msg->group_id);
+  pn_string_clear(msg->group_id);
   msg->group_sequence = 0;
-  if (msg->reply_to_group_id) pn_buffer_clear(msg->reply_to_group_id);
+  pn_string_clear(msg->reply_to_group_id);
   msg->inferred = false;
   pn_data_clear(msg->data);
   pn_data_clear(msg->instructions);
@@ -167,36 +168,32 @@ void pn_message_clear(pn_message_t *msg)
 
 int pn_message_errno(pn_message_t *msg)
 {
-  if (msg) {
-    return pn_error_code(msg->error);
-  } else {
-    return 0;
-  }
+  assert(msg);
+  return pn_error_code(msg->error);
 }
 
 const char *pn_message_error(pn_message_t *msg)
 {
-  if (msg) {
-    return pn_error_text(msg->error);
-  } else {
-    return NULL;
-  }
+  assert(msg);
+  return pn_error_text(msg->error);
 }
 
 bool pn_message_is_inferred(pn_message_t *msg)
 {
-  return msg ? msg->inferred : false;
+  assert(msg);
+  return msg->inferred;
 }
 
 int pn_message_set_inferred(pn_message_t *msg, bool inferred)
 {
-  if (!msg) return PN_ARG_ERR;
+  assert(msg);
   msg->inferred = inferred;
   return 0;
 }
 
 pn_parser_t *pn_message_parser(pn_message_t *msg)
 {
+  assert(msg);
   if (!msg->parser) {
     msg->parser = pn_parser();
   }
@@ -205,11 +202,12 @@ pn_parser_t *pn_message_parser(pn_messag
 
 bool pn_message_is_durable(pn_message_t *msg)
 {
-  return msg ? msg->durable : false;
+  assert(msg);
+  return msg->durable;
 }
 int pn_message_set_durable(pn_message_t *msg, bool durable)
 {
-  if (!msg) return PN_ARG_ERR;
+  assert(msg);
   msg->durable = durable;
   return 0;
 }
@@ -217,245 +215,223 @@ int pn_message_set_durable(pn_message_t 
 
 uint8_t pn_message_get_priority(pn_message_t *msg)
 {
-  return msg ? msg->priority : PN_DEFAULT_PRIORITY;
+  assert(msg);
+  return msg->priority;
 }
 int pn_message_set_priority(pn_message_t *msg, uint8_t priority)
 {
-  if (!msg) return PN_ARG_ERR;
+  assert(msg);
   msg->priority = priority;
   return 0;
 }
 
 pn_millis_t pn_message_get_ttl(pn_message_t *msg)
 {
-  return msg ? msg->ttl : 0;
+  assert(msg);
+  return msg->ttl;
 }
 int pn_message_set_ttl(pn_message_t *msg, pn_millis_t ttl)
 {
-  if (!msg) return PN_ARG_ERR;
+  assert(msg);
   msg->ttl = ttl;
   return 0;
 }
 
 bool pn_message_is_first_acquirer(pn_message_t *msg)
 {
-  return msg ? msg->first_acquirer : false;
+  assert(msg);
+  return msg->first_acquirer;
 }
 int pn_message_set_first_acquirer(pn_message_t *msg, bool first)
 {
-  if (!msg) return PN_ARG_ERR;
+  assert(msg);
   msg->first_acquirer = first;
   return 0;
 }
 
 uint32_t pn_message_get_delivery_count(pn_message_t *msg)
 {
-  return msg ? msg->delivery_count : 0;
+  assert(msg);
+  return msg->delivery_count;
 }
 int pn_message_set_delivery_count(pn_message_t *msg, uint32_t count)
 {
-  if (!msg) return PN_ARG_ERR;
+  assert(msg);
   msg->delivery_count = count;
   return 0;
 }
 
 pn_data_t *pn_message_id(pn_message_t *msg)
 {
-  return msg ? msg->id : NULL;
+  assert(msg);
+  return msg->id;
 }
 pn_atom_t pn_message_get_id(pn_message_t *msg)
 {
-  if (msg) return pn_data_get_atom(msg->id);
-  pn_atom_t atom = {PN_NULL};
-  return atom;
+  assert(msg);
+  return pn_data_get_atom(msg->id);
 }
 int pn_message_set_id(pn_message_t *msg, pn_atom_t id)
 {
-  if (!msg) return PN_ARG_ERR;
-
+  assert(msg);
   pn_data_rewind(msg->id);
   return pn_data_put_atom(msg->id, id);
 }
 
-static int pn_buffer_set_bytes(pn_buffer_t **buf, pn_bytes_t bytes)
+static pn_bytes_t pn_string_get_bytes(pn_string_t *string)
 {
-  if (!*buf) {
-    *buf = pn_buffer(64);
-  }
-
-  pn_buffer_clear(*buf);
-
-  return pn_buffer_append(*buf, bytes.start, bytes.size);
+  return pn_bytes(pn_string_size(string), (char *) pn_string_get(string));
 }
 
-static const char *pn_buffer_str(pn_buffer_t *buf)
+static int pn_string_set_bytes(pn_string_t *string, pn_bytes_t bytes)
 {
-  if (buf) {
-    pn_bytes_t bytes = pn_buffer_bytes(buf);
-    if (bytes.size) {
-      return bytes.start;
-    }
-  }
-
-  return NULL;
-}
-
-static int pn_buffer_set_strn(pn_buffer_t **buf, const char *str, size_t size)
-{
-  if (!*buf) {
-    *buf = pn_buffer(64);
-  }
-
-  pn_buffer_clear(*buf);
-  int err = pn_buffer_append(*buf, str, size);
-  if (err) return err;
-  if (str && str[size-1]) {
-    return pn_buffer_append(*buf, "\0", 1);
-  } else {
-    return 0;
-  }
-}
-
-static int pn_buffer_set_str(pn_buffer_t **buf, const char *str)
-{
-  size_t size = str ? strlen(str) + 1 : 0;
-  return pn_buffer_set_strn(buf, str, size);
+  return pn_string_setn(string, bytes.start, bytes.size);
 }
 
 pn_bytes_t pn_message_get_user_id(pn_message_t *msg)
 {
-  return msg && msg->user_id ? pn_buffer_bytes(msg->user_id) : pn_bytes(0, 
NULL);
+  assert(msg);
+  return pn_string_get_bytes(msg->user_id);
 }
 int pn_message_set_user_id(pn_message_t *msg, pn_bytes_t user_id)
 {
-  if (!msg) return PN_ARG_ERR;
-  return pn_buffer_set_bytes(&msg->user_id, user_id);
+  assert(msg);
+  return pn_string_set_bytes(msg->user_id, user_id);
 }
 
 const char *pn_message_get_address(pn_message_t *msg)
 {
-  return msg ? pn_buffer_str(msg->address) : NULL;
+  assert(msg);
+  return pn_string_get(msg->address);
 }
 int pn_message_set_address(pn_message_t *msg, const char *address)
 {
-  if (!msg) return PN_ARG_ERR;
-  return pn_buffer_set_str(&msg->address, address);
+  assert(msg);
+  return pn_string_set(msg->address, address);
 }
 
 const char *pn_message_get_subject(pn_message_t *msg)
 {
-  return msg ? pn_buffer_str(msg->subject) : NULL;
+  assert(msg);
+  return pn_string_get(msg->subject);
 }
 int pn_message_set_subject(pn_message_t *msg, const char *subject)
 {
-  if (!msg) return PN_ARG_ERR;
-  return pn_buffer_set_str(&msg->subject, subject);
+  assert(msg);
+  return pn_string_set(msg->subject, subject);
 }
 
 const char *pn_message_get_reply_to(pn_message_t *msg)
 {
-  return msg ? pn_buffer_str(msg->reply_to) : NULL;
+  assert(msg);
+  return pn_string_get(msg->reply_to);
 }
 int pn_message_set_reply_to(pn_message_t *msg, const char *reply_to)
 {
-  if (!msg) return PN_ARG_ERR;
-  return pn_buffer_set_str(&msg->reply_to, reply_to);
+  assert(msg);
+  return pn_string_set(msg->reply_to, reply_to);
 }
 
 pn_data_t *pn_message_correlation_id(pn_message_t *msg)
 {
-  return msg ? msg->correlation_id : NULL;
+  assert(msg);
+  return msg->correlation_id;
 }
 pn_atom_t pn_message_get_correlation_id(pn_message_t *msg)
 {
-  if (msg) return pn_data_get_atom(msg->correlation_id);
-  pn_atom_t atom = {PN_NULL};
-  return atom;
+  assert(msg);
+  return pn_data_get_atom(msg->correlation_id);
 }
 int pn_message_set_correlation_id(pn_message_t *msg, pn_atom_t atom)
 {
-  if (!msg) return PN_ARG_ERR;
-
+  assert(msg);
   pn_data_rewind(msg->correlation_id);
   return pn_data_put_atom(msg->correlation_id, atom);
 }
 
 const char *pn_message_get_content_type(pn_message_t *msg)
 {
-  return msg ? pn_buffer_str(msg->content_type) : NULL;
+  assert(msg);
+  return pn_string_get(msg->content_type);
 }
 int pn_message_set_content_type(pn_message_t *msg, const char *type)
 {
-  if (!msg) return PN_ARG_ERR;
-  return pn_buffer_set_str(&msg->content_type, type);
+  assert(msg);
+  return pn_string_set(msg->content_type, type);
 }
 
 const char *pn_message_get_content_encoding(pn_message_t *msg)
 {
-  return msg ? pn_buffer_str(msg->content_encoding) : NULL;
+  assert(msg);
+  return pn_string_get(msg->content_encoding);
 }
 int pn_message_set_content_encoding(pn_message_t *msg, const char *encoding)
 {
-  if (!msg) return PN_ARG_ERR;
-  return pn_buffer_set_str(&msg->content_encoding, encoding);
+  assert(msg);
+  return pn_string_set(msg->content_encoding, encoding);
 }
 
 pn_timestamp_t pn_message_get_expiry_time(pn_message_t *msg)
 {
-  return msg ? msg->expiry_time : 0;
+  assert(msg);
+  return msg->expiry_time;
 }
 int pn_message_set_expiry_time(pn_message_t *msg, pn_timestamp_t time)
 {
-  if (!msg) return PN_ARG_ERR;
+  assert(msg);
   msg->expiry_time = time;
   return 0;
 }
 
 pn_timestamp_t pn_message_get_creation_time(pn_message_t *msg)
 {
-  return msg ? msg->creation_time : 0;
+  assert(msg);
+  return msg->creation_time;
 }
 int pn_message_set_creation_time(pn_message_t *msg, pn_timestamp_t time)
 {
-  if (!msg) return PN_ARG_ERR;
+  assert(msg);
   msg->creation_time = time;
   return 0;
 }
 
 const char *pn_message_get_group_id(pn_message_t *msg)
 {
-  return msg ? pn_buffer_str(msg->group_id) : NULL;
+  assert(msg);
+  return pn_string_get(msg->group_id);
 }
 int pn_message_set_group_id(pn_message_t *msg, const char *group_id)
 {
-  if (!msg) return PN_ARG_ERR;
-  return pn_buffer_set_str(&msg->group_id, group_id);
+  assert(msg);
+  return pn_string_set(msg->group_id, group_id);
 }
 
 pn_sequence_t pn_message_get_group_sequence(pn_message_t *msg)
 {
-  return msg ? msg->group_sequence : 0;
+  assert(msg);
+  return msg->group_sequence;
 }
 int pn_message_set_group_sequence(pn_message_t *msg, pn_sequence_t n)
 {
-  if (!msg) return PN_ARG_ERR;
+  assert(msg);
   msg->group_sequence = n;
   return 0;
 }
 
 const char *pn_message_get_reply_to_group_id(pn_message_t *msg)
 {
-  return msg ? pn_buffer_str(msg->reply_to_group_id) : NULL;
+  assert(msg);
+  return pn_string_get(msg->reply_to_group_id);
 }
 int pn_message_set_reply_to_group_id(pn_message_t *msg, const char 
*reply_to_group_id)
 {
-  if (!msg) return PN_ARG_ERR;
-  return pn_buffer_set_str(&msg->reply_to_group_id, reply_to_group_id);
+  assert(msg);
+  return pn_string_set(msg->reply_to_group_id, reply_to_group_id);
 }
 
 int pn_message_decode(pn_message_t *msg, const char *bytes, size_t size)
 {
-  if (!msg || !bytes || !size) return PN_ARG_ERR;
+  assert(msg && bytes && size);
 
   pn_message_clear(msg);
 
@@ -498,23 +474,23 @@ int pn_message_decode(pn_message_t *msg,
                            &msg->group_sequence, &reply_to_group_id);
         if (err) return pn_error_format(msg->error, err, "data error: %s",
                                         pn_data_error(msg->data));
-        err = pn_buffer_set_bytes(&msg->user_id, user_id);
+        err = pn_string_set_bytes(msg->user_id, user_id);
         if (err) return pn_error_format(msg->error, err, "error setting 
user_id");
-        err = pn_buffer_set_strn(&msg->address, address.start, address.size);
+        err = pn_string_setn(msg->address, address.start, address.size);
         if (err) return pn_error_format(msg->error, err, "error setting 
address");
-        err = pn_buffer_set_strn(&msg->subject, subject.start, subject.size);
+        err = pn_string_setn(msg->subject, subject.start, subject.size);
         if (err) return pn_error_format(msg->error, err, "error setting 
subject");
-        err = pn_buffer_set_strn(&msg->reply_to, reply_to.start, 
reply_to.size);
+        err = pn_string_setn(msg->reply_to, reply_to.start, reply_to.size);
         if (err) return pn_error_format(msg->error, err, "error setting 
reply_to");
-        err = pn_buffer_set_strn(&msg->content_type, ctype.start, ctype.size);
+        err = pn_string_setn(msg->content_type, ctype.start, ctype.size);
         if (err) return pn_error_format(msg->error, err, "error setting 
content_type");
-        err = pn_buffer_set_strn(&msg->content_encoding, cencoding.start,
-                                 cencoding.size);
+        err = pn_string_setn(msg->content_encoding, cencoding.start,
+                             cencoding.size);
         if (err) return pn_error_format(msg->error, err, "error setting 
content_encoding");
-        err = pn_buffer_set_strn(&msg->group_id, group_id.start, 
group_id.size);
+        err = pn_string_setn(msg->group_id, group_id.start, group_id.size);
         if (err) return pn_error_format(msg->error, err, "error setting 
group_id");
-        err = pn_buffer_set_strn(&msg->reply_to_group_id, 
reply_to_group_id.start,
-                                 reply_to_group_id.size);
+        err = pn_string_setn(msg->reply_to_group_id, reply_to_group_id.start,
+                             reply_to_group_id.size);
         if (err) return pn_error_format(msg->error, err, "error setting 
reply_to_group_id");
       }
       break;
@@ -592,18 +568,18 @@ int pn_message_encode(pn_message_t *msg,
 
   err = pn_data_fill(msg->data, "DL[CzSSSCssttSIS]", PROPERTIES,
                      msg->id,
-                     pn_buffer_bytes(msg->user_id),
-                     pn_buffer_str(msg->address),
-                     pn_buffer_str(msg->subject),
-                     pn_buffer_str(msg->reply_to),
+                     pn_string_get_bytes(msg->user_id),
+                     pn_string_get(msg->address),
+                     pn_string_get(msg->subject),
+                     pn_string_get(msg->reply_to),
                      msg->correlation_id,
-                     pn_buffer_str(msg->content_type),
-                     pn_buffer_str(msg->content_encoding),
+                     pn_string_get(msg->content_type),
+                     pn_string_get(msg->content_encoding),
                      msg->expiry_time,
                      msg->creation_time,
-                     pn_buffer_str(msg->group_id),
+                     pn_string_get(msg->group_id),
                      msg->group_sequence,
-                     pn_buffer_str(msg->reply_to_group_id));
+                     pn_string_get(msg->reply_to_group_id));
   if (err)
     return pn_error_format(msg->error, err, "data error: %s",
                            pn_data_error(msg->data));

Modified: qpid/proton/trunk/proton-c/src/object/object.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/object/object.c?rev=1480604&r1=1480603&r2=1480604&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/object/object.c (original)
+++ qpid/proton/trunk/proton-c/src/object/object.c Thu May  9 12:30:27 2013
@@ -21,6 +21,7 @@
 
 #include <proton/error.h>
 #include <proton/object.h>
+#include <sys/types.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
@@ -498,9 +499,11 @@ void pn_hash_del(pn_hash_t *hash, uintpt
   pn_map_del(&hash->map, (void *) key);
 }
 
+#define PNI_NULL_SIZE (-1)
+
 struct pn_string_t {
   char *bytes;
-  size_t size;
+  ssize_t size;       // PNI_NULL_SIZE (-1) means null
   size_t capacity;
 };
 
@@ -513,8 +516,12 @@ static void pn_string_finalize(void *obj
 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 (size_t i = 0; i < string->size; i++) {
+  for (ssize_t i = 0; i < string->size; i++) {
     hashcode = hashcode * 31 + string->bytes[i];
   }
   return hashcode;
@@ -528,12 +535,16 @@ static intptr_t pn_string_compare(void *
     return b->size - a->size;
   }
 
-  return memcmp(a->bytes, b->bytes, a->size);
+  if (a->size == PNI_NULL_SIZE) {
+    return 0;
+  } else {
+    return memcmp(a->bytes, b->bytes, a->size);
+  }
 }
 
 pn_string_t *pn_string(const char *bytes)
 {
-  return pn_stringn(bytes, strlen(bytes) + 1);
+  return pn_stringn(bytes, bytes ? strlen(bytes) : 0);
 }
 
 static pn_class_t clazz = {pn_string_finalize, pn_string_hashcode,
@@ -552,24 +563,32 @@ pn_string_t *pn_stringn(const char *byte
 const char *pn_string_get(pn_string_t *string)
 {
   assert(string);
-  return string->bytes;
+  if (string->size == PNI_NULL_SIZE) {
+    return NULL;
+  } else {
+    return string->bytes;
+  }
 }
 
 size_t pn_string_size(pn_string_t *string)
 {
   assert(string);
-  return string->size;
+  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, strlen(bytes) + 1);
+  return pn_string_setn(string, bytes, bytes ? strlen(bytes) : 0);
 }
 
 int pn_string_setn(pn_string_t *string, const char *bytes, size_t n)
 {
   bool grow = false;
-  while (string->capacity < n*sizeof(char)) {
+  while (string->capacity < (n*sizeof(char) + 1)) {
     string->capacity *= 2;
     grow = true;
   }
@@ -583,7 +602,18 @@ int pn_string_setn(pn_string_t *string, 
     }
   }
 
-  memcpy(string->bytes, bytes, n*sizeof(char));
-  string->size = n;
+  if (bytes) {
+    memcpy(string->bytes, bytes, n*sizeof(char));
+    string->bytes[n] = '\0';
+    string->size = n;
+  } else {
+    string->size = PNI_NULL_SIZE;
+  }
+
   return 0;
 }
+
+void pn_string_clear(pn_string_t *string)
+{
+  pn_string_set(string, NULL);
+}

Modified: qpid/proton/trunk/proton-c/src/tests/object.c
URL: 
http://svn.apache.org/viewvc/qpid/proton/trunk/proton-c/src/tests/object.c?rev=1480604&r1=1480603&r2=1480604&view=diff
==============================================================================
--- qpid/proton/trunk/proton-c/src/tests/object.c (original)
+++ qpid/proton/trunk/proton-c/src/tests/object.c Thu May  9 12:30:27 2013
@@ -315,6 +315,74 @@ static void test_hash()
   pn_decref(three);
 }
 
+static bool equals(const char *a, const char *b)
+{
+  if (a == NULL && b == NULL) {
+    return true;
+  }
+
+  if (a == NULL || b == NULL) {
+    return false;
+  }
+
+  return !strcmp(a, b);
+}
+
+static void test_string(const char *value)
+{
+  size_t size = value ? strlen(value) : 0;
+
+  pn_string_t *str = pn_string(value);
+  assert(equals(pn_string_get(str), value));
+  assert(pn_string_size(str) == size);
+
+  pn_string_t *strn = pn_stringn(value, size);
+  assert(equals(pn_string_get(strn), value));
+  assert(pn_string_size(strn) == size);
+
+  pn_string_t *strset = pn_string(NULL);
+  pn_string_set(strset, value);
+  assert(equals(pn_string_get(strset), value));
+  assert(pn_string_size(strset) == size);
+
+  pn_string_t *strsetn = pn_string(NULL);
+  pn_string_setn(strsetn, value, size);
+  assert(equals(pn_string_get(strsetn), value));
+  assert(pn_string_size(strsetn) == size);
+
+  assert(pn_hashcode(str) == pn_hashcode(strn));
+  assert(pn_hashcode(str) == pn_hashcode(strset));
+  assert(pn_hashcode(str) == pn_hashcode(strsetn));
+
+  assert(!pn_compare(str, str));
+  assert(!pn_compare(str, strn));
+  assert(!pn_compare(str, strset));
+  assert(!pn_compare(str, strsetn));
+
+  pn_free(str);
+  pn_free(strn);
+  pn_free(strset);
+  pn_free(strsetn);
+}
+
+static void test_stringn(const char *value, size_t size)
+{
+  pn_string_t *strn = pn_stringn(value, size);
+  assert(equals(pn_string_get(strn), value));
+  assert(pn_string_size(strn) == size);
+
+  pn_string_t *strsetn = pn_string(NULL);
+  pn_string_setn(strsetn, value, size);
+  assert(equals(pn_string_get(strsetn), value));
+  assert(pn_string_size(strsetn) == size);
+
+  assert(pn_hashcode(strn) == pn_hashcode(strsetn));
+  assert(!pn_compare(strn, strsetn));
+
+  pn_free(strn);
+  pn_free(strsetn);
+}
+
 int main(int argc, char **argv)
 {
   for (size_t i = 0; i < 128; i++) {
@@ -335,11 +403,22 @@ int main(int argc, char **argv)
   for (size_t i = 0; i < 4; i++) {
     test_list(i);
   }
+
   for (size_t i = 0; i < 4; i++) {
     test_list_refcount(i);
   }
+
   test_map();
+
   test_hash();
 
+  test_string(NULL);
+  test_string("");
+  test_string("this is a test");
+  test_string("012345678910111213151617181920212223242526272829303132333435363"
+              
"738394041424344454647484950515253545556575859606162636465666768");
+  test_string("this has an embedded \000 in it");
+  test_stringn("this has an embedded \000 in it", 28);
+
   return 0;
 }



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

Reply via email to