## BSSize

BSSize — a class facilitating work with sizes in bytes

## Functions

BSSize | bs_size_new ()
BSSize | bs_size_new_from_bytes ()
BSSize | bs_size_new_from_str ()
BSSize | bs_size_new_from_size ()
void | bs_size_free ()
void | bs_clear_error ()
uint64_t | bs_size_get_bytes ()
int | bs_size_sgn ()
char * | bs_size_get_bytes_str ()
char * | bs_size_convert_to ()
char * | bs_size_human_readable ()
BSSize | bs_size_add ()
BSSize | bs_size_grow ()
BSSize | bs_size_add_bytes ()
BSSize | bs_size_grow_bytes ()
BSSize | bs_size_sub ()
BSSize | bs_size_shrink ()
BSSize | bs_size_sub_bytes ()
BSSize | bs_size_shrink_bytes ()
BSSize | bs_size_mul_int ()
BSSize | bs_size_grow_mul_int ()
BSSize | bs_size_mul_float_str ()
BSSize | bs_size_grow_mul_float_str ()
uint64_t | bs_size_div ()
BSSize | bs_size_div_int ()
BSSize | bs_size_shrink_div_int ()
char * | bs_size_true_div ()
char * | bs_size_true_div_int ()
BSSize | bs_size_mod ()
BSSize | bs_size_round_to_nearest ()
int | bs_size_cmp ()
int | bs_size_cmp_bytes ()

## Types and Values

typedef | BSSize
enum | BSErrorCode
| BSError
enum | BSBunit
enum | BSDunit
enum | BSRoundDir
| BSUnit
#define | BS_FLOAT_PREC_BITS

## Includes

    #include <bs_size.h>

## Description

BSSize is a type that facilitates work with sizes in bytes by providing functions/methods that are required for parsing users input when entering size, showing size in nice human-readable format, storing sizes bigger than UINT64_MAX and doing calculations with sizes without loss of precision/information. The class is able to hold negative sizes and do operations on/with them, but some of the (division and multiplication) operations simply ignore the signs of the operands (check the documentation).

The reason why some functions take or return a float as a string instead of a float directly is because a string "0.3" can be translated into 0.3 with appropriate precision while 0.3 as float is probably something like 0.294343... with unknown precision.

## Functions

### bs_size_new ()

    BSSize
    bs_size_new (void);

Creates a new BSSize instance initialized to 0.

[constructor]

#### Returns

a new BSSize initialized to 0.

### bs_size_new_from_bytes ()

    BSSize
    bs_size_new_from_bytes (uint64_t bytes,
                            int sgn);

Creates a new BSSize instance.

[constructor]

#### Parameters

bytes | number of bytes |
sgn | sign of the size -- if being -1, the size is initialized to -`bytes` , other values are ignored |

#### Returns

a new BSSize

### bs_size_new_from_str ()

    BSSize
    bs_size_new_from_str (const char *size_str,
                          BSError **error);

Creates a new BSSize instance.

[constructor]

#### Parameters

size_str | string representing the size as a number and an optional unit (e.g. "1 GiB") |
error | place to store error (if any). | [out][optional]

#### Returns

a new BSSize

### bs_size_new_from_size ()

    BSSize
    bs_size_new_from_size (const BSSize size);

Creates a new instance of BSSize.

[constructor]

#### Parameters

size | the size to create a new instance from (a copy of) |

#### Returns

a new BSSize instance which is copy of `size` .

[transfer full]

### bs_size_free ()

    void
    bs_size_free (BSSize size);

Clears `size` and frees the allocated resources.

#### Parameters

size | `BSSize` to free. | [nullable]

### bs_clear_error ()

    void
    bs_clear_error (BSError **error);

Clears `error` and frees the allocated resources.

#### Parameters

error | `BSError` to clear. | [nullable]

### bs_size_get_bytes ()

    uint64_t
    bs_size_get_bytes (const BSSize size,
                       int *sgn,
                       BSError **error);

Get the number of bytes of the `size` .

#### Parameters

sgn | sign of the `size` - -1, 0 or 1 for negative, zero or positive size respectively. | [out][optional]
error | place to store error (if any). | [out][optional]

#### Returns

the `size` in a number of bytes

