| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #include "router_core_private.h" |
| #include <stdio.h> |
| |
| |
| // The AMQP 'error' type |
| // |
| // The AMQP standard defines an 'error' type for expressing various formal |
| // errors. Corresponds to a Proton Condition (pn_condition_t) that is associate |
| // with the Proton Disposition (pn_disposition_t). |
| // |
| struct qdr_error_t { |
| qdr_field_t *name; // symbol, e.g. "amqp:connection:forced" |
| qdr_field_t *description; // string |
| pn_data_t *info; // symbol-keyed map |
| }; |
| |
| ALLOC_DECLARE(qdr_error_t); |
| ALLOC_DEFINE(qdr_error_t); |
| |
| qdr_error_t *qdr_error_from_pn(pn_condition_t *pn) |
| { |
| if (!pn) |
| return 0; |
| |
| qdr_error_t *error = 0; |
| |
| const char *name = pn_condition_get_name(pn); |
| const char *desc = pn_condition_get_description(pn); |
| pn_data_t *info = pn_condition_info(pn); |
| const bool info_ok = (info && pn_data_size(info) > 0); |
| |
| if ((name && *name) || (desc && *desc) || info_ok) { |
| error = new_qdr_error_t(); |
| ZERO(error); |
| |
| if (name && *name) |
| error->name = qdr_field(name); |
| |
| if (desc && *desc) |
| error->description = qdr_field(desc); |
| |
| if (info_ok) { |
| error->info = pn_data(0); |
| pn_data_copy(error->info, info); |
| } |
| } |
| |
| return error; |
| } |
| |
| |
| qdr_error_t *qdr_error(const char *name, const char *description) |
| { |
| qdr_error_t *error = new_qdr_error_t(); |
| |
| error->name = qdr_field(name); |
| error->description = qdr_field(description); |
| error->info = 0; |
| |
| return error; |
| } |
| |
| |
| void qdr_error_free(qdr_error_t *error) |
| { |
| if (error == 0) |
| return; |
| |
| qdr_field_free(error->name); |
| qdr_field_free(error->description); |
| if (error->info) |
| pn_data_free(error->info); |
| |
| free_qdr_error_t(error); |
| } |
| |
| |
| void qdr_error_copy(qdr_error_t *from, pn_condition_t *to) |
| { |
| if (from == 0) |
| return; |
| |
| if (from->name) { |
| unsigned char *name = qd_iterator_copy(from->name->iterator); |
| pn_condition_set_name(to, (char*) name); |
| free(name); |
| } |
| |
| if (from->description) { |
| unsigned char *desc = qd_iterator_copy(from->description->iterator); |
| pn_condition_set_description(to, (char*) desc); |
| free(desc); |
| } |
| |
| if (from->info) |
| pn_data_copy(pn_condition_info(to), from->info); |
| } |
| |
| |
| char *qdr_error_description(const qdr_error_t *err) |
| { |
| if (!err || !err->description || !err->description->iterator) |
| return 0; |
| int length = qd_iterator_length(err->description->iterator); |
| char *text = (char*) malloc(length + 1); |
| qd_iterator_ncopy(err->description->iterator, (unsigned char*) text, length); |
| text[length] = '\0'; |
| return text; |
| } |
| |
| char *qdr_error_name(const qdr_error_t *err) |
| { |
| if (!err || !err->name || !err->name->iterator) |
| return 0; |
| int length = qd_iterator_length(err->name->iterator); |
| char *text = (char*) malloc(length + 1); |
| qd_iterator_ncopy(err->name->iterator, (unsigned char*) text, length); |
| text[length] = '\0'; |
| return text; |
| } |
| |
| |
| pn_data_t *qdr_error_info(const qdr_error_t *err) |
| { |
| if (err == 0) |
| return 0; |
| |
| return err->info; |
| } |
| |