void qd_iterator_hash_view_segments(qd_iterator_t *iter) { if (!iter) return; // Reset the pointers in the iterator qd_iterator_reset(iter); uint32_t hash = HASH_INIT; char octet; int segment_length=0; qd_iterator_free_hash_segments(iter); while (!qd_iterator_end(iter)) { // Get the octet at which the iterator is currently pointing to. octet = qd_iterator_octet(iter); segment_length += 1; if (strrchr(SEPARATORS, (int) octet)) { qd_insert_hash_segment(iter, &hash, segment_length-1); } hash = ((hash << 5) + hash) + octet; /* hash * 33 + c */ } // Segments should never end with a separator. see view_initialize which in turn calls // 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_iterator_reset(iter); }
int64_t qd_parse_as_long(qd_parsed_field_t *field) { int64_t result = 0; qd_iterator_reset(field->raw_iter); switch (field->tag) { case QD_AMQP_LONG: result |= ((int64_t) qd_iterator_octet(field->raw_iter)) << 56; result |= ((int64_t) qd_iterator_octet(field->raw_iter)) << 48; result |= ((int64_t) qd_iterator_octet(field->raw_iter)) << 40; result |= ((int64_t) qd_iterator_octet(field->raw_iter)) << 32; result |= ((int64_t) qd_iterator_octet(field->raw_iter)) << 24; result |= ((int64_t) qd_iterator_octet(field->raw_iter)) << 16; result |= ((int64_t) qd_iterator_octet(field->raw_iter)) << 8; result |= (uint64_t) qd_iterator_octet(field->raw_iter); break; case QD_AMQP_SMALLLONG: result = (int8_t) qd_iterator_octet(field->raw_iter); break; } return result; }
int32_t qd_parse_as_int(qd_parsed_field_t *field) { int32_t result = 0; qd_iterator_reset(field->raw_iter); switch (field->tag) { case QD_AMQP_INT: result |= ((int32_t) qd_iterator_octet(field->raw_iter)) << 24; result |= ((int32_t) qd_iterator_octet(field->raw_iter)) << 16; // Fall Through... case QD_AMQP_SHORT: result |= ((int32_t) qd_iterator_octet(field->raw_iter)) << 8; // Fall Through... case QD_AMQP_BYTE: case QD_AMQP_BOOLEAN: result |= (int32_t) qd_iterator_octet(field->raw_iter); break; case QD_AMQP_SMALLINT: result = (int8_t) qd_iterator_octet(field->raw_iter); break; case QD_AMQP_TRUE: result = 1; break; } return result; }
uint64_t qd_parse_as_ulong(qd_parsed_field_t *field) { uint64_t result = 0; qd_iterator_reset(field->raw_iter); switch (field->tag) { case QD_AMQP_ULONG: case QD_AMQP_TIMESTAMP: result |= ((uint64_t) qd_iterator_octet(field->raw_iter)) << 56; result |= ((uint64_t) qd_iterator_octet(field->raw_iter)) << 48; result |= ((uint64_t) qd_iterator_octet(field->raw_iter)) << 40; result |= ((uint64_t) qd_iterator_octet(field->raw_iter)) << 32; result |= ((uint64_t) qd_iterator_octet(field->raw_iter)) << 24; result |= ((uint64_t) qd_iterator_octet(field->raw_iter)) << 16; result |= ((uint64_t) qd_iterator_octet(field->raw_iter)) << 8; // Fall Through... case QD_AMQP_SMALLULONG: result |= (uint64_t) qd_iterator_octet(field->raw_iter); // Fall Through... case QD_AMQP_ULONG0: break; } return result; }
qdr_field_t *qdr_field_from_iter(qd_iterator_t *iter) { if (!iter) return 0; qdr_field_t *field = new_qdr_field_t(); qd_buffer_t *buf; int remaining; int length; ZERO(field); qd_iterator_reset(iter); remaining = qd_iterator_remaining(iter); length = remaining; while (remaining) { buf = qd_buffer(); size_t cap = qd_buffer_capacity(buf); int copied = qd_iterator_ncopy(iter, qd_buffer_cursor(buf), cap); qd_buffer_insert(buf, copied); DEQ_INSERT_TAIL(field->buffers, buf); remaining = qd_iterator_remaining(iter); } field->iterator = qd_iterator_buffer(DEQ_HEAD(field->buffers), 0, length, ITER_VIEW_ALL); return field; }
bool qd_iterator_equal(qd_iterator_t *iter, const unsigned char *string) { if (!iter) return false; qd_iterator_reset(iter); while (!qd_iterator_end(iter) && *string) { if (*string != qd_iterator_octet(iter)) break; string++; } bool match = (qd_iterator_end(iter) && (*string == 0)); qd_iterator_reset(iter); return match; }
static char *test_trim(void *context) { qd_iterator_t *iter = qd_iterator_string("testing.trim", ITER_VIEW_ALL); qd_iterator_trim_view(iter, 7); if (!qd_iterator_equal(iter, (unsigned char*) "testing")) return "Trim on ITER_VIEW_ALL failed (1)"; qd_iterator_reset_view(iter, ITER_VIEW_ALL); if (!qd_iterator_equal(iter, (unsigned char*) "testing.trim")) return "Trim on ITER_VIEW_ALL failed (2)"; qd_iterator_advance(iter, 4); qd_iterator_trim_view(iter, 5); if (!qd_iterator_equal(iter, (unsigned char*) "ing.t")) return "Trim on ITER_VIEW_ALL failed (3)"; qd_iterator_reset_view(iter, ITER_VIEW_ADDRESS_HASH); qd_iterator_trim_view(iter, 9); if (!qd_iterator_equal(iter, (unsigned char*) "M0testing")) return "Trim on ITER_VIEW_ADDRESS_HASH failed"; qd_iterator_reset(iter); qd_iterator_annotate_space(iter, "my_space.", 9); qd_iterator_trim_view(iter, 18); if (!qd_iterator_equal(iter, (unsigned char*) "M0my_space.testing")) return "Trim on ITER_VIEW_ADDRESS_HASH (with space 1) failed"; qd_iterator_reset(iter); qd_iterator_trim_view(iter, 10); if (!qd_iterator_equal(iter, (unsigned char*) "M0my_space")) return "Trim on ITER_VIEW_ADDRESS_HASH (in space 1) failed"; qd_iterator_reset(iter); qd_iterator_trim_view(iter, 2); if (!qd_iterator_equal(iter, (unsigned char*) "M0")) return "Trim on ITER_VIEW_ADDRESS_HASH (in annotation 1) failed"; qd_iterator_reset(iter); qd_iterator_trim_view(iter, 1); if (!qd_iterator_equal(iter, (unsigned char*) "M")) return "Trim on ITER_VIEW_ADDRESS_HASH (in annotation 2) failed"; qd_iterator_free(iter); return 0; }
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; }
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_iterator_end(iter) && i < n) buffer[i++] = qd_iterator_octet(iter); return i; }
bool qd_parse_as_bool(qd_parsed_field_t *field) { bool result = false; qd_iterator_reset(field->raw_iter); switch (field->tag) { case QD_AMQP_BYTE: case QD_AMQP_BOOLEAN: result = !!qd_iterator_octet(field->raw_iter); break; case QD_AMQP_TRUE: result = true; break; } return result; }
const char *qd_parse_annotations_v1( bool strip_anno_in, qd_iterator_t *ma_iter_in, qd_parsed_field_t **ma_ingress, qd_parsed_field_t **ma_phase, qd_parsed_field_t **ma_to_override, qd_parsed_field_t **ma_trace, qd_iterator_pointer_t *blob_pointer, uint32_t *blob_item_count) { // Do full parse qd_iterator_reset(ma_iter_in); qd_parsed_turbo_list_t annos; uint32_t user_entries; uint32_t user_bytes; const char * parse_error = qd_parse_turbo(ma_iter_in, &annos, &user_entries, &user_bytes); if (parse_error) { return parse_error; } qd_parsed_turbo_t *anno; if (!strip_anno_in) { anno = DEQ_HEAD(annos); while (anno) { qd_iterator_t *key_iter = qd_iterator_buffer(anno->bufptr.buffer, anno->bufptr.cursor - qd_buffer_base(anno->bufptr.buffer), anno->size, ITER_VIEW_ALL); assert(key_iter); qd_parsed_field_t *key_field = qd_parse(key_iter); assert(key_field); qd_iterator_t *iter = qd_parse_raw(key_field); assert(iter); qd_parsed_turbo_t *anno_val = DEQ_NEXT(anno); assert(anno_val); qd_iterator_t *val_iter = qd_iterator_buffer(anno_val->bufptr.buffer, anno_val->bufptr.cursor - qd_buffer_base(anno_val->bufptr.buffer), anno_val->size, ITER_VIEW_ALL); assert(val_iter); qd_parsed_field_t *val_field = qd_parse(val_iter); assert(val_field); // Hoist the key name out of the buffers into a normal char array char key_name[QD_MA_MAX_KEY_LEN + 1]; (void)qd_iterator_strncpy(iter, key_name, QD_MA_MAX_KEY_LEN + 1); // transfer ownership of the extracted value to the message if (!strcmp(key_name, QD_MA_TRACE)) { *ma_trace = val_field; } else if (!strcmp(key_name, QD_MA_INGRESS)) { *ma_ingress = val_field; } else if (!strcmp(key_name, QD_MA_TO)) { *ma_to_override = val_field; } else if (!strcmp(key_name, QD_MA_PHASE)) { *ma_phase = val_field; } else { // TODO: this key had the QD_MA_PREFIX but it does not match // one of the actual fields. qd_parse_free(val_field); } qd_iterator_free(key_iter); qd_parse_free(key_field); qd_iterator_free(val_iter); // val_field is usually handed over to message_private and is freed anno = DEQ_NEXT(anno_val); } } anno = DEQ_HEAD(annos); while (anno) { DEQ_REMOVE_HEAD(annos); free_qd_parsed_turbo_t(anno); anno = DEQ_HEAD(annos); } // Adjust size of user annotation blob by the size of the router // annotations blob_pointer->remaining = user_bytes; assert(blob_pointer->remaining >= 0); *blob_item_count = user_entries; assert(*blob_item_count >= 0); return 0; }