static void qdr_agent_set_columns(qdr_query_t *query, qd_parsed_field_t *attribute_names, const char *qdr_columns[], int column_count) { if (!attribute_names || (qd_parse_tag(attribute_names) != QD_AMQP_LIST8 && qd_parse_tag(attribute_names) != QD_AMQP_LIST32) || qd_parse_sub_count(attribute_names) == 0 || qd_parse_sub_count(attribute_names) >= QDR_AGENT_MAX_COLUMNS) { // // Either the attribute_names field is absent, it's not a list, or it's an empty list. // In this case, we will include all available attributes. // int i; for (i = 0; i < column_count; i++) query->columns[i] = i; query->columns[i] = -1; assert(i < QDR_AGENT_MAX_COLUMNS); return; } // // We have a valid, non-empty attribute list. Set the columns appropriately. // uint32_t count = qd_parse_sub_count(attribute_names); uint32_t idx; for (idx = 0; idx < count; idx++) { qd_parsed_field_t *name = qd_parse_sub_value(attribute_names, idx); if (!name || (qd_parse_tag(name) != QD_AMQP_STR8_UTF8 && qd_parse_tag(name) != QD_AMQP_STR32_UTF8)) query->columns[idx] = QDR_AGENT_COLUMN_NULL; else { int j = 0; while (qdr_columns[j]) { qd_field_iterator_t *iter = qd_parse_raw(name); if (qd_field_iterator_equal(iter, (const unsigned char*) qdr_columns[j])) { query->columns[idx] = j; break; } j+=1; } } } query->columns[idx+1] = -1; }
qd_parsed_field_t *qd_parse_value_by_key(qd_parsed_field_t *field, const char *key) { uint32_t count = qd_parse_sub_count(field); for (uint32_t idx = 0; idx < count; idx++) { qd_parsed_field_t *sub = qd_parse_sub_key(field, idx); if (!sub) return 0; qd_iterator_t *iter = qd_parse_raw(sub); if (!iter) return 0; if (qd_iterator_equal(iter, (const unsigned char*) key)) { return qd_parse_sub_value(field, idx); } } return 0; }
static qd_iterator_t *router_annotate_message(qd_router_t *router, qd_parsed_field_t *in_ma, qd_message_t *msg, qd_bitmask_t **link_exclusions, bool strip_inbound_annotations) { qd_iterator_t *ingress_iter = 0; qd_parsed_field_t *trace = 0; qd_parsed_field_t *ingress = 0; qd_parsed_field_t *to = 0; qd_parsed_field_t *phase = 0; *link_exclusions = 0; if (in_ma && !strip_inbound_annotations) { uint32_t count = qd_parse_sub_count(in_ma); bool done = false; for (uint32_t idx = 0; idx < count && !done; idx++) { qd_parsed_field_t *sub = qd_parse_sub_key(in_ma, idx); if (!sub) continue; qd_iterator_t *iter = qd_parse_raw(sub); if (!iter) continue; if (qd_iterator_equal(iter, (unsigned char*) QD_MA_TRACE)) { trace = qd_parse_sub_value(in_ma, idx); } else if (qd_iterator_equal(iter, (unsigned char*) QD_MA_INGRESS)) { ingress = qd_parse_sub_value(in_ma, idx); } else if (qd_iterator_equal(iter, (unsigned char*) QD_MA_TO)) { to = qd_parse_sub_value(in_ma, idx); } else if (qd_iterator_equal(iter, (unsigned char*) QD_MA_PHASE)) { phase = qd_parse_sub_value(in_ma, idx); } done = trace && ingress && to && phase; } } // // QD_MA_TRACE: // If there is a trace field, append this router's ID to the trace. // If the router ID is already in the trace the msg has looped. // qd_composed_field_t *trace_field = qd_compose_subfield(0); qd_compose_start_list(trace_field); if (trace) { if (qd_parse_is_list(trace)) { // // Create a link-exclusion map for the items in the trace. This map will // contain a one-bit for each link that leads to a neighbor router that // the message has already passed through. // *link_exclusions = qd_tracemask_create(router->tracemask, trace); // // Append this router's ID to the trace. // uint32_t idx = 0; qd_parsed_field_t *trace_item = qd_parse_sub_value(trace, idx); while (trace_item) { qd_iterator_t *iter = qd_parse_raw(trace_item); qd_iterator_reset_view(iter, ITER_VIEW_ALL); qd_compose_insert_string_iterator(trace_field, iter); idx++; trace_item = qd_parse_sub_value(trace, idx); } } } qd_compose_insert_string(trace_field, node_id); qd_compose_end_list(trace_field); qd_message_set_trace_annotation(msg, trace_field); // // QD_MA_TO: // Preserve the existing value. // if (to) { qd_composed_field_t *to_field = qd_compose_subfield(0); qd_compose_insert_string_iterator(to_field, qd_parse_raw(to)); qd_message_set_to_override_annotation(msg, to_field); } // // QD_MA_PHASE: // Preserve the existing value. // if (phase) { int phase_val = qd_parse_as_int(phase); qd_message_set_phase_annotation(msg, phase_val); } // // QD_MA_INGRESS: // If there is no ingress field, annotate the ingress as // this router else keep the original field. // qd_composed_field_t *ingress_field = qd_compose_subfield(0); if (ingress && qd_parse_is_scalar(ingress)) { ingress_iter = qd_parse_raw(ingress); qd_compose_insert_string_iterator(ingress_field, ingress_iter); } else qd_compose_insert_string(ingress_field, node_id); qd_message_set_ingress_annotation(msg, ingress_field); // // Return the iterator to the ingress field _if_ it was present. // If we added the ingress, return NULL. // return ingress_iter; }
static char *test_map(void *context) { static char error[1000]; const char *data = "\xd1\x00\x00\x00\x2d\x00\x00\x00\x06" // map32, 6 items "\xa3\x05\x66irst\xa1\x0evalue_of_first" // (23) "first":"value_of_first" "\xa3\x06second\x52\x20" // (10) "second":32 "\xa3\x05third\x41"; // (8) "third":true int data_len = 50; qd_iterator_t *data_iter = qd_iterator_binary(data, data_len, ITER_VIEW_ALL); qd_parsed_field_t *field = qd_parse(data_iter); if (!qd_parse_ok(field)) { snprintf(error, 1000, "Parse failed: %s", qd_parse_error(field)); qd_iterator_free(data_iter); qd_parse_free(field); return error; } if (!qd_parse_is_map(field)) { qd_iterator_free(data_iter); qd_parse_free(field); return "Expected field to be a map"; } uint32_t count = qd_parse_sub_count(field); if (count != 3) { snprintf(error, 1000, "Expected sub-count==3, got %"PRIu32, count); qd_iterator_free(data_iter); qd_parse_free(field); return error; } qd_parsed_field_t *key_field = qd_parse_sub_key(field, 0); qd_iterator_t *key_iter = qd_parse_raw(key_field); qd_iterator_t *typed_iter = qd_parse_typed(key_field); if (!qd_iterator_equal(key_iter, (unsigned char*) "first")) { unsigned char *result = qd_iterator_copy(key_iter); snprintf(error, 1000, "First key: expected 'first', got '%s'", result); free (result); return error; } if (!qd_iterator_equal(typed_iter, (unsigned char*) "\xa3\x05\x66irst")) return "Incorrect typed iterator on first-key"; qd_parsed_field_t *val_field = qd_parse_sub_value(field, 0); qd_iterator_t *val_iter = qd_parse_raw(val_field); typed_iter = qd_parse_typed(val_field); if (!qd_iterator_equal(val_iter, (unsigned char*) "value_of_first")) { unsigned char *result = qd_iterator_copy(val_iter); snprintf(error, 1000, "First value: expected 'value_of_first', got '%s'", result); free (result); return error; } if (!qd_iterator_equal(typed_iter, (unsigned char*) "\xa1\x0evalue_of_first")) return "Incorrect typed iterator on first-key"; key_field = qd_parse_sub_key(field, 1); key_iter = qd_parse_raw(key_field); if (!qd_iterator_equal(key_iter, (unsigned char*) "second")) { unsigned char *result = qd_iterator_copy(key_iter); snprintf(error, 1000, "Second key: expected 'second', got '%s'", result); free (result); return error; } val_field = qd_parse_sub_value(field, 1); if (qd_parse_as_uint(val_field) != 32) { snprintf(error, 1000, "Second value: expected 32, got %"PRIu32, qd_parse_as_uint(val_field)); return error; } key_field = qd_parse_sub_key(field, 2); key_iter = qd_parse_raw(key_field); if (!qd_iterator_equal(key_iter, (unsigned char*) "third")) { unsigned char *result = qd_iterator_copy(key_iter); snprintf(error, 1000, "Third key: expected 'third', got '%s'", result); free (result); return error; } val_field = qd_parse_sub_value(field, 2); if (!qd_parse_as_bool(val_field)) { snprintf(error, 1000, "Third value: expected true"); return error; } qd_iterator_free(data_iter); qd_parse_free(field); return 0; }
PyObject *qd_field_to_py(qd_parsed_field_t *field) { qd_python_check_lock(); PyObject *result = 0; uint8_t tag = qd_parse_tag(field); switch (tag) { case QD_AMQP_NULL: Py_INCREF(Py_None); result = Py_None; break; case QD_AMQP_BOOLEAN: case QD_AMQP_TRUE: case QD_AMQP_FALSE: result = qd_parse_as_uint(field) ? Py_True : Py_False; break; case QD_AMQP_UBYTE: case QD_AMQP_USHORT: case QD_AMQP_UINT: case QD_AMQP_SMALLUINT: case QD_AMQP_UINT0: result = PyInt_FromLong((long) qd_parse_as_uint(field)); break; case QD_AMQP_ULONG: case QD_AMQP_SMALLULONG: case QD_AMQP_ULONG0: case QD_AMQP_TIMESTAMP: result = PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) qd_parse_as_ulong(field)); break; case QD_AMQP_BYTE: case QD_AMQP_SHORT: case QD_AMQP_INT: case QD_AMQP_SMALLINT: result = PyInt_FromLong((long) qd_parse_as_int(field)); break; case QD_AMQP_LONG: case QD_AMQP_SMALLLONG: result = PyLong_FromLongLong((PY_LONG_LONG)qd_parse_as_long(field)); break; case QD_AMQP_FLOAT: case QD_AMQP_DOUBLE: case QD_AMQP_DECIMAL32: case QD_AMQP_DECIMAL64: case QD_AMQP_DECIMAL128: case QD_AMQP_UTF32: case QD_AMQP_UUID: break; case QD_AMQP_VBIN8: case QD_AMQP_VBIN32: case QD_AMQP_STR8_UTF8: case QD_AMQP_STR32_UTF8: case QD_AMQP_SYM8: case QD_AMQP_SYM32: result = parsed_to_py_string(field); break; case QD_AMQP_LIST0: case QD_AMQP_LIST8: case QD_AMQP_LIST32: { uint32_t count = qd_parse_sub_count(field); result = PyList_New(count); for (uint32_t idx = 0; idx < count; idx++) { qd_parsed_field_t *sub = qd_parse_sub_value(field, idx); PyObject *pysub = qd_field_to_py(sub); if (pysub == 0) return 0; PyList_SetItem(result, idx, pysub); } break; } case QD_AMQP_MAP8: case QD_AMQP_MAP32: { uint32_t count = qd_parse_sub_count(field); result = PyDict_New(); for (uint32_t idx = 0; idx < count; idx++) { qd_parsed_field_t *key = qd_parse_sub_key(field, idx); qd_parsed_field_t *val = qd_parse_sub_value(field, idx); PyObject *pykey = parsed_to_py_string(key); PyObject *pyval = qd_field_to_py(val); if (pyval == 0) return 0; PyDict_SetItem(result, pykey, pyval); Py_DECREF(pykey); Py_DECREF(pyval); } break; } case QD_AMQP_ARRAY8: case QD_AMQP_ARRAY32: break; } if (!result) Py_RETURN_NONE; return result; }