1
/*
2
*******************************************************************************
3
\file obj.c
4
\brief Compound objects
5
\project bee2 [cryptographic library]
6
\author (C) Sergey Agievich [agievich@{bsu.by|gmail.com}]
7
\created 2014.04.14
8
\version 2015.05.22
9
\license This program is released under the GNU General Public License 
10
version 3. See Copyright Notices in bee2/info.h.
11
*******************************************************************************
12
*/
13

14
#include "bee2/core/mem.h"
15
#include "bee2/core/obj.h"
16
#include "bee2/core/util.h"
17

18
/*
19
*******************************************************************************
20
Внутренние макросы
21
*******************************************************************************
22
*/
23

24
#define objHdr(obj)\
25
	((obj_hdr_t*)obj)
26

27
/*
28
*******************************************************************************
29
Проверка
30
*******************************************************************************
31
*/
32

33 1
bool_t objIsOperable2(const void* obj)
34
{
35 1
	return memIsValid(obj, sizeof(obj_hdr_t)) &&
36 1
		memIsValid(obj, objKeep(obj)) &&
37 1
		objOCount(obj) <= objPCount(obj) &&
38 1
		sizeof(obj_hdr_t) + sizeof(void*) * objPCount(obj) <= objKeep(obj);
39
}
40

41 1
bool_t objIsOperable(const void* obj)
42
{
43
	size_t i;
44
	// проверить сам объект
45 1
	if (!objIsOperable2(obj))
46 0
		return FALSE;
47
	// проверить ссылочные объекты
48 1
	for (i = 0; i < objOCount(obj); ++i)
49 1
		if (!objIsOperable(objCPtr(obj, i, void)))
50 0
			return FALSE;
51
	// все нормально
52 1
	return TRUE;
53
}
54

55
/*
56
*******************************************************************************
57
Копирование
58
*******************************************************************************
59
*/
60

61 1
static void objShiftPtrs(void* obj, ptrdiff_t diff)
62
{
63
	size_t i;
64
	// просмотреть объекты
65 1
	for (i = 0; i < objOCount(obj); ++i)
66
		// вложенный объект?
67 1
		if ((octet*)obj <= objPtr(obj, i, octet) + diff && 
68 1
			objPtr(obj, i, octet) + diff < objEnd(obj, octet))
69
		{
70 1
			objShiftPtrs(objPtr(obj, i, void), diff);
71 1
			objPtr(obj, i, octet) += diff;
72
		}
73
	// просмотреть оставшиеся указатели
74 1
	for (; i < objPCount(obj); ++i)
75
		// вложенный указатель?
76 1
		if ((octet*)obj <= objPtr(obj, i, octet) + diff && 
77 1
			objPtr(obj, i, octet) + diff < objEnd(obj, octet))
78 1
			objPtr(obj, i, octet) += diff;
79
}
80

81 1
void objCopy(void* dest, const void* src)
82
{
83 1
	ASSERT(objIsOperable(src));
84 1
	ASSERT(memIsValid(dest, objKeep(src)));
85
	// скопировать данные
86 1
	memMove(dest, src, objKeep(src));
87
	// сдвинуть указатели
88 1
	objShiftPtrs(dest, (const octet*)dest - (const octet*)src);
89
}
90

91 1
void objAppend(void* dest, const void* src, size_t i)
92
{
93
	size_t t;
94
	// pre
95 1
	ASSERT(objIsOperable(src));
96 1
	ASSERT(objIsOperable(dest));
97 1
	ASSERT(memIsValid(objEnd(dest, void), objKeep(src)));
98 1
	ASSERT(i < objOCount(dest));
99
	// запомнить размер src
100 1
	t = objKeep(src);
101
	// скопировать src в конец dest
102 1
	objCopy(objEnd(dest, void), src);
103
	// установить ссылку на конец dest
104 1
	objPtr(dest, i, void) = objEnd(dest, void);
105
	// расширить dest
106 1
	objHdr(dest)->keep += t;
107
}

Read our documentation on viewing source code .

Loading