From 8ec1588722809a35a7d149bff10de56424e2658a Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Wed, 25 Nov 2020 17:58:50 -0800 Subject: src: initial commit of jio WIP source This is a very quick and dirty experimental hack written in some sort of bastard continuation-passing style in C w/io_uring using journal-file introspection and manipulation duty as an excuse for its existence. Consider this unfinished prototype quality code. --- src/humane.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 src/humane.c (limited to 'src/humane.c') diff --git a/src/humane.c b/src/humane.c new file mode 100644 index 0000000..3fdce03 --- /dev/null +++ b/src/humane.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2020 - Vito Caputo - + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include + +#include "humane.h" + +/* Print bytes as a "human-readable" string in Si storage units into humane->buf and return it. */ +char * humane_bytes(humane_t *humane, uint64_t bytes) +{ + double z = bytes; + + static const char * units[] = { + "B", + "KiB", + "MiB", + "GiB", + "TiB", + "PiB", + "EiB", + }; + int order = 0; + + while (z >= 1024) { + order++; + z /= 1024; + } + + /* FIXME: isn't there a format specifier for adaptive precision? where %.2 means + * use a maximum of two digits but only extend a non-zero fraction up to that limit, + * i.e. don't produce outputs like 1.00. but produce 1.1 or 1.01, but 1.00 should be 1. + * I can't remember if there's a double format to do that, and can't waste more time + * reading the printf(3) man page. + */ + snprintf(humane->buf, sizeof(humane->buf), "%.2f %s", z, units[order]); + + return humane->buf; +} + + +#if 0 +/* TODO: when/if unit tests become a thing in this tree, turn this into one of them and assert the + * stringified "humane" outputs match expectations. + */ + +#define U64(x) UINT64_C(x) +int main(int argc, char *argv[]) +{ + uint64_t nums[] = { + 0, + U64(1), + U64(512), + U64(1024), + U64(1024) + U64(512), + U64(1024) * U64(1024), + U64(1024) * U64(1024) * U64(1024), + U64(1024) * U64(1024) * U64(1024) * U64(1024), + U64(1024) * U64(1024) * U64(1024) * U64(1024) * U64(1024), + U64(1024) * U64(1024) * U64(1024) * U64(1024) * U64(1024) * U64(1024), + UINT64_MAX, + }; + humane_t humane = {}; + + for (int i = 0; i < sizeof(nums) / sizeof(*nums); i++) + printf("%"PRIu64" humane: %s\n", nums[i], humane_bytes(&humane, nums[i])); +} +#endif -- cgit v1.2.3