mirror of
https://github.com/tezc/sc.git
synced 2025-01-28 07:03:06 +08:00
create sc for utility functions
This commit is contained in:
parent
ed0e154a83
commit
42865541c6
@ -20,13 +20,12 @@ add_subdirectory(ini)
|
||||
add_subdirectory(linked-list)
|
||||
add_subdirectory(logger)
|
||||
add_subdirectory(map)
|
||||
add_subdirectory(math)
|
||||
add_subdirectory(memory-map)
|
||||
add_subdirectory(mutex)
|
||||
add_subdirectory(option)
|
||||
add_subdirectory(queue)
|
||||
add_subdirectory(perf)
|
||||
add_subdirectory(rc4)
|
||||
add_subdirectory(sc)
|
||||
add_subdirectory(signal)
|
||||
add_subdirectory(socket)
|
||||
add_subdirectory(string)
|
||||
|
@ -22,13 +22,12 @@ CI runs on Linux, MacOS, FreeBSD and Windows with gcc, clang and msvc.
|
||||
| **[linked list](linked-list)** | Intrusive linked list |
|
||||
| **[logger](logger)** | Logger |
|
||||
| **[map](map)** | A high performance open addressing hashmap |
|
||||
| **[math](math)** | Utility functions |
|
||||
| **[memory map](memory-map)** | Mmap wrapper for Posix and Windows |
|
||||
| **[mutex](mutex)** | Mutex wrapper for Posix and Windows |
|
||||
| **[option](option)** | Cmdline argument parser. Very basic one |
|
||||
| **[perf](perf)** | Benchmark utility to get performance counters info via perf_event_open() |
|
||||
| **[queue](queue)** | Generic queue which can be used as dequeue/stack/list as well |
|
||||
| **[rc4](rc4)** | Random number generator |
|
||||
| **[sc](sc)** | Utility functions |
|
||||
| **[signal](signal)** | Signal handler & signal safe snprintf (handling CTRL+C, printing backtrace on crash etc) |
|
||||
| **[socket](socket)** | Pipe, TCP sockets, Epoll/Kqueue/WSAPoll for Posix and Windows |
|
||||
| **[string](string)** | Length prefixed, null terminated C strings. |
|
||||
|
132
math/math_test.c
132
math/math_test.c
@ -1,132 +0,0 @@
|
||||
|
||||
|
||||
|
||||
#include "sc_math.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void test1()
|
||||
{
|
||||
uint64_t x;
|
||||
char *t;
|
||||
char buf[32];
|
||||
|
||||
assert(sc_math_min(199, 299) == 199);
|
||||
assert(sc_math_max(199, 299) == 299);
|
||||
assert(sc_math_is_pow2(0) == false);
|
||||
|
||||
x = sc_math_to_pow2(0);
|
||||
assert(x == 1);
|
||||
assert(sc_math_is_pow2(x) == true);
|
||||
x = sc_math_to_pow2(1);
|
||||
assert(x == 1);
|
||||
assert(sc_math_is_pow2(x) == true);
|
||||
x = sc_math_to_pow2(1023);
|
||||
assert(x == 1024);
|
||||
assert(sc_math_is_pow2(x) == true);
|
||||
|
||||
x = sc_math_size_to_bytes("1");
|
||||
assert(x == 1);
|
||||
x = sc_math_size_to_bytes("1b");
|
||||
assert(x == 1);
|
||||
|
||||
x = sc_math_size_to_bytes("1k");
|
||||
assert(x == 1 * 1024);
|
||||
x = sc_math_size_to_bytes("1kb");
|
||||
assert(x == 1 * 1024);
|
||||
|
||||
x = sc_math_size_to_bytes("1m");
|
||||
assert(x == 1 * 1024 * 1024);
|
||||
x = sc_math_size_to_bytes("1mb");
|
||||
assert(x == 1 * 1024 * 1024);
|
||||
|
||||
x = sc_math_size_to_bytes("1g");
|
||||
assert(x == 1 * 1024 * 1024 * 1024);
|
||||
x = sc_math_size_to_bytes("1gb");
|
||||
assert(x == 1 * 1024 * 1024 * 1024);
|
||||
|
||||
x = sc_math_size_to_bytes("1gx");
|
||||
assert(x == -1);
|
||||
|
||||
x = sc_math_size_to_bytes("gx");
|
||||
assert(x == -1);
|
||||
|
||||
x = sc_math_size_to_bytes("1xgx");
|
||||
assert(x == -1);
|
||||
|
||||
|
||||
x = sc_math_size_to_bytes("1xb");
|
||||
assert(x == -1);
|
||||
|
||||
x = sc_math_size_to_bytes("1p");
|
||||
assert(x == UINT64_C(1 * 1024 * 1024 * 1024 * 1024));
|
||||
x = sc_math_size_to_bytes("1pb");
|
||||
assert(x == UINT64_C(1 * 1024 * 1024 * 1024 * 1024));
|
||||
|
||||
t = sc_math_bytes_to_size(buf, sizeof(buf), 1024);
|
||||
assert(strcmp(t, "1024.00 B") == 0);
|
||||
|
||||
t = sc_math_bytes_to_size(buf, sizeof(buf), 2 * 1024);
|
||||
assert(strcmp(t, "2.00 KB") == 0);
|
||||
|
||||
t = sc_math_bytes_to_size(buf, sizeof(buf), 2 * 1024 * 1024);
|
||||
assert(strcmp(t, "2.00 MB") == 0);
|
||||
|
||||
t = sc_math_bytes_to_size(buf, sizeof(buf), (uint64_t)2 * 1024 * 1024 * 1024);
|
||||
assert(strcmp(t, "2.00 GB") == 0);
|
||||
|
||||
t = sc_math_bytes_to_size(buf, sizeof(buf), (uint64_t)2 * 1024 * 1024 * 1024 * 1024);
|
||||
assert(strcmp(t, "2.00 TB") == 0);
|
||||
|
||||
t = sc_math_bytes_to_size(buf, sizeof(buf), (uint64_t)2 * 1024 * 1024 * 1024 * 1024 * 1024);
|
||||
assert(strcmp(t, "2.00 PB") == 0);
|
||||
}
|
||||
|
||||
#ifdef SC_HAVE_WRAP
|
||||
|
||||
bool fail_snprintf;
|
||||
|
||||
int __wrap_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
int rc;
|
||||
va_list va;
|
||||
|
||||
if (!fail_snprintf) {
|
||||
va_start(va, format);
|
||||
rc = vsnprintf(str, size, format, va);
|
||||
va_end(va);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fail_test()
|
||||
{
|
||||
char* t;
|
||||
char buf[32];
|
||||
|
||||
fail_snprintf = true;
|
||||
t = sc_math_bytes_to_size(buf, sizeof(buf), 2 * 1024);
|
||||
assert(t == NULL);
|
||||
fail_snprintf = false;
|
||||
}
|
||||
|
||||
#else
|
||||
void fail_test()
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
int main()
|
||||
{
|
||||
test1();
|
||||
fail_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,93 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
project(sc_rc4 C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
|
||||
add_executable(sc_rc4 rc4_example.c sc_rc4.h sc_rc4.c)
|
||||
|
||||
if (NOT CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -pedantic -Werror")
|
||||
endif ()
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------- #
|
||||
# --------------------- Test Configuration Start ---------------------------- #
|
||||
# --------------------------------------------------------------------------- #
|
||||
|
||||
include(CTest)
|
||||
include(CheckCCompilerFlag)
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_executable(${PROJECT_NAME}_test rc4_test.c sc_rc4.c)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_SIZE_MAX=4000ul)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
|
||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
|
||||
|
||||
target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_HAVE_WRAP)
|
||||
target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-builtin)
|
||||
endif ()
|
||||
endif ()
|
||||
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
|
||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang" OR
|
||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
|
||||
|
||||
target_compile_options(${PROJECT_NAME}_test PRIVATE -fno-omit-frame-pointer)
|
||||
|
||||
if (SANITIZER)
|
||||
target_compile_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER})
|
||||
target_link_options(${PROJECT_NAME}_test PRIVATE -fsanitize=${SANITIZER})
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test)
|
||||
|
||||
SET(MEMORYCHECK_COMMAND_OPTIONS
|
||||
"-q --log-fd=2 --trace-children=yes --track-origins=yes \
|
||||
--leak-check=full --show-leak-kinds=all \
|
||||
--error-exitcode=255")
|
||||
|
||||
add_custom_target(valgrind_${PROJECT_NAME} ${CMAKE_COMMAND}
|
||||
-E env CTEST_OUTPUT_ON_FAILURE=1
|
||||
${CMAKE_CTEST_COMMAND} -C $<CONFIG>
|
||||
--overwrite MemoryCheckCommandOptions=${MEMORYCHECK_COMMAND_OPTIONS}
|
||||
--verbose -T memcheck WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
add_custom_target(check_${PROJECT_NAME} ${CMAKE_COMMAND}
|
||||
-E env CTEST_OUTPUT_ON_FAILURE=1
|
||||
${CMAKE_CTEST_COMMAND} -C $<CONFIG> --verbose
|
||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
# ----------------------- - Code Coverage Start ----------------------------- #
|
||||
|
||||
if (${CMAKE_BUILD_TYPE} MATCHES "Coverage")
|
||||
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
|
||||
target_compile_options(${PROJECT_NAME}_test PRIVATE --coverage)
|
||||
target_link_libraries(${PROJECT_NAME}_test gcov)
|
||||
else()
|
||||
message(FATAL_ERROR "Only GCC is supported for coverage")
|
||||
endif()
|
||||
endif ()
|
||||
|
||||
add_custom_target(coverage_${PROJECT_NAME})
|
||||
add_custom_command(
|
||||
TARGET coverage_${PROJECT_NAME}
|
||||
COMMAND lcov --capture --directory .
|
||||
--output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert'
|
||||
COMMAND lcov --remove coverage.info '/usr/*' '*example*' '*test*'
|
||||
--output-file coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert'
|
||||
COMMAND lcov --list coverage.info --rc lcov_branch_coverage=1 --rc lcov_excl_br_line='assert'
|
||||
)
|
||||
|
||||
add_dependencies(coverage_${PROJECT_NAME} check_${PROJECT_NAME})
|
||||
|
||||
# -------------------------- Code Coverage End ------------------------------ #
|
||||
|
||||
|
||||
# ----------------------- Test Configuration End ---------------------------- #
|
||||
|
@ -1,3 +0,0 @@
|
||||
# RC4 Random generator
|
||||
|
||||
https://en.wikipedia.org/wiki/RC4
|
@ -1,5 +0,0 @@
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return 0;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
|
||||
|
||||
#include "sc_rc4.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <memory.h>
|
||||
|
||||
void test()
|
||||
{
|
||||
unsigned char tmp[256] = {0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 1, 5, 3, 5, 5, 6};
|
||||
unsigned char tmp2[256] = {0, 1, 2, 3, 4, 3, 6, 6, 6, 6, 1, 2, 3, 5, 5, 6};
|
||||
|
||||
unsigned char out1[256];
|
||||
unsigned char out2[256];
|
||||
|
||||
struct sc_rc4 rc4_1;
|
||||
struct sc_rc4 rc4_2;
|
||||
|
||||
sc_rc4_init(&rc4_1, tmp);
|
||||
sc_rc4_init(&rc4_2, tmp);
|
||||
|
||||
sc_rc4_random(&rc4_1, out1, sizeof(out1));
|
||||
sc_rc4_random(&rc4_2, out2, sizeof(out2));
|
||||
|
||||
assert(memcmp(out1, out2, sizeof(out1)) == 0);
|
||||
|
||||
sc_rc4_init(&rc4_1, tmp);
|
||||
sc_rc4_init(&rc4_2, tmp2);
|
||||
|
||||
sc_rc4_random(&rc4_1, out1, sizeof(out1));
|
||||
sc_rc4_random(&rc4_2, out2, sizeof(out2));
|
||||
|
||||
assert(memcmp(out1, out2, sizeof(out1)) != 0);
|
||||
|
||||
sc_rc4_random(&rc4_1, out1, 0);
|
||||
sc_rc4_random(&rc4_1, NULL, 0);
|
||||
sc_rc4_random(&rc4_1, NULL, 10);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
test();
|
||||
return 0;
|
||||
}
|
65
rc4/sc_rc4.c
65
rc4/sc_rc4.c
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2021 Ozan Tezcan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sc_rc4.h"
|
||||
|
||||
#include <memory.h>
|
||||
|
||||
void sc_rc4_init(struct sc_rc4 *rc4, const unsigned char rand[256])
|
||||
{
|
||||
unsigned char t;
|
||||
|
||||
rc4->j = 0;
|
||||
rc4->i = 0;
|
||||
|
||||
memcpy(rc4->s, rand, 256);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
rc4->j += rc4->s[i] + rand[i];
|
||||
t = rc4->s[rc4->j];
|
||||
rc4->s[rc4->j] = rc4->s[i];
|
||||
rc4->s[i] = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void sc_rc4_random(struct sc_rc4 *rc4, void *buf, int size)
|
||||
{
|
||||
unsigned char t;
|
||||
unsigned char *p = buf;
|
||||
|
||||
if (size <= 0 || buf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
rc4->i++;
|
||||
t = rc4->s[rc4->i];
|
||||
rc4->j += t;
|
||||
rc4->s[rc4->i] = rc4->s[rc4->j];
|
||||
rc4->s[rc4->j] = t;
|
||||
t += rc4->s[rc4->i];
|
||||
*(p++) = rc4->s[t];
|
||||
} while (--size);
|
||||
}
|
48
rc4/sc_rc4.h
48
rc4/sc_rc4.h
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2021 Ozan Tezcan
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef SC_RC4_H
|
||||
#define SC_RC4_H
|
||||
|
||||
struct sc_rc4
|
||||
{
|
||||
unsigned char i, j;
|
||||
unsigned char s[256];
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param rc4 rc4
|
||||
* @param rand rand source, possibly from /dev/urandom
|
||||
*/
|
||||
void sc_rc4_init(struct sc_rc4 *rc4, const unsigned char rand[256]);
|
||||
|
||||
/**
|
||||
* @param rc4 rc4
|
||||
* @param buf out buf
|
||||
* @param size buf size
|
||||
*/
|
||||
void sc_rc4_random(struct sc_rc4 *rc4, void *buf, int size);
|
||||
|
||||
|
||||
#endif
|
@ -1,11 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
project(sc_math C)
|
||||
project(sc C)
|
||||
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
|
||||
add_executable(sc_math math_example.c sc_math.h sc_math.c)
|
||||
add_executable(sc sc_example.c sc.h sc.c)
|
||||
|
||||
if (NOT CMAKE_C_COMPILER_ID MATCHES "MSVC")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -Wall -pedantic -Werror -pthread")
|
||||
@ -21,7 +21,7 @@ include(CheckCCompilerFlag)
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_executable(${PROJECT_NAME}_test math_test.c sc_math.c)
|
||||
add_executable(${PROJECT_NAME}_test sc_test.c sc.c)
|
||||
|
||||
target_compile_options(${PROJECT_NAME}_test PRIVATE -DSC_SIZE_MAX=1400000ul)
|
||||
|
@ -1,6 +1,4 @@
|
||||
# Math
|
||||
|
||||
### Math
|
||||
# Sc
|
||||
|
||||
- Utility functions
|
||||
|
@ -22,7 +22,7 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "sc_math.h"
|
||||
#include "sc.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
@ -40,12 +40,50 @@
|
||||
#error unknown size_t bits
|
||||
#endif
|
||||
|
||||
bool sc_math_is_pow2(size_t num)
|
||||
#include <memory.h>
|
||||
|
||||
void sc_rand_init(struct sc_rand *r, const unsigned char *init)
|
||||
{
|
||||
unsigned char t;
|
||||
|
||||
*r = (struct sc_rand){0};
|
||||
|
||||
memcpy(r->init, init, 256);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
r->j += r->init[i] + init[i];
|
||||
t = r->init[r->j];
|
||||
r->init[r->j] = r->init[i];
|
||||
r->init[i] = t;
|
||||
}
|
||||
}
|
||||
|
||||
void sc_rand_read(struct sc_rand *r, void *buf, int size)
|
||||
{
|
||||
unsigned char t;
|
||||
unsigned char *p = buf;
|
||||
|
||||
if (size <= 0 || buf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
do {
|
||||
r->i++;
|
||||
t = r->init[r->i];
|
||||
r->j += t;
|
||||
r->init[r->i] = r->init[r->j];
|
||||
r->init[r->j] = t;
|
||||
t += r->init[r->i];
|
||||
*(p++) = r->init[t];
|
||||
} while (--size);
|
||||
}
|
||||
|
||||
bool sc_is_pow2(size_t num)
|
||||
{
|
||||
return (num != 0) && (num & (num - 1)) == 0;
|
||||
}
|
||||
|
||||
size_t sc_math_to_pow2(size_t size)
|
||||
size_t sc_to_pow2(size_t size)
|
||||
{
|
||||
if (size == 0) {
|
||||
return 1;
|
||||
@ -62,7 +100,7 @@ size_t sc_math_to_pow2(size_t size)
|
||||
return size;
|
||||
}
|
||||
|
||||
char *sc_math_bytes_to_size(char *buf, size_t len, uint64_t val)
|
||||
char *sc_bytes_to_size(char *buf, size_t len, uint64_t val)
|
||||
{
|
||||
int i, size;
|
||||
uint64_t bytes = 1;
|
||||
@ -81,7 +119,7 @@ char *sc_math_bytes_to_size(char *buf, size_t len, uint64_t val)
|
||||
return buf;
|
||||
}
|
||||
|
||||
int64_t sc_math_size_to_bytes(const char *buf)
|
||||
int64_t sc_size_to_bytes(const char *buf)
|
||||
{
|
||||
int count;
|
||||
int64_t val;
|
@ -21,27 +21,69 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef SC_MATH_H
|
||||
#define SC_MATH_H
|
||||
#ifndef SC_H
|
||||
#define SC_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define sc_math_max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define sc_math_min(a, b) (((a) > (b)) ? (b) : (a))
|
||||
#define sc_max(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#define sc_min(a, b) (((a) > (b)) ? (b) : (a))
|
||||
|
||||
struct sc_rand
|
||||
{
|
||||
unsigned char i;
|
||||
unsigned char j;
|
||||
unsigned char init[256];
|
||||
};
|
||||
|
||||
/**
|
||||
* Pseudo random number generator - RC4
|
||||
* e.g :
|
||||
* char buf[256], tmp1[16], tmp2[4];
|
||||
*
|
||||
* int fd = open("/dev/urandom", O_RDONLY);
|
||||
* if (fd < 0) {
|
||||
* return; // Error
|
||||
* }
|
||||
*
|
||||
* retry:
|
||||
* ssize_t sz = read(fd, buf, size);
|
||||
* if (sz < 0 && errno == EINTR) {
|
||||
* goto retry;
|
||||
* }
|
||||
* close(fd);
|
||||
*
|
||||
* struct sc_rand rnd;
|
||||
* sc_rand_init(&rnd, buf); // Init generator
|
||||
*
|
||||
* sc_rand_read(&rnd, tmp, sizeof(tmp); // Read random
|
||||
* sc_rand_read(&rnd, tmp, sizeof(tmp2); // Read random
|
||||
*
|
||||
* @param r rand
|
||||
* @param init rand source, possibly from /dev/urandom, must be 256 bytes long.
|
||||
*/
|
||||
void sc_rand_init(struct sc_rand *r, const unsigned char *init);
|
||||
|
||||
/**
|
||||
* @param r sc_rand
|
||||
* @param buf out buf
|
||||
* @param size buf size
|
||||
*/
|
||||
void sc_rand_read(struct sc_rand *r, void *buf, int size);
|
||||
|
||||
/**
|
||||
* @param num num
|
||||
* @return 'true' if num is power of 2
|
||||
*/
|
||||
bool sc_math_is_pow2(size_t num);
|
||||
bool sc_is_pow2(size_t num);
|
||||
|
||||
/**
|
||||
* @param size size
|
||||
* @return next nearest power of two of size
|
||||
*/
|
||||
size_t sc_math_to_pow2(size_t size);
|
||||
size_t sc_to_pow2(size_t size);
|
||||
|
||||
/**
|
||||
* Bytes to human readable form, e.g 10240 bytes to 10 KB.
|
||||
@ -51,7 +93,7 @@ size_t sc_math_to_pow2(size_t size);
|
||||
* @param val val to be converted into human readable form
|
||||
* @return 'buf' on success, 'NULL' on failure.
|
||||
*/
|
||||
char *sc_math_bytes_to_size(char *buf, size_t len, uint64_t val);
|
||||
char *sc_bytes_to_size(char *buf, size_t len, uint64_t val);
|
||||
|
||||
/**
|
||||
* Human readable string to bytes, e.g 10 KB to 10240 bytes.
|
||||
@ -59,6 +101,6 @@ char *sc_math_bytes_to_size(char *buf, size_t len, uint64_t val);
|
||||
* @param buf buf to write output
|
||||
* @return positive value on success, '-1' on error
|
||||
*/
|
||||
int64_t sc_math_size_to_bytes(const char *buf);
|
||||
int64_t sc_size_to_bytes(const char *buf);
|
||||
|
||||
#endif
|
168
sc/sc_test.c
Normal file
168
sc/sc_test.c
Normal file
@ -0,0 +1,168 @@
|
||||
|
||||
|
||||
|
||||
#include "sc.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void test1()
|
||||
{
|
||||
uint64_t x;
|
||||
char *t;
|
||||
char buf[32];
|
||||
|
||||
assert(sc_min(199, 299) == 199);
|
||||
assert(sc_max(199, 299) == 299);
|
||||
assert(sc_is_pow2(0) == false);
|
||||
|
||||
x = sc_to_pow2(0);
|
||||
assert(x == 1);
|
||||
assert(sc_is_pow2(x) == true);
|
||||
x = sc_to_pow2(1);
|
||||
assert(x == 1);
|
||||
assert(sc_is_pow2(x) == true);
|
||||
x = sc_to_pow2(1023);
|
||||
assert(x == 1024);
|
||||
assert(sc_is_pow2(x) == true);
|
||||
|
||||
x = sc_size_to_bytes("1");
|
||||
assert(x == 1);
|
||||
x = sc_size_to_bytes("1b");
|
||||
assert(x == 1);
|
||||
|
||||
x = sc_size_to_bytes("1k");
|
||||
assert(x == 1 * 1024);
|
||||
x = sc_size_to_bytes("1kb");
|
||||
assert(x == 1 * 1024);
|
||||
|
||||
x = sc_size_to_bytes("1m");
|
||||
assert(x == 1 * 1024 * 1024);
|
||||
x = sc_size_to_bytes("1mb");
|
||||
assert(x == 1 * 1024 * 1024);
|
||||
|
||||
x = sc_size_to_bytes("1g");
|
||||
assert(x == 1 * 1024 * 1024 * 1024);
|
||||
x = sc_size_to_bytes("1gb");
|
||||
assert(x == 1 * 1024 * 1024 * 1024);
|
||||
|
||||
x = sc_size_to_bytes("1gx");
|
||||
assert(x == -1);
|
||||
|
||||
x = sc_size_to_bytes("gx");
|
||||
assert(x == -1);
|
||||
|
||||
x = sc_size_to_bytes("1xgx");
|
||||
assert(x == -1);
|
||||
|
||||
|
||||
x = sc_size_to_bytes("1xb");
|
||||
assert(x == -1);
|
||||
|
||||
x = sc_size_to_bytes("1p");
|
||||
assert(x == UINT64_C(1 * 1024 * 1024 * 1024 * 1024));
|
||||
x = sc_size_to_bytes("1pb");
|
||||
assert(x == UINT64_C(1 * 1024 * 1024 * 1024 * 1024));
|
||||
|
||||
t = sc_bytes_to_size(buf, sizeof(buf), 1024);
|
||||
assert(strcmp(t, "1024.00 B") == 0);
|
||||
|
||||
t = sc_bytes_to_size(buf, sizeof(buf), 2 * 1024);
|
||||
assert(strcmp(t, "2.00 KB") == 0);
|
||||
|
||||
t = sc_bytes_to_size(buf, sizeof(buf), 2 * 1024 * 1024);
|
||||
assert(strcmp(t, "2.00 MB") == 0);
|
||||
|
||||
t = sc_bytes_to_size(buf, sizeof(buf),
|
||||
(uint64_t) 2 * 1024 * 1024 * 1024);
|
||||
assert(strcmp(t, "2.00 GB") == 0);
|
||||
|
||||
t = sc_bytes_to_size(buf, sizeof(buf),
|
||||
(uint64_t) 2 * 1024 * 1024 * 1024 * 1024);
|
||||
assert(strcmp(t, "2.00 TB") == 0);
|
||||
|
||||
t = sc_bytes_to_size(buf, sizeof(buf),
|
||||
(uint64_t) 2 * 1024 * 1024 * 1024 * 1024 * 1024);
|
||||
assert(strcmp(t, "2.00 PB") == 0);
|
||||
}
|
||||
|
||||
void test_rand()
|
||||
{
|
||||
unsigned char tmp[256] = {0, 1, 2, 3, 4, 5, 6, 6, 6, 6, 1, 5, 3, 5, 5, 6};
|
||||
unsigned char tmp2[256] = {0, 1, 2, 3, 4, 3, 6, 6, 6, 6, 1, 2, 3, 5, 5, 6};
|
||||
|
||||
unsigned char out1[256];
|
||||
unsigned char out2[256];
|
||||
|
||||
struct sc_rand rc4_1;
|
||||
struct sc_rand rc4_2;
|
||||
|
||||
sc_rand_init(&rc4_1, tmp);
|
||||
sc_rand_init(&rc4_2, tmp);
|
||||
|
||||
sc_rand_read(&rc4_1, out1, sizeof(out1));
|
||||
sc_rand_read(&rc4_2, out2, sizeof(out2));
|
||||
|
||||
assert(memcmp(out1, out2, sizeof(out1)) == 0);
|
||||
|
||||
sc_rand_init(&rc4_1, tmp);
|
||||
sc_rand_init(&rc4_2, tmp2);
|
||||
|
||||
sc_rand_read(&rc4_1, out1, sizeof(out1));
|
||||
sc_rand_read(&rc4_2, out2, sizeof(out2));
|
||||
|
||||
assert(memcmp(out1, out2, sizeof(out1)) != 0);
|
||||
|
||||
sc_rand_read(&rc4_1, out1, 0);
|
||||
sc_rand_read(&rc4_1, NULL, 0);
|
||||
sc_rand_read(&rc4_1, NULL, 10);
|
||||
}
|
||||
|
||||
#ifdef SC_HAVE_WRAP
|
||||
|
||||
bool fail_snprintf;
|
||||
|
||||
int __wrap_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
int rc;
|
||||
va_list va;
|
||||
|
||||
if (!fail_snprintf) {
|
||||
va_start(va, format);
|
||||
rc = vsnprintf(str, size, format, va);
|
||||
va_end(va);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fail_test()
|
||||
{
|
||||
char* t;
|
||||
char buf[32];
|
||||
|
||||
fail_snprintf = true;
|
||||
t = sc_bytes_to_size(buf, sizeof(buf), 2 * 1024);
|
||||
assert(t == NULL);
|
||||
fail_snprintf = false;
|
||||
}
|
||||
|
||||
#else
|
||||
void fail_test()
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
int main()
|
||||
{
|
||||
test1();
|
||||
test_rand();
|
||||
fail_test();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user