Example #1
1
//===========================================================================
// Public API
//===========================================================================
void Dim::endpointQuery(
    int * cancelId,
    IEndpointNotify * notify,
    string_view name,
    int defaultPort
) {
    QueryTask * task = nullptr;
    for (;;) {
        *cancelId = ++s_lastCancelId;
        auto ib = s_tasks.try_emplace(*cancelId);
        if (ib.second) {
            task = &ib.first->second;
            break;
        }
    }
    task->id = *cancelId;
    task->notify = notify;

    // if the name is the string form of an address just return the address
    Endpoint end;
    if (parse(&end, name, defaultPort)) {
        task->ends.push_back(end);
        taskPushEvent(task);
        return;
    }

    // Asynchronous completion requires wchar version of:
    wstring wname{toWstring(name)};
    wstring wport{to_wstring(defaultPort)};

    // extract non-default port if present in name
    size_t pos = wname.rfind(L':');
    if (pos != string::npos) {
        wport = wname.substr(pos + 1);
        wname.resize(pos);
    }

    WinError err = GetAddrInfoExW(
        wname.c_str(),
        wport.c_str(),
        NS_ALL,
        NULL, // namespace provider id
        NULL, // hints
        &task->results,
        NULL, // timeout
        &task->overlapped(),
        &addressQueryCallback,
        &task->cancel
    );
    if (err != ERROR_IO_PENDING)
        addressQueryCallback(err, 0, &task->overlapped());
}