1 /*
2  * \file       ocsd_lib_dcd_register.cpp
3  * \brief      OpenCSD : Library decoder register object
4  *
5  * \copyright  Copyright (c) 2016, ARM Limited. All Rights Reserved.
6  */
7 
8 /*
9  * Redistribution and use in source and binary forms, with or without modification,
10  * are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. Neither the name of the copyright holder nor the names of its contributors
20  * may be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26  * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include "common/ocsd_lib_dcd_register.h"
36 
37 // include built-in decode manager headers
38 #include "opencsd/etmv4/trc_dcd_mngr_etmv4i.h"
39 #include "opencsd/etmv3/trc_dcd_mngr_etmv3.h"
40 #include "opencsd/ptm/trc_dcd_mngr_ptm.h"
41 #include "opencsd/stm/trc_dcd_mngr_stm.h"
42 #include "opencsd/ete/trc_dcd_mngr_ete.h"
43 
44 // create array of built-in decoders to register with library
45 static built_in_decoder_info_t sBuiltInArray[] = {
46     CREATE_BUILTIN_ENTRY(DecoderMngrEtmV4I,OCSD_BUILTIN_DCD_ETMV4I),
47     CREATE_BUILTIN_ENTRY(DecoderMngrEtmV3, OCSD_BUILTIN_DCD_ETMV3),
48     CREATE_BUILTIN_ENTRY(DecoderMngrPtm, OCSD_BUILTIN_DCD_PTM),
49     CREATE_BUILTIN_ENTRY(DecoderMngrStm, OCSD_BUILTIN_DCD_STM),
50     CREATE_BUILTIN_ENTRY(DecoderMngrETE, OCSD_BUILTIN_DCD_ETE)
51     //{ 0, 0, 0}
52 };
53 
54 #define NUM_BUILTINS sizeof(sBuiltInArray) / sizeof(built_in_decoder_info_t)
55 
56 
57 OcsdLibDcdRegister *OcsdLibDcdRegister::m_p_libMngr = 0;
58 bool OcsdLibDcdRegister::m_b_registeredBuiltins = false;
59 ocsd_trace_protocol_t OcsdLibDcdRegister::m_nextCustomProtocolID = OCSD_PROTOCOL_CUSTOM_0;
60 
61 OcsdLibDcdRegister *OcsdLibDcdRegister::getDecoderRegister()
62 {
63     if(m_p_libMngr == 0)
64         m_p_libMngr = new (std::nothrow) OcsdLibDcdRegister();
65     return m_p_libMngr;
66 }
67 
68 const ocsd_trace_protocol_t OcsdLibDcdRegister::getNextCustomProtocolID()
69 {
70     ocsd_trace_protocol_t ret = m_nextCustomProtocolID;
71     if(m_nextCustomProtocolID < OCSD_PROTOCOL_END)
72         m_nextCustomProtocolID = (ocsd_trace_protocol_t)(((int)m_nextCustomProtocolID)+1);
73     return ret;
74 }
75 
76 void OcsdLibDcdRegister::releaseLastCustomProtocolID()
77 {
78     if(m_nextCustomProtocolID > OCSD_PROTOCOL_CUSTOM_0)
79         m_nextCustomProtocolID = (ocsd_trace_protocol_t)(((int)m_nextCustomProtocolID)-1);
80 }
81 
82 OcsdLibDcdRegister::OcsdLibDcdRegister()
83 {
84     m_iter = m_decoder_mngrs.begin();
85     m_pLastTypedDecoderMngr = 0;
86 }
87 
88 OcsdLibDcdRegister::~OcsdLibDcdRegister()
89 {
90     m_decoder_mngrs.clear();
91     m_typed_decoder_mngrs.clear();
92     m_pLastTypedDecoderMngr = 0;
93 }
94 
95 const ocsd_err_t OcsdLibDcdRegister::registerDecoderTypeByName(const std::string &name, IDecoderMngr *p_decoder_fact)
96 {
97     if(isRegisteredDecoder(name))
98         return OCSD_ERR_DCDREG_NAME_REPEAT;
99     m_decoder_mngrs.emplace(std::pair<const std::string, IDecoderMngr *>(name,p_decoder_fact));
100     m_typed_decoder_mngrs.emplace(std::pair<const ocsd_trace_protocol_t, IDecoderMngr *>(p_decoder_fact->getProtocolType(),p_decoder_fact));
101     return OCSD_OK;
102 }
103 
104 void OcsdLibDcdRegister::registerBuiltInDecoders()
105 {
106     bool memFail = false;
107     for(unsigned i = 0; i < NUM_BUILTINS; i++)
108     {
109         if(sBuiltInArray[i].PFn)
110         {
111             sBuiltInArray[i].pMngr = sBuiltInArray[i].PFn( sBuiltInArray[i].name);
112             if(!sBuiltInArray[i].pMngr)
113                 memFail=true;
114         }
115     }
116     m_b_registeredBuiltins = !memFail;
117 }
118 
119 void OcsdLibDcdRegister::deregisterAllDecoders()
120 {
121     if(m_b_registeredBuiltins)
122     {
123         for(unsigned i = 0; i < NUM_BUILTINS; i++)
124             delete sBuiltInArray[i].pMngr;
125         m_b_registeredBuiltins = false;
126     }
127 
128     if(m_p_libMngr)
129     {
130         m_p_libMngr->deRegisterCustomDecoders();
131         delete m_p_libMngr;
132         m_p_libMngr = 0;
133     }
134 }
135 
136 void OcsdLibDcdRegister::deRegisterCustomDecoders()
137 {
138     std::map<const ocsd_trace_protocol_t, IDecoderMngr *>::const_iterator iter = m_typed_decoder_mngrs.begin();
139     while(iter != m_typed_decoder_mngrs.end())
140     {
141         IDecoderMngr *pMngr = iter->second;
142         if(pMngr->getProtocolType() >= OCSD_PROTOCOL_CUSTOM_0)
143             delete pMngr;
144         iter++;
145     }
146 }
147 
148 const ocsd_err_t OcsdLibDcdRegister::getDecoderMngrByName(const std::string &name, IDecoderMngr **p_decoder_mngr)
149 {
150     if(!m_b_registeredBuiltins)
151     {
152         registerBuiltInDecoders();
153         if(!m_b_registeredBuiltins)
154             return OCSD_ERR_MEM;
155     }
156 
157     std::map<const std::string,  IDecoderMngr *>::const_iterator iter = m_decoder_mngrs.find(name);
158     if(iter == m_decoder_mngrs.end())
159         return OCSD_ERR_DCDREG_NAME_UNKNOWN;
160     *p_decoder_mngr = iter->second;
161     return OCSD_OK;
162 }
163 
164 const ocsd_err_t OcsdLibDcdRegister::getDecoderMngrByType(const ocsd_trace_protocol_t decoderType, IDecoderMngr **p_decoder_mngr)
165 {
166     if(!m_b_registeredBuiltins)
167     {
168         registerBuiltInDecoders();
169         if(!m_b_registeredBuiltins)
170             return OCSD_ERR_MEM;
171     }
172 
173     if (m_pLastTypedDecoderMngr && (m_pLastTypedDecoderMngr->getProtocolType() == decoderType))
174         *p_decoder_mngr = m_pLastTypedDecoderMngr;
175     else
176     {
177         std::map<const ocsd_trace_protocol_t, IDecoderMngr *>::const_iterator iter = m_typed_decoder_mngrs.find(decoderType);
178         if (iter == m_typed_decoder_mngrs.end())
179             return OCSD_ERR_DCDREG_TYPE_UNKNOWN;
180         *p_decoder_mngr = m_pLastTypedDecoderMngr = iter->second;
181     }
182     return OCSD_OK;
183 }
184 
185 const bool OcsdLibDcdRegister::isRegisteredDecoder(const std::string &name)
186 {
187     std::map<const std::string,  IDecoderMngr *>::const_iterator iter = m_decoder_mngrs.find(name);
188     if(iter != m_decoder_mngrs.end())
189         return true;
190     return false;
191 }
192 
193 const bool OcsdLibDcdRegister::isRegisteredDecoderType(const ocsd_trace_protocol_t decoderType)
194 {
195     std::map<const ocsd_trace_protocol_t, IDecoderMngr *>::const_iterator iter = m_typed_decoder_mngrs.find(decoderType);
196     if(iter !=  m_typed_decoder_mngrs.end())
197         return true;
198     return false;
199 }
200 
201 const bool OcsdLibDcdRegister::getFirstNamedDecoder(std::string &name)
202 {
203     m_iter = m_decoder_mngrs.begin();
204     return getNextNamedDecoder(name);
205 }
206 
207 const bool OcsdLibDcdRegister::getNextNamedDecoder(std::string &name)
208 {
209     if(m_iter == m_decoder_mngrs.end())
210         return false;
211     name = m_iter->first;
212     m_iter++;
213     return true;
214 }
215 
216 /* End of File ocsd_lib_dcd_register.cpp */
217