Autobinder.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 _SUPPORT_AUTOBINDER_H_
00014 #define _SUPPORT_AUTOBINDER_H_
00015 
00021 #include <support/Value.h>
00022 #include <support/Parcel.h>
00023 
00028 #if _SUPPORTS_NAMESPACE
00029 namespace palmos {
00030 namespace osp {
00031 using namespace palmos::support;
00032 #endif
00033 
00034 class BAutobinderDummiClass
00035 {
00036 public:
00037     virtual void Method();
00038 };
00039 
00040 typedef void (BAutobinderDummiClass::*BSomeMethod)();
00041 
00042 #if _SUPPORTS_NAMESPACE
00043 } } // namespace palmos::osp
00044 #endif
00045 
00046 
00047 
00048 #if _SUPPORTS_NAMESPACE
00049 namespace palmos {
00050 namespace support {
00051 #endif
00052 
00053 enum {
00054     B_IN_PARAM      = 0x00000001,
00055     B_OUT_PARAM     = 0x00000002
00056 };
00057 
00058 struct BAutobinderDef;
00059 struct BEffectMethodDef;
00060 struct PTypeMarshaller;
00061 struct BParameterInfo;
00062 struct PPointerToMemberFunction;
00063 
00064 typedef status_t (*autobinder_local_hook_t)(const sptr<IInterface>& target, SParcel *in, SParcel *out);
00065 typedef void (*untyped_func)(void);
00066 
00068 status_t    autobinder_unmarshal_args(const BParameterInfo* pi, const BParameterInfo* pi_end, uint32_t dir, SParcel& inParcel, void** outArgs, uint32_t* outDirs);
00070 status_t    autobinder_marshal_args(const BParameterInfo* pi, const BParameterInfo* pi_end, uint32_t dir, void** inArgs, SParcel& outParcel, uint32_t* outDirs);
00071 
00073 
00075 status_t    autobinder_from_parcel(const BEffectMethodDef &def, SParcel &parcel, void **args, uint32_t* outDirs);
00077 
00081 status_t    autobinder_to_parcel(const BEffectMethodDef &def, void **args, void *result, SParcel &parcel, uint32_t dirs);
00082 
00083 // execute_autobinder requires that the definitions be sorted in SValue order of the keys
00084 status_t    execute_autobinder(uint32_t code, const sptr<IInterface>& target,
00085                                 SParcel &data, SParcel *reply,
00086                                 const BAutobinderDef **defs, size_t def_count,
00087                                 uint32_t flags);
00088 
00089 status_t    parameter_from_value(type_code type, const struct PTypeMarshaller* marshaller, const SValue &v, void *result);
00090 status_t    parameter_to_value(type_code type, const struct PTypeMarshaller* marshaller, const void *value, SValue *out);
00091 
00101 status_t
00102 InvokeAutobinderFunction(   const BEffectMethodDef  * def,
00103                             void                    * object,
00104                             const SValue            & args,
00105                             SValue                  * returnValue
00106                             );
00107 
00113 void
00114 PerformRemoteBinderCall(    int                     ebp,
00115                             const BEffectMethodDef  *def,
00116                             unsigned char           *returnValue,
00117                             const sptr<IBinder>&    remote,
00118                             SValue                  binding,
00119                             uint32_t                which
00120                             );
00121 
00122 struct PTypeMarshaller
00123 {
00124     // Amount of data in structure.
00125     size_t                  structSize;
00126 
00127     // This function is used to marshall data.
00128     // It writes the var into the given parcel and returns the amount
00129     // of data or an error.
00130     // (This is exactly the same as SParcel::MarshallFixedData().)
00131     ssize_t                 (*marshal_parcel)(SParcel& dest, const void* var);
00132 
00133     // This function is used to unmarshall data.
00134     // It reads the data at the current location in the parcel and
00135     // stored it into 'var'.  If the parcel does not contain the
00136     // expected type, an error should be returned and 'value'
00137     // remain unmodified.  If the parcel contains B_NULL_VALUE, you
00138     // MUST ALWAYS read that value and return B_BINDER_READ_NULL_VALUE.
00139     // (This is exactly the same as SParcel::UnmarshallFixedData().)
00140     status_t                (*unmarshal_parcel)(SParcel& src, void* var);
00141 
00142     // Marshall to an SValue.  'var' is always non-NULL.
00143     status_t                (*marshal_value)(SValue* dest, const void* var);
00144 
00145     // Unmarshall from an SValue.  'var' is always non-NULL.
00146     status_t                (*unmarshal_value)(const SValue& src, void* var);
00147 };
00148 
00149 // ADS can't handle static structure members in templates!!! ARGH!!!!
00150 #if 0
00151 template<class TYPE>
00152 class SMarshallerForType
00153 {
00154 public:
00155     static const PTypeMarshaller marshaller;
00156 private:
00157     TYPE* adsIsLame;
00158 };
00159 
00160 template<class TYPE>
00161 const PTypeMarshaller SMarshallerForType<TYPE>::marshaller =
00162 {
00163     sizeof(PTypeMarshaller),
00164     &TYPE::PreMarshalParcel,
00165     &TYPE::MarshalParcel,
00166     &TYPE::UnmarshalParcel,
00167     &TYPE::MarshalValue,
00168     &TYPE::UnmarshalValue
00169 };
00170 #else
00171 template<class TYPE>
00172 class SMarshallerForType
00173 {
00174 public:
00175     static const size_t marshaller;
00176     static const size_t f1;
00177     static const size_t f2;
00178     static const size_t f3;
00179     static const size_t f4;
00180     static const size_t f5;
00181 private:
00182     TYPE* adsIsLame;
00183 };
00184 
00185 template<class TYPE>
00186 const size_t SMarshallerForType<TYPE>::marshaller = sizeof(PTypeMarshaller);
00187 template<class TYPE>
00188 const size_t SMarshallerForType<TYPE>::f1 = (size_t)&TYPE::PreMarshalParcel;
00189 template<class TYPE>
00190 const size_t SMarshallerForType<TYPE>::f2 = (size_t)&TYPE::MarshalParcel;
00191 template<class TYPE>
00192 const size_t SMarshallerForType<TYPE>::f3 = (size_t)&TYPE::UnmarshalParcel;
00193 template<class TYPE>
00194 const size_t SMarshallerForType<TYPE>::f4 = (size_t)&TYPE::MarshalValue;
00195 template<class TYPE>
00196 const size_t SMarshallerForType<TYPE>::f5 = (size_t)&TYPE::UnmarshalValue;
00197 #endif
00198 
00199 struct BParameterInfo
00200 {
00201     type_code               type;   // if type == 0 then this is not a primitive type
00202     uint32_t                direction;
00203     const PTypeMarshaller*  marshaller;
00204 };
00205 
00206 struct PPointerToMemberFunction
00207 {
00208     short delta;                // offset of this pointer
00209     short index;                //  index into vtable  or negative if not virtual
00210     union {
00211         int32_t func;           // address of nonvirtual function
00212         short offset;           // offset if vtable pointer
00213     };
00214 };
00215 
00216 struct BEffectMethodDef
00217 {
00218     type_code                           returnType;
00219     const PTypeMarshaller*              returnMarshaller;
00220     size_t                              paramCount;
00221     const BParameterInfo                *paramTypes;
00222     autobinder_local_hook_t             localFunc;
00223     union {
00224         BNS(palmos::osp::)BSomeMethod   pointer;
00225         PPointerToMemberFunction        pmf;
00226     };
00227 };
00228 
00229 struct BAutobinderDef
00230 {
00231     size_t                  index;          // index in array
00232     const void              * raw_key;
00233     const BEffectMethodDef  * put;
00234     const BEffectMethodDef  * get;
00235     const BEffectMethodDef  * invoke;
00236     int32_t                 classOffset;    // B_FIND_CLASS_OFFSET(LSuck, ISuck)
00237     
00238     const SValue&       key() const;
00239 };
00240 
00241 inline const SValue& BAutobinderDef::key() const
00242 {
00243     return *reinterpret_cast<const SValue*>(raw_key);
00244 }
00245 
00246 #if _SUPPORTS_NAMESPACE
00247 } } // namespace palmos::support
00248 #endif
00249 
00256 #define B_FUNC_INFO(method)     { NULL }//(BNS(palmos::osp::)BSomeMethod)&(method)}
00257 
00258 
00262 #define B_FIND_BINDER_I_CLASS_OFFSET(L) ((((int)static_cast<IInterface*>((L*)10))-10)) // use 10-10 because 0 is special cased for NULL
00263 
00264 
00268 #define B_IMPLEMENT_MARSHAL_PLAN(def, returnValue, remote, binding, which) \
00269         { \
00270             int ebp;                                    \
00271             __asm__ __volatile__ (" movl %%ebp, %0;" :"=r"(ebp) );      \
00272             PerformRemoteBinderCall(ebp, (def), (unsigned char *)(returnValue), (remote), (binding), (which));  \
00273         }
00274 
00277 #endif // _SUPPORT_AUTOBINDER_H_