### bs_size_sgn ()

    int
    bs_size_sgn (const BSSize size);

Get the sign of the size.

#### Returns

-1, 0 or 1 if `size` is negative, zero or positive, respectively

### bs_size_get_bytes_str ()

    char *
    bs_size_get_bytes_str (const BSSize size);

Get the number of bytes in `size` as a string. This way, the caller doesn't have to care about the limitations of some particular integer type.

#### Returns

the string representing the `size` as a number of bytes.

[transfer full]

### bs_size_convert_to ()

    char *
    bs_size_convert_to (const BSSize size,
                        BSUnit unit,
                        BSError **error);

Get the `size` converted to `unit` as a string representing a floating-point number.

#### Parameters

unit | the unit to convert `size` to |
error | place to store error (if any). | [out][optional]

#### Returns

a string representing the floating-point number that equals to `size` converted to `unit` .

[transfer full]

### bs_size_human_readable ()

    char *
    bs_size_human_readable (const BSSize size,
                            BSBunit min_unit,
                            int max_places,
                            bool xlate);

Get a human-readable representation of `size` .

#### Parameters

min_unit | the smallest unit the returned representation should use |
max_places | maximum number of decimal places the representation should use |
xlate | whether to try to translate the representation or not |

#### Returns

a string which is human-readable representation of `size` according to the restrictions given by the other parameters.

[transfer full]

### bs_size_add ()

    BSSize
    bs_size_add (const BSSize size1,
                 const BSSize size2);

Add two sizes.

#### Returns

a new instance of BSSize which is a sum of `size1` and `size2` .

[transfer full]

### bs_size_grow ()

    BSSize
    bs_size_grow (BSSize size1,
                  const BSSize size2);

Grows `size1` by `size2` . IOW, adds `size2` to `size1` in-place (modifying `size1` ).

Basically an in-place variant of `bs_size_add()`.

#### Returns

`size1` modified by adding `size2` to it.

[transfer none]

### bs_size_add_bytes ()

    BSSize
    bs_size_add_bytes (const BSSize size,
                       uint64_t bytes);

Add `bytes` to the `size` . To add a negative number of bytes use `bs_size_sub_bytes()`.

#### Returns

a new instance of BSSize which is a sum of `size` and `bytes` .

[transfer full]

### bs_size_grow_bytes ()

    BSSize
    bs_size_grow_bytes (BSSize size,
                        uint64_t bytes);

Grows `size` by `bytes` . IOW, adds `bytes` to `size` in-place (modifying `size` ).

Basically an in-place variant of `bs_size_add_bytes()`.

#### Returns

`size` modified by adding `bytes` to it.

[transfer none]

### bs_size_sub ()

    BSSize
    bs_size_sub (const BSSize size1,
                 const BSSize size2);

Subtract `size2` from `size1` .

#### Returns

a new instance of BSSize which is equals to `size1` - `size2` .

[transfer full]

### bs_size_shrink ()

    BSSize
    bs_size_shrink (BSSize size1,
                    const BSSize size2);

Shrinks `size1` by `size2` . IOW, subtracts `size2` from `size1` in-place (modifying `size1` ).

Basically an in-place variant of `bs_size_sub()`.

#### Returns

`size1` modified by subtracting `size2` from it.

[transfer none]

### bs_size_sub_bytes ()

    BSSize
    bs_size_sub_bytes (const BSSize size,
                       uint64_t bytes);

Subtract `bytes` from the `size` . To subtract a negative number of bytes use `bs_size_add_bytes()`.

#### Returns

a new instance of BSSize which equals to `size` - `bytes` .

[transfer full]

### bs_size_shrink_bytes ()

    BSSize
    bs_size_shrink_bytes (BSSize size,
                          uint64_t bytes);

Shrinks `size` by `bytes` . IOW, subtracts `bytes` from `size` in-place (modifying `size` ). To shrink by a negative number of bytes use `bs_size_grow_bytes()`.

Basically an in-place variant of `bs_size_sub_bytes()`.

#### Returns

`size` modified by subtracting `bytes` from it.

[transfer none]

### bs_size_mul_int ()

    BSSize
    bs_size_mul_int (const BSSize size,
                     uint64_t times);

