qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kgiu...@apache.org
Subject svn commit: r1657961 - in /qpid/dispatch/trunk: include/qpid/dispatch/message.h src/message.c src/message_private.h tests/message_test.c
Date Fri, 06 Feb 2015 20:58:41 GMT
Author: kgiusti
Date: Fri Feb  6 20:58:41 2015
New Revision: 1657961

URL: http://svn.apache.org/r1657961
Log:
DISPATCH-109: add parsing of the subject field.

Refactored the parse logic a bit to be more linear and avoid parsing
previously parsed fields.

Modified:
    qpid/dispatch/trunk/include/qpid/dispatch/message.h
    qpid/dispatch/trunk/src/message.c
    qpid/dispatch/trunk/src/message_private.h
    qpid/dispatch/trunk/tests/message_test.c

Modified: qpid/dispatch/trunk/include/qpid/dispatch/message.h
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/include/qpid/dispatch/message.h?rev=1657961&r1=1657960&r2=1657961&view=diff
==============================================================================
--- qpid/dispatch/trunk/include/qpid/dispatch/message.h (original)
+++ qpid/dispatch/trunk/include/qpid/dispatch/message.h Fri Feb  6 20:58:41 2015
@@ -65,6 +65,8 @@ typedef enum {
 
 /** Message fields */
 typedef enum {
+    QD_FIELD_NONE,   // reserved
+
     //
     // Message Sections
     //
@@ -78,6 +80,7 @@ typedef enum {
 
     //
     // Fields of the Header Section
+    // Ordered by list position
     //
     QD_FIELD_DURABLE,
     QD_FIELD_PRIORITY,
@@ -87,6 +90,7 @@ typedef enum {
 
     //
     // Fields of the Properties Section
+    // Ordered by list position
     //
     QD_FIELD_MESSAGE_ID,
     QD_FIELD_USER_ID,

Modified: qpid/dispatch/trunk/src/message.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/message.c?rev=1657961&r1=1657960&r2=1657961&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/message.c (original)
+++ qpid/dispatch/trunk/src/message.c Fri Feb  6 20:58:41 2015
@@ -354,124 +354,175 @@ static int qd_check_and_advance(qd_buffe
 }
 
 
-static qd_field_location_t *qd_message_field_location(qd_message_t *msg, qd_message_field_t
field)
+// translate a field into its proper section of the message
+static qd_message_field_t qd_field_section(qd_message_field_t field)
 {
+    switch (field) {
+
+    case QD_FIELD_HEADER:
+    case QD_FIELD_DELIVERY_ANNOTATION:
+    case QD_FIELD_MESSAGE_ANNOTATION:
+    case QD_FIELD_PROPERTIES:
+    case QD_FIELD_APPLICATION_PROPERTIES:
+    case QD_FIELD_BODY:
+    case QD_FIELD_FOOTER:
+        return field;
+
+    case QD_FIELD_DURABLE:
+    case QD_FIELD_PRIORITY:
+    case QD_FIELD_TTL:
+    case QD_FIELD_FIRST_ACQUIRER:
+    case QD_FIELD_DELIVERY_COUNT:
+        return QD_FIELD_HEADER;
+
+    case QD_FIELD_MESSAGE_ID:
+    case QD_FIELD_USER_ID:
+    case QD_FIELD_TO:
+    case QD_FIELD_SUBJECT:
+    case QD_FIELD_REPLY_TO:
+    case QD_FIELD_CORRELATION_ID:
+    case QD_FIELD_CONTENT_TYPE:
+    case QD_FIELD_CONTENT_ENCODING:
+    case QD_FIELD_ABSOLUTE_EXPIRY_TIME:
+    case QD_FIELD_CREATION_TIME:
+    case QD_FIELD_GROUP_ID:
+    case QD_FIELD_GROUP_SEQUENCE:
+    case QD_FIELD_REPLY_TO_GROUP_ID:
+        return QD_FIELD_PROPERTIES;
+
+    default:
+        assert(false);  // TBD: add new fields here
+        return QD_FIELD_NONE;
+    }
+}
+
+
+// get the field location of a field in the message properties (if it exists,
+// else 0).
+static qd_field_location_t *qd_message_properties_field(qd_message_t *msg, qd_message_field_t
field)
+{
+    static const intptr_t offsets[] = {
+        // position of the field's qd_field_location_t in the message content
+        // object
+        (intptr_t) &((qd_message_content_t *)0)->field_message_id,
+        (intptr_t) &((qd_message_content_t *)0)->field_user_id,
+        (intptr_t) &((qd_message_content_t *)0)->field_to,
+        (intptr_t) &((qd_message_content_t *)0)->field_subject,
+        (intptr_t) &((qd_message_content_t *)0)->field_reply_to,
+        (intptr_t) &((qd_message_content_t *)0)->field_correlation_id
+    };
+    // update table above if new fields need to be accessed:
+    assert(QD_FIELD_MESSAGE_ID <= field && field <= QD_FIELD_CORRELATION_ID);
+
     qd_message_content_t *content = MSG_CONTENT(msg);
+    if (!content->section_message_properties.parsed) {
+        if (!qd_message_check(msg, QD_DEPTH_PROPERTIES) || !content->section_message_properties.parsed)
+            return 0;
+    }
+    if (field == QD_FIELD_PROPERTIES) return &content->section_message_properties;
+
+    const int index = field - QD_FIELD_MESSAGE_ID;
+    qd_field_location_t *const location = (qd_field_location_t *)((char *)content + offsets[index]);
+    if (location->parsed)
+        return location;
+
+    // requested field not parsed out.  Need to parse out up to the requested field:
+    qd_buffer_t   *buffer = content->section_message_properties.buffer;
+    unsigned char *cursor = qd_buffer_base(buffer) + content->section_message_properties.offset;
+    advance(&cursor, &buffer, content->section_message_properties.hdr_length,
0, 0);
+    if (index >= start_list(&cursor, &buffer)) return 0;  // properties list too
short
+
+    int position = 0;
+    while (position < index) {
+        qd_field_location_t *f = (qd_field_location_t *)((char *)content + offsets[position]);
+        if (f->parsed)
+            advance(&cursor, &buffer, f->hdr_length + f->length, 0, 0);
+        else // parse it out
+            if (!traverse_field(&cursor, &buffer, f)) return 0;
+        position++;
+    }
+
+    // all fields previous to the target have now been parsed and cursor/buffer
+    // are in the correct position, parse out the field:
+    if (traverse_field(&cursor, &buffer, location))
+        return location;
+
+    return 0;
+}
+
+
+// get the field location of a field in the message header (if it exists,
+// else 0)
+static qd_field_location_t *qd_message_header_field(qd_message_t *msg, qd_message_field_t
field)
+{
+    qd_message_content_t *content = MSG_CONTENT(msg);
+
+    if (!content->section_message_header.parsed) {
+        if (!qd_message_check(msg, QD_DEPTH_HEADER) || !content->section_message_header.parsed)
+            return 0;
+    }
 
     switch (field) {
-    case QD_FIELD_TO:
-        while (1) {
-            if (content->field_to.parsed)
-                return &content->field_to;
-
-            if (content->section_message_properties.parsed == 0)
-                break;
-
-            qd_buffer_t   *buffer = content->section_message_properties.buffer;
-            unsigned char *cursor = qd_buffer_base(buffer) + content->section_message_properties.offset;
-            advance(&cursor, &buffer, content->section_message_properties.hdr_length,
0, 0);
-
-            int count = start_list(&cursor, &buffer);
-            int result;
-
-            if (count < 3)
-                break;
-
-            result = traverse_field(&cursor, &buffer, 0); // message_id
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, &content->field_user_id);
// user_id
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, &content->field_to);
// to
-            if (!result) return 0;
-        }
-        break;
+    case QD_FIELD_HEADER:
+        return &content->section_message_properties;
+    default:
+        // TBD: add header fields as needed (see qd_message_properties_field()
+        // as an example)
+        assert(false);
+        return 0;
+    }
+}
 
-    case QD_FIELD_REPLY_TO:
-        while (1) {
-            if (content->field_reply_to.parsed)
-                return &content->field_reply_to;
-
-            if (content->section_message_properties.parsed == 0)
-                break;
-
-            qd_buffer_t   *buffer = content->section_message_properties.buffer;
-            unsigned char *cursor = qd_buffer_base(buffer) + content->section_message_properties.offset;
-            advance(&cursor, &buffer, content->section_message_properties.hdr_length,
0, 0);
-
-            int count = start_list(&cursor, &buffer);
-            int result;
-
-            if (count < 5)
-                break;
-
-            result = traverse_field(&cursor, &buffer, 0); // message_id
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, &content->field_user_id);
// user_id
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, &content->field_to);
// to
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, 0); // subject
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, &content->field_reply_to);
// reply_to
-            if (!result) return 0;
-        }
-        break;
 
