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 <[email protected]> Authored: Wed Nov 23 08:50:47 2016 -0500 Committer: Ted Ross <[email protected]> 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: [email protected] For additional commands, e-mail: [email protected]