Multiply `size` by `times` .

#### Returns

a new instance of BSSize which equals to `size` * `times` .

[transfer full]

### bs_size_grow_mul_int ()

    BSSize
    bs_size_grow_mul_int (BSSize size,
                          uint64_t times);

Grow `size` `times` times. IOW, multiply `size` by `times` in-place.

Basically an in-place variant of `bs_size_mul_int()`.

#### Returns

`size` modified by growing it `times` times.

[transfer none]

### bs_size_mul_float_str ()

    BSSize
    bs_size_mul_float_str (const BSSize size,
                           const char *float_str,
                           BSError **error);

Multiply `size` by the floating-point number `float_str` represents.

#### Parameters

error | place to store error (if any). | [out][optional]

#### Returns

a new BSSize instance which equals to `size` * `times_str` .

[transfer full]

### bs_size_grow_mul_float_str ()

    BSSize
    bs_size_grow_mul_float_str (BSSize size,
                                const char *float_str,
                                BSError **error);

Grow `size` by the floating-point number `float_str` represents times. IOW, multiply `size` by `float_str` in-place.

Basically an in-place variant of `bs_size_grow_mul_float_str()`.

#### Parameters

error | place to store error (if any). | [out][optional]

#### Returns

`size` modified by growing it `float_str` times.

[transfer none]

### bs_size_div ()

    uint64_t
    bs_size_div (const BSSize size1,
                 const BSSize size2,
                 int *sgn,
                 BSError **error);

Divide `size1` by `size2` . Gives the answer to the question "How many times does `size2` fit in `size1` ?".

#### Parameters

sgn | sign of the result. | [out][optional]
error | place to store error (if any). | [out][optional]

#### Returns

integer number x so that x * `size1` < `size2` and (x+1) * `size1` > `size2` (IOW, `size1` / `size2` using integer division)

### bs_size_div_int ()

    BSSize
    bs_size_div_int (const BSSize size,
                     uint64_t divisor,
                     BSError **error);

Divide `size` by `divisor` . Gives the answer to the question "What is the size of each chunk if `size` is split into a `divisor` number of pieces?"

Note: Due to the limitations of the current implementation the maximum value `divisor` is ULONG_MAX (which can differ from UINT64_MAX). An error (BS_ERROR_OVER) is returned if overflow happens.

#### Parameters

error | place to store error (if any). | [out][optional]

#### Returns

a BSSize instance x so that x * `divisor` = `size` , rounded to a number of bytes.

[transfer full]

### bs_size_shrink_div_int ()

    BSSize
    bs_size_shrink_div_int (BSSize size,
                            uint64_t shrink_divisor,
                            BSError **error);

Shrink `size` by dividing by `divisor` . IOW, divide `size` by `divisor` in-place.

Basically an in-place variant of `bs_size_div_int()`.

Note: Due to the limitations of the current implementation the maximum value `divisor` is ULONG_MAX (which can differ from UINT64_MAX). An error (BS_ERROR_OVER) is returned if overflow happens.

#### Parameters

error | place to store error (if any). | [out][optional]

#### Returns

`size` modified by division by `divisor` .

[transfer none]

### bs_size_true_div ()

    char *
    bs_size_true_div (const BSSize size1,
                      const BSSize size2,
                      BSError **error);

Divides `size1` by `size2` .

#### Parameters

error | place to store error (if any). | [out][optional]

#### Returns

a string representing the floating-point number that equals to `size1` / `size2` .

[transfer full]

### bs_size_true_div_int ()

    char *
    bs_size_true_div_int (const BSSize size,
                          uint64_t divisor,
                          BSError **error);

Divides `size` by `divisor` .

Note: Due to the limitations of the current implementation the maximum value `divisor` is ULONG_MAX (which can differ from UINT64_MAX). An error (BS_ERROR_OVER) is returned if overflow happens.

#### Parameters

error | place to store error (if any). | [out][optional]

#### Returns

a string representing the floating-point number that equals to `size` / `divisor` .

[transfer full]

### bs_size_mod ()

    BSSize
    bs_size_mod (const BSSize size1,
                 const BSSize size2,
                 BSError **error);

