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
|
|
}
|