InformList.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
00011  */
00012 
00013 #ifndef INFORMLIST_H
00014 #define INFORMLIST_H
00015 
00016 #include <support/KeyedVector.h>
00017 #include <support/ITextStream.h>
00018 #include <support/INode.h>
00019 
00020 #if _SUPPORTS_NAMESPACE
00021 using namespace palmos::support;
00022 #endif
00023 
00024 class CallbackInfo
00025 {
00026 public:
00027     CallbackInfo();
00028     CallbackInfo(const sptr<IBinder>& target, const SValue &method, uint32_t flags, const SValue &cookie);
00029     CallbackInfo(const sptr<IBinder>& target, const SValue &method, uint32_t flags);
00030     CallbackInfo(const CallbackInfo &);
00031     ~CallbackInfo();
00032 
00033     sptr<IBinder>   Target() const;
00034     SValue          Method() const;
00035     uint32_t            Flags() const;
00036     SValue          Cookie() const;
00037 
00038 private:
00039     IBinder * m_target;
00040     SValue  m_method;
00041     uint32_t    m_flags;
00042     SValue  m_cookie;
00043 };
00044 
00045 class CreationInfo
00046 {
00047 public:
00048     CreationInfo();
00049     CreationInfo(const sptr<INode>& context, const sptr<IProcess>& team, const SString &component, const SValue &interface,
00050                     const SValue &method, uint32_t flags,  const SValue &cookie);
00051     CreationInfo(const sptr<INode>& context, const sptr<IProcess>& team, const SString &component, const SValue &interface,
00052                     const SValue &method, uint32_t flags);
00053     CreationInfo(const CreationInfo &);
00054     ~CreationInfo();
00055     
00056     sptr<INode>     Context() const;
00057     sptr<IProcess>  Process() const;
00058     SString         Component() const;
00059     SValue          Interface() const;
00060     SValue          Method() const;
00061     uint32_t        Flags() const;
00062     SValue          Cookie() const;
00063 
00064 private:
00065     sptr<INode>     m_context;
00066     IProcess*       m_team;
00067     SString         m_component;
00068     SValue          m_interface;
00069     SValue          m_method;
00070     uint32_t        m_flags;
00071     SValue          m_cookie;
00072 };
00073 
00074 template <class T>
00075 class InformList
00076 {
00077 public:
00078                 InformList();
00079                 ~InformList();
00080 
00081     status_t    Add(const SValue &key, const T &info);
00082     status_t    Remove(const SValue &key, const T &info);
00083     status_t    Find(const SValue &key, SSortedVector<T> *info);
00084     
00085     SKeyedVector<SValue, SSortedVector<T>* > m_list;
00086 };
00087 
00088 
00089 // ----------------------------------------------------------------------
00090 inline
00091 CallbackInfo::CallbackInfo()
00092     :m_target(NULL),
00093      m_method(),
00094      m_flags(0),
00095      m_cookie()
00096 {
00097 }
00098 
00099 inline
00100 CallbackInfo::CallbackInfo(const sptr<IBinder>& target, const SValue &method, uint32_t flags, const SValue &cookie)
00101     :m_target(target.ptr()),
00102      m_method(method),
00103      m_flags(flags),
00104      m_cookie(cookie)
00105 {
00106     if (m_target != NULL) {
00107         if (m_flags & B_WEAK_BINDER_LINK) {
00108             m_target->IncWeak(m_target);
00109         } else {
00110             m_target->IncStrong(m_target);
00111         }
00112     }
00113 }
00114 
00115 inline
00116 CallbackInfo::CallbackInfo(const sptr<IBinder>& target, const SValue &method, uint32_t flags)
00117     :m_target(target.ptr()),
00118      m_method(method),
00119      m_flags(flags),
00120      m_cookie()
00121 {
00122     if (m_target != NULL) {
00123         if (m_flags & B_WEAK_BINDER_LINK) {
00124             m_target->IncWeak(m_target);
00125         } else {
00126             m_target->IncStrong(m_target);
00127         }
00128     }
00129 }
00130 
00131 inline
00132 CallbackInfo::CallbackInfo(const CallbackInfo &o)
00133     :m_target(o.m_target),
00134      m_method(o.m_method),
00135      m_flags(o.m_flags),
00136      m_cookie(o.m_cookie)
00137 {
00138     if (m_target != NULL) {
00139         if (m_flags & B_WEAK_BINDER_LINK) {
00140             m_target->IncWeak(m_target);
00141         } else {
00142             m_target->IncStrong(m_target);
00143         }
00144     }
00145 
00146 }
00147 
00148 inline
00149 CallbackInfo::~CallbackInfo()
00150 {
00151     if (m_target != NULL) {
00152         if (m_flags & B_WEAK_BINDER_LINK) {
00153             m_target->DecWeak(m_target);
00154         } else {
00155             m_target->DecStrong(m_target);
00156         }
00157     }
00158 
00159 }
00160 
00161 inline
00162 sptr<IBinder>
00163 CallbackInfo::Target() const
00164 {
00165     if (m_flags & B_WEAK_BINDER_LINK) {
00166         wptr<IBinder> wptr(m_target);
00167         return wptr.promote();
00168     } else {
00169         return m_target;
00170     }
00171 }
00172 
00173 inline
00174 SValue
00175 CallbackInfo::Method() const
00176 {
00177     return m_method;
00178 }
00179 
00180 inline
00181 uint32_t
00182 CallbackInfo::Flags() const
00183 {
00184     return m_flags;
00185 }
00186 
00187 inline
00188 SValue
00189 CallbackInfo::Cookie() const
00190 {
00191     return m_cookie;
00192 }
00193 
00194 inline
00195 int32_t
00196 BCompare(const CallbackInfo& l, const CallbackInfo& r)
00197 {
00198     if (l.Flags() > r.Flags()) return 1;
00199     if (l.Flags() < r.Flags()) return -1;
00200     // flags are equal
00201     if (l.Target().ptr() > r.Target().ptr()) return 1;
00202     if (l.Target().ptr() < r.Target().ptr()) return -1;
00203     // targets are equal
00204     if (l.Method() > r.Method()) return 1;
00205     if (l.Method() < r.Method()) return -1;
00206     // targets are equal
00207     return 0;
00208 };
00209 
00210 inline
00211 bool
00212 BLessThan(const CallbackInfo& l, const CallbackInfo& r)
00213 {
00214     return BCompare(l, r) < 0;
00215 };
00216 
00217 inline
00218 const sptr<ITextOutput>&
00219 operator << (const sptr<ITextOutput>& os, const CallbackInfo &info)
00220 {
00221     os << "target: " << info.Target();
00222     os << " method: \"" << info.Method().AsString();
00223     os << "\" flags: " << (void*)info.Flags();
00224     os << " cookie: " << info.Cookie();
00225     return os;
00226 }
00227 
00228 
00229 // ----------------------------------------------------------------------
00230 inline
00231 CreationInfo::CreationInfo()
00232     :m_context(),
00233      m_team(NULL),
00234      m_component(),
00235      m_interface(),
00236      m_method(),
00237      m_flags(0),
00238      m_cookie()
00239 {
00240 }
00241 
00242 inline
00243 CreationInfo::CreationInfo(const sptr<INode>& context, const sptr<IProcess>& team, const SString &component, const SValue &interface,
00244                     const SValue &method, uint32_t flags, const SValue &cookie)
00245     :m_context(context),
00246      m_team(team.ptr()),
00247      m_component(component),
00248      m_interface(interface),
00249      m_method(method),
00250      m_flags(flags),
00251      m_cookie(cookie)
00252 {
00253     if (m_team != NULL) {
00254         if (m_flags & B_WEAK_BINDER_LINK) {
00255             m_team->IncWeak(m_team);
00256         } else {
00257             m_team->IncStrong(m_team);
00258         }
00259     }
00260 }
00261 
00262 inline
00263 CreationInfo::CreationInfo(const sptr<INode>& context, const sptr<IProcess>& team, const SString &component, const SValue &interface,
00264                     const SValue &method, uint32_t flags)
00265     :m_context(context),
00266      m_team(team.ptr()),
00267      m_component(component),
00268      m_interface(interface),
00269      m_method(method),
00270      m_flags(flags),
00271      m_cookie()
00272 {
00273     if (m_team != NULL) {
00274         if (m_flags & B_WEAK_BINDER_LINK) {
00275             m_team->IncWeak(m_team);
00276         } else {
00277             m_team->IncStrong(m_team);
00278         }
00279     }
00280 }
00281 
00282 inline
00283 CreationInfo::CreationInfo(const CreationInfo &o)
00284     :m_context(o.m_context),
00285      m_team(o.m_team),
00286      m_component(o.m_component),
00287      m_interface(o.m_interface),
00288      m_method(o.m_method),
00289      m_flags(o.m_flags),
00290      m_cookie(o.m_cookie)
00291 {
00292     if (m_team != NULL) {
00293         if (m_flags & B_WEAK_BINDER_LINK) {
00294             m_team->IncWeak(m_team);
00295         } else {
00296             m_team->IncStrong(m_team);
00297         }
00298     }
00299 }
00300 
00301 inline
00302 CreationInfo::~CreationInfo()
00303 {
00304     if (m_team != NULL) {
00305         if (m_flags & B_WEAK_BINDER_LINK) {
00306             m_team->DecWeak(m_team);
00307         } else {
00308             m_team->DecStrong(m_team);
00309         }
00310     }
00311 }
00312 
00313 inline
00314 sptr<INode>
00315 CreationInfo::Context() const
00316 {
00317     return m_context;
00318 }
00319 
00320 inline
00321 sptr<IProcess>
00322 CreationInfo::Process() const
00323 {
00324     if (m_flags & B_WEAK_BINDER_LINK) {
00325         wptr<IProcess> wptr(m_team);
00326         return wptr.promote();
00327     } else {
00328         return m_team;
00329     }
00330 }
00331 
00332 inline
00333 SString
00334 CreationInfo::Component() const
00335 {
00336     return m_component;
00337 }
00338 
00339 inline
00340 SValue
00341 CreationInfo::Interface() const
00342 {
00343     return m_interface;
00344 }
00345 
00346 inline
00347 SValue
00348 CreationInfo::Method() const
00349 {
00350     return m_method;
00351 }
00352 
00353 inline
00354 uint32_t
00355 CreationInfo::Flags() const
00356 {
00357     return m_flags;
00358 }
00359 
00360 inline
00361 SValue
00362 CreationInfo::Cookie() const
00363 {
00364     return m_cookie;
00365 }
00366 
00367 inline
00368 int32_t
00369 BCompare(const CreationInfo& l, const CreationInfo& r)
00370 {
00371     if (l.Flags() > r.Flags()) return 1;
00372     if (l.Flags() < r.Flags()) return -1;
00373     // flags are equal
00374     if (l.Component() > r.Component()) return 1;
00375     if (l.Component() < r.Component()) return -1;
00376     // components are equal
00377     if (l.Process()->AsBinder().ptr() > r.Process()->AsBinder().ptr()) return 1;
00378     if (l.Process()->AsBinder().ptr() < r.Process()->AsBinder().ptr()) return -1;
00379     // teams are equal
00380     if (l.Context()->AsBinder().ptr() > r.Context()->AsBinder().ptr()) return 1;
00381     if (l.Context()->AsBinder().ptr() < r.Context()->AsBinder().ptr()) return -1;
00382     // contexts are equal
00383     if (l.Interface() > r.Interface()) return 1;
00384     if (l.Interface() < r.Interface()) return -1;
00385     // interfaces are equal
00386     if (l.Method() > r.Method()) return 1;
00387     if (l.Method() < r.Method()) return -1;
00388     // interfaces are equal
00389     return 0;
00390 };
00391 
00392 inline
00393 bool
00394 BLessThan(const CreationInfo& l, const CreationInfo& r)
00395 {
00396     return BCompare(l, r) < 0;
00397 };
00398 
00399 inline
00400 const sptr<ITextOutput>&
00401 operator << (const sptr<ITextOutput>& os, const CreationInfo &info)
00402 {
00403     os << "context: " << info.Context()->AsBinder();
00404     os << " proc: " << info.Process()->AsBinder();
00405     os << " component: " << info.Component();
00406     os << " interface: " << info.Interface();
00407     os << " method: " << info.Method();
00408     os << " flags: " << (void*)info.Flags();
00409     os << " cookie: " << info.Cookie();
00410     return os;
00411 }
00412 
00413 
00414 
00415 // ----------------------------------------------------------------------
00416 template <class T> inline
00417 InformList<T>::InformList()
00418     :m_list()
00419 {
00420 }
00421 
00422 template <class T> inline
00423 InformList<T>::~InformList()
00424 {
00425     size_t count = m_list.CountItems();
00426     for (size_t i=0; i<count; i++) {
00427         delete m_list.EditValueAt(i);
00428     }
00429 }
00430 
00431 template <class T> inline
00432 status_t
00433 InformList<T>::Add(const SValue &key, const T &info)
00434 {
00435     size_t keyIndex;
00436     size_t infoIndex;
00437     bool foundKey;
00438     bool foundInfo;
00439     bool added;
00440     
00441     foundKey = m_list.GetIndexOf(key, &keyIndex);
00442     if (foundKey) {
00443         SSortedVector<T> *registered = m_list.EditValueAt(keyIndex);
00444         foundInfo = registered->GetIndexOf(info, &infoIndex);
00445         if (foundInfo) return B_NAME_IN_USE;
00446         registered->AddItem(info, &added);
00447         if (!added) return B_NO_MEMORY;
00448         return B_OK;
00449     } else {
00450         SSortedVector<T> *registration = new SSortedVector<T>;
00451         registration->AddItem(info, &added);
00452         if (!added) goto err;
00453         added = 0 <= m_list.AddItem(key, registration);
00454         if (!added) goto err;
00455         return B_OK;
00456 err:
00457         delete registration;
00458         return B_NO_MEMORY;
00459     }
00460 }
00461 
00462 template <class T> inline
00463 status_t
00464 InformList<T>::Remove(const SValue &key, const T &info)
00465 {
00466     ssize_t keyIndex;
00467     ssize_t infoIndex;
00468     
00469     keyIndex = m_list.IndexOf(key);
00470     if (keyIndex < 0) return B_NAME_NOT_FOUND;
00471     SSortedVector<T> * infoList = m_list.EditValueAt(keyIndex);
00472     infoIndex = infoList->RemoveItemFor(info);
00473     if (infoList->CountItems() == 0) {
00474         m_list.RemoveItemsAt(keyIndex, 1);
00475         delete infoList;
00476     }
00477     return infoIndex >= 0 ? B_OK : infoIndex;
00478 }
00479 
00480 template <class T> inline
00481 status_t
00482 InformList<T>::Find(const SValue &key, SSortedVector<T> *info)
00483 {
00484     bool found;
00485     SSortedVector<T> *items = m_list.ValueFor(key, &found);
00486     if (items) *info = *items;
00487     return found ? B_OK : B_NAME_NOT_FOUND;
00488 }
00489 
00490 template <class T> inline
00491 const sptr<ITextOutput>&
00492 operator << (const sptr<ITextOutput>& os, const SSortedVector<T> &list)
00493 {
00494     size_t i, count = list.CountItems();
00495     for (i=0; i<count; i++) {
00496         os << "[" << i << "] " << list[i] << endl;
00497     }
00498     return os;
00499 }
00500 
00501 template <class T> inline
00502 const sptr<ITextOutput>&
00503 operator << (const sptr<ITextOutput>& os, const InformList<T> &list)
00504 {
00505     size_t i, count = list.m_list.CountItems();
00506     for (i=0; i<count; i++) {
00507         os << "[" << list.m_list.KeyAt(i) << "] {" << indent << endl;
00508         if (list.m_list.ValueAt(i)) os << *list.m_list.ValueAt(i);
00509         else os << "NULL";
00510         os << dedent << "}" << endl;
00511     }
00512     return os;
00513 }
00514 
00515 #endif // INFORMLIST_H