Gives `size1` modulo `size2` (i.e. the remainder of integer division `size1` / `size2` ). Gives the answer to the question "If I split `size1` into chunks of size `size2` , what will be the remainder?" **This function ignores the signs of the sizes.**

#### Parameters

error | place to store error (if any). | [out][optional]

#### Returns

a BSSize instance that is a remainder of `size1` / `size2` using integer division.

[transfer full]

### bs_size_round_to_nearest ()

    BSSize
    bs_size_round_to_nearest (const BSSize size,
                              const BSSize round_to,
                              BSRoundDir dir,
                              BSError **error);

Round `size` to the nearest multiple of `round_to` according to the direction given by `dir` .

#### Parameters

round_to | to a multiple of what to round `size` |
dir | `BS_ROUND_DIR_UP` to round up (to the nearest multiple of `round_to` bigger than `size` ) or `BS_ROUND_DIR_DOWN` to round down (to the nearest multiple of `round_to` smaller than `size` ) |
error | place to store error (if any). | [out][optional]

#### Returns

a new instance of BSSize that is `size` rounded to a multiple of `round_to` according to `dir` .

[transfer full]

### bs_size_cmp ()

    int
    bs_size_cmp (const BSSize size1,
                 const BSSize size2,
                 bool abs);

Compare `size1` and `size2` . This function behaves like the standard *cmp*() functions.

#### Parameters

abs | whether to compare absolute values of `size1` and `size2` instead |

#### Returns

-1, 0, or 1 if `size1` is smaller, equal to or bigger than `size2` respectively comparing absolute values if `abs` is `TRUE`

### bs_size_cmp_bytes ()

    int
    bs_size_cmp_bytes (const BSSize size1,
                       uint64_t bytes,
                       bool abs);

Compare `size` and `bytes` , i.e. the number of bytes `size` has with `bytes` . This function behaves like the standard *cmp*() functions.

#### Parameters

abs | whether to compare absolute values of `size` and `bytes` instead. |

#### Returns

-1, 0, or 1 if `size` is smaller, equal to or bigger than `bytes` respectively comparing absolute values if `abs` is `TRUE`

## Types and Values

### BSSize

    typedef struct _BSSize * BSSize;

An opaque type representing a size in bytes.

### enum BSErrorCode

Error codes that identify various errors that can occur while working with BSSize instances.

#### Members

BS_ERROR_INVALID_SPEC | invalid size or unit spec provided |
BS_ERROR_OVER | a value is over the limits imposed by a type |
BS_ERROR_ZERO_DIV | an attempt to do division by zero |
BS_ERROR_FAIL |  |

### BSError

    typedef struct {
        BSErrorCode code;
        char *msg;
    } BSError;

#### Members

BSErrorCode `code`; | error code |
char *`msg`; | optional error message |

### enum BSBunit

Binary units (multiples of 1024) of size in bytes.

#### Members

BS_BUNIT_B |  |
BS_BUNIT_KiB |  |
BS_BUNIT_MiB |  |
BS_BUNIT_GiB |  |
BS_BUNIT_TiB |  |
BS_BUNIT_PiB |  |
BS_BUNIT_EiB |  |
BS_BUNIT_ZiB |  |
BS_BUNIT_YiB |  |
BS_BUNIT_UNDEF |  |

### enum BSDunit

Decimal units (multiples of 1000) of size in bytes.

#### Members

BS_DUNIT_B |  |
BS_DUNIT_KB |  |
BS_DUNIT_MB |  |
BS_DUNIT_GB |  |
BS_DUNIT_TB |  |
BS_DUNIT_PB |  |
BS_DUNIT_EB |  |
BS_DUNIT_ZB |  |
BS_DUNIT_YB |  |
BS_DUNIT_UNDEF |  |

### enum BSRoundDir

Rounding direction for rounding operations.

#### Members

BS_ROUND_DIR_UP |  |
BS_ROUND_DIR_DOWN |  |
BS_ROUND_DIR_HALF_UP |  |

### BSUnit

Generic unit fo size in bytes.

#### Members

BSBunit `bunit`; | a binary unit |
BSDunit `dunit`; | a decimal unit |

### BS_FLOAT_PREC_BITS

    #define BS_FLOAT_PREC_BITS 256

Precision (in bits) of floating-point numbers used internally.