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); }
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; }
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; }
void qd_iterator_advance(qd_iterator_t *iter, uint32_t length) { 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_iterator_octet(iter); length--; } } }
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->view_pointer; char current_octet = 0; while (!qd_iterator_end(iter)) { current_octet = qd_iterator_octet(iter); } // We have the last octet in current_octet iter->view_pointer = save_pointer; if (current_octet && strrchr(SEPARATORS, (int) current_octet)) iter->view_pointer.remaining--; }
/** * size = the number of bytes following the tag * count = the number of elements. Applies only to compound structures */ static char *get_type_info(qd_iterator_t *iter, uint8_t *tag, uint32_t *size, uint32_t *count, uint32_t *length_of_size, uint32_t *length_of_count) { if (qd_iterator_end(iter)) return "Insufficient Data to Determine Tag"; *tag = qd_iterator_octet(iter); *count = 0; *size = 0; *length_of_count = 0; *length_of_size = 0; switch (*tag & 0xF0) { case 0x40: *size = 0; break; case 0x50: *size = 1; break; case 0x60: *size = 2; break; case 0x70: *size = 4; break; case 0x80: *size = 8; break; case 0x90: *size = 16; break; case 0xB0: case 0xD0: case 0xF0: *size += ((unsigned int) qd_iterator_octet(iter)) << 24; *size += ((unsigned int) qd_iterator_octet(iter)) << 16; *size += ((unsigned int) qd_iterator_octet(iter)) << 8; *length_of_size = 3; // fall through to the next case case 0xA0: case 0xC0: case 0xE0: if (qd_iterator_end(iter)) return "Insufficient Data to Determine Length"; *size += (unsigned int) qd_iterator_octet(iter); *length_of_size += 1; break; default: return "Invalid Tag - No Length Information"; } switch (*tag & 0xF0) { case 0xD0: case 0xF0: *count += ((unsigned int) qd_iterator_octet(iter)) << 24; *count += ((unsigned int) qd_iterator_octet(iter)) << 16; *count += ((unsigned int) qd_iterator_octet(iter)) << 8; *length_of_count = 3; // fall through to the next case case 0xC0: case 0xE0: if (qd_iterator_end(iter)) return "Insufficient Data to Determine Count"; *count += (unsigned int) qd_iterator_octet(iter); *length_of_count += 1; break; } if ((*tag == QD_AMQP_MAP8 || *tag == QD_AMQP_MAP32) && (*count & 1)) return "Odd Number of Elements in a Map"; if (*length_of_count > *size) return "Insufficient Length to Determine Count"; return 0; }
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_BODY; iter->prefix = '\0'; iter->mode = MODE_TO_END; iter->annotation_length = 0; iter->annotation_remaining = 0; if (iter->view == ITER_VIEW_ALL) return; // // Advance to the node-id. // state_t state = STATE_START; unsigned int octet; pointer_t save_pointer = {0,0,0}; 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->view_pointer; } else state = STATE_SCANNING; break; case STATE_SLASH_LEFT : if (octet == '/') state = STATE_SKIPPING_TO_NEXT_SLASH; else { state = STATE_AT_NODE_ID; iter->view_pointer = save_pointer; } break; case STATE_SKIPPING_TO_NEXT_SLASH : if (octet == '/') state = STATE_AT_NODE_ID; break; case STATE_SCANNING : if (octet == ':') state = STATE_COLON; break; case STATE_COLON : if (octet == '/') { state = STATE_COLON_SLASH; save_pointer = iter->view_pointer; } else state = STATE_SCANNING; break; case STATE_COLON_SLASH : if (octet == '/') state = STATE_SKIPPING_TO_NEXT_SLASH; else { state = STATE_AT_NODE_ID; iter->view_pointer = save_pointer; } break; case STATE_AT_NODE_ID : break; } } if (state != STATE_AT_NODE_ID){ // // The address string was relative, not absolute. The node-id // is at the beginning of the string. // iter->view_pointer = iter->start_pointer; } // // Cursor is now on the first octet of the node-id // if (iter->view == ITER_VIEW_ADDRESS_NO_HOST) return; if (iter->view == ITER_VIEW_ADDRESS_HASH) { qd_iterator_remove_trailing_separator(iter); // FIXME - need this? parse_address_view(iter); return; } if (iter->view == ITER_VIEW_NODE_HASH) { parse_node_view(iter); return; } }