00001 /* 00002 * File Name: collection_impl.h 00003 */ 00004 00005 /* 00006 * This file is part of uds-plugin-plaintext. 00007 * 00008 * uds-plugin-plaintext is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation, either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * uds-plugin-plaintext is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00020 */ 00021 00022 /** 00023 * Copyright (C) 2008 iRex Technologies B.V. 00024 * All rights reserved. 00025 */ 00026 00027 #ifndef TEXT_PLUGIN_COLLECTION_IMPL_H_ 00028 #define TEXT_PLUGIN_COLLECTION_IMPL_H_ 00029 00030 #include <vector> 00031 #include <cassert> 00032 #include "plugin_inc.h" 00033 #include "interfaces_utils.h" 00034 #include "signal_slot.h" 00035 00036 using namespace utils; 00037 00038 namespace text 00039 { 00040 00041 class DataContainerBase 00042 { 00043 public: 00044 DataContainerBase(){} 00045 virtual ~DataContainerBase(){} 00046 00047 public: 00048 virtual bool get_first_element(void **data_ptr) = 0; 00049 virtual int get_count() = 0; 00050 }; 00051 00052 template <typename T> 00053 class DataContainer : public DataContainerBase 00054 { 00055 public: 00056 DataContainer(){} 00057 ~DataContainer(){} 00058 00059 public: 00060 virtual bool get_first_element(void **data_ptr) 00061 { 00062 *data_ptr = &data[0]; 00063 return true; 00064 } 00065 00066 virtual int get_count() 00067 { 00068 return static_cast<int>(data.size()); 00069 } 00070 00071 std::vector<T> & ref() 00072 { 00073 return data; 00074 } 00075 00076 private: 00077 std::vector<T> data; 00078 }; 00079 00080 template <typename T> 00081 class DataContainer<T*> : public DataContainerBase 00082 { 00083 public: 00084 DataContainer(){} 00085 ~DataContainer() 00086 { 00087 for (unsigned int i=0; i<data.size(); i++) 00088 { 00089 delete data[i]; 00090 } 00091 } 00092 00093 public: 00094 virtual bool get_first_element(void **data_ptr) 00095 { 00096 *data_ptr = &data[0]; 00097 return true; 00098 } 00099 00100 virtual int get_count() 00101 { 00102 return static_cast<int>(data.size()); 00103 } 00104 00105 std::vector<T*>& ref() 00106 { 00107 return data; 00108 } 00109 00110 private: 00111 std::vector<T*> data; 00112 }; 00113 00114 /// PluginCollectionImpl provides a template based collection container. 00115 /// Through this class, caller is able to store data inside the collection. 00116 /// If caller wants to strore pointe data in the collection, it's necessary 00117 /// for caller to connect the release_signal, so that when collection object 00118 /// is to be released, the caller can be notified. 00119 class PluginCollectionImpl : public IPluginUnknown 00120 , public IPluginCollection 00121 { 00122 public: 00123 PluginCollectionImpl(void) 00124 : data(0) 00125 { 00126 query_interface = query_interface_impl; 00127 release = release_impl; 00128 get_data = get_data_impl; 00129 get_num_elements = get_num_elements_impl; 00130 00131 g_instances_table.add_interface<IPluginUnknown>(this); 00132 g_instances_table.add_interface<IPluginCollection>(this); 00133 } 00134 00135 ~PluginCollectionImpl(void) 00136 { 00137 if (data) 00138 { 00139 delete data; 00140 data = 0; 00141 } 00142 g_instances_table.remove(this); 00143 } 00144 00145 public: 00146 Signal<PluginCollectionImpl *> release_signal; 00147 00148 public: 00149 template <typename T> 00150 void create() 00151 { 00152 data = new DataContainer<T>; 00153 } 00154 00155 template <typename T> 00156 std::vector<T> & take_data_ref() 00157 { 00158 DataContainer<T> *ptr = static_cast<DataContainer<T> *>(data); 00159 return ptr->ref(); 00160 } 00161 00162 private: 00163 // IPluginUnknown 00164 static PluginStatus query_interface_impl(IPluginUnknown *thiz, 00165 const UDSString *id, 00166 void **ptr ) 00167 { 00168 // check object. 00169 PluginCollectionImpl *instance = g_instances_table.get_object(thiz); 00170 if (g_instances_table.query_interface(instance, id->get_buffer(id), ptr)) 00171 { 00172 return PLUGIN_OK; 00173 } 00174 return PLUGIN_FAIL; 00175 } 00176 00177 static int release_impl(IPluginUnknown *thiz ) 00178 { 00179 PluginCollectionImpl *instance = g_instances_table.get_object(thiz); 00180 if (instance->release_signal.count() > 0) 00181 { 00182 instance->release_signal.broadcast(instance); 00183 } 00184 else 00185 { 00186 delete instance; 00187 } 00188 return 0; 00189 } 00190 00191 // IPluginCollection 00192 static PluginStatus get_data_impl(IPluginUnknown *thiz, 00193 void **data_ptr) 00194 { 00195 PluginCollectionImpl *instance = g_instances_table.get_object(thiz); 00196 instance->data->get_first_element(data_ptr); 00197 return PLUGIN_OK; 00198 } 00199 00200 static int get_num_elements_impl(IPluginUnknown *thiz ) 00201 { 00202 PluginCollectionImpl *instance = g_instances_table.get_object(thiz); 00203 return instance->data->get_count(); 00204 } 00205 private: 00206 static ObjectTable<PluginCollectionImpl> g_instances_table; 00207 DataContainerBase * data; 00208 00209 }; 00210 00211 00212 00213 }; // namespace text 00214 00215 #endif // PLUGIN_COLLECTION_IMPL_H_ 00216