-    case QD_FIELD_CORRELATION_ID:
-        while (1) {
-            if (content->field_correlation_id.parsed)
-                return &content->field_correlation_id;
-
-            if (content->section_message_properties.parsed == 0)
-                break;
-
-            qd_buffer_t   *buffer = content->section_message_properties.buffer;
-            unsigned char *cursor = qd_buffer_base(buffer) + content->section_message_properties.offset;
-            advance(&cursor, &buffer, content->section_message_properties.hdr_length,
0, 0);
-
-            int count = start_list(&cursor, &buffer);
-            int result;
-
-            if (count < 6)
-                break;
-
-            result = traverse_field(&cursor, &buffer, 0); // message_id
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, &content->field_user_id);
// user_id
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, &content->field_to);
// to
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, 0); // subject
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, &content->field_reply_to);
// reply_to
-            if (!result) return 0;
-            result = traverse_field(&cursor, &buffer, &content->field_correlation_id);
// correlation_id
-            if (!result) return 0;
-        }
-        break;
+// Get the field's location in the buffer.  Return 0 if the field does not exist.
+// Note that even if the field location is returned, it may contain a
+// QD_AMQP_NULL value (qd_field_location->tag == QD_AMQP_NULL).
+//
+static qd_field_location_t *qd_message_field_location(qd_message_t *msg, qd_message_field_t
field)
+{
+    qd_message_content_t *content = MSG_CONTENT(msg);
+    qd_message_field_t section = qd_field_section(field);
+
+    switch (section) {
+    case QD_FIELD_HEADER:
+        return qd_message_header_field(msg, field);
+
+    case QD_FIELD_PROPERTIES:
+        return qd_message_properties_field(msg, field);
 
     case QD_FIELD_DELIVERY_ANNOTATION:
-        if (content->section_delivery_annotation.parsed)
+        if (content->section_delivery_annotation.parsed ||
+            (qd_message_check(msg, QD_DEPTH_DELIVERY_ANNOTATIONS) && content->section_delivery_annotation.parsed))
             return &content->section_delivery_annotation;
         break;
 
     case QD_FIELD_MESSAGE_ANNOTATION:
-        if (content->section_message_annotation.parsed)
+        if (content->section_message_annotation.parsed ||
+            (qd_message_check(msg, QD_DEPTH_MESSAGE_ANNOTATIONS) && content->section_message_annotation.parsed))
             return &content->section_message_annotation;
         break;
 
     case QD_FIELD_APPLICATION_PROPERTIES:
-        if (content->section_application_properties.parsed)
+        if (content->section_application_properties.parsed ||
+            (qd_message_check(msg, QD_DEPTH_APPLICATION_PROPERTIES) && content->section_application_properties.parsed))
             return &content->section_application_properties;
         break;
 
     case QD_FIELD_BODY:
-        if (content->section_body.parsed)
+        if (content->section_body.parsed ||
+            (qd_message_check(msg, QD_DEPTH_BODY) && content->section_body.parsed))
             return &content->section_body;
         break;
 
-    default:
+    case QD_FIELD_FOOTER:
+        if (content->section_footer.parsed ||
+            (qd_message_check(msg, QD_DEPTH_ALL) && content->section_footer.parsed))
+            return &content->section_footer;
         break;
+
+    default:
+        assert(false); // TBD: add support as needed
+        return 0;
     }
 
     return 0;
@@ -1051,3 +1102,4 @@ void qd_message_compose_3(qd_message_t *
         buf = DEQ_HEAD(*field2_buffers);
     }
 }
+

Modified: qpid/dispatch/trunk/src/message_private.h
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/message_private.h?rev=1657961&r1=1657960&r2=1657961&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/message_private.h (original)
+++ qpid/dispatch/trunk/src/message_private.h Fri Feb  6 20:58:41 2015
@@ -80,8 +80,10 @@ typedef struct {
     qd_field_location_t  section_application_properties;  // The application properties list
     qd_field_location_t  section_body;                    // The message body: Data
     qd_field_location_t  section_footer;                  // The footer
+    qd_field_location_t  field_message_id;                // The string value of the message-id
     qd_field_location_t  field_user_id;                   // The string value of the user-id
     qd_field_location_t  field_to;                        // The string value of the to field
+    qd_field_location_t  field_subject;                   // The string value of the subject
field
     qd_field_location_t  field_reply_to;                  // The string value of the reply_to
field
     qd_field_location_t  field_correlation_id;            // The string value of the correlation_id
field
     qd_field_location_t  body;                            // The body of the message

Modified: qpid/dispatch/trunk/tests/message_test.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/message_test.c?rev=1657961&r1=1657960&r2=1657961&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/message_test.c (original)
+++ qpid/dispatch/trunk/tests/message_test.c Fri Feb  6 20:58:41 2015
@@ -125,10 +125,20 @@ static char* test_receive_from_messenger
 }
 
 
-static char* test_insufficient_check_depth(void *context)
+// load a few interesting message properties and validate
+static char* test_message_properties(void *context)
 {
+    pn_atom_t id = {.type = PN_STRING,
+                    .u.as_bytes.start = "messageId",
+                    .u.as_bytes.size = 9};
+    pn_atom_t cid = {.type = PN_STRING,
+                     .u.as_bytes.start = "correlationId",
+                     .u.as_bytes.size = 13};
+    const char *subject = "A Subject";
     pn_message_t *pn_msg = pn_message();
-    pn_message_set_address(pn_msg, "test_addr_2");
+    pn_message_set_id(pn_msg, id);
+    pn_message_set_subject(pn_msg, subject);
+    pn_message_set_correlation_id(pn_msg, cid);
 
     size_t       size = 10000;
     int result = pn_message_encode(pn_msg, buffer, &size);
@@ -139,10 +149,24 @@ static char* test_insufficient_check_dep
 
     set_content(content, size);
 
-    int valid = qd_message_check(msg, QD_DEPTH_DELIVERY_ANNOTATIONS);
-    if (!valid) return "qd_message_check returns 'invalid'";
+    qd_field_iterator_t *iter = qd_message_field_iterator(msg, QD_FIELD_CORRELATION_ID);
+    if (!iter) return "Expected iterator for the 'correlation-id' field";
+    if (qd_field_iterator_length(iter) != 13) return "Bad length for correlation-id";
+    if (!qd_field_iterator_equal(iter, (const unsigned char *)"correlationId"))
+        return "Invalid correlation-id";
+
+    iter = qd_message_field_iterator(msg, QD_FIELD_SUBJECT);
+    if (!iter) return "Expected iterator for the 'subject' field";
+    if (!qd_field_iterator_equal(iter, (const unsigned char *)subject))
+        return "Bad value for subject";
+
+    iter = qd_message_field_iterator(msg, QD_FIELD_MESSAGE_ID);
+    if (!iter) return "Expected iterator for the 'message-id' field";
+    if (qd_field_iterator_length(iter) != 9) return "Bad length for message-id";
+    if (!qd_field_iterator_equal(iter, (const unsigned char *)"messageId"))
+        return "Invalid message-id";
 
-    qd_field_iterator_t *iter = qd_message_field_iterator(msg, QD_FIELD_TO);
+    iter = qd_message_field_iterator(msg, QD_FIELD_TO);
     if (iter) return "Expected no iterator for the 'to' field";
 
     qd_message_free(msg);
@@ -186,7 +210,7 @@ int message_tests(void)
 
     TEST_CASE(test_send_to_messenger, 0);
     TEST_CASE(test_receive_from_messenger, 0);
-    TEST_CASE(test_insufficient_check_depth, 0);
+    TEST_CASE(test_message_properties, 0);
     TEST_CASE(test_check_multiple, 0);
 
     return result;



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


Mime
View raw message