source: trunk/sources/thelib/src/protocols/protocolfactorymanager.cpp @ 734

Revision 734, 5.5 KB checked in by shiretu, 3 months ago (diff)

-- imported changes thelib and crtmpserver from commercial version (evostream)

Line 
1/*
2 *  Copyright (c) 2010,
3 *  Gavriloaie Eugen-Andrei (shiretu@gmail.com)
4 *
5 *  This file is part of crtmpserver.
6 *  crtmpserver is free software: you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation, either version 3 of the License, or
9 *  (at your option) any later version.
10 *
11 *  crtmpserver is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with crtmpserver.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21
22
23#include "protocols/protocolfactorymanager.h"
24#include "protocols/baseprotocolfactory.h"
25#include "protocols/baseprotocol.h"
26
27map<uint32_t, BaseProtocolFactory *> ProtocolFactoryManager::_factoriesById;
28map<uint64_t, BaseProtocolFactory *> ProtocolFactoryManager::_factoriesByProtocolId;
29map<string, BaseProtocolFactory *> ProtocolFactoryManager::_factoriesByChainName;
30
31bool ProtocolFactoryManager::RegisterProtocolFactory(BaseProtocolFactory *pFactory) {
32
33        //1. Test to see if this factory is already registered
34        if (MAP_HAS1(_factoriesById, pFactory->GetId())) {
35                FATAL("Factory id %u already registered", pFactory->GetId());
36                return false;
37        }
38
39        //2. Test to see if the protocol chains exported by this factory are already in use
40        vector<string> protocolChains = pFactory->HandledProtocolChains();
41
42        FOR_VECTOR(protocolChains, i) {
43                if (MAP_HAS1(_factoriesByChainName, protocolChains[i])) {
44                        FATAL("protocol chain %s already handled by factory %u",
45                                        STR(protocolChains[i]),
46                                        _factoriesByChainName[protocolChains[i]]->GetId());
47                        return false;
48                }
49        }
50
51        //3. Test to see if the protocols exported by this factory are already in use
52        vector<uint64_t> protocols = pFactory->HandledProtocols();
53
54        FOR_VECTOR(protocols, i) {
55                if (MAP_HAS1(_factoriesByProtocolId, protocols[i])) {
56                        FATAL("protocol %"PRIx64" already handled by factory %u", protocols[i],
57                                        _factoriesByProtocolId[protocols[i]]->GetId());
58                        return false;
59                }
60        }
61
62        //4. Register everything
63
64        FOR_VECTOR(protocolChains, i) {
65                _factoriesByChainName[protocolChains[i]] = pFactory;
66        }
67
68        FOR_VECTOR(protocols, i) {
69                _factoriesByProtocolId[protocols[i]] = pFactory;
70        }
71
72        _factoriesById[pFactory->GetId()] = pFactory;
73
74        return true;
75}
76
77bool ProtocolFactoryManager::UnRegisterProtocolFactory(uint32_t factoryId) {
78        if (!MAP_HAS1(_factoriesById, factoryId)) {
79                WARN("Factory id not found: %u", factoryId);
80                return true;
81        }
82        return UnRegisterProtocolFactory(_factoriesById[factoryId]);
83}
84
85bool ProtocolFactoryManager::UnRegisterProtocolFactory(BaseProtocolFactory *pFactory) {
86        if (pFactory == NULL) {
87                WARN("pFactory is NULL");
88                return true;
89        }
90
91        if (!MAP_HAS1(_factoriesById, pFactory->GetId())) {
92                WARN("Factory id not found: %u", pFactory->GetId());
93                return true;
94        }
95
96        vector<string> protocolChains = pFactory->HandledProtocolChains();
97        vector<uint64_t> protocols = pFactory->HandledProtocols();
98
99        FOR_VECTOR(protocolChains, i) {
100                _factoriesByChainName.erase(protocolChains[i]);
101        }
102
103        FOR_VECTOR(protocols, i) {
104                _factoriesByProtocolId.erase(protocols[i]);
105        }
106
107        _factoriesById.erase(pFactory->GetId());
108
109        return true;
110}
111
112vector<uint64_t> ProtocolFactoryManager::ResolveProtocolChain(string name) {
113        if (!MAP_HAS1(_factoriesByChainName, name)) {
114                FATAL("chain %s not registered by any protocol factory", STR(name));
115                return vector<uint64_t > ();
116        }
117
118        return _factoriesByChainName[name]->ResolveProtocolChain(name);
119}
120
121BaseProtocol *ProtocolFactoryManager::CreateProtocolChain(string name,
122                Variant &parameters) {
123        vector<uint64_t> chain = ResolveProtocolChain(name);
124        if (chain.size() == 0) {
125                FATAL("Unable to create protocol chain");
126                return NULL;
127        }
128
129        return CreateProtocolChain(chain, parameters);
130}
131
132BaseProtocol *ProtocolFactoryManager::CreateProtocolChain(vector<uint64_t> &chain,
133                Variant &parameters) {
134        BaseProtocol *pResult = NULL;
135
136        //1. Check and see if all the protocols are handled by a factory
137
138        FOR_VECTOR(chain, i) {
139                if (!MAP_HAS1(_factoriesByProtocolId, chain[i])) {
140                        FATAL("protocol %"PRIx64" not handled by anyone", chain[i]);
141                        return NULL;
142                }
143        }
144
145        //2. Spawn the protocols
146
147        bool failed = false;
148
149        FOR_VECTOR(chain, i) {
150                BaseProtocol *pProtocol = _factoriesByProtocolId[chain[i]]->SpawnProtocol(
151                                chain[i], parameters);
152                if (pProtocol == NULL) {
153                        FATAL("Unable to spawn protocol %s handled by factory %u",
154                                        STR(tagToString(chain[i])),
155                                        _factoriesByProtocolId[chain[i]]->GetId());
156                        failed = true;
157                        break;
158                }
159                if (pResult != NULL)
160                        pResult->SetNearProtocol(pProtocol);
161
162                pResult = pProtocol;
163        }
164
165        if (failed) {
166                if (pResult != NULL)
167                        delete pResult->GetFarEndpoint();
168                pResult = NULL;
169        } else {
170                pResult = pResult->GetNearEndpoint();
171        }
172
173        return pResult;
174}
175
176string ProtocolFactoryManager::Dump() {
177        string result = "Factories by id\n";
178
179        FOR_MAP(_factoriesById, uint32_t, BaseProtocolFactory *, i) {
180                result += format("\t%u\t%p\n", MAP_KEY(i), MAP_VAL(i));
181        }
182
183        result += "Factories by protocol id\n";
184
185        FOR_MAP(_factoriesByProtocolId, uint64_t, BaseProtocolFactory *, i) {
186                result += format("\t%s\t%p\n",
187                                STR(tagToString(MAP_KEY(i))),
188                                MAP_VAL(i));
189        }
190
191        result += "Factories by chain name\n";
192
193        FOR_MAP(_factoriesByChainName, string, BaseProtocolFactory *, i) {
194                result += format("\t%s\t%p\n",
195                                STR(MAP_KEY(i)),
196                                MAP_VAL(i));
197        }
198
199        return result;
200}
201
Note: See TracBrowser for help on using the repository browser.