A C++ cross-platform library including JSON, XML, HTTP, Sockets, WebSockets, threads, processes, logs, file system, CSV, INI files, etc.
An old, bad and outdated C++ utility library
ASL is a collection of multiplatform general purpose classes and utilities focused on simplicity and ease of use. Builds in seconds and facilitates writing code that works on different operating systems and compilers.
OS-related functionalities:
Utilities:
Basic data types:
Here are some snippets that showcase some simple uses of ASL. There are also more complex ways
of using the library with added functionalities. Namespace asl
omitted for clarity.
Get command line options (suppose we run program.exe -iterations 10
):
CmdArgs args(argc, argv);
int iterations = args["iterations"] | 10; // default to 10 if no parameter given
Read or write a configuration INI file (“config.ini” contains this):
[parameters]
threshold=0.25
IniFile config("config.ini");
float threshold = config["parameters/threshold"] | 0.2;
config.set("parameters/threshold", 0.5);
Do HTTP requests (you can post a body or send headers, too):
HttpResponse resp = Http::get("https://www.somewhere.com/page.xhtml");
if(resp.code() != 200)
return -1;
String type = resp.header("Content-Type");
String text = resp.text();
Or create HTTP services:
struct TimeServer : public HttpServer
{
void serve(HttpRequest& req, HttpResponse& resp)
{
if(req.is("GET", "/time")
{
resp.put(Var{{"time", Date::now().toString()}});
}
else
{
resp.put(Var{{"status", "error"}});
resp.setCode(500);
}
}
};
TimeServer server;
server.bind(80);
server.start();
Decode XML:
Xml html = Xml::decode( "<html><head><meta charset='utf8'/></head></html>" );
String charset = html("head")("meta")["charset"]; // -> "utf8"
String rootTag = html.tag(); // -> "html"
Read or write a file in one line:
String content = TextFile("somefile-uнicoδe.json").text();
The path given above can be Unicode UTF8, and the file content can be UTF8 with or wothout BOM,
UTF16-BE or UTF16-LE. And it will be converted to UTF8.
Emulate a simple wget
:
File("image.png").put( Http::get("http://hello.com/image.png").body() );
Decode JSON (but you can also directly load/save JSON from a file):
Var data = Json::decode(content);
String name = data["name"];
int number = data["age"];
Write JSON:
Var particle = Var{
{"name", "proton"},
{"mass", 1.67e-27},
{"position", {x, y, z}}
};
String json = Json::encode(particle);
Write to the console with colors:
Console console;
console.color(Console::BRED); // bright red text
console.bgcolor(Console::CYAN); // cyan background
printf("some highlighted text");
Create threads (but you can also use lambdas):
class MyThread : public Thread
{
void run() { do_stuff(); }
};
MyThread thread;
thread.start();
Send data through a TCP socket (that will try different hosts
if DNS “host” maps to several IPv4 or IPv6 addresses):
Socket socket; // or TlsSocket for SSL/TLS
socket.connect("host", 9000);
socket << "hello\n";
Or a message through a WebSocket:
WebSocket socket;
socket.connect("host", 9000); // or "ws://host:9000"
socket.send("hello");
Strings are 8 bit, by default assumed to be UTF8, and can be case converted even beyond ASCII:
String country = "Ελλάδα";
String upper = country.toUpperCase(); // -> "ΕΛΛΆΔΑ"
Strings have some additional handy methods:
if(filename.startsWith(prefix) || filename.contains("-"))
A string can be split and joined back:
String names = "one,two,three";
Array<String> numbers = names.split(",");
String s123 = numbers.join(" "); // -> "one two three"
and can be automatically converted to UTF16:
String dirname = "newdir";
CreateDirectoryW( dirname ); // autoconverted to UTF16
But don’t use the above Windows-only function when you can (in UTF8):
Directory::create("newdir");
or enumerate the contents of a directory:
Directory dir("some/dir");
for(File& file : dir.files("*.txt"))
{
String path = file.path();
Long size = file.size();
Date date = file.lastModified();
}
Copy, move or delete files:
File("letter.doc").copy("/backup/");
File("file.conf").move("file.ini");
File("trash.doc").remove();
Directory::remove("/trash/"); // must be empty
Start a subprocess and read its output:
Process p = Process::execute("someprogram.exe");
if(p.success())
output = p.output();
Get the parent directory, file name and extension of a path:
Path path = "/some/dir/file.txt";
path.directory() // -> "/some/dir/"
path.name() // -> "file.txt"
path.nameNoExt() // -> "file"
path.extension() // -> "txt"
Time an operation with precision (around microseconds) and sleep for some time:
double t1 = now();
sleep(0.5); // 0.5 seconds
double t2 = now();
double elapsed = t2 - t1; // should be around 0.5
Log a message to the console and to a file:
ASL_LOG_W("Only %i bytes available", bytesAvailable);
And much more.
ASL can be used as a static or as a dynamic/shared library. The easiest way to
build and use it is with CMake (2.8.12 or later). By default both the dynamic
and static libraries are built.
Just compile the library with whatever compilers and architecturs (32/64bit) you need. There is no need to install.
To use the library in another project just find the ASL package and link against one of
the imported targets, asl
for the dynamic version or asls
for the static version. The static library is recommended
as you don’t need to copy or distribute a DLL at runtime.
find_package(ASL REQUIRED)
target_link_libraries(my_application asls) # for the static version, or
target_link_libraries(my_application asl) # for the dynamic library
There is no need to provide the library directory or set include_directories. find_package
will
find the library compatible with the current project among the versions compiled.
With CMmake 3.14+, instead of using find_package()
, you can download and build the library automatically as a subproject (and then link with it as before):
include(FetchContent)
FetchContent_Declare(asl URL https://github.com/aslze/asl/archive/1.11.12.zip)
FetchContent_MakeAvailable(asl)
Remember that all header files have the asl/
prefix directory and are named like the class they define
(case-sensitively), and that all symbols are in the asl
namespace. So, for example, to use the Directory
class:
#include <asl/Directory.h>
asl::Directory dir;
HTTPS, TLS WebSockets and TlsSocket require the mbedTLS library (up to v3.2.1). Download and compile
the library, enable ASL_TLS
in CMake and provide the mbedTLS install directory (and library locations, which should
normally be automatically found).
On Ubuntu Linux you can just install package libmbedtls-dev with:
sudo apt-get install libmbedtls-dev
On FreeBSD use:
pkg install mbedtls
With a recent CMake (3.14+) you can also build mbedTLS together with ASL as subprojects (e.g. using FetchContent
):
set(ASL_TLS ON)
set(ENABLE_PROGRAMS OFF CACHE BOOL "") # skip samples
FetchContent_Declare(mbedtls URL https://github.com/Mbed-TLS/mbedtls/archive/v3.2.1.zip)
FetchContent_Declare(asl URL https://github.com/aslze/asl/archive/1.11.12.zip)
FetchContent_MakeAvailable(mbedtls asl)
Then just link your project to asls
after that block.