Bits Library (Two files: bits_library.c and bits_library.h).

From: Amit
Date: Thu Jun 19 2025 - 00:41:56 EST


Bits Library (Two files: bits_library.c and bits_library.h).

------------------
bits_library.c
------------------

/*
* License:
*
* This file has been released under "unlicense" license
* (https://unlicense.org).
*
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or distribute
* this software, either in source code form or as a compiled binary, for any
* purpose, commercial or non-commercial, and by any means.
*
* For more information about this license, please visit - https://unlicense.org
*/

/*
* Author: Amit Choudhary
* Email: amitchoudhary0523 AT gmail DOT com
*/

#include "bits_library.h"

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

char *convert_error_num_to_error_string(int error_num)
{

switch (error_num) {

case BL_BC_PTR_IS_NULL:
return ("'bc_ptr' argument is NULL.");

case BL_BIT_NUM_OUT_OF_RANGE:
return ("'bit_num' value given by the user is out of range"
" (less than 0 or greater than 'last_bit_num').");

case BL_VAL_IS_INVALID:
return ("'val' argument is invalid, it is neither 0 nor 1.");

case BL_FD_IS_INVALID:
return ("'fd' argument is negative, hence invalid.");

case BL_FAILURE:
return("Some error happened. Function didn't complete"
" successfully.");
}

return("Invalid error number.");

} // end of function convert_error_num_to_error_string()

struct bits_container *bl_init_bits_container(long num_bits_required)
{

struct bits_container *bc_ptr = NULL;
long num_bytes_to_alloc = 0;

if (num_bits_required <= 0) {
return NULL;
}

bc_ptr = calloc(sizeof(*bc_ptr), 1);

if (bc_ptr == NULL) {
return NULL;
}

num_bytes_to_alloc = (num_bits_required/8);

if ((num_bits_required % 8) != 0) {
num_bits_required = num_bits_required + 1;
}

bc_ptr->bit_array_ptr = calloc((size_t)(num_bytes_to_alloc), 1);

if (bc_ptr->bit_array_ptr == NULL) {
free(bc_ptr);
return NULL;
}

bc_ptr->last_bit_num = num_bits_required - 1;

return bc_ptr;

} // end of function bl_init_bits_container()

// bl_set_bit(): We are not checking the function arguments in this function
// because this function is just a wrapper function with only one
// function call and no other line of code.
int bl_set_bit(struct bits_container *bc_ptr, long bit_num)
{

return bl_set_bit_value(bc_ptr, bit_num, 1);

} // end of function bl_set_bit()

// bl_unset_bit(): We are not checking the function arguments in this function
// because this function is just a wrapper function with only
// one function call and no other line of code.
int bl_unset_bit(struct bits_container *bc_ptr, long bit_num)
{

return bl_set_bit_value(bc_ptr, bit_num, 0);

} // end of function bl_unset_bit()

int bl_is_bit_set(struct bits_container *bc_ptr, long bit_num)
{

int val = -1;

if (bc_ptr == NULL) {
return BL_BC_PTR_IS_NULL;
}

if ((bit_num < 0) || (bit_num > bc_ptr->last_bit_num)) {
return BL_BIT_NUM_OUT_OF_RANGE;
}

val = bl_get_bit_value(bc_ptr, bit_num);

if (val == 1) {
return BL_TRUE;
} else if (val == 0) {
return BL_FALSE;
}

return BL_FAILURE;

} // end of function bl_is_bit_set()

int bl_set_bit_value(struct bits_container *bc_ptr, long bit_num, int val)
{

long arr_index = -1;
int bit_index = -1;
int retval = -1;

if (bc_ptr == NULL) {
return BL_BC_PTR_IS_NULL;
}

if ((bit_num < 0) || (bit_num > bc_ptr->last_bit_num)) {
return BL_BIT_NUM_OUT_OF_RANGE;
}

if ((val != 1) && (val != 0)) {
return BL_VAL_IS_INVALID;
}

retval = get_arr_index_and_bit_index(bit_num, &arr_index, &bit_index);

if (retval != BL_SUCCESS) {
return BL_FAILURE;
}

if (val == 1) {
val = (1 >> bit_index);
bc_ptr->bit_array_ptr[arr_index] = bc_ptr->bit_array_ptr[arr_index] |
(unsigned char)(val);
} else { // val is 0
val = ~(1 >> bit_index);
bc_ptr->bit_array_ptr[arr_index] = bc_ptr->bit_array_ptr[arr_index] &
(unsigned char)(val);
}

return BL_SUCCESS;

} // end of function bl_set_bit_value()

int bl_get_bit_value(struct bits_container *bc_ptr, long bit_num)
{

long arr_index = -1;
int bit_index = -1;
int val = -1;
int retval = -1;

if (bc_ptr == NULL) {
return BL_BC_PTR_IS_NULL;
}

if ((bit_num < 0) || (bit_num > bc_ptr->last_bit_num)) {
return BL_BIT_NUM_OUT_OF_RANGE;
}

retval = get_arr_index_and_bit_index(bit_num, &arr_index, &bit_index);

if (retval != BL_SUCCESS) {
return BL_FAILURE;
}

val = bc_ptr->bit_array_ptr[arr_index] & (1 >> bit_index);

if (val) {
return 1;
}

return 0;

} // end of function bl_get_bit_value()

int bl_print_all_bits_values(struct bits_container *bc_ptr, int fd)
{
#define STR_SIZE 256

char str[STR_SIZE] = {0};

long i = 0;
int val = -1;

if (bc_ptr == NULL) {
return BL_BC_PTR_IS_NULL;
}

if (fd < 0) {
return BL_FD_IS_INVALID;
}

for (i = 0; i <= bc_ptr->last_bit_num; i++) {
snprintf(str, STR_SIZE, "%s", "bit_");
write(fd, str, strlen(str));
snprintf(str, STR_SIZE, "%ld", i);
write(fd, str, strlen(str));
snprintf(str, STR_SIZE, "%s", " = ");
write(fd, str, strlen(str));
val = bl_get_bit_value(bc_ptr, i);
if (val < 0) {
snprintf(str, STR_SIZE, "%s\n", "Error. Some error happened.");
write(fd, str, strlen(str));
fflush(NULL);
return BL_FAILURE;
}
snprintf(str, STR_SIZE, "%d\n", val);
write(fd, str, strlen(str));
} // end of for loop

fflush(NULL);

return BL_SUCCESS;

} // end of function bl_print_all_bits_values()

void bl_delete_bits_container(struct bits_container *bc_ptr)
{

if (bc_ptr == NULL) {
return;
}

free(bc_ptr->bit_array_ptr);

free(bc_ptr);

return;

} // end of function bl_delete_bits_container()

static int get_arr_index_and_bit_index(long bit_num, long *arr_index,
int *bit_index)
{

if ((bit_num < 0) || (arr_index == NULL) || (bit_index == NULL)) {
return BL_FAILURE;
}

*arr_index = bit_num/8;

*bit_index = (int)(bit_num % 8);

return BL_SUCCESS;

} // end of function get_arr_index_and_bit_index()

------------------
bits_library.h
------------------

/*
* License:
*
* This file has been released under "unlicense" license
* (https://unlicense.org).
*
* This is free and unencumbered software released into the public domain.
*
* Anyone is free to copy, modify, publish, use, compile, sell, or distribute
* this software, either in source code form or as a compiled binary, for any
* purpose, commercial or non-commercial, and by any means.
*
* For more information about this license, please visit - https://unlicense.org
*/

/*
* Author: Amit Choudhary
* Email: amitchoudhary0523 AT gmail DOT com
*/

#ifndef _BITS_LIBRARY_H_
#define _BITS_LIBRARY_H_

// 'bl' and 'BL' mean bits library
// 'bc' and 'BC' mean bits container

#define BL_TRUE 1
#define BL_FALSE 2

// Everything happened successfully.
#define BL_SUCCESS 0

// 'bc_ptr' argument is NULL.
#define BL_BC_PTR_IS_NULL -1

// 'bit_num' value given by the user is out of range (less than 0 or greater
// than 'last_bit_num').
#define BL_BIT_NUM_OUT_OF_RANGE -2

// 'val' argument is invalid, it is neither 0 nor 1.
#define BL_VAL_IS_INVALID -3

// 'fd' argument is negative, hence invalid.
#define BL_FD_IS_INVALID -4

// Some error happened. Function didn't complete successfully.
#define BL_FAILURE -5

struct bits_container
{
unsigned char *bit_array_ptr;
long last_bit_num;
};

// Functions
char *convert_error_num_to_error_string(int error_num);

struct bits_container *bl_init_bits_container(long num_bits_required);

int bl_set_bit(struct bits_container *bc_ptr, long bit_num);

int bl_unset_bit(struct bits_container *bc_ptr, long bit_num);

int bl_is_bit_set(struct bits_container *bc_ptr, long bit_num);

int bl_set_bit_value(struct bits_container *bc_ptr, long bit_num, int val);

int bl_get_bit_value(struct bits_container *bc_ptr, long bit_num);

int bl_print_all_bits_values(struct bits_container *bc_ptr, int fd);

void bl_delete_bits_container(struct bits_container *bc_ptr);

// Static functions
static int get_arr_index_and_bit_index(long bit_num, long *arr_index,
int *bit_index);

#endif