Skip to content

C++

More information about the API can be found from C++ API Reference.

The project is self-contained and has no dependency. A recent C++ compiler supporting C++20. We test GCC 12 or better, LLVM 14 or better and Microsoft Visual Studio 2022.

Ada uses cmake as a build system. It’s recommended to have cmake available in your system. Run the following commands to compile and build Ada locally.

  1. Prepare

    Terminal window
    cmake -B build
  2. Build

    Terminal window
    cmake --build build

Linux or macOS users can get started quickly with the single-header release:

  1. Download the single-header release

    Terminal window
    wget https://github.com/ada-url/ada/releases/download/v3.0.0/ada.cpp
    wget https://github.com/ada-url/ada/releases/download/v3.0.0/ada.h
  2. Create a demo.cpp file

    #include "ada.cpp"
    #include "ada.h"
    #include <iostream>
    int main(int, char *[]) {
    auto url = ada::parse("https://www.google.com");
    if (!url) {
    std::cout << "failure" << std::endl;
    return EXIT_FAILURE;
    }
    url->set_protocol("http");
    std::cout << url->get_protocol() << std::endl;
    std::cout << url->get_host() << std::endl;
    return EXIT_SUCCESS;
    }
  3. Compile and run

    Terminal window
    c++ -std=c++20 -o demo demo.cpp
    ./demo

    Output:

    http:
    www.google.com

Ada supports two URL instance types: ada::url and ada::url_aggregator. The ada::url_aggregator is smaller and backed by a precomputed serialized URL string; ada::url stores each component as a separate string.

Use the ada::parse function template to parse either type.

Parse and validate a URL from an ASCII or UTF-8 string

ada::result<ada::url_aggregator> url =
ada::parse<ada::url_aggregator>("https://www.google.com");
if (url) { /* URL is valid */ }

After calling parse function, you must check that the result is valid before accessing it when you are not sure that it will succeed. The following code is unsafe:

ada::result<ada::url_aggregator> url =
ada::parse<ada::url_aggregator>("some bad url");
url->get_href();

You should do…

ada::result<ada::url_aggregator> url =
ada::parse<ada::url_aggregator>("some bad url");
if(url) {
// next line is now safe:
url->get_href();
} else {
// report a parsing failure
}

For simplicity, in the examples below, we skip the check because we know that parsing succeeds.

auto url = ada::parse<ada::url_aggregator>("https://www.google.com");
url->set_username("username");
url->set_password("password");
// ada->get_href() will return "https://username:password@www.google.com/"
auto url = ada::parse<ada::url_aggregator>("https://www.google.com");
url->set_protocol("wss");
// url->get_protocol() will return "wss:"
// url->get_href() will return "wss://www.google.com/"
auto url = ada::parse<ada::url_aggregator>("https://www.google.com");
url->set_host("github.com");
// url->get_host() will return "github.com"
// you can use `url.set_hostname` depending on your usage.
auto url = ada::parse<ada::url_aggregator>("https://www.google.com");
url->set_port("8080");
// url->get_port() will return "8080"
auto url = ada::parse<ada::url_aggregator>("https://www.google.com");
url->set_pathname("/my-super-long-path")
// url->get_pathname() will return "/my-super-long-path"
auto url = ada::parse<ada::url_aggregator>("https://www.google.com");
url->set_search("target=self");
// url->get_search() will return "?target=self"
auto url = ada::parse<ada::url_aggregator>("https://www.google.com");
url->set_hash("is-this-the-real-life");
// url->get_hash() will return "#is-this-the-real-life"
ada::url_search_params search_params("a=b&c=d&e=f");
search_params.append("g=h");
search_params.get("g"); // will return "h"
auto keys = search_params.get_keys();
while (keys.has_next()) {
auto key = keys.next(); // "a", "c", "e", "g"
}

Ada includes a URLPattern implementation compatible with the web-platform tests. The implementation does not bundle a regex engine — you provide one that fits your security requirements.

// Define a regex engine conforming to the required interface.
// This example uses the V8 engine as used by Node.js and Cloudflare Workers.
class v8_regex_provider {
public:
v8_regex_provider() = default;
using regex_type = v8::Global<v8::RegExp>;
static std::optional<regex_type> create_instance(std::string_view pattern,
bool ignore_case);
static std::optional<std::vector<std::optional<std::string>>> regex_search(
std::string_view input, const regex_type& pattern);
static bool regex_match(std::string_view input, const regex_type& pattern);
};
// Define a URLPattern
auto pattern = ada::parse_url_pattern<v8_regex_provider>(
"/books/:id(\\d+)", "https://example.com");
if (!pattern) { return EXIT_FAILURE; }
// Match a URL
auto match = pattern->match("https://example.com/books/123");
// Test a URL
auto matched = pattern->test("https://example.com/books/123");

Ada provides a C interface for use from C or other languages that can bind to C libraries. See include/ada_c.h for the full API. Inputs must be ASCII or UTF-8.

#include "ada_c.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int c, char *arg[]) {
const char* input =
"https://username:password@www.google.com:8080/"
"pathname?query=true#hash-exists";
ada_url url = ada_parse(input, strlen(input));
if (!ada_is_valid(url)) { puts("failure"); return EXIT_FAILURE; }
ada_string href = ada_get_href(url);
printf("%.*s\n", (int)href.length, href.data);
// https://username:password@www.google.com:8080/pathname?query=true#hash-exists
ada_free(url);
return EXIT_SUCCESS;
}

When linking against Ada from C, link with the C++ compiler so the C++ standard library is available:

Terminal window
c++ -c ada.cpp -std=c++20
cc -c demo.c
c++ demo.o ada.o -o cdemo
./cdemo