-
Notifications
You must be signed in to change notification settings - Fork 60
/
SubUser.sol
108 lines (88 loc) · 3.5 KB
/
SubUser.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
This file is part of the DAO.
The DAO is free software: you can redistribute it and/or modify
it under the terms of the GNU lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The DAO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU lesser General Public License for more details.
You should have received a copy of the GNU lesser General Public License
along with the DAO. If not, see <http://www.gnu.org/licenses/>.
*/
contract SubUser {
address public user;
// pointer used to find a free slot in m_subUsers
uint public m_numSubUsers;
// list of subUsers
uint[256] m_subUsers;
uint constant c_maxsubUsers = 250;
// index on the list of subUsers to allow reverse lookup
mapping(uint => uint) m_subUserIndex;
event SubUserChanged(address indexed oldOwner, address indexed newOwner);
event SubUserAdded(address indexed newOwner);
event SubUserRemoved(address indexed oldOwner);
function SubUser() {
user = msg.sender;
}
modifier onlyUser {
if (msg.sender == user)
_
}
function isSubUser(address _addr) returns (bool) {
return m_subUserIndex[uint(_addr)] > 0;
}
function isAUser(address _addr) returns (bool) {
return _addr == user || isSubUser(_addr);
}
// Replaces a subUser `_from` with another `_to`.
function changeSubUser(address _from, address _to) onlyUser external {
if (isSubUser(_to)) return;
uint subUserIndex = m_subUserIndex[uint(_from)];
if (subUserIndex == 0) return;
m_subUsers[subUserIndex] = uint(_to);
m_subUserIndex[uint(_from)] = 0;
m_subUserIndex[uint(_to)] = subUserIndex;
SubUserChanged(_from, _to);
}
function addSubUser(address _subUser) onlyUser external {
if (isSubUser(_subUser)) return;
if (m_numSubUsers >= c_maxsubUsers)
reorganizeSubUsers();
if (m_numSubUsers >= c_maxsubUsers)
throw;
m_numSubUsers++;
m_subUsers[m_numSubUsers] = uint(_subUser);
m_subUserIndex[uint(_subUser)] = m_numSubUsers;
SubUserAdded(_subUser);
}
function removeSubUser(address _subUser) onlyUser external {
uint subUserIndex = m_subUserIndex[uint(_subUser)];
if (subUserIndex == 0) return;
m_subUsers[subUserIndex] = 0;
m_subUserIndex[uint(_subUser)] = 0;
reorganizeSubUsers(); //make sure m_numsubUser is equal to the number of subUsers and always points to the optimal free slot
SubUserRemoved(_subUser);
}
function removeAllSubUsers() internal {
for (var i = 1; i <= m_numSubUsers; i++)
m_subUserIndex[m_subUsers[i]] = 0;
delete m_subUsers;
m_numSubUsers = 0;
}
function reorganizeSubUsers() private {
uint free = 1;
while (free < m_numSubUsers)
{
while (free < m_numSubUsers && m_subUsers[free] != 0) free++;
while (m_numSubUsers > 1 && m_subUsers[m_numSubUsers] == 0) m_numSubUsers--;
if (free < m_numSubUsers && m_subUsers[m_numSubUsers] != 0 && m_subUsers[free] == 0)
{
m_subUsers[free] = m_subUsers[m_numSubUsers];
m_subUserIndex[m_subUsers[free]] = free;
m_subUsers[m_numSubUsers] = 0;
}
}
}
}