/*
*******************************************************************************
\file blob.h
\brief Blobs
\project bee2 [cryptographic library]
\created 2012.04.01
\version 2025.08.28
\copyright The Bee2 authors
\license Licensed under the Apache License, Version 2.0 (see LICENSE.txt).
*******************************************************************************
*/

/*!
*******************************************************************************
\file blob.h
\brief Блобы
*******************************************************************************
*/

#ifndef __BEE2_BLOB_H
#define __BEE2_BLOB_H

#include "bee2/defs.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
*******************************************************************************
\file blob.h

Блоб -- объект в памяти определенного размера. В функциях работы с блобами
используются их дескрипторы -- "умные" указатели. С дескрипторами можно
работать как с обычными указателями, т.е. использовать их в функциях типа
memcpy, memset. Дополнительно по указателю можно определить размер блоба.

Реализация работы с блобами может быть платформенно-зависимой.

Реализация должна гарантировать защиту содержимого блобов от утечек,
например, через файл подкачки. Поэтому в блобах рекомендуется размещать
ключи и другие критические объекты.

\pre В функциях работы с блобами дескрипторы входных блобов корректны.
*******************************************************************************
*/

/*! Дескриптор блоба. */
typedef void* blob_t;

/*!	\brief Создание блоба

	Создается блоб размера size.
	\return Дескриптор созданного блоба. Нулевой дескриптор возвращается
	при нулевом size и при нехватке памяти.
	\post Выходной блоб корректен.
	\remark При создании блоба все его октеты обнуляются.
*/
blob_t blobCreate(
	size_t size		/*!< [in] размер */
);

/*!	\brief Создание блоба с разметкой памяти

	Создается блоб blob для хранения фрагментов памяти [с1]p1, [с2]p2, ...., 
	[сn]pn. Фрагменты описываются параметрами c1 и .... Описание имеет вид:
		c1, pp1, c2, pp2, ..., cn, ppn, SIZE_MAX,
	где сi -- длина фрагмента в октетах (size_t), ppi -- указатель на pi 
	(const void**), SIZE_MAX -- маркер окончания списка параметров. 
	Действуют правила функции memSlice(). В частности, 
	- указатели pi выровнены на границу фундаментального блока;
	- при установке в ci флага SIZE_HI указатель pi повторяет предыдущий, если
	  таковой имеется.
	\return Дескриптор блоба. Нулевой дескриптор возвращается при 
	нехватке памяти.
	\post Указатели pi, если они формируются, выровнены на границу 
	фундаментального блока. 
*/
blob_t blobCreate2(
	size_t c1,		/*!< [in] начало описания фрагментов памяти */
	...				/*!< [in,out] окончание описания */
);

/*!	\brief Корректный блоб?

	Проверяется корректность блоба blob.
	\return Признак корректности.
	\remark Блоб с нулевым дескриптором считается корректным.
*/
bool_t blobIsValid(
	const blob_t blob		/*!< [in] блоб */
);

/*!	\brief Изменение размера блоба

	Размер блоба blob изменяется на size с сохранением содержимого.
	\return Дескриптор созданного блоба. Нулевой дескриптор
	возвращается при нулевом size и при нехватке памяти.
	\remark Если блоб еще не создан, то он создается.
	\remark При ошибках выделения памяти blob остается действительным.
	\remark Если размер блоба не меняется, то и дескриптор не меняется.
	\remark Вызов с нулевым size эквивалентен вызову blobClose().
	\remark При увеличении размера в блоб дописываются нулевые октеты.
	\remark При уменьшении размера ненужные октеты отбрасываются,
	но первые size октетов сохраняются.
*/
blob_t blobResize(
	blob_t blob,	/*!< [in] блоб */
	size_t size		/*!< [in] новый размер */
);

/*!	\brief Очистка блоба

	Выполняется очистка блоба blob.
*/
void blobWipe(
	blob_t blob		/*!< [in] блоб */
);

/*!	\brief Очистка и освобождение блоба

	Выполняется очистка и освобождение блоба blob.
*/
void blobClose(
	blob_t blob		/*!< [in] блоб */
);

/*!	\brief Размер блоба

	Определяется размер блоба blob.
	\return Размер блоба.
*/
size_t blobSize(
	const blob_t blob		/*!< [in] блоб */
);

/*!	\brief Копирование блоба

	Блоб src копируется в блоб dest.
	\return Дескриптор блоба-приемника. Дескриптор совпадает c dest
	при совпадении размеров dest и src. Нулевой дескриптор
	возвращается при нулевом src и при нехватке памяти.
	\remark При нулевом dest блоб-приемник создается, при ненулевом --
	настраивается размер блоба.
*/
blob_t blobCopy(
	blob_t dest,			/*!< [out] назначение */
	const blob_t src		/*!< [in] источник */
);

/*!	\brief Совпадение блобов

	Проверяется совпадение блобов blob1 и blob2: a == b, если 
	size(a) == size(b) и value(a) < value(b).
	\return Признак совпадения.
*/
bool_t blobEq(
	const blob_t blob1,		/*!< [in] первый блоб */
	const blob_t blob2		/*!< [in] второй блоб */
);

/*!	\brief Сравнение блобов

	Блоб blob1 сравнивается с блобом blob2: a < b, если size(a) < size(b) 
	или size(a) == size(b) и value(a) < value(b).
	Условие value(a) < value(b) означает, что имеется i < size(a) т.ч.
	value(a)[0..i - 1] == value(b)[0..i - 1] и value(a)[i] < value(b)[i].
	\return 0, если блобы совпадают,
	< 0, если blob1 меньше blob2,
	> 0, если blob1 больше blob2.
*/
int blobCmp(
	const blob_t blob1,		/*!< [in] первый блоб */
	const blob_t blob2		/*!< [in] второй блоб */
);

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* __BEE2_BLOB_H */
