commit 09b6fe75ba71320f3f386d9c5ee0eb2f8094e555 Author: cinqatte Date: Thu Oct 3 14:49:23 2024 +0200 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c901ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.idea +.vs +.vscode +build \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..96b6328 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,44 @@ +cmake_minimum_required(VERSION 3.10) + +project(numa VERSION 0.0.0 LANGUAGES C) + +set(CMAKE_C_STANDARD 99) +set(CMAKE_C_STANDARD_REQUIRED ON) + +set(INSTALL_DIR "/usr/local" CACHE PATH "installation directory") +option(BUILD_SHARED_LIBS "build as shared library" OFF) + +include_directories(${PROJECT_SOURCE_DIR}/include) + +set(SOURCE_FILES numa.c) +set(HEADER_FILES numa.h) + +if(BUILD_SHARED_LIBS) + add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES}) +else() + add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES}) +endif() + +set_target_properties(${PROJECT_NAME} PROPERTIES + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) + +install(TARGETS ${PROJECT_NAME} + LIBRARY DESTINATION ${INSTALL_DIR}/lib + ARCHIVE DESTINATION ${INSTALL_DIR}/lib +) + +install(FILES ${HEADER_FILES} DESTINATION ${INSTALL_DIR}/include) + +message(STATUS "") +message(STATUS "===== numa configuration summary =====") +message(STATUS "library name: ${PROJECT_NAME}") +if(BUILD_SHARED_LIBS) + message(STATUS "library type: shared") +else() + message(STATUS "library type: static") +endif() +message(STATUS "install directory: ${INSTALL_DIR}") +message(STATUS "======================================") +message(STATUS "") diff --git a/README.md b/README.md new file mode 100644 index 0000000..fd78ec0 --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Numa Library + +## Description + +Numa Library is a lightweight C library that provides functionality to generate hexadecimal dumps of binary data. It's designed to be easy to use, efficient, and flexible. + +## Key Features + +- Customizable output format +- Support for different grouping sizes (1, 2, 4, or 8 bytes) +- ASCII representation alongside hex output +- Configurable number of bytes per row + +## Installation + +### Prerequisities + +- CMake (version 3.10 or higher) +- A C compiler (supporting C99 standard) + + +### Building the Library + +1. For the default static library build +```shell +cmake -B build +cmake --build build +``` +2. To build a shared library: +```shell +cmake -B build -DBUILD_SHARED_LIBS=ON +cmake --build build +``` + +### Installing the Library + +To install the library to the default location (/usr/local): +```shell +sudo cmake --install build +``` + +To specify a custom installation directory: +```shell +cmake -B build -DINSTALL_DIR=/usr +cmake --build build +cmake --install build +``` \ No newline at end of file diff --git a/numa.c b/numa.c new file mode 100644 index 0000000..2034f1b --- /dev/null +++ b/numa.c @@ -0,0 +1,55 @@ +#include "numa.h" +#include +#include + +void numa(const uint8_t *data, uint32_t length, uint16_t width, uint8_t bytes) { + uint32_t i, j; + for (i = 0; i < length; i += width) { + printf("%08x: ", i); + + for (j = 0; j < width; j += bytes) { + if (i + j < length) { + switch (bytes) { + case 1: printf("%02x ", data[i + j]); break; + case 2: + if (i + j + 1 < length) + printf("%04x ", *((uint16_t *)(data + i + j))); + else + printf("%02x ", data[i + j]); + break; + case 4: + if (i + j + 3 < length) + printf("%08x ", *((uint32_t *)(data + i + j))); + else { + for (int k = 0; k < 4 && i + j + k < length; k++) + printf("%02x", data[i + j + k]); + printf("%*s", 2 * (4 - (length - (i + j))), ""); + } + break; + case 8: + if (i + j + 7 < length) + printf("%016lx ", *((uint64_t *)(data + i + j))); + else { + for (int k = 0; k < 8 && i + j + k < length; k++) + printf("%02x", data[i + j + k]); + printf("%*s", 2 * (8 - (length - (i + j))), ""); + } + break; + default: + fprintf(stderr, "Unsupported byte width\n"); + return; + } + } else { + printf("%*s", bytes * 2 + 1, ""); + } + } + + // Print ASCII representation + printf(" | "); + for (j = 0; j < width && i + j < length; ++j) { + uint8_t byte = data[i + j]; + printf("%c", isprint(byte) ? byte : '.'); + } + printf("\n"); + } +} \ No newline at end of file diff --git a/numa.h b/numa.h new file mode 100644 index 0000000..09c5bc7 --- /dev/null +++ b/numa.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +/** + * @brief prints a hexadecimal dump of the given data + * + * This function prints offset, hexadecimal representation, and ASCII representation. + * + * @param data pointer to the input data buffer + * @param length length of the input data in bytes + * @param width number of bytes to display per row + * @param bytes number of bytes to group together (1, 2, 4, or 8) + * + * @note The function supports grouping bytes in 1, 2, 4, or 8 byte chunks. + * For multi-byte groupings, the data is interpreted as little-endian. + * + * @warning if an unsupported byte width is provided, the function will print + * an error message to stderr and return without processing the data +*/ +void numa(const uint8_t * data, uint32_t length, uint16_t width, uint8_t bytes);