You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2016/11/23 13:56:46 UTC
[3/3] qpid-dispatch git commit: DISPATCH-568 - Cleanup of the
iterator module - Renamed type and methods to qd_iterator_* (removed
field/address hierarchy) - Organized the header/API around lifecycle, usage,
annotation, and hashing - Added namespac
DISPATCH-568 - Cleanup of the iterator module
- Renamed type and methods to qd_iterator_* (removed field/address hierarchy)
- Organized the header/API around lifecycle, usage, annotation, and hashing
- Added namespace support
- Added tests
- Moved the parse tests into the buffer-size-specific unit test set
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/6a783b07
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/6a783b07
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/6a783b07
Branch: refs/heads/master
Commit: 6a783b07fab75e92f0b0e2db86f6a9cec388d44b
Parents: 456f618
Author: Ted Ross <tr...@redhat.com>
Authored: Wed Nov 23 08:50:47 2016 -0500
Committer: Ted Ross <tr...@redhat.com>
Committed: Wed Nov 23 08:50:47 2016 -0500
----------------------------------------------------------------------
include/qpid/dispatch/compose.h | 4 +-
include/qpid/dispatch/hash.h | 14 +-
include/qpid/dispatch/iterator.h | 300 ++++++++-----
include/qpid/dispatch/message.h | 4 +-
include/qpid/dispatch/parse.h | 8 +-
include/qpid/dispatch/router.h | 8 +-
include/qpid/dispatch/router_core.h | 18 +-
src/compose.c | 20 +-
src/container.c | 65 +--
src/hash.c | 40 +-
src/iterator.c | 588 +++++++++++++------------
src/message.c | 28 +-
src/parse.c | 122 ++---
src/python_embedded.c | 22 +-
src/router_config.c | 40 +-
src/router_core/agent.c | 44 +-
src/router_core/agent_address.c | 10 +-
src/router_core/agent_address.h | 6 +-
src/router_core/agent_config_address.c | 52 +--
src/router_core/agent_config_address.h | 16 +-
src/router_core/agent_config_auto_link.c | 42 +-
src/router_core/agent_config_auto_link.h | 16 +-
src/router_core/agent_config_link_route.c | 46 +-
src/router_core/agent_config_link_route.h | 16 +-
src/router_core/agent_link.c | 22 +-
src/router_core/agent_link.h | 4 +-
src/router_core/connections.c | 38 +-
src/router_core/error.c | 8 +-
src/router_core/forwarder.c | 8 +-
src/router_core/management_agent.c | 72 +--
src/router_core/route_control.c | 32 +-
src/router_core/route_control.h | 4 +-
src/router_core/route_tables.c | 24 +-
src/router_core/router_core.c | 30 +-
src/router_core/router_core_private.h | 16 +-
src/router_core/terminus.c | 10 +-
src/router_core/transfer.c | 10 +-
src/router_node.c | 48 +-
src/trace_mask.c | 8 +-
tests/CMakeLists.txt | 2 +-
tests/field_test.c | 456 ++++++++++++-------
tests/message_test.c | 26 +-
tests/parse_test.c | 99 ++++-
tests/run_unit_tests.c | 2 -
tests/run_unit_tests_size.c | 2 +
45 files changed, 1376 insertions(+), 1074 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/compose.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/compose.h b/include/qpid/dispatch/compose.h
index 956900c..00d505e 100644
--- a/include/qpid/dispatch/compose.h
+++ b/include/qpid/dispatch/compose.h
@@ -190,7 +190,7 @@ void qd_compose_insert_string(qd_composed_field_t *field, const char *value);
* @param iter An iterator for a string value. The caller is responsible for freeing
* this iterator after the call is complete.
*/
-void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_field_iterator_t *iter);
+void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_iterator_t *iter);
/**
* Insert a symbol into the field.
@@ -207,7 +207,7 @@ void qd_compose_insert_symbol(qd_composed_field_t *field, const char *value);
* @param iter An iterator for a typed value. The caller is responsible for freeing
* this iterator after the call is complete.
*/
-void qd_compose_insert_typed_iterator(qd_composed_field_t *field, qd_field_iterator_t *iter);
+void qd_compose_insert_typed_iterator(qd_composed_field_t *field, qd_iterator_t *iter);
/**
* Begin composing a new sub field that can be appended to a composed field.
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/hash.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/hash.h b/include/qpid/dispatch/hash.h
index aaedc0b..7b9b3ec 100644
--- a/include/qpid/dispatch/hash.h
+++ b/include/qpid/dispatch/hash.h
@@ -34,11 +34,11 @@ qd_hash_t *qd_hash(int bucket_exponent, int batch_size, int value_is_const);
void qd_hash_free(qd_hash_t *h);
size_t qd_hash_size(qd_hash_t *h);
-qd_error_t qd_hash_insert(qd_hash_t *h, qd_field_iterator_t *key, void *val, qd_hash_handle_t **handle);
-qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_field_iterator_t *key, const void *val, qd_hash_handle_t **handle);
-qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_field_iterator_t *key, void **val);
-qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_field_iterator_t *key, const void **val);
-qd_error_t qd_hash_remove(qd_hash_t *h, qd_field_iterator_t *key);
+qd_error_t qd_hash_insert(qd_hash_t *h, qd_iterator_t *key, void *val, qd_hash_handle_t **handle);
+qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_iterator_t *key, const void *val, qd_hash_handle_t **handle);
+qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_iterator_t *key, void **val);
+qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_iterator_t *key, const void **val);
+qd_error_t qd_hash_remove(qd_hash_t *h, qd_iterator_t *key);
void qd_hash_handle_free(qd_hash_handle_t *handle);
const unsigned char *qd_hash_key_by_handle(const qd_hash_handle_t *handle);
@@ -57,12 +57,12 @@ qd_error_t qd_hash_remove_by_handle2(qd_hash_t *h, qd_hash_handle_t *handle, uns
* @param iter An iterator containing the address string to search on.
* @param **val The qd_address_t value if there is a full or prefix match.
*/
-void qd_hash_retrieve_prefix(qd_hash_t *h, qd_field_iterator_t *iter, void **val);
+void qd_hash_retrieve_prefix(qd_hash_t *h, qd_iterator_t *iter, void **val);
/**
* Same as qd_hash_retrieve_prefix but returns the value as a constant which cannot be modified.
* @see qd_hash_retrieve_prefix
*/
-void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_field_iterator_t *iter, const void **val);
+void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_iterator_t *iter, const void **val);
#endif
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/iterator.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/iterator.h b/include/qpid/dispatch/iterator.h
index b2669ef..ad7b7f9 100644
--- a/include/qpid/dispatch/iterator.h
+++ b/include/qpid/dispatch/iterator.h
@@ -24,9 +24,9 @@
#include <qpid/dispatch/buffer.h>
#include <qpid/dispatch/iovec.h>
+
/**@file
- * Iterate over message buffer chains and addresse fields.
- *
+ * Iterate over message buffer chains and address fields.
*
* @defgroup iterator iterator
*
@@ -38,34 +38,30 @@
*
* @{
*/
-typedef struct qd_field_iterator_t qd_field_iterator_t;
+
+/** \name typedef
+ * Type Definitions
+ * @{
+ */
+typedef struct qd_iterator_t qd_iterator_t;
+
/**
+ * qd_iterator_view_t
+ *
* Type of iterator view. Iterator views allow the code traversing an address
* field to see a transformed view of the raw field.
*
* ITER_VIEW_ALL - No transformation of the raw field data
*
- * ITER_VIEW_NO_HOST - Remove the scheme and host fields from the view
- *
- * amqp://host.domain.com:port/node-id/node/specific
- * ^^^^^^^^^^^^^^^^^^^^^
- * node-id/node/specific
- * ^^^^^^^^^^^^^^^^^^^^^
- *
- * ITER_VIEW_NODE_ID - Isolate the node identifier from an address
- *
- * amqp://host.domain.com:port/node-id/node/specific
- * ^^^^^^^
- * node-id/node/specific
- * ^^^^^^^
- *
- * ITER_VIEW_NODE_SPECIFIC - Isolate node-specific text from an address
+ * ITER_VIEW_ADDRESS_NO_HOST - Remove the scheme and host fields from the view
*
- * amqp://host.domain.com:port/node-id/node/specific
- * ^^^^^^^^^^^^^
- * node-id/node/specific
- * ^^^^^^^^^^^^^
+ * amqp://host.domain.com:port/other/address/text
+ * ^^^^^^^^^^^^^^^^^^
+ * amqp:/other/address/text
+ * ^^^^^^^^^^^^^^^^^^
+ * other/address/text
+ * ^^^^^^^^^^^^^^^^^^
*
* ITER_VIEW_ADDRESS_HASH - Isolate the hashable part of the address depending on address syntax
*
@@ -97,118 +93,150 @@ typedef struct qd_field_iterator_t qd_field_iterator_t;
*/
typedef enum {
ITER_VIEW_ALL,
- ITER_VIEW_NO_HOST,
- ITER_VIEW_NODE_ID,
- ITER_VIEW_NODE_SPECIFIC,
+ ITER_VIEW_ADDRESS_NO_HOST,
ITER_VIEW_ADDRESS_HASH,
ITER_VIEW_NODE_HASH
} qd_iterator_view_t;
+/** @} */
+/** \name global
+ * Global Methods
+ * @{
+ */
/**
- * Create an iterator from a null-terminated string.
+ * Set the area and router names for the local router. These are used to match
+ * my-area and my-router in address fields. These settings are global and used
+ * for all iterators in the process.
*
- * The "text" string must stay intact for the whole life of the iterator. The iterator
- * does not copy the string, it references it.
+ * @param area The name of the router's area
+ * @param router The identifier of the router in the area
*/
-qd_field_iterator_t* qd_address_iterator_string(const char *text,
- qd_iterator_view_t view);
+void qd_iterator_set_address(const char *area, const char *router);
-static inline qd_field_iterator_t* qd_field_iterator_string(const char *text)
-{
- return qd_address_iterator_string(text, ITER_VIEW_ALL);
-}
+/** @} */
+/** \name lifecycle
+ * Methods to control iterator lifecycle
+ * @{
+ */
+/**
+ * Create an iterator for a null-terminated string.
+ *
+ * The "text" string must stay intact for the whole life of the iterator. The iterator
+ * does not copy the string, it references it.
+ *
+ * @param text A null-terminated character string
+ * @param view The view for the iterator
+ * @return A newly allocated iterator that references the text string.
+ */
+qd_iterator_t* qd_iterator_string(const char *text,
+ qd_iterator_view_t view);
/**
* Create an iterator from binary data.
*
* The "text" string must stay intact for the whole life of the iterator. The iterator
* does not copy the data, it references it.
+ *
+ * @param text Pointer to the first octet in an octet string
+ * @param length Number of octets in the contiguous octet string
+ * @param view The view for the iterator
+ * @return A newly allocated iterator that references the octet string.
*/
-qd_field_iterator_t* qd_address_iterator_binary(const char *text,
- int length,
- qd_iterator_view_t view);
-static inline qd_field_iterator_t *qd_field_iterator_binary(const char *text,
- int length)
-{
- return qd_address_iterator_binary(text, length, ITER_VIEW_ALL);
-}
-
+qd_iterator_t* qd_iterator_binary(const char *text,
+ int length,
+ qd_iterator_view_t view);
/**
* Create an iterator from a field in a buffer chain
-
+ *
* The buffer chain must stay intact for the whole life of the iterator. The iterator
* does not copy the buffer, it references it.
+ *
+ * @param buffer Pointer to the first buffer in the buffer chain
+ * @param offset The offset in the first buffer where the first octet of the field is
+ * @param length Number of octets in the field
+ * @param view The view for the iterator
+ * @return A newly allocated iterator that references the field.
*/
-qd_field_iterator_t *qd_address_iterator_buffer(qd_buffer_t *buffer,
- int offset,
- int length,
- qd_iterator_view_t view);
-static inline qd_field_iterator_t *qd_field_iterator_buffer(qd_buffer_t *buffer,
- int offset,
- int length)
-{
- return qd_address_iterator_buffer(buffer, offset, length, ITER_VIEW_ALL);
-}
+qd_iterator_t *qd_iterator_buffer(qd_buffer_t *buffer,
+ int offset,
+ int length,
+ qd_iterator_view_t view);
/**
- * Free an iterator
+ * Free an allocated iterator
+ *
+ * @param iter An allocated iterator that is no longer to be used
*/
-void qd_field_iterator_free(qd_field_iterator_t *iter);
+void qd_iterator_free(qd_iterator_t *iter);
-/**
- * Set the area and router names for the local router. These are used to match
- * my-area and my-router in address fields.
+
+/** @} */
+/** \name normal
+ * Methods to manipulate and traverse an iterator
+ * @{
*/
-void qd_field_iterator_set_address(const char *area, const char *router);
/**
- * Reset the iterator to the first octet and set a new view
+ * Reset the iterator to the first octet.
+ *
+ * @param iter Pointer to an iterator to be reset
*/
-void qd_field_iterator_reset(qd_field_iterator_t *iter);
-
-void qd_address_iterator_reset_view(qd_field_iterator_t *iter,
- qd_iterator_view_t view);
-qd_iterator_view_t qd_address_iterator_get_view(const qd_field_iterator_t *iter);
+void qd_iterator_reset(qd_iterator_t *iter);
-void qd_address_iterator_set_phase(qd_field_iterator_t *iter, char phase);
+/**
+ * Reset the iterator and set the view. If the iterator was trimmed, clear the trim state.
+ *
+ * @param iter Pointer to an iterator to be reset
+ * @param view The new view for the iterator
+ */
+void qd_iterator_reset_view(qd_iterator_t *iter,
+ qd_iterator_view_t view);
/**
- * Override the hash-prefix with a custom character.
+ * Return the view for the iterator
+ *
+ * @param iter Pointer to an iterator
+ * @return The view for the iterator
*/
-void qd_address_iterator_override_prefix(qd_field_iterator_t *iter, char prefix);
+qd_iterator_view_t qd_iterator_get_view(const qd_iterator_t *iter);
/**
- * Trims octets from the end of the iterator's field by reducing the length of the iterator.
+ * Trims octets from both ends of the iterator's view by reducing the length of the view and by
+ * resetting the base of the view to the current location.
+ *
+ * Note that an iterator may be repeatedly trimmed, but the trimming must always reduce
+ * the size of the view. Trimming will never increase the size of the view. To re-trim
+ * with a bigger size, qd_iterator_reset_view must be called to clear the trimmed state.
*
- * @param iter - the iterator whose length should be trimmed
- * @param length - the length of the trimmed field. If greater than or equal to the current length,
- * then there shall be no effect.
+ * @param iter The iterator whose length should be trimmed
+ * @param length The length of the trimmed field. If greater than or equal to the current length,
+ * then there shall be no effect.
*/
-void qd_field_iterator_trim(qd_field_iterator_t *iter, int length);
+void qd_iterator_trim_view(qd_iterator_t *iter, int length);
/**
* Return the current octet in the iterator's view and step to the next.
*/
-unsigned char qd_field_iterator_octet(qd_field_iterator_t *iter);
+unsigned char qd_iterator_octet(qd_iterator_t *iter);
/**
* Return true iff the iterator has no more octets in the view.
*/
-int qd_field_iterator_end(const qd_field_iterator_t *iter);
+bool qd_iterator_end(const qd_iterator_t *iter);
/**
* Return a sub-iterator that equals the supplied iterator except that it
* starts at the supplied iterator's current position.
*/
-qd_field_iterator_t *qd_field_iterator_sub(const qd_field_iterator_t *iter, uint32_t length);
+qd_iterator_t *qd_iterator_sub(const qd_iterator_t *iter, uint32_t length);
/**
* Move the iterator's cursor forward up to length bytes
*/
-void qd_field_iterator_advance(qd_field_iterator_t *iter, uint32_t length);
+void qd_iterator_advance(qd_iterator_t *iter, uint32_t length);
/**
* Return the remaining length (in octets) for the iterator.
@@ -220,12 +248,17 @@ void qd_field_iterator_advance(qd_field_iterator_t *iter, uint32_t length);
* @param iter A field iterator
* @return The number of octets remaining in the view (or more)
*/
-uint32_t qd_field_iterator_remaining(const qd_field_iterator_t *iter);
+uint32_t qd_iterator_remaining(const qd_iterator_t *iter);
+
+/**
+ * Return the exact length of the iterator's view.
+ */
+int qd_iterator_length(const qd_iterator_t *iter);
/**
* Compare an input string to the iterator's view. Return true iff they are equal.
*/
-int qd_field_iterator_equal(qd_field_iterator_t *iter, const unsigned char *string);
+bool qd_iterator_equal(qd_iterator_t *iter, const unsigned char *string);
/**
* Return true iff the string matches the characters at the current location in the view.
@@ -233,26 +266,21 @@ int qd_field_iterator_equal(qd_field_iterator_t *iter, const unsigned char *stri
* This function does not alter the position of the iterator if the prefix does not match,
* if it matches, the prefix is consumed.
*/
-int qd_field_iterator_prefix(qd_field_iterator_t *iter, const char *prefix);
-
-/**
- * Return the exact length of the iterator's view.
- */
-int qd_field_iterator_length(const qd_field_iterator_t *iter);
+bool qd_iterator_prefix(qd_iterator_t *iter, const char *prefix);
/**
* Copy the iterator's view into buffer up to a maximum of n bytes. Cursor is
* advanced by the number of bytes copied. There is no trailing '\0' added.
* @return number of bytes copied.
*/
-int qd_field_iterator_ncopy(qd_field_iterator_t *iter, unsigned char* buffer, int n);
+int qd_iterator_ncopy(qd_iterator_t *iter, unsigned char* buffer, int n);
/**
* Return a new copy of the iterator's view, with a trailing '\0' added. The
* cursor is advanced to the end of the view.
* @return Copy of the view, free with free()
*/
-unsigned char *qd_field_iterator_copy(qd_field_iterator_t *iter);
+unsigned char *qd_iterator_copy(qd_iterator_t *iter);
/**
* Return a new iterator that is a duplicate of the original iterator, referring
@@ -261,7 +289,7 @@ unsigned char *qd_field_iterator_copy(qd_field_iterator_t *iter);
* @param iter Input iterator
* @return Pointer to a new, identical iterator referring to the same data.
*/
-qd_field_iterator_t *qd_field_iterator_dup(const qd_field_iterator_t *iter);
+qd_iterator_t *qd_iterator_dup(const qd_iterator_t *iter);
/**
* Copy the iterator's view into buffer as a null terminated string,
@@ -269,7 +297,7 @@ qd_field_iterator_t *qd_field_iterator_dup(const qd_field_iterator_t *iter);
* copied. Useful for log messages.
* @return buffer.
*/
-char* qd_field_iterator_strncpy(qd_field_iterator_t *iter, char* buffer, int n);
+char* qd_iterator_strncpy(qd_iterator_t *iter, char* buffer, int n);
/**
* Return the contents of this iter into an iovec structure. This is used in a
@@ -279,48 +307,92 @@ char* qd_field_iterator_strncpy(qd_field_iterator_t *iter, char* buffer, int n);
* @param iter A field iterator
* @return An iovec structure that references the data in the iterator's buffers.
*/
-qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter);
+qd_iovec_t *qd_iterator_iovec(const qd_iterator_t *iter);
+
+
+/** @} */
+/** \name annotation
+ * Methods to modify the view annotations of an iterator
+ * @{
+ */
+
+/**
+ * Set the phase character to annotate a mobile address view.
+ *
+ * @param iter Pointer to an iterator
+ * @param phase A character used to annotate a mobile address view
+ */
+void qd_iterator_annotate_phase(qd_iterator_t *iter, char phase);
/**
- * Steps through the iterator hashing each octet and also trying to find a separator. The separator is hardcoded to be a '/'.
- * It stores the hash of each segment as a node (qd_hash_segment_t) in the linked list qd_hash_segment_list_t of the iterator.
- * The linked list contains as many nodes as there are segments.
+ * Override the prefix character for a mobile address view.
*
- * +------------------------+
- * | |
- * | qd_hash_segment_list_t |----------->+
- * | | |
- * +------------------------+ | "policy" "policy/org" "policy/org/apache"
- * | +-------------------+ +-------------------+ +-------------------+
- * +--->| qd_hash_segment_t |-->| qd_hash_segment_t |-->| qd_hash_segment_t |--/
- * +-------------------+ +-------------------+ +-------------------+
+ * @param iter Pointer to an iterator
+ * @param prefix A character to use as the prefix of a mobile address view
+ */
+void qd_iterator_annotate_prefix(qd_iterator_t *iter, char prefix);
+
+/**
+ * Annotate a mobile address view with a tenant namespace.
*
- * In the above example the first qd_hash_segment_t stores the hash of the string "policy" and the next qd_hash_segment_t contains \
- * the hash to "policy/org" and so on. The purpose of doing this is to pre-generate the hash and hash length and store
- * it so matches can be quickly made.
+ * Note that the space string is not copied into the iterator. It must remain in-place
+ * and unchanged for the lifetime of the iterator.
*
+ * @param iter Pointer to an iterator
+ * @param space Pointer to the first character of a character string representing a namespace
+ * @param space_len The number of characters in the space string
+ */
+void qd_iterator_annotate_space(qd_iterator_t *iter, const char* space, int space_len);
+
+
+/** @} */
+/** \name hash
+ * Methods to calculate hash values for iterator views
*
- * @param iter An address iterator
+ * All hashing functions use the djb2 algorithm (http://www.cse.yorku.ca/~oz/hash.html).
+ * @{
*/
-void qd_iterator_hash_segments(qd_field_iterator_t *iter);
/**
- * Populates the passed in hash with the hash from the tail hash segment and deletes and frees it.
- * This hash can be further used arrive at the hash bucket.
- * Returns false if it cannot find anymore tail hash_segments, true otherwise.
+ * Generate the hash of the view of the iterator.
*
* @param iter A field iterator
+ * @return The hash value of the iterator's view
+ */
+uint32_t qd_iterator_hash_view(qd_iterator_t *iter);
+
+/**
+ * Generate a series of hash values for a segmented view. For example, consider the following view:
+ *
+ * "M0policy/org.apache.qpid"
+ *
+ * The hash values computed will be for the following strings:
+ *
+ * "M0policy/org.apache.qpid"
+ * "M0policy/org.apache"
+ * "M0policy/org"
+ * "M0policy"
+ *
+ * These hash values and the sub-views associated with them shall be stored in the iterator.
+ *
+ * @param iter An address iterator
*/
-bool qd_iterator_hash_and_reset(qd_field_iterator_t *iter, uint32_t *hash);
+void qd_iterator_hash_view_segments(qd_iterator_t *iter);
/**
- * Generates and returns a hash of the contents of the iterator by stepping through the iterator octet by octet.
- * Uses the djb2 algorithm for hashing - can be found at http://www.cse.yorku.ca/~oz/hash.html
+ * Iterate over the segment hash values pre-computed using qd_iterator_hash_view_segments.
+ *
+ * This function returns the longest remaining segment hash, removes the hash from the set of
+ * stored segment values, and adjusts the view so that it includes only the subset of the view
+ * associated with the hash value.
*
* @param iter A field iterator
+ * @param hash (output) Hash value for the next segment
+ * @return True iff there is another segment hash to be compared
*/
-uint32_t qd_iterator_hash_function(qd_field_iterator_t *iter);
+bool qd_iterator_next_segment(qd_iterator_t *iter, uint32_t *hash);
/** @} */
+/** @} */
#endif
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/message.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/message.h b/include/qpid/dispatch/message.h
index 66601ba..b60f118 100644
--- a/include/qpid/dispatch/message.h
+++ b/include/qpid/dispatch/message.h
@@ -233,8 +233,8 @@ int qd_message_check(qd_message_t *msg, qd_message_depth_t depth);
* @param field The field to be returned via iterator.
* @return A field iterator that spans the requested field.
*/
-qd_field_iterator_t *qd_message_field_iterator_typed(qd_message_t *msg, qd_message_field_t field);
-qd_field_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_field_t field);
+qd_iterator_t *qd_message_field_iterator_typed(qd_message_t *msg, qd_message_field_t field);
+qd_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_field_t field);
ssize_t qd_message_field_length(qd_message_t *msg, qd_message_field_t field);
ssize_t qd_message_field_copy(qd_message_t *msg, qd_message_field_t field, void *buffer, size_t *hdr_length);
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/parse.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/parse.h b/include/qpid/dispatch/parse.h
index d4fdf42..454e99f 100644
--- a/include/qpid/dispatch/parse.h
+++ b/include/qpid/dispatch/parse.h
@@ -27,7 +27,7 @@
*
* @defgroup parse parse
*
- * Parse data from qd_field_iterator_t into a tree structure represeniting
+ * Parse data from qd_iterator_t into a tree structure represeniting
* an AMQP data type tree.
*@{
*/
@@ -40,7 +40,7 @@ typedef struct qd_parsed_field_t qd_parsed_field_t;
* @param iter Field iterator for the field being parsed
* @return A pointer to the newly created field.
*/
-qd_parsed_field_t *qd_parse(qd_field_iterator_t *iter);
+qd_parsed_field_t *qd_parse(qd_iterator_t *iter);
/**
* Free the resources associated with a parsed field.
@@ -97,7 +97,7 @@ uint8_t qd_parse_tag(qd_parsed_field_t *field);
* @param field The field pointer returned by qd_parse.
* @return A field iterator that describes the field's raw content.
*/
-qd_field_iterator_t *qd_parse_raw(qd_parsed_field_t *field);
+qd_iterator_t *qd_parse_raw(qd_parsed_field_t *field);
/**
@@ -109,7 +109,7 @@ qd_field_iterator_t *qd_parse_raw(qd_parsed_field_t *field);
* @param field The field pointer returned by qd_parse.
* @return A field iterator that describes the field's typed content.
*/
-qd_field_iterator_t *qd_parse_typed(qd_parsed_field_t *field);
+qd_iterator_t *qd_parse_typed(qd_parsed_field_t *field);
/**
* Return the raw content as an unsigned integer up to 32-bits. This is
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/router.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/router.h b/include/qpid/dispatch/router.h
index f050775..86e6e6d 100644
--- a/include/qpid/dispatch/router.h
+++ b/include/qpid/dispatch/router.h
@@ -73,7 +73,7 @@ struct qd_router_forwarder_t {
qd_message_t *msg,
qd_router_delivery_t *delivery,
qd_address_t *addr,
- qd_field_iterator_t *ingress_iterator,
+ qd_iterator_t *ingress_iterator,
bool is_direct);
/** release the descriptor
@@ -119,9 +119,9 @@ void qd_address_set_static_cc(qd_address_t *address, qd_address_t *cc);
void qd_address_set_dynamic_cc(qd_address_t *address, qd_address_t *cc);
/** Send msg to local links and next-hops for address */
-void qd_router_send(qd_dispatch_t *qd,
- qd_field_iterator_t *address,
- qd_message_t *msg);
+void qd_router_send(qd_dispatch_t *qd,
+ qd_iterator_t *address,
+ qd_message_t *msg);
/** Send msg to local links and next-hops for address */
void qd_router_send2(qd_dispatch_t *qd,
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/include/qpid/dispatch/router_core.h
----------------------------------------------------------------------
diff --git a/include/qpid/dispatch/router_core.h b/include/qpid/dispatch/router_core.h
index 9421481..b3f293b 100644
--- a/include/qpid/dispatch/router_core.h
+++ b/include/qpid/dispatch/router_core.h
@@ -115,7 +115,7 @@ void qdr_core_unsubscribe(qdr_subscription_t *sub);
* @param exclude_inprocess If true, the message will not be sent to in-process subscribers.
* @param control If true, this message is to be treated as control traffic and flow on a control link.
*/
-void qdr_send_to1(qdr_core_t *core, qd_message_t *msg, qd_field_iterator_t *addr,
+void qdr_send_to1(qdr_core_t *core, qd_message_t *msg, qd_iterator_t *addr,
bool exclude_inprocess, bool control);
void qdr_send_to2(qdr_core_t *core, qd_message_t *msg, const char *addr,
bool exclude_inprocess, bool control);
@@ -323,7 +323,7 @@ void qdr_terminus_set_address(qdr_terminus_t *term, const char *addr);
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @return A pointer to an iterator or 0 if the terminus is anonymous.
*/
-qd_field_iterator_t *qdr_terminus_get_address(qdr_terminus_t *term);
+qd_iterator_t *qdr_terminus_get_address(qdr_terminus_t *term);
/**
* qdr_terminus_dnp_address
@@ -334,7 +334,7 @@ qd_field_iterator_t *qdr_terminus_get_address(qdr_terminus_t *term);
* @param term A qdr_terminus pointer returned by qdr_terminus()
* @return A pointer to an iterator or 0 if there is no such field.
*/
-qd_field_iterator_t *qdr_terminus_dnp_address(qdr_terminus_t *term);
+qd_iterator_t *qdr_terminus_dnp_address(qdr_terminus_t *term);
/**
@@ -508,10 +508,10 @@ void qdr_link_detach(qdr_link_t *link, qd_detach_type_t dt, qdr_error_t *error);
* it built on the trace header from a received message.
* @return Pointer to the qdr_delivery that will track the lifecycle of this delivery on this link.
*/
-qdr_delivery_t *qdr_link_deliver(qdr_link_t *link, qd_message_t *msg, qd_field_iterator_t *ingress,
+qdr_delivery_t *qdr_link_deliver(qdr_link_t *link, qd_message_t *msg, qd_iterator_t *ingress,
bool settled, qd_bitmask_t *link_exclusion);
qdr_delivery_t *qdr_link_deliver_to(qdr_link_t *link, qd_message_t *msg,
- qd_field_iterator_t *ingress, qd_field_iterator_t *addr,
+ qd_iterator_t *ingress, qd_iterator_t *addr,
bool settled, qd_bitmask_t *link_exclusion);
qdr_delivery_t *qdr_link_deliver_to_routed_link(qdr_link_t *link, qd_message_t *msg, bool settled,
const uint8_t *tag, int tag_length);
@@ -594,7 +594,7 @@ typedef struct qdr_query_t qdr_query_t;
* @param out_body A composed field for the body of the response message
*/
void qdr_manage_create(qdr_core_t *core, void *context, qd_router_entity_type_t type,
- qd_field_iterator_t *name, qd_parsed_field_t *in_body, qd_composed_field_t *out_body);
+ qd_iterator_t *name, qd_parsed_field_t *in_body, qd_composed_field_t *out_body);
/**
* qdr_manage_delete
@@ -608,7 +608,7 @@ void qdr_manage_create(qdr_core_t *core, void *context, qd_router_entity_type_t
* @param identity The identity supplied with the request (or 0 if the name was supplied)
*/
void qdr_manage_delete(qdr_core_t *core, void *context, qd_router_entity_type_t type,
- qd_field_iterator_t *name, qd_field_iterator_t *identity);
+ qd_iterator_t *name, qd_iterator_t *identity);
/**
* qdr_manage_read
@@ -623,7 +623,7 @@ void qdr_manage_delete(qdr_core_t *core, void *context, qd_router_entity_type_t
* @param body A composed field for the body of the response message
*/
void qdr_manage_read(qdr_core_t *core, void *context, qd_router_entity_type_t type,
- qd_field_iterator_t *name, qd_field_iterator_t *identity, qd_composed_field_t *body);
+ qd_iterator_t *name, qd_iterator_t *identity, qd_composed_field_t *body);
/**
@@ -640,7 +640,7 @@ void qdr_manage_read(qdr_core_t *core, void *context, qd_router_entity_type_t ty
* @param out_body A composed field for the body of the response message
*/
void qdr_manage_update(qdr_core_t *core, void *context, qd_router_entity_type_t type,
- qd_field_iterator_t *name, qd_field_iterator_t *identity,
+ qd_iterator_t *name, qd_iterator_t *identity,
qd_parsed_field_t *in_body, qd_composed_field_t *out_body);
/**
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/compose.c
----------------------------------------------------------------------
diff --git a/src/compose.c b/src/compose.c
index df77f44..77b705d 100644
--- a/src/compose.c
+++ b/src/compose.c
@@ -432,17 +432,17 @@ void qd_compose_insert_string(qd_composed_field_t *field, const char *value)
}
-void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_field_iterator_t *iter)
+void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_iterator_t *iter)
{
uint32_t len = 0;
- qd_field_iterator_reset(iter);
- while (!qd_field_iterator_end(iter)) {
- qd_field_iterator_octet(iter);
+ qd_iterator_reset(iter);
+ while (!qd_iterator_end(iter)) {
+ qd_iterator_octet(iter);
len++;
}
- qd_field_iterator_reset(iter);
+ qd_iterator_reset(iter);
if (len < 256) {
qd_insert_8(field, QD_AMQP_STR8_UTF8);
qd_insert_8(field, (uint8_t) len);
@@ -451,8 +451,8 @@ void qd_compose_insert_string_iterator(qd_composed_field_t *field, qd_field_iter
qd_insert_32(field, len);
}
- while (!qd_field_iterator_end(iter)) {
- uint8_t octet = qd_field_iterator_octet(iter);
+ while (!qd_iterator_end(iter)) {
+ uint8_t octet = qd_iterator_octet(iter);
qd_insert_8(field, octet);
}
@@ -476,10 +476,10 @@ void qd_compose_insert_symbol(qd_composed_field_t *field, const char *value)
}
-void qd_compose_insert_typed_iterator(qd_composed_field_t *field, qd_field_iterator_t *iter)
+void qd_compose_insert_typed_iterator(qd_composed_field_t *field, qd_iterator_t *iter)
{
- while (!qd_field_iterator_end(iter)) {
- uint8_t octet = qd_field_iterator_octet(iter);
+ while (!qd_iterator_end(iter)) {
+ uint8_t octet = qd_iterator_octet(iter);
qd_insert_8(field, octet);
}
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/container.c
----------------------------------------------------------------------
diff --git a/src/container.c b/src/container.c
index 7abc3b2..9c0680b 100644
--- a/src/container.c
+++ b/src/container.c
@@ -85,29 +85,14 @@ struct qd_container_t {
static void setup_outgoing_link(qd_container_t *container, pn_link_t *pn_link)
{
- sys_mutex_lock(container->lock);
- qd_node_t *node = 0;
- const char *source = pn_terminus_get_address(pn_link_remote_source(pn_link));
- qd_field_iterator_t *iter;
- // TODO - Extract the name from the structured source
-
- if (source) {
- iter = qd_address_iterator_string(source, ITER_VIEW_NODE_ID);
- qd_hash_retrieve(container->node_map, iter, (void*) &node);
- qd_field_iterator_free(iter);
- }
- sys_mutex_unlock(container->lock);
+ qd_node_t *node = container->default_node;
if (node == 0) {
- if (container->default_node)
- node = container->default_node;
- else {
- pn_condition_t *cond = pn_link_condition(pn_link);
- pn_condition_set_name(cond, "amqp:not-found");
- pn_condition_set_description(cond, "Source node does not exist");
- pn_link_close(pn_link);
- return;
- }
+ pn_condition_t *cond = pn_link_condition(pn_link);
+ pn_condition_set_name(cond, "amqp:not-found");
+ pn_condition_set_description(cond, "Source node does not exist");
+ pn_link_close(pn_link);
+ return;
}
qd_link_t *link = new_qd_link_t();
@@ -136,28 +121,14 @@ static void setup_outgoing_link(qd_container_t *container, pn_link_t *pn_link)
static void setup_incoming_link(qd_container_t *container, pn_link_t *pn_link)
{
- sys_mutex_lock(container->lock);
- qd_node_t *node = 0;
- const char *target = pn_terminus_get_address(pn_link_remote_target(pn_link));
- qd_field_iterator_t *iter;
-
- if (target) {
- iter = qd_address_iterator_string(target, ITER_VIEW_NODE_ID);
- qd_hash_retrieve(container->node_map, iter, (void*) &node);
- qd_field_iterator_free(iter);
- }
- sys_mutex_unlock(container->lock);
+ qd_node_t *node = container->default_node;
if (node == 0) {
- if (container->default_node)
- node = container->default_node;
- else {
- pn_condition_t *cond = pn_link_condition(pn_link);
- pn_condition_set_name(cond, "amqp:not-found");
- pn_condition_set_description(cond, "Target node does not exist");
- pn_link_close(pn_link);
- return;
- }
+ pn_condition_t *cond = pn_link_condition(pn_link);
+ pn_condition_set_name(cond, "amqp:not-found");
+ pn_condition_set_description(cond, "Target node does not exist");
+ pn_link_close(pn_link);
+ return;
}
qd_link_t *link = new_qd_link_t();
@@ -615,7 +586,7 @@ int qd_container_register_node_type(qd_dispatch_t *qd, const qd_node_type_t *nt)
qd_container_t *container = qd->container;
int result;
- qd_field_iterator_t *iter = qd_field_iterator_string(nt->type_name);
+ qd_iterator_t *iter = qd_iterator_string(nt->type_name, ITER_VIEW_ALL);
qdc_node_type_t *nt_item = NEW(qdc_node_type_t);
DEQ_ITEM_INIT(nt_item);
nt_item->ntype = nt;
@@ -625,7 +596,7 @@ int qd_container_register_node_type(qd_dispatch_t *qd, const qd_node_type_t *nt)
DEQ_INSERT_TAIL(container->node_type_list, nt_item);
sys_mutex_unlock(container->lock);
- qd_field_iterator_free(iter);
+ qd_iterator_free(iter);
if (result < 0)
return result;
qd_log(container->log_source, QD_LOG_TRACE, "Node Type Registered - %s", nt->type_name);
@@ -678,13 +649,13 @@ qd_node_t *qd_container_create_node(qd_dispatch_t *qd,
node->life_policy = life_policy;
if (name) {
- qd_field_iterator_t *iter = qd_field_iterator_string(name);
+ qd_iterator_t *iter = qd_iterator_string(name, ITER_VIEW_ALL);
sys_mutex_lock(container->lock);
result = qd_hash_insert(container->node_map, iter, node, 0);
if (result >= 0)
DEQ_INSERT_HEAD(container->nodes, node);
sys_mutex_unlock(container->lock);
- qd_field_iterator_free(iter);
+ qd_iterator_free(iter);
if (result < 0) {
free_qd_node_t(node);
return 0;
@@ -706,12 +677,12 @@ void qd_container_destroy_node(qd_node_t *node)
qd_container_t *container = node->container;
if (node->name) {
- qd_field_iterator_t *iter = qd_field_iterator_string(node->name);
+ qd_iterator_t *iter = qd_iterator_string(node->name, ITER_VIEW_ALL);
sys_mutex_lock(container->lock);
qd_hash_remove(container->node_map, iter);
DEQ_REMOVE(container->nodes, node);
sys_mutex_unlock(container->lock);
- qd_field_iterator_free(iter);
+ qd_iterator_free(iter);
free(node->name);
}
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/hash.c
----------------------------------------------------------------------
diff --git a/src/hash.c b/src/hash.c
index b5471f0..8e27a23 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -111,13 +111,13 @@ size_t qd_hash_size(qd_hash_t *h)
}
-static qd_hash_item_t *qd_hash_internal_insert(qd_hash_t *h, qd_field_iterator_t *key, int *exists, qd_hash_handle_t **handle)
+static qd_hash_item_t *qd_hash_internal_insert(qd_hash_t *h, qd_iterator_t *key, int *exists, qd_hash_handle_t **handle)
{
- unsigned long idx = qd_iterator_hash_function(key) & h->bucket_mask;
+ unsigned long idx = qd_iterator_hash_view(key) & h->bucket_mask;
qd_hash_item_t *item = DEQ_HEAD(h->buckets[idx].items);
while (item) {
- if (qd_field_iterator_equal(key, item->key))
+ if (qd_iterator_equal(key, item->key))
break;
item = item->next;
}
@@ -134,7 +134,7 @@ static qd_hash_item_t *qd_hash_internal_insert(qd_hash_t *h, qd_field_iterator_t
return 0;
DEQ_ITEM_INIT(item);
- item->key = qd_field_iterator_copy(key);
+ item->key = qd_iterator_copy(key);
DEQ_INSERT_TAIL(h->buckets[idx].items, item);
h->size++;
@@ -153,7 +153,7 @@ static qd_hash_item_t *qd_hash_internal_insert(qd_hash_t *h, qd_field_iterator_t
}
-qd_error_t qd_hash_insert(qd_hash_t *h, qd_field_iterator_t *key, void *val, qd_hash_handle_t **handle)
+qd_error_t qd_hash_insert(qd_hash_t *h, qd_iterator_t *key, void *val, qd_hash_handle_t **handle)
{
int exists = 0;
qd_hash_item_t *item = qd_hash_internal_insert(h, key, &exists, handle);
@@ -170,7 +170,7 @@ qd_error_t qd_hash_insert(qd_hash_t *h, qd_field_iterator_t *key, void *val, qd_
}
-qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_field_iterator_t *key, const void *val, qd_hash_handle_t **handle)
+qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_iterator_t *key, const void *val, qd_hash_handle_t **handle)
{
assert(h->is_const);
@@ -183,14 +183,14 @@ qd_error_t qd_hash_insert_const(qd_hash_t *h, qd_field_iterator_t *key, const vo
}
-static qd_hash_item_t *qd_hash_internal_retrieve_with_hash(qd_hash_t *h, uint32_t hash, qd_field_iterator_t *key)
+static qd_hash_item_t *qd_hash_internal_retrieve_with_hash(qd_hash_t *h, uint32_t hash, qd_iterator_t *key)
{
uint32_t idx = hash & h->bucket_mask;
qd_hash_item_t *item = DEQ_HEAD(h->buckets[idx].items);
while (item) {
- if (qd_field_iterator_equal(key, item->key))
+ if (qd_iterator_equal(key, item->key))
break;
item = item->next;
}
@@ -199,22 +199,22 @@ static qd_hash_item_t *qd_hash_internal_retrieve_with_hash(qd_hash_t *h, uint32_
}
-static qd_hash_item_t *qd_hash_internal_retrieve(qd_hash_t *h, qd_field_iterator_t *key)
+static qd_hash_item_t *qd_hash_internal_retrieve(qd_hash_t *h, qd_iterator_t *key)
{
- uint32_t hash = qd_iterator_hash_function(key);
+ uint32_t hash = qd_iterator_hash_view(key);
return qd_hash_internal_retrieve_with_hash(h, hash, key);
}
-void qd_hash_retrieve_prefix(qd_hash_t *h, qd_field_iterator_t *iter, void **val)
+void qd_hash_retrieve_prefix(qd_hash_t *h, qd_iterator_t *iter, void **val)
{
//Hash individual segments by iterating thru the octets in the iterator.
- qd_iterator_hash_segments(iter);
+ qd_iterator_hash_view_segments(iter);
uint32_t hash = 0;
qd_hash_item_t *item;
- while (qd_iterator_hash_and_reset(iter, &hash)) {
+ while (qd_iterator_next_segment(iter, &hash)) {
item = qd_hash_internal_retrieve_with_hash(h, hash, iter);
if (item)
break;
@@ -227,7 +227,7 @@ void qd_hash_retrieve_prefix(qd_hash_t *h, qd_field_iterator_t *iter, void **val
}
-void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_field_iterator_t *iter, const void **val)
+void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_iterator_t *iter, const void **val)
{
assert(h->is_const);
@@ -235,7 +235,7 @@ void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_field_iterator_t *iter, cons
qd_hash_item_t *item;
- while (qd_iterator_hash_and_reset(iter, &hash)) {
+ while (qd_iterator_next_segment(iter, &hash)) {
item = qd_hash_internal_retrieve_with_hash(h, hash, iter);
if (item)
break;
@@ -248,7 +248,7 @@ void qd_hash_retrieve_prefix_const(qd_hash_t *h, qd_field_iterator_t *iter, cons
}
-qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_field_iterator_t *key, void **val)
+qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_iterator_t *key, void **val)
{
qd_hash_item_t *item = qd_hash_internal_retrieve(h, key);
if (item)
@@ -260,7 +260,7 @@ qd_error_t qd_hash_retrieve(qd_hash_t *h, qd_field_iterator_t *key, void **val)
}
-qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_field_iterator_t *key, const void **val)
+qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_iterator_t *key, const void **val)
{
assert(h->is_const);
@@ -274,13 +274,13 @@ qd_error_t qd_hash_retrieve_const(qd_hash_t *h, qd_field_iterator_t *key, const
}
-qd_error_t qd_hash_remove(qd_hash_t *h, qd_field_iterator_t *key)
+qd_error_t qd_hash_remove(qd_hash_t *h, qd_iterator_t *key)
{
- uint32_t idx = qd_iterator_hash_function(key) & h->bucket_mask;
+ uint32_t idx = qd_iterator_hash_view(key) & h->bucket_mask;
qd_hash_item_t *item = DEQ_HEAD(h->buckets[idx].items);
while (item) {
- if (qd_field_iterator_equal(key, item->key))
+ if (qd_iterator_equal(key, item->key))
break;
item = item->next;
}
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/iterator.c
----------------------------------------------------------------------
diff --git a/src/iterator.c b/src/iterator.c
index 8ae5abf..5f2f30a 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -25,7 +25,6 @@
#include <stdio.h>
#include <string.h>
-//static const char *log_module = "FIELD";
typedef enum {
MODE_TO_END,
@@ -35,43 +34,46 @@ typedef enum {
typedef enum {
STATE_AT_PREFIX,
STATE_AT_PHASE,
- STATE_IN_ADDRESS
-} addr_state_t;
+ STATE_IN_SPACE,
+ STATE_IN_BODY
+} view_state_t;
typedef struct {
qd_buffer_t *buffer;
unsigned char *cursor;
- int length;
+ int remaining;
} pointer_t;
-typedef struct qd_hash_segment_t qd_hash_segment_t;
-
-struct qd_hash_segment_t {
- DEQ_LINKS(qd_hash_segment_t); //Adds the *prev and *next links
- uint32_t hash; //The hash of the segment
- uint32_t segment_length; //The length of each hash segment
-};
+typedef struct qd_hash_segment_t {
+ DEQ_LINKS(struct qd_hash_segment_t);
+ uint32_t hash; //The hash of the segment
+ uint32_t segment_length; //The length of the segment
+} qd_hash_segment_t;
DEQ_DECLARE(qd_hash_segment_t, qd_hash_segment_list_t);
ALLOC_DECLARE(qd_hash_segment_t);
ALLOC_DEFINE(qd_hash_segment_t);
-struct qd_field_iterator_t {
- pointer_t start_pointer;
- pointer_t view_start_pointer;
- pointer_t pointer;
+struct qd_iterator_t {
+ pointer_t start_pointer; // Pointer to the raw data
+ pointer_t view_start_pointer; // Pointer to the start of the view
+ pointer_t view_pointer; // Pointer to the remaining view
qd_iterator_view_t view;
+ int annotation_length;
+ int annotation_remaining;
qd_hash_segment_list_t hash_segments;
parse_mode_t mode;
- addr_state_t state;
- bool view_prefix;
+ view_state_t state;
unsigned char prefix;
unsigned char prefix_override;
unsigned char phase;
+ const char *space;
+ int space_length;
+ int space_cursor;
};
-ALLOC_DECLARE(qd_field_iterator_t);
-ALLOC_DEFINE(qd_field_iterator_t);
+ALLOC_DECLARE(qd_iterator_t);
+ALLOC_DEFINE(qd_iterator_t);
typedef enum {
STATE_START,
@@ -84,114 +86,112 @@ typedef enum {
} state_t;
-static char *my_area = "";
-static char *my_router = "";
-
-const char *SEPARATORS = "./";
+static char *my_area = "";
+static char *my_router = "";
-const uint32_t HASH_INIT = 5381;
+static const char *SEPARATORS = "./";
+static const uint32_t HASH_INIT = 5381;
-static void parse_address_view(qd_field_iterator_t *iter)
+static void parse_address_view(qd_iterator_t *iter)
{
//
// This function starts with an iterator view that is identical to
- // ITER_VIEW_NO_HOST. We will now further refine the view in order
- // to aid the router in looking up addresses.
+ // ITER_VIEW_ADDRESS_NO_HOST. We will now further refine the view
+ // in order to aid the router in looking up addresses.
//
- if (iter->prefix_override == '\0' && qd_field_iterator_prefix(iter, "_")) {
- if (qd_field_iterator_prefix(iter, "local/")) {
- iter->prefix = 'L';
- iter->state = STATE_AT_PREFIX;
- iter->view_prefix = true;
+ iter->annotation_length = 1;
+
+ if (iter->prefix_override == '\0' && qd_iterator_prefix(iter, "_")) {
+ if (qd_iterator_prefix(iter, "local/")) {
+ iter->prefix = 'L';
+ iter->state = STATE_AT_PREFIX;
return;
}
- if (qd_field_iterator_prefix(iter, "topo/")) {
- if (qd_field_iterator_prefix(iter, "all/") || qd_field_iterator_prefix(iter, my_area)) {
- if (qd_field_iterator_prefix(iter, "all/")) {
- iter->prefix = 'T';
- iter->state = STATE_AT_PREFIX;
- iter->view_prefix = true;
+ if (qd_iterator_prefix(iter, "topo/")) {
+ if (qd_iterator_prefix(iter, "all/") || qd_iterator_prefix(iter, my_area)) {
+ if (qd_iterator_prefix(iter, "all/")) {
+ iter->prefix = 'T';
+ iter->state = STATE_AT_PREFIX;
return;
- } else if (qd_field_iterator_prefix(iter, my_router)) {
- iter->prefix = 'L';
- iter->state = STATE_AT_PREFIX;
- iter->view_prefix = true;
+ } else if (qd_iterator_prefix(iter, my_router)) {
+ iter->prefix = 'L';
+ iter->state = STATE_AT_PREFIX;
return;
}
- iter->prefix = 'R';
- iter->state = STATE_AT_PREFIX;
- iter->view_prefix = true;
- iter->mode = MODE_TO_SLASH;
+ iter->prefix = 'R';
+ iter->state = STATE_AT_PREFIX;
+ iter->mode = MODE_TO_SLASH;
return;
}
- iter->prefix = 'A';
- iter->state = STATE_AT_PREFIX;
- iter->view_prefix = true;
- iter->mode = MODE_TO_SLASH;
+ iter->prefix = 'A';
+ iter->state = STATE_AT_PREFIX;
+ iter->mode = MODE_TO_SLASH;
return;
}
}
- iter->prefix = iter->prefix_override ? iter->prefix_override : 'M';
- iter->state = STATE_AT_PREFIX;
- iter->view_prefix = true;
+ iter->prefix = iter->prefix_override ? iter->prefix_override : 'M';
+ iter->state = STATE_AT_PREFIX;
+ iter->annotation_length = iter->space_length + (iter->prefix == 'M' ? 2 : 1);
}
-static void parse_node_view(qd_field_iterator_t *iter)
+static void parse_node_view(qd_iterator_t *iter)
{
//
// This function starts with an iterator view that is identical to
- // ITER_VIEW_NO_HOST. We will now further refine the view in order
+ // ITER_VIEW_ADDRESS_NO_HOST. We will now further refine the view in order
// to aid the router in looking up nodes.
//
- if (qd_field_iterator_prefix(iter, my_area)) {
- iter->prefix = 'R';
- iter->state = STATE_AT_PREFIX;
- iter->view_prefix = true;
- iter->mode = MODE_TO_END;
+ iter->annotation_length = 1;
+
+ if (qd_iterator_prefix(iter, my_area)) {
+ iter->prefix = 'R';
+ iter->state = STATE_AT_PREFIX;
+ iter->mode = MODE_TO_END;
return;
}
- iter->prefix = 'A';
- iter->state = STATE_AT_PREFIX;
- iter->view_prefix = true;
- iter->mode = MODE_TO_SLASH;
+ iter->prefix = 'A';
+ iter->state = STATE_AT_PREFIX;
+ iter->mode = MODE_TO_SLASH;
}
-static void qd_address_iterator_remove_trailing_separator(qd_field_iterator_t *iter)
+void qd_iterator_remove_trailing_separator(qd_iterator_t *iter)
{
// Save the iterator's pointer so we can apply it back before returning from this function.
- pointer_t save_pointer = iter->pointer;
+ pointer_t save_pointer = iter->view_pointer;
char current_octet = 0;
- while (!qd_field_iterator_end(iter)) {
- current_octet = qd_field_iterator_octet(iter);
+ while (!qd_iterator_end(iter)) {
+ current_octet = qd_iterator_octet(iter);
}
// We have the last octet in current_octet
- iter->pointer = save_pointer;
+ iter->view_pointer = save_pointer;
if (current_octet && strrchr(SEPARATORS, (int) current_octet))
- iter->pointer.length--;
+ iter->view_pointer.remaining--;
}
-static void view_initialize(qd_field_iterator_t *iter)
+static void view_initialize(qd_iterator_t *iter)
{
//
// The default behavior is for the view to *not* have a prefix.
// We'll add one if it's needed later.
//
- iter->state = STATE_IN_ADDRESS;
- iter->view_prefix = false;
- iter->mode = MODE_TO_END;
+ iter->state = STATE_IN_BODY;
+ iter->prefix = '\0';
+ iter->mode = MODE_TO_END;
+ iter->annotation_length = 0;
+ iter->annotation_remaining = 0;
if (iter->view == ITER_VIEW_ALL)
return;
@@ -199,18 +199,18 @@ static void view_initialize(qd_field_iterator_t *iter)
//
// Advance to the node-id.
//
- state_t state = STATE_START;
- unsigned int octet;
- pointer_t save_pointer = {0,0,0};
+ state_t state = STATE_START;
+ unsigned int octet;
+ pointer_t save_pointer = {0,0,0};
- while (!qd_field_iterator_end(iter) && state != STATE_AT_NODE_ID) {
- octet = qd_field_iterator_octet(iter);
+ while (!qd_iterator_end(iter) && state != STATE_AT_NODE_ID) {
+ octet = qd_iterator_octet(iter);
switch (state) {
case STATE_START :
if (octet == '/') {
state = STATE_SLASH_LEFT;
- save_pointer = iter->pointer;
+ save_pointer = iter->view_pointer;
} else
state = STATE_SCANNING;
break;
@@ -220,7 +220,7 @@ static void view_initialize(qd_field_iterator_t *iter)
state = STATE_SKIPPING_TO_NEXT_SLASH;
else {
state = STATE_AT_NODE_ID;
- iter->pointer = save_pointer;
+ iter->view_pointer = save_pointer;
}
break;
@@ -237,7 +237,7 @@ static void view_initialize(qd_field_iterator_t *iter)
case STATE_COLON :
if (octet == '/') {
state = STATE_COLON_SLASH;
- save_pointer = iter->pointer;
+ save_pointer = iter->view_pointer;
} else
state = STATE_SCANNING;
break;
@@ -247,7 +247,7 @@ static void view_initialize(qd_field_iterator_t *iter)
state = STATE_SKIPPING_TO_NEXT_SLASH;
else {
state = STATE_AT_NODE_ID;
- iter->pointer = save_pointer;
+ iter->view_pointer = save_pointer;
}
break;
@@ -256,87 +256,78 @@ static void view_initialize(qd_field_iterator_t *iter)
}
}
- if (state != STATE_AT_NODE_ID) {
+ if (state != STATE_AT_NODE_ID){
//
// The address string was relative, not absolute. The node-id
// is at the beginning of the string.
//
- iter->pointer = iter->start_pointer;
+ iter->view_pointer = iter->start_pointer;
}
//
// Cursor is now on the first octet of the node-id
//
- if (iter->view == ITER_VIEW_NODE_ID) {
- iter->mode = MODE_TO_SLASH;
- return;
- }
-
- if (iter->view == ITER_VIEW_NO_HOST) {
- iter->mode = MODE_TO_END;
+ if (iter->view == ITER_VIEW_ADDRESS_NO_HOST)
return;
- }
if (iter->view == ITER_VIEW_ADDRESS_HASH) {
- iter->mode = MODE_TO_END;
- qd_address_iterator_remove_trailing_separator(iter);
+ qd_iterator_remove_trailing_separator(iter); // FIXME - need this?
parse_address_view(iter);
return;
}
if (iter->view == ITER_VIEW_NODE_HASH) {
- iter->mode = MODE_TO_END;
parse_node_view(iter);
return;
}
-
- if (iter->view == ITER_VIEW_NODE_SPECIFIC) {
- iter->mode = MODE_TO_END;
- while (!qd_field_iterator_end(iter)) {
- octet = qd_field_iterator_octet(iter);
- if (octet == '/')
- break;
- }
- return;
- }
}
-static inline void field_iterator_move_cursor(qd_field_iterator_t *iter, uint32_t length)
+static inline void field_iterator_move_cursor(qd_iterator_t *iter, uint32_t length)
{
// Only safe to call this help method if the cursor is parsing the data,
// i.e. if iter is an address iterator, the cursor must be 'past' the
// prefix
- assert(iter->state == STATE_IN_ADDRESS);
- uint32_t count = ((length > iter->pointer.length)
- ? iter->pointer.length
- : length);
+ assert(iter->state == STATE_IN_BODY);
+ uint32_t count = (length > iter->view_pointer.remaining) ? iter->view_pointer.remaining : length;
- if (iter->pointer.buffer) {
+ if (iter->view_pointer.buffer) {
while (count) {
- uint32_t remaining = qd_buffer_cursor(iter->pointer.buffer) - iter->pointer.cursor;
+ uint32_t remaining = qd_buffer_cursor(iter->view_pointer.buffer) - iter->view_pointer.cursor;
remaining = (remaining > count) ? count : remaining;
- iter->pointer.cursor += remaining;
- iter->pointer.length -= remaining;
+ iter->view_pointer.cursor += remaining;
+ iter->view_pointer.remaining -= remaining;
count -= remaining;
- if (iter->pointer.cursor == qd_buffer_cursor(iter->pointer.buffer)) {
- iter->pointer.buffer = iter->pointer.buffer->next;
- if (iter->pointer.buffer == 0) {
- iter->pointer.length = 0;
- iter->pointer.cursor = 0;
+ if (iter->view_pointer.cursor == qd_buffer_cursor(iter->view_pointer.buffer)) {
+ iter->view_pointer.buffer = iter->view_pointer.buffer->next;
+ if (iter->view_pointer.buffer == 0) {
+ iter->view_pointer.remaining = 0;
+ iter->view_pointer.cursor = 0;
break;
} else {
- iter->pointer.cursor = qd_buffer_base(iter->pointer.buffer);
+ iter->view_pointer.cursor = qd_buffer_base(iter->view_pointer.buffer);
}
}
}
} else { // string/binary data
- iter->pointer.cursor += count;
- iter->pointer.length -= count;
+ iter->view_pointer.cursor += count;
+ iter->view_pointer.remaining -= count;
}
}
-void qd_field_iterator_set_address(const char *area, const char *router)
+
+static void qd_iterator_free_hash_segments(qd_iterator_t *iter)
+{
+ qd_hash_segment_t *seg = DEQ_HEAD(iter->hash_segments);
+ while (seg) {
+ DEQ_REMOVE_HEAD(iter->hash_segments);
+ free_qd_hash_segment_t(seg);
+ seg = DEQ_HEAD(iter->hash_segments);
+ }
+}
+
+
+void qd_iterator_set_address(const char *area, const char *router)
{
my_area = (char*) malloc(strlen(area) + 2);
strcpy(my_area, area);
@@ -348,283 +339,333 @@ void qd_field_iterator_set_address(const char *area, const char *router)
}
-qd_field_iterator_t* qd_address_iterator_string(const char *text, qd_iterator_view_t view)
+qd_iterator_t* qd_iterator_string(const char *text, qd_iterator_view_t view)
{
- qd_field_iterator_t *iter = new_qd_field_iterator_t();
+ qd_iterator_t *iter = new_qd_iterator_t();
if (!iter)
return 0;
- iter->start_pointer.buffer = 0;
- iter->start_pointer.cursor = (unsigned char*) text;
- iter->start_pointer.length = strlen(text);
- iter->phase = '0';
- iter->prefix_override = '\0';
-
- DEQ_INIT(iter->hash_segments);
+ ZERO(iter);
+ iter->start_pointer.cursor = (unsigned char*) text;
+ iter->start_pointer.remaining = strlen(text);
+ iter->phase = '0';
- qd_address_iterator_reset_view(iter, view);
+ qd_iterator_reset_view(iter, view);
return iter;
}
-qd_field_iterator_t* qd_address_iterator_binary(const char *text, int length, qd_iterator_view_t view)
+qd_iterator_t* qd_iterator_binary(const char *text, int length, qd_iterator_view_t view)
{
- qd_field_iterator_t *iter = new_qd_field_iterator_t();
+ qd_iterator_t *iter = new_qd_iterator_t();
if (!iter)
return 0;
- iter->start_pointer.buffer = 0;
- iter->start_pointer.cursor = (unsigned char*) text;
- iter->start_pointer.length = length;
- iter->phase = '0';
- iter->prefix_override = '\0';
+ ZERO(iter);
+ iter->start_pointer.cursor = (unsigned char*) text;
+ iter->start_pointer.remaining = length;
+ iter->phase = '0';
- DEQ_INIT(iter->hash_segments);
-
- qd_address_iterator_reset_view(iter, view);
+ qd_iterator_reset_view(iter, view);
return iter;
}
-qd_field_iterator_t *qd_address_iterator_buffer(qd_buffer_t *buffer, int offset, int length, qd_iterator_view_t view)
+qd_iterator_t *qd_iterator_buffer(qd_buffer_t *buffer, int offset, int length, qd_iterator_view_t view)
{
- qd_field_iterator_t *iter = new_qd_field_iterator_t();
+ qd_iterator_t *iter = new_qd_iterator_t();
if (!iter)
return 0;
- iter->start_pointer.buffer = buffer;
- iter->start_pointer.cursor = qd_buffer_base(buffer) + offset;
- iter->start_pointer.length = length;
- iter->phase = '0';
- iter->prefix_override = '\0';
-
- DEQ_INIT(iter->hash_segments);
+ ZERO(iter);
+ iter->start_pointer.buffer = buffer;
+ iter->start_pointer.cursor = qd_buffer_base(buffer) + offset;
+ iter->start_pointer.remaining = length;
+ iter->phase = '0';
- qd_address_iterator_reset_view(iter, view);
+ qd_iterator_reset_view(iter, view);
return iter;
}
-void qd_field_iterator_free(qd_field_iterator_t *iter)
+void qd_iterator_free(qd_iterator_t *iter)
{
- if (!iter) return;
- free_qd_field_iterator_t(iter);
+ if (!iter)
+ return;
+
+ qd_iterator_free_hash_segments(iter);
+ free_qd_iterator_t(iter);
}
-void qd_field_iterator_reset(qd_field_iterator_t *iter)
+void qd_iterator_reset(qd_iterator_t *iter)
{
- iter->pointer = iter->view_start_pointer;
- iter->state = iter->view_prefix ? STATE_AT_PREFIX : STATE_IN_ADDRESS;
+ if (iter) {
+ iter->view_pointer = iter->view_start_pointer;
+ iter->state = iter->prefix ? STATE_AT_PREFIX : STATE_IN_BODY;
+ iter->annotation_remaining = iter->annotation_length;
+ }
}
-void qd_address_iterator_reset_view(qd_field_iterator_t *iter, qd_iterator_view_t view)
+void qd_iterator_reset_view(qd_iterator_t *iter, qd_iterator_view_t view)
{
- iter->pointer = iter->start_pointer;
- iter->view = view;
+ if (iter) {
+ iter->view_pointer = iter->start_pointer;
+ iter->view = view;
+ view_initialize(iter);
+ iter->view_start_pointer = iter->view_pointer;
+ iter->annotation_remaining = iter->annotation_length;
+ }
+}
- view_initialize(iter);
- iter->view_start_pointer = iter->pointer;
+qd_iterator_view_t qd_iterator_get_view(const qd_iterator_t *iter)
+{
+ return iter ? iter->view : ITER_VIEW_ALL;
}
-qd_iterator_view_t qd_address_iterator_get_view(const qd_field_iterator_t *iter)
+void qd_iterator_annotate_phase(qd_iterator_t *iter, char phase)
{
- return iter->view;
+ if (iter)
+ iter->phase = phase;
}
-void qd_address_iterator_set_phase(qd_field_iterator_t *iter, char phase)
+void qd_iterator_trim_view(qd_iterator_t *iter, int length)
{
- iter->phase = phase;
+ if (!iter)
+ return;
+
+ iter->view_start_pointer = iter->view_pointer;
+ int view_length = qd_iterator_length(iter);
+ if (view_length > length) {
+ if (iter->annotation_length > length) {
+ iter->annotation_length = length;
+ iter->annotation_remaining = length;
+ iter->view_start_pointer.remaining = 0;
+ } else
+ iter->view_start_pointer.remaining -= view_length - length;
+ iter->view_pointer = iter->view_start_pointer;
+ }
}
-void qd_field_iterator_trim(qd_field_iterator_t *iter, int length)
+
+void qd_iterator_annotate_prefix(qd_iterator_t *iter, char prefix)
{
- if (qd_field_iterator_length(iter) > length) {
- iter->start_pointer = iter->pointer;
- iter->start_pointer.length = length;
- iter->view_start_pointer = iter->start_pointer;
- iter->pointer = iter->start_pointer;
+ if (iter) {
+ iter->prefix_override = prefix;
+ qd_iterator_reset_view(iter, iter->view);
}
}
-void qd_address_iterator_override_prefix(qd_field_iterator_t *iter, char prefix)
+
+void qd_iterator_annotate_space(qd_iterator_t *iter, const char* space, int space_length)
{
- iter->prefix_override = prefix;
- qd_address_iterator_reset_view(iter, iter->view);
+ if (iter) {
+ iter->space = space;
+ iter->space_length = space_length;
+ if (iter->view == ITER_VIEW_ADDRESS_HASH)
+ iter->annotation_length = space_length + (iter->prefix == 'M' ? 2 : 1);
+ }
}
-unsigned char qd_field_iterator_octet(qd_field_iterator_t *iter)
+unsigned char qd_iterator_octet(qd_iterator_t *iter)
{
+ if (!iter)
+ return 0;
+
if (iter->state == STATE_AT_PREFIX) {
- iter->state = iter->prefix == 'M' ? STATE_AT_PHASE : STATE_IN_ADDRESS;
+ iter->state = iter->prefix == 'M' ? STATE_AT_PHASE : (iter->space ? STATE_IN_SPACE : STATE_IN_BODY);
+ iter->space_cursor = 0;
+ iter->annotation_remaining--;
return iter->prefix;
}
if (iter->state == STATE_AT_PHASE) {
- iter->state = STATE_IN_ADDRESS;
+ iter->state = iter->space ? STATE_IN_SPACE : STATE_IN_BODY;
+ iter->space_cursor = 0;
+ iter->annotation_remaining--;
return iter->phase;
}
- if (iter->pointer.length == 0)
+ if (iter->state == STATE_IN_SPACE) {
+ if (iter->space_cursor == iter->space_length - 1) {
+ iter->state = STATE_IN_BODY;
+ assert(iter->annotation_remaining == 1);
+ }
+ iter->annotation_remaining--;
+ return iter->space[iter->space_cursor++];
+ }
+
+ if (iter->view_pointer.remaining == 0)
return (unsigned char) 0;
- unsigned char result = *(iter->pointer.cursor);
+ unsigned char result = *(iter->view_pointer.cursor);
field_iterator_move_cursor(iter, 1);
- if (iter->pointer.length && iter->mode == MODE_TO_SLASH && *(iter->pointer.cursor) == '/')
- iter->pointer.length = 0;
+ if (iter->view_pointer.remaining && iter->mode == MODE_TO_SLASH && *(iter->view_pointer.cursor) == '/')
+ iter->view_pointer.remaining = 0;
return result;
}
-int qd_field_iterator_end(const qd_field_iterator_t *iter)
+bool qd_iterator_end(const qd_iterator_t *iter)
{
- return iter->pointer.length == 0;
+ return iter ? qd_iterator_remaining(iter) == 0 : true;
}
-qd_field_iterator_t *qd_field_iterator_sub(const qd_field_iterator_t *iter, uint32_t length)
+qd_iterator_t *qd_iterator_sub(const qd_iterator_t *iter, uint32_t length)
{
- qd_field_iterator_t *sub = new_qd_field_iterator_t();
- if (!sub)
+ if (!iter)
return 0;
- sub->start_pointer = iter->pointer;
- sub->start_pointer.length = length;
- sub->view_start_pointer = sub->start_pointer;
- sub->pointer = sub->start_pointer;
- sub->view = iter->view;
- sub->mode = iter->mode;
- sub->state = STATE_IN_ADDRESS;
- sub->view_prefix = false;
- sub->prefix_override = '\0';
- sub->phase = '0';
+ qd_iterator_t *sub = new_qd_iterator_t();
+ if (!sub)
+ return 0;
- DEQ_INIT(sub->hash_segments);
+ ZERO(sub);
+ sub->start_pointer = iter->view_pointer;
+ sub->start_pointer.remaining = length;
+ sub->view_start_pointer = sub->start_pointer;
+ sub->view_pointer = sub->start_pointer;
+ sub->view = iter->view;
+ sub->mode = iter->mode;
+ sub->state = STATE_IN_BODY;
+ sub->phase = '0';
return sub;
}
-void qd_field_iterator_advance(qd_field_iterator_t *iter, uint32_t length)
+void qd_iterator_advance(qd_iterator_t *iter, uint32_t length)
{
- while (length > 0 && !qd_field_iterator_end(iter)) {
- if (iter->state == STATE_IN_ADDRESS) {
+ if (!iter)
+ return;
+
+ while (length > 0 && !qd_iterator_end(iter)) {
+ if (iter->state == STATE_IN_BODY) {
field_iterator_move_cursor(iter, length);
break;
} else {
- qd_field_iterator_octet(iter);
+ qd_iterator_octet(iter);
length--;
}
}
}
-uint32_t qd_field_iterator_remaining(const qd_field_iterator_t *iter)
+uint32_t qd_iterator_remaining(const qd_iterator_t *iter)
{
- return iter->pointer.length;
+ return iter ? iter->annotation_remaining + iter->view_pointer.remaining : 0;
}
-int qd_field_iterator_equal(qd_field_iterator_t *iter, const unsigned char *string)
+bool qd_iterator_equal(qd_iterator_t *iter, const unsigned char *string)
{
- qd_field_iterator_reset(iter);
+ if (!iter)
+ return false;
+
+ qd_iterator_reset(iter);
- while (!qd_field_iterator_end(iter) && *string) {
- if (*string != qd_field_iterator_octet(iter))
+ while (!qd_iterator_end(iter) && *string) {
+ if (*string != qd_iterator_octet(iter))
break;
string++;
}
- int match = (qd_field_iterator_end(iter) && (*string == 0));
- qd_field_iterator_reset(iter);
+ bool match = (qd_iterator_end(iter) && (*string == 0));
+ qd_iterator_reset(iter);
return match;
}
-int qd_field_iterator_prefix(qd_field_iterator_t *iter, const char *prefix)
+bool qd_iterator_prefix(qd_iterator_t *iter, const char *prefix)
{
- pointer_t save_pointer = iter->pointer;
+ if (!iter)
+ return false;
+
+ pointer_t save_pointer = iter->view_pointer;
unsigned char *c = (unsigned char*) prefix;
while(*c) {
- if (*c != qd_field_iterator_octet(iter))
+ if (*c != qd_iterator_octet(iter))
break;
c++;
}
if (*c) {
- iter->pointer = save_pointer;
- return 0;
+ iter->view_pointer = save_pointer;
+ return false;
}
- return 1;
+ return true;
}
-int qd_field_iterator_length(const qd_field_iterator_t *iter)
+int qd_iterator_length(const qd_iterator_t *iter)
{
- qd_field_iterator_t copy = *iter;
- int length = 0;
- qd_field_iterator_reset(©);
- while (!qd_field_iterator_end(©)) {
- qd_field_iterator_octet(©);
- length++;
- }
- return length;
+ return iter ? iter->annotation_length + iter->view_start_pointer.remaining : 0;
}
-int qd_field_iterator_ncopy(qd_field_iterator_t *iter, unsigned char* buffer, int n) {
- qd_field_iterator_reset(iter);
+int qd_iterator_ncopy(qd_iterator_t *iter, unsigned char* buffer, int n)
+{
+ if (!iter)
+ return 0;
+
+ qd_iterator_reset(iter);
int i = 0;
- while (!qd_field_iterator_end(iter) && i < n)
- buffer[i++] = qd_field_iterator_octet(iter);
+ while (!qd_iterator_end(iter) && i < n)
+ buffer[i++] = qd_iterator_octet(iter);
return i;
}
-char* qd_field_iterator_strncpy(qd_field_iterator_t *iter, char* buffer, int n) {
- int i = qd_field_iterator_ncopy(iter, (unsigned char*)buffer, n-1);
+char* qd_iterator_strncpy(qd_iterator_t *iter, char* buffer, int n)
+{
+ int i = qd_iterator_ncopy(iter, (unsigned char*) buffer, n-1);
buffer[i] = '\0';
return buffer;
}
-unsigned char *qd_field_iterator_copy(qd_field_iterator_t *iter)
+unsigned char *qd_iterator_copy(qd_iterator_t *iter)
{
- int length = qd_field_iterator_length(iter);
+ if (!iter)
+ return 0;
+
+ int length = qd_iterator_length(iter);
unsigned char *copy = malloc(length+1);
- int i = qd_field_iterator_ncopy(iter, copy, length+1);
+ int i = qd_iterator_ncopy(iter, copy, length+1);
copy[i] = '\0';
return copy;
}
-qd_field_iterator_t *qd_field_iterator_dup(const qd_field_iterator_t *iter)
+qd_iterator_t *qd_iterator_dup(const qd_iterator_t *iter)
{
- if (iter == 0)
+ if (!iter)
return 0;
- qd_field_iterator_t *dup = new_qd_field_iterator_t();
+ qd_iterator_t *dup = new_qd_iterator_t();
if (dup)
*dup = *iter;
return dup;
}
-qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter)
+qd_iovec_t *qd_iterator_iovec(const qd_iterator_t *iter)
{
- assert(!iter->view_prefix); // Not supported for views with a prefix
+ if (!iter)
+ return 0;
//
// Count the number of buffers this field straddles
@@ -633,7 +674,7 @@ qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter)
int bufcnt = 1;
qd_buffer_t *buf = pointer.buffer;
size_t bufsize = qd_buffer_size(buf) - (pointer.cursor - qd_buffer_base(pointer.buffer));
- ssize_t remaining = pointer.length - bufsize;
+ ssize_t remaining = pointer.remaining - bufsize;
while (remaining > 0) {
bufcnt++;
@@ -657,7 +698,7 @@ qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter)
buf = pointer.buffer;
bufsize = qd_buffer_size(buf) - (pointer.cursor - qd_buffer_base(pointer.buffer));
void *base = pointer.cursor;
- remaining = pointer.length;
+ remaining = pointer.remaining;
while (remaining > 0) {
if (bufsize > remaining)
@@ -677,18 +718,6 @@ qd_iovec_t *qd_field_iterator_iovec(const qd_field_iterator_t *iter)
}
-uint32_t qd_iterator_hash_function(qd_field_iterator_t *iter)
-{
- uint32_t hash = HASH_INIT;
-
- qd_field_iterator_reset(iter);
- while (!qd_field_iterator_end(iter))
- hash = ((hash << 5) + hash) + (int) qd_field_iterator_octet(iter); /* hash * 33 + c */
-
- return hash;
-}
-
-
/**
* Creates and returns a new qd_hash_segment_t and initializes it.
*/
@@ -696,7 +725,7 @@ static qd_hash_segment_t *qd_iterator_hash_segment(void)
{
qd_hash_segment_t *hash_segment = new_qd_hash_segment_t();
DEQ_ITEM_INIT(hash_segment);
- hash_segment->hash = 0;
+ hash_segment->hash = 0;
hash_segment->segment_length = 0;
return hash_segment;
}
@@ -705,7 +734,7 @@ static qd_hash_segment_t *qd_iterator_hash_segment(void)
/**
* Create a new hash segment and insert it at the end of the linked list
*/
-static void qd_insert_hash_segment(qd_field_iterator_t *iter, uint32_t *hash, int segment_length)
+static void qd_insert_hash_segment(qd_iterator_t *iter, uint32_t *hash, int segment_length)
{
qd_hash_segment_t *hash_segment = qd_iterator_hash_segment();
@@ -717,17 +746,34 @@ static void qd_insert_hash_segment(qd_field_iterator_t *iter, uint32_t *hash, in
}
-void qd_iterator_hash_segments(qd_field_iterator_t *iter)
+uint32_t qd_iterator_hash_view(qd_iterator_t *iter)
{
+ uint32_t hash = HASH_INIT;
+
+ qd_iterator_reset(iter);
+ while (!qd_iterator_end(iter))
+ hash = ((hash << 5) + hash) + (uint32_t) qd_iterator_octet(iter); /* hash * 33 + c */
+
+ return hash;
+}
+
+
+void qd_iterator_hash_view_segments(qd_iterator_t *iter)
+{
+ if (!iter)
+ return;
+
// Reset the pointers in the iterator
- qd_field_iterator_reset(iter);
+ qd_iterator_reset(iter);
uint32_t hash = HASH_INIT;
char octet;
int segment_length=0;
- while (!qd_field_iterator_end(iter)) {
+ qd_iterator_free_hash_segments(iter);
+
+ while (!qd_iterator_end(iter)) {
// Get the octet at which the iterator is currently pointing to.
- octet = qd_field_iterator_octet(iter);
+ octet = qd_iterator_octet(iter);
segment_length += 1;
if (strrchr(SEPARATORS, (int) octet)) {
@@ -738,34 +784,24 @@ void qd_iterator_hash_segments(qd_field_iterator_t *iter)
}
// Segments should never end with a separator. see view_initialize which in turn calls
- // qd_address_iterator_remove_trailing_separator
+ // qd_iterator_remove_trailing_separator
// Insert the last segment which was not inserted in the previous while loop
qd_insert_hash_segment(iter, &hash, segment_length);
// Return the pointers in the iterator back to the original state before returning from this function.
- qd_field_iterator_reset(iter);
+ qd_iterator_reset(iter);
}
-bool qd_iterator_hash_and_reset(qd_field_iterator_t *iter, uint32_t *hash)
+bool qd_iterator_next_segment(qd_iterator_t *iter, uint32_t *hash)
{
qd_hash_segment_t *hash_segment = DEQ_TAIL(iter->hash_segments);
if (!hash_segment)
return false;
*hash = hash_segment->hash;
+ qd_iterator_trim_view(iter, hash_segment->segment_length);
- // Get the length of the hashed segment and set it on the iterator so that the iterator can only advance till that length
- // Check for a non empty iter->prefix and reduce the segment length by 1
- if (iter->view_prefix) {
- if (iter->prefix == 'M')
- iter->view_start_pointer.length = hash_segment->segment_length - 2;
- else
- iter->view_start_pointer.length = hash_segment->segment_length - 1;
- } else
- iter->view_start_pointer.length = hash_segment->segment_length;
-
- // Remove the tail from the hash segments since we have already compared it.
DEQ_REMOVE_TAIL(iter->hash_segments);
free_qd_hash_segment_t(hash_segment);
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/6a783b07/src/message.c
----------------------------------------------------------------------
diff --git a/src/message.c b/src/message.c
index 03586ee..5ae8f2e 100644
--- a/src/message.c
+++ b/src/message.c
@@ -86,16 +86,16 @@ static void quote(char* bytes, int n, char **begin, char *end) {
static void copy_field(qd_message_t *msg, int field, int max, char *pre, char *post,
char **begin, char *end)
{
- qd_field_iterator_t* iter = qd_message_field_iterator(msg, field);
+ qd_iterator_t* iter = qd_message_field_iterator(msg, field);
if (iter) {
aprintf(begin, end, "%s", pre);
- qd_field_iterator_reset(iter);
- for (int j = 0; !qd_field_iterator_end(iter) && j < max; ++j) {
- char byte = qd_field_iterator_octet(iter);
+ qd_iterator_reset(iter);
+ for (int j = 0; !qd_iterator_end(iter) && j < max; ++j) {
+ char byte = qd_iterator_octet(iter);
quote(&byte, 1, begin, end);
}
aprintf(begin, end, "%s", post);
- qd_field_iterator_free(iter);
+ qd_iterator_free(iter);
}
}
@@ -633,7 +633,7 @@ qd_parsed_field_t *qd_message_message_annotations(qd_message_t *in_msg)
if (content->parsed_message_annotations)
return content->parsed_message_annotations;
- qd_field_iterator_t *ma = qd_message_field_iterator(in_msg, QD_FIELD_MESSAGE_ANNOTATION);
+ qd_iterator_t *ma = qd_message_field_iterator(in_msg, QD_FIELD_MESSAGE_ANNOTATION);
if (ma == 0)
return 0;
@@ -641,13 +641,13 @@ qd_parsed_field_t *qd_message_message_annotations(qd_message_t *in_msg)
if (content->parsed_message_annotations == 0 ||
!qd_parse_ok(content->parsed_message_annotations) ||
!qd_parse_is_map(content->parsed_message_annotations)) {
- qd_field_iterator_free(ma);
+ qd_iterator_free(ma);
qd_parse_free(content->parsed_message_annotations);
content->parsed_message_annotations = 0;
return 0;
}
- qd_field_iterator_free(ma);
+ qd_iterator_free(ma);
return content->parsed_message_annotations;
}
@@ -805,9 +805,9 @@ static void compose_message_annotations(qd_message_pvt_t *msg, qd_buffer_list_t
if (!sub_key)
continue;
- qd_field_iterator_t *iter = qd_parse_raw(sub_key);
+ qd_iterator_t *iter = qd_parse_raw(sub_key);
- if (!qd_field_iterator_prefix(iter, QD_MA_PREFIX)) {
+ if (!qd_iterator_prefix(iter, QD_MA_PREFIX)) {
if (!map_started) {
qd_compose_start_map(out_ma);
map_started = true;
@@ -1099,17 +1099,17 @@ int qd_message_check(qd_message_t *in_msg, qd_message_depth_t depth)
}
-qd_field_iterator_t *qd_message_field_iterator_typed(qd_message_t *msg, qd_message_field_t field)
+qd_iterator_t *qd_message_field_iterator_typed(qd_message_t *msg, qd_message_field_t field)
{
qd_field_location_t *loc = qd_message_field_location(msg, field);
if (!loc)
return 0;
- return qd_field_iterator_buffer(loc->buffer, loc->offset, loc->length + loc->hdr_length);
+ return qd_iterator_buffer(loc->buffer, loc->offset, loc->length + loc->hdr_length, ITER_VIEW_ALL);
}
-qd_field_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_field_t field)
+qd_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_field_t field)
{
qd_field_location_t *loc = qd_message_field_location(msg, field);
if (!loc)
@@ -1122,7 +1122,7 @@ qd_field_iterator_t *qd_message_field_iterator(qd_message_t *msg, qd_message_fie
unsigned char *cursor = qd_buffer_base(loc->buffer) + loc->offset;
advance(&cursor, &buffer, loc->hdr_length, 0, 0);
- return qd_field_iterator_buffer(buffer, cursor - qd_buffer_base(buffer), loc->length);
+ return qd_iterator_buffer(buffer, cursor - qd_buffer_base(buffer), loc->length, ITER_VIEW_ALL);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org