napi_value aws_napi_mqtt_client_connection_publish()

in source/mqtt_client_connection.c [911:1007]


napi_value aws_napi_mqtt_client_connection_publish(napi_env env, napi_callback_info info) {

    struct aws_allocator *allocator = aws_napi_get_allocator();

    struct puback_args *args = aws_mem_calloc(allocator, 1, sizeof(struct puback_args));
    AWS_FATAL_ASSERT(args);
    args->allocator = allocator;

    struct aws_byte_buf topic_buf;
    struct aws_byte_buf payload_buf;
    AWS_ZERO_STRUCT(topic_buf);
    AWS_ZERO_STRUCT(payload_buf);

    napi_value node_args[6];
    size_t num_args = AWS_ARRAY_SIZE(node_args);
    napi_value *arg = &node_args[0];
    AWS_NAPI_CALL(env, napi_get_cb_info(env, info, &num_args, node_args, NULL, NULL), {
        napi_throw_error(env, NULL, "Failed to retreive callback information");
        goto cleanup;
    });
    if (num_args != AWS_ARRAY_SIZE(node_args)) {
        napi_throw_error(env, NULL, "mqtt_client_connection_publish needs exactly 6 arguments");
        goto cleanup;
    }

    napi_value node_binding = *arg++;
    struct mqtt_connection_binding *binding = NULL;
    AWS_NAPI_CALL(env, napi_get_value_external(env, node_binding, (void **)&binding), {
        napi_throw_error(env, NULL, "Failed to extract binding from external");
        goto cleanup;
    });

    args->binding = binding;

    napi_value node_topic = *arg++;
    AWS_NAPI_CALL(env, aws_byte_buf_init_from_napi(&topic_buf, env, node_topic), {
        napi_throw_type_error(env, NULL, "topic must be a String");
        goto cleanup;
    });

    napi_value node_payload = *arg++;
    AWS_NAPI_CALL(env, aws_byte_buf_init_from_napi(&payload_buf, env, node_payload), {
        napi_throw_type_error(env, NULL, "payload is invalid type");
        goto cleanup;
    });

    napi_value node_qos = *arg++;
    uint32_t qos_uint = 0;
    AWS_NAPI_CALL(env, napi_get_value_uint32(env, node_qos, &qos_uint), {
        napi_throw_type_error(env, NULL, "qos must be a number");
        goto cleanup;
    });
    enum aws_mqtt_qos qos = (enum aws_mqtt_qos)qos_uint;

    napi_value node_retain = *arg++;
    bool retain = false;
    AWS_NAPI_CALL(env, napi_get_value_bool(env, node_retain, &retain), {
        napi_throw_type_error(env, NULL, "retain must be a bool");
        goto cleanup;
    });

    napi_value node_on_puback = *arg++;
    if (!aws_napi_is_null_or_undefined(env, node_on_puback)) {
        AWS_NAPI_CALL(
            env,
            aws_napi_create_threadsafe_function(
                env,
                node_on_puback,
                "aws_mqtt_client_connection_on_puback",
                s_on_publish_complete_call,
                binding,
                &args->on_puback),
            { goto cleanup; });
    }

    const struct aws_byte_cursor topic_cur = aws_byte_cursor_from_buf(&topic_buf);
    const struct aws_byte_cursor payload_cur = aws_byte_cursor_from_buf(&payload_buf);
    uint16_t pub_id = aws_mqtt_client_connection_publish(
        binding->connection, &topic_cur, qos, retain, &payload_cur, s_on_publish_complete, args);
    if (!pub_id) {
        aws_napi_throw_last_error(env);
        goto cleanup;
    }

    aws_byte_buf_clean_up(&payload_buf);
    aws_byte_buf_clean_up(&topic_buf);
    return NULL;

cleanup:

    aws_byte_buf_clean_up(&payload_buf);
    aws_byte_buf_clean_up(&topic_buf);

    s_destroy_puback_args(args);

    return NULL;
}