/*************************************************************************** kdehandlers.cpp - KDE specific marshallers ------------------- begin : Sun Sep 28 2003 copyright : (C) 2003 by Richard Dale email : Richard_Dale@tipitina.demon.co.uk ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if TDE_VERSION >= 0x030200 #include #include #include #endif #include #include #include #include #include #define HAVE_STRLCAT_PROTO 1 #define HAVE_STRLCPY_PROTO 1 #include "config.h" #ifndef HAVE_RUBY_1_9 #define RARRAY_LEN(x) (RARRAY(x)->len) #define RSTRING_LEN(x) (RSTRING(x)->len) #define rb_str_catf_1 rb_str_catf #endif extern "C" { extern VALUE set_obj_info(const char * className, smokeruby_object * o); }; extern bool isDerivedFromByName(Smoke *smoke, const char *className, const char *baseClassName); extern "C" { /* * Given an approximate classname and a kde instance, try to improve the resolution of the name * by using the various KDE rtti mechanisms */ const char * kde_resolve_classname(Smoke * smoke, int classId, void * ptr) { if (isDerivedFromByName(smoke, smoke->classes[classId].className, "KArchiveEntry")) { KArchiveEntry * entry = (KArchiveEntry *) smoke->cast(ptr, classId, smoke->idClass("KArchiveEntry")); if (entry->isDirectory()) { return "KDE::ArchiveDirectory"; } else { return "KDE::ArchiveFile"; } } else if (strcmp(smoke->classes[classId].className, "DOM::Node") == 0) { DOM::Node * node = (DOM::Node *) smoke->cast(ptr, classId, smoke->idClass("DOM::Node")); switch (node->nodeType()) { case DOM::Node::ELEMENT_NODE: if (((DOM::Element*)node)->isHTMLElement()) { return "DOM::HTMLElement"; } else { return "DOM::Element"; } case DOM::Node::ATTRIBUTE_NODE: return "DOM::Attr"; case DOM::Node::TEXT_NODE: return "DOM::Text"; case DOM::Node::CDATA_SECTION_NODE: return "DOM::CDATASection"; case DOM::Node::ENTITY_REFERENCE_NODE: return "DOM::EntityReference"; case DOM::Node::ENTITY_NODE: return "DOM::Entity"; case DOM::Node::PROCESSING_INSTRUCTION_NODE: return "DOM::ProcessingInstruction"; case DOM::Node::COMMENT_NODE: return "DOM::Comment"; case DOM::Node::DOCUMENT_NODE: return "DOM::Document"; case DOM::Node::DOCUMENT_TYPE_NODE: return "DOM::DocumentType"; case DOM::Node::DOCUMENT_FRAGMENT_NODE: return "DOM::DocumentFragment"; case DOM::Node::NOTATION_NODE: return "DOM::Notation"; } } return smoke->binding->className(classId); } }; void marshall_TQCStringList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE list = *(m->var()); if (TYPE(list) != T_ARRAY) { m->item().s_voidp = 0; break; } int count = RARRAY_LEN(list); QCStringList *stringlist = new QCStringList; for(long i = 0; i < count; i++) { VALUE item = rb_ary_entry(list, i); if(TYPE(item) != T_STRING) { stringlist->append(TQCString()); continue; } stringlist->append(TQCString(StringValuePtr(item), RSTRING_LEN(item) + 1)); } m->item().s_voidp = stringlist; m->next(); if(m->cleanup()) { rb_ary_clear(list); for(QCStringList::Iterator it = stringlist->begin(); it != stringlist->end(); ++it) rb_ary_push(list, rb_str_new2(static_cast(*it))); delete stringlist; } break; } case Marshall::ToVALUE: { QCStringList *stringlist = static_cast(m->item().s_voidp); if(!stringlist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(QCStringList::Iterator it = stringlist->begin(); it != stringlist->end(); ++it) { VALUE rv = rb_str_new2(static_cast((*it))); rb_ary_push(av, rv); } if(m->cleanup()) delete stringlist; *(m->var()) = av; } break; default: m->unsupported(); break; } } #if defined (__i386__) && defined (__GNUC__) && __GNUC__ >= 2 # define BREAKPOINT { __asm__ __volatile__ ("int $03"); } #else # define BREAKPOINT { fprintf(stderr, "hit ctrl-c\n"); int b = 0; while (b == 0) { ; } } #endif void marshall_KCmdLineOptions(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE optionslist = *(m->var()); if (optionslist == Qnil || TYPE(optionslist) != T_ARRAY || RARRAY_LEN(optionslist) == 0 ) { m->item().s_voidp = 0; break; } // Allocate 'length + 1' entries, to include an all NULLs last entry KCmdLineOptions *cmdLineOptions = (KCmdLineOptions *) calloc( RARRAY_LEN(optionslist) + 1, sizeof(struct KCmdLineOptions) ); VALUE options; long i; for(i = 0; i < RARRAY_LEN(optionslist); i++) { options = rb_ary_entry(optionslist, i); VALUE temp = rb_ary_entry(options, 0); cmdLineOptions[i].name = StringValuePtr(temp); temp = rb_ary_entry(options, 1); cmdLineOptions[i].description = StringValuePtr(temp); temp = rb_ary_entry(options, 2); cmdLineOptions[i].def = StringValuePtr(temp); } cmdLineOptions[i].name = 0; cmdLineOptions[i].description = 0; cmdLineOptions[i].def = 0; m->item().s_voidp = cmdLineOptions; m->next(); /* if(m->cleanup()) { rb_ary_clear(optionslist); for(i = 0; cmdLineOptions[i].name; i++) options = rb_ary_new(); rb_ary_push(options, rb_str_new2(cmdLineOptions[i].name)); rb_ary_push(options, rb_str_new2(cmdLineOptions[i].description)); rb_ary_push(options, rb_str_new2(cmdLineOptions[i].def)); rb_ary_push(optionslist, options); } */ } break; case Marshall::ToVALUE: { } break; default: m->unsupported(); break; } } void marshall_WIdList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE list = *(m->var()); if (TYPE(list) != T_ARRAY) { m->item().s_voidp = 0; break; } int count = RARRAY_LEN(list); TQValueList *valuelist = new TQValueList; long i; for(i = 0; i < count; i++) { VALUE item = rb_ary_entry(list, i); if(TYPE(item) != T_FIXNUM && TYPE(item) != T_BIGNUM) { valuelist->append(0); continue; } valuelist->append(NUM2LONG(item)); } m->item().s_voidp = valuelist; m->next(); if (!m->type().isConst()) { rb_ary_clear(list); for(TQValueListIterator it = valuelist->begin(); it != valuelist->end(); ++it) rb_ary_push(list, LONG2NUM((int)*it)); } if (m->cleanup()) { delete valuelist; } } break; case Marshall::ToVALUE: { TQValueList *valuelist = (TQValueList*)m->item().s_voidp; if(!valuelist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(TQValueListIterator it = valuelist->begin(); it != valuelist->end(); ++it) rb_ary_push(av, LONG2NUM(*it)); *(m->var()) = av; if(m->cleanup()) delete valuelist; } break; default: m->unsupported(); break; } } void marshall_KMimeTypeList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { KMimeType::List *offerList = (KMimeType::List*)m->item().s_voidp; if(!offerList) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(KMimeType::List::Iterator it = offerList->begin(); it != offerList->end(); ++it) { KMimeType * item = new KMimeType (*(KMimeType*)((KMimeType::Ptr)(*it)).data()); VALUE obj = getPointerObject(item); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KMimeType"); o->ptr = item; o->allocated = true; obj = set_obj_info("KDE::MimeType", o); } rb_ary_push(av, obj); } *(m->var()) = av; if(m->cleanup()) delete offerList; } break; default: m->unsupported(); break; } } void marshall_KMimeTypePtr(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { KMimeType::Ptr ptr(*(KMimeType::Ptr*)m->item().s_voidp); if(ptr == 0) { *(m->var()) = Qnil; break; } KMimeType * mimeType = new KMimeType(*(KMimeType*)ptr); VALUE obj = getPointerObject(mimeType); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KMimeType"); o->ptr = mimeType; o->allocated = true; obj = set_obj_info("KDE::MimeType", o); } *(m->var()) = obj; if(m->cleanup()) ; } break; default: m->unsupported(); break; } } void marshall_KServicePtr(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { TDESharedPtr *ptr = new TDESharedPtr(*(TDESharedPtr*)m->item().s_voidp); if(ptr == 0) { *(m->var()) = Qnil; break; } KService * service = ptr->data(); VALUE obj = getPointerObject(service); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KService"); o->ptr = service; o->allocated = true; obj = set_obj_info("KDE::Service", o); } *(m->var()) = obj; if(m->cleanup()) ; } break; default: m->unsupported(); break; } } void marshall_KServiceList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { KService::List *offerList = (KService::List*)m->item().s_voidp; if(!offerList) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(KService::List::Iterator it = offerList->begin(); it != offerList->end(); ++it) { TDESharedPtr *ptr = new TDESharedPtr(*it); KService * currentOffer = ptr->data(); VALUE obj = getPointerObject(currentOffer); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KService"); o->ptr = currentOffer; o->allocated = false; obj = set_obj_info("KDE::Service", o); } rb_ary_push(av, obj); } *(m->var()) = av; if(m->cleanup()) delete offerList; } break; default: m->unsupported(); break; } } void marshall_KServiceGroupPtr(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { KServiceGroup::Ptr ptr(*(KServiceGroup::Ptr*)m->item().s_voidp); if(ptr == 0) { *(m->var()) = Qnil; break; } KServiceGroup * serviceGroup = new KServiceGroup(*(KServiceGroup*)ptr); VALUE obj = getPointerObject(serviceGroup); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KServiceGroup"); o->ptr = serviceGroup; o->allocated = true; obj = set_obj_info("KDE::ServiceGroup", o); } *(m->var()) = obj; if(m->cleanup()) ; } break; default: m->unsupported(); break; } } void marshall_KServiceTypeList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { KServiceType::List *offerList = (KServiceType::List*)m->item().s_voidp; if(!offerList) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(KServiceType::List::Iterator it = offerList->begin(); it != offerList->end(); ++it) { KServiceType * currentOffer = new KServiceType(*((KServiceType*)*it)); VALUE obj = getPointerObject(currentOffer); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KServiceType"); o->ptr = currentOffer; o->allocated = true; obj = set_obj_info("KDE::ServiceType", o); } rb_ary_push(av, obj); } *(m->var()) = av; if(m->cleanup()) delete offerList; } break; default: m->unsupported(); break; } } void marshall_KServiceGroupList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { KServiceGroup::List *offerList = (KServiceGroup::List*)m->item().s_voidp; if(!offerList) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(KServiceGroup::List::ConstIterator it = offerList->begin(); it != offerList->end(); ++it) { KSycocaEntry *p = (*it); VALUE obj = Qnil; if (p->isType(KST_KService)) { KService *s = static_cast(p); obj = getPointerObject(s); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KService"); o->ptr = s; o->allocated = true; obj = set_obj_info("KDE::Service", o); } } else if (p->isType(KST_KServiceGroup)) { KServiceGroup *g = static_cast(p); obj = getPointerObject(g); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KServiceGroup"); o->ptr = g; o->allocated = true; obj = set_obj_info("KDE::ServiceGroup", o); } } rb_ary_push(av, obj); } *(m->var()) = av; if(m->cleanup()) delete offerList; } break; default: m->unsupported(); break; } } #if TDE_VERSION >= 0x030200 void marshall_KMountPointList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { KMountPoint::List *list = (KMountPoint::List*)m->item().s_voidp; if(!list) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(KMountPoint::List::Iterator it = list->begin(); it != list->end(); ++it) { KMountPoint * item = new KMountPoint(*((KMountPoint*)*it)); VALUE obj = getPointerObject(item); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KMountPoint"); o->ptr = item; o->allocated = true; obj = set_obj_info("KDE::MountPoint", o); } rb_ary_push(av, obj); } *(m->var()) = av; if(m->cleanup()) delete list; } break; default: m->unsupported(); break; } } void marshall_KPluginInfoList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { KPluginInfo::List *valuelist = (KPluginInfo::List*)m->item().s_voidp; if(!valuelist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); int ix = m->smoke()->idClass("KPluginInfo"); const char * className = m->smoke()->binding->className(ix); for(KPluginInfo::List::Iterator it = valuelist->begin(); it != valuelist->end(); ++it) { void *p = (*it); if(m->item().s_voidp == 0) { *(m->var()) = Qnil; break; } VALUE obj = getPointerObject(p); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = o->smoke->idClass("KPluginInfo"); o->ptr = p; o->allocated = false; obj = set_obj_info(className, o); } rb_ary_push(av, obj); } if(m->cleanup()) delete valuelist; else *(m->var()) = av; } break; default: m->unsupported(); break; } } #endif void marshall_TDEActionPtrList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { TDEActionPtrList *valuelist = (TDEActionPtrList*)m->item().s_voidp; if (!valuelist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); int ix = m->smoke()->idClass("TDEAction"); const char * className = m->smoke()->binding->className(ix); for ( TDEActionPtrList::Iterator it = valuelist->begin(); it != valuelist->end(); ++it ) { void *p = (*it); if (m->item().s_voidp == 0) { *(m->var()) = Qnil; break; } VALUE obj = getPointerObject(p); if (obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = o->smoke->idClass("TDEAction"); o->ptr = p; o->allocated = false; obj = set_obj_info(className, o); } rb_ary_push(av, obj); } if (m->cleanup()) delete valuelist; else *(m->var()) = av; } break; default: m->unsupported(); break; } } void marshall_TDETraderOfferList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { } break; case Marshall::ToVALUE: { TDETrader::OfferList *offerList = (TDETrader::OfferList*)m->item().s_voidp; if(!offerList) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); for(TDETrader::OfferList::Iterator it = offerList->begin(); it != offerList->end(); ++it) { TDESharedPtr *ptr = new TDESharedPtr(*it); KService * currentOffer = ptr->data(); VALUE obj = getPointerObject(currentOffer); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = m->smoke()->idClass("KService"); o->ptr = currentOffer; o->allocated = false; obj = set_obj_info("KDE::Service", o); } rb_ary_push(av, obj); } *(m->var()) = av; if(m->cleanup()) delete offerList; } break; default: m->unsupported(); break; } } void marshall_KURLList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE list = *(m->var()); if (TYPE(list) != T_ARRAY) { m->item().s_voidp = 0; break; } int count = RARRAY_LEN(list); KURL::List *kurllist = new KURL::List; long i; for(i = 0; i < count; i++) { VALUE item = rb_ary_entry(list, i); // TODO do type checking! smokeruby_object *o = value_obj_info(item); if(!o || !o->ptr) continue; void *ptr = o->ptr; ptr = o->smoke->cast( ptr, // pointer o->classId, // from o->smoke->idClass("KURL") // to ); kurllist->append((KURL&)*(KURL*)ptr); } m->item().s_voidp = kurllist; m->next(); rb_ary_clear(list); int ix = m->smoke()->idClass("KURL"); const char * className = m->smoke()->binding->className(ix); for ( KURL::List::Iterator it = kurllist->begin(); it != kurllist->end(); ++it ) { void *p = new KURL(*it); VALUE obj = getPointerObject(p); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = ix; o->ptr = p; o->allocated = true; obj = set_obj_info(className, o); } rb_ary_push(list, obj); } if(m->cleanup()) { delete kurllist; } } break; case Marshall::ToVALUE: { KURL::List *kurllist = (KURL::List*)m->item().s_voidp; if(!kurllist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); int ix = m->smoke()->idClass("KURL"); const char * className = m->smoke()->binding->className(ix); for(KURL::List::Iterator it = kurllist->begin(); it != kurllist->end(); ++it) { void *p = new KURL(*it); VALUE obj = getPointerObject(p); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = ix; o->ptr = p; o->allocated = true; obj = set_obj_info(className, o); } rb_ary_push(av, obj); } *(m->var()) = av; if(m->cleanup()) { delete kurllist; } } break; default: m->unsupported(); break; } } void marshall_UDSEntryList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE list = *(m->var()); if (TYPE(list) != T_ARRAY) { m->item().s_voidp = 0; break; } TDEIO::UDSEntryList *cpplist = new TDEIO::UDSEntryList; for(long i = 0; i < RARRAY_LEN(list); i++) { VALUE item = rb_ary_entry(list, i); TDEIO::UDSEntry *cppsublist = new TDEIO::UDSEntry; for (int j = 0; j < RARRAY_LEN(item); j++) { VALUE subitem = rb_ary_entry(item, j); smokeruby_object *o = value_obj_info(subitem); if(!o || !o->ptr) continue; void *ptr = o->ptr; ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("TDEIO::UDSAtom")); cppsublist->append(*(TDEIO::UDSAtom*)ptr); } cpplist->append(*cppsublist); } m->item().s_voidp = cpplist; m->next(); } break; case Marshall::ToVALUE: { TDEIO::UDSEntryList *valuelist = (TDEIO::UDSEntryList*)m->item().s_voidp; if (!valuelist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); int ix = m->smoke()->idClass("TDEIO::UDSAtom"); for ( TDEIO::UDSEntryList::Iterator it = valuelist->begin(); it != valuelist->end(); ++it ) { TDEIO::UDSEntry * udsentry = &(*it); VALUE subav = rb_ary_new(); for ( TDEIO::UDSEntry::Iterator it = udsentry->begin(); it != udsentry->end(); ++it ) { void * p = &(*it); VALUE obj = getPointerObject(p); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = ix; o->ptr = p; o->allocated = false; obj = set_obj_info("TDEIO::UDSAtom", o); } rb_ary_push(subav, obj); } rb_ary_push(av, subav); } *(m->var()) = av; } break; default: m->unsupported(); break; } } // Some time saving magic from Alex Kellett here.. template void marshall_ItemList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE list = *(m->var()); if (TYPE(list) != T_ARRAY) { m->item().s_voidp = 0; break; } int count = RARRAY_LEN(list); ItemList *cpplist = new ItemList; long i; for(i = 0; i < count; i++) { VALUE item = rb_ary_entry(list, i); // TODO do type checking! smokeruby_object *o = value_obj_info(item); if(!o || !o->ptr) continue; void *ptr = o->ptr; ptr = o->smoke->cast( ptr, // pointer o->classId, // from o->smoke->idClass(ItemSTR) // to ); cpplist->append((Item*)ptr); } m->item().s_voidp = cpplist; m->next(); if(m->cleanup()) { rb_ary_clear(list); for( Item * it = cpplist->first(); it != 0; it = cpplist->next()) { VALUE obj = getPointerObject((void*)it); rb_ary_push(list, obj); } delete cpplist; } } break; case Marshall::ToVALUE: { ItemList *valuelist = (ItemList*)m->item().s_voidp; if(!valuelist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); int ix = m->smoke()->idClass(ItemSTR); const char * className = m->smoke()->binding->className(ix); for(Item * it = valuelist->first(); it != 0; it = valuelist->next()) { void *p = it; if(m->item().s_voidp == 0) { *(m->var()) = Qnil; break; } VALUE obj = getPointerObject(p); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = o->smoke->idClass(ItemSTR); o->ptr = p; o->allocated = false; obj = set_obj_info(className, o); } rb_ary_push(av, obj); } if(m->cleanup()) delete valuelist; else *(m->var()) = av; } break; default: m->unsupported(); break; } } #define DEF_LIST_MARSHALLER(ListIdent,ItemList,Item) namespace { char ListIdent##STR[] = #Item; }; \ Marshall::HandlerFn marshall_##ListIdent = marshall_ItemList; DEF_LIST_MARSHALLER( KFileItemList, TQPtrList, KFileItem ) DEF_LIST_MARSHALLER( TDEMainWindowList, TQPtrList, TDEMainWindow ) DEF_LIST_MARSHALLER( TDEActionList, TQPtrList, TDEAction ) DEF_LIST_MARSHALLER( DCOPObjectList, TQPtrList, DCOPObject ) DEF_LIST_MARSHALLER( KDockWidgetList, TQPtrList, KDockWidget ) DEF_LIST_MARSHALLER( KFileTreeBranch, TQPtrList, KFileTreeBranch ) DEF_LIST_MARSHALLER( KFileTreeViewItem, TQPtrList, KFileTreeViewItem ) DEF_LIST_MARSHALLER( KPartList, TQPtrList, KParts::Part ) DEF_LIST_MARSHALLER( KPartPluginList, TQPtrList, KParts::Plugin ) DEF_LIST_MARSHALLER( KPartReadOnlyPartList, TQPtrList, KParts::ReadOnlyPart ) DEF_LIST_MARSHALLER( KServiceTypeProfileList, TQPtrList, KServiceTypeProfile ) template void marshall_ValueItemList(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE list = *(m->var()); if (TYPE(list) != T_ARRAY) { m->item().s_voidp = 0; break; } int count = RARRAY_LEN(list); ItemList *cpplist = new ItemList; long i; for(i = 0; i < count; i++) { VALUE item = rb_ary_entry(list, i); // TODO do type checking! smokeruby_object *o = value_obj_info(item); if(!o || !o->ptr) continue; void *ptr = o->ptr; ptr = o->smoke->cast( ptr, // pointer o->classId, // from o->smoke->idClass(ItemSTR) // to ); cpplist->append(*(Item*)ptr); } m->item().s_voidp = cpplist; m->next(); if(m->cleanup()) { rb_ary_clear(list); for(ItemListIterator it = cpplist->begin(); it != cpplist->end(); ++it) { VALUE obj = getPointerObject((void*)&(*it)); rb_ary_push(list, obj); } delete cpplist; } } break; case Marshall::ToVALUE: { ItemList *valuelist = (ItemList*)m->item().s_voidp; if(!valuelist) { *(m->var()) = Qnil; break; } VALUE av = rb_ary_new(); int ix = m->smoke()->idClass(ItemSTR); const char * className = m->smoke()->binding->className(ix); for(ItemListIterator it = valuelist->begin(); it != valuelist->end(); ++it) { void *p = &(*it); if(m->item().s_voidp == 0) { *(m->var()) = Qnil; break; } VALUE obj = getPointerObject(p); if(obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->smoke = m->smoke(); o->classId = o->smoke->idClass(ItemSTR); o->ptr = p; o->allocated = false; obj = set_obj_info(className, o); } rb_ary_push(av, obj); } if(m->cleanup()) delete valuelist; else *(m->var()) = av; } break; default: m->unsupported(); break; } } #define DEF_VALUELIST_MARSHALLER(ListIdent,ItemList,Item,Itr) namespace { char ListIdent##STR[] = #Item; }; \ Marshall::HandlerFn marshall_##ListIdent = marshall_ValueItemList; #if TDE_VERSION >= 0x030200 DEF_VALUELIST_MARSHALLER( ChoicesList, TQValueList, TDEConfigSkeleton::ItemEnum::Choice, TQValueList::Iterator ) #endif DEF_VALUELIST_MARSHALLER( KAboutPersonList, TQValueList, KAboutPerson, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( KAboutTranslatorList, TQValueList, KAboutTranslator, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( KIOCopyInfoList, TQValueList, TDEIO::CopyInfo, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( KServiceOfferList, TQValueList, KServiceOffer, TQValueList::Iterator ) DEF_VALUELIST_MARSHALLER( UDSEntry, TQValueList, TDEIO::UDSAtom, TQValueList::Iterator ) template void marshall_Map(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE hash = *(m->var()); if (TYPE(hash) != T_HASH) { m->item().s_voidp = 0; break; } TQMap * map = new TQMap; // Convert the ruby hash to an array of key/value arrays VALUE temp = rb_funcall(hash, rb_intern("to_a"), 0); for (long i = 0; i < RARRAY_LEN(temp); i++) { VALUE key = rb_ary_entry(rb_ary_entry(temp, i), 0); VALUE value = rb_ary_entry(rb_ary_entry(temp, i), 1); smokeruby_object *o = value_obj_info(key); if( !o || !o->ptr) continue; void * key_ptr = o->ptr; key_ptr = o->smoke->cast(key_ptr, o->classId, o->smoke->idClass(KeySTR)); o = value_obj_info(value); if( !o || !o->ptr) continue; void * val_ptr = o->ptr; val_ptr = o->smoke->cast(val_ptr, o->classId, o->smoke->idClass(ValueSTR)); (*map)[(Key)*(Key*)key_ptr] = (Value)*(Value*)val_ptr; } m->item().s_voidp = map; m->next(); if(m->cleanup()) delete map; } break; case Marshall::ToVALUE: { TQMap *map = (TQMap*)m->item().s_voidp; if(!map) { *(m->var()) = Qnil; break; } VALUE hv = rb_hash_new(); int key_ix = m->smoke()->idClass(KeySTR); const char * key_className = m->smoke()->binding->className(key_ix); int val_ix = m->smoke()->idClass(ValueSTR); const char * val_className = m->smoke()->binding->className(val_ix); ItemMapIterator it; for (it = map->begin(); it != map->end(); ++it) { void *key_p = new Key(it.key()); VALUE key_obj = getPointerObject(key_p); smokeruby_object * o; if (key_obj == Qnil) { o = ALLOC(smokeruby_object); o->classId = m->smoke()->idClass(KeySTR); o->smoke = m->smoke(); o->ptr = key_p; o->allocated = true; key_obj = set_obj_info(key_className, o); } void *val_p = new Value(it.data()); VALUE value_obj = getPointerObject(val_p); if (value_obj == Qnil) { o = ALLOC(smokeruby_object); o->classId = m->smoke()->idClass(ValueSTR); o->smoke = m->smoke(); o->ptr = val_p; o->allocated = true; value_obj = set_obj_info(val_className, o); } rb_hash_aset(hv, key_obj, value_obj); } *(m->var()) = hv; m->next(); if(m->cleanup()) delete map; } break; default: m->unsupported(); break; } } #define DEF_MAP_MARSHALLER(MapIdent,Key,Value) namespace { char KeyIdent##STR[] = #Key; char ValueIdent##STR[] = #Value; }; \ Marshall::HandlerFn marshall_##MapIdent = marshall_Map::Iterator,KeyIdent##STR, ValueIdent##STR>; DEF_MAP_MARSHALLER( TQMapKEntryKeyKEntry, KEntryKey, KEntry ) void marshall_TQMapTQCStringDCOPRef(Marshall *m) { switch(m->action()) { case Marshall::FromVALUE: { VALUE hash = *(m->var()); if (TYPE(hash) != T_HASH) { m->item().s_voidp = 0; break; } TQMap * map = new TQMap; // Convert the ruby hash to an array of key/value arrays VALUE temp = rb_funcall(hash, rb_intern("to_a"), 0); for (long i = 0; i < RARRAY_LEN(temp); i++) { VALUE key = rb_ary_entry(rb_ary_entry(temp, i), 0); VALUE value = rb_ary_entry(rb_ary_entry(temp, i), 1); smokeruby_object *o = value_obj_info(value); if( !o || !o->ptr) continue; void * ptr = o->ptr; ptr = o->smoke->cast(ptr, o->classId, o->smoke->idClass("DCOPRef")); (*map)[TQCString(StringValuePtr(key))] = (DCOPRef)*(DCOPRef*)ptr; } m->item().s_voidp = map; m->next(); if(m->cleanup()) delete map; } break; case Marshall::ToVALUE: { TQMap *map = (TQMap*)m->item().s_voidp; if(!map) { *(m->var()) = Qnil; break; } VALUE hv = rb_hash_new(); TQMap::Iterator it; for (it = map->begin(); it != map->end(); ++it) { void *p = new DCOPRef(it.data()); VALUE obj = getPointerObject(p); if (obj == Qnil) { smokeruby_object * o = ALLOC(smokeruby_object); o->classId = m->smoke()->idClass("DCOPRef"); o->smoke = m->smoke(); o->ptr = p; o->allocated = true; obj = set_obj_info("KDE::DCOPRef", o); } rb_hash_aset(hv, rb_str_new2((const char *) it.key()), obj); } *(m->var()) = hv; m->next(); if(m->cleanup()) delete map; } break; default: m->unsupported(); break; } } TypeHandler KDE_handlers[] = { { "QCStringList", marshall_TQCStringList }, { "KCmdLineOptions*", marshall_KCmdLineOptions }, { "TDEActionPtrList", marshall_TDEActionList }, { "TQPtrList", marshall_TDEActionList }, { "TQPtrList&", marshall_TDEActionList }, { "KMimeType::List", marshall_KMimeTypeList }, { "KMimeType::Ptr", marshall_KMimeTypePtr }, { "KService::Ptr", marshall_KServicePtr }, { "KService::List", marshall_KServiceList }, { "KServiceGroup::List", marshall_KServiceGroupList }, { "KServiceGroup::Ptr", marshall_KServiceGroupPtr }, #if TDE_VERSION >= 0x030200 { "KMountPoint::List", marshall_KMountPointList }, { "KPluginInfo::List", marshall_KPluginInfoList }, { "TQValueList", marshall_ChoicesList }, { "TQValueList&", marshall_ChoicesList }, #endif { "KServiceType::List", marshall_KServiceTypeList }, { "TDETrader::OfferList", marshall_TDETraderOfferList }, { "KURL::List", marshall_KURLList }, { "KURL::List&", marshall_KURLList }, { "KFileItemList", marshall_KFileItemList }, { "KFileItemList*", marshall_KFileItemList }, { "TQPtrList*", marshall_TDEMainWindowList }, { "TQPtrList", marshall_DCOPObjectList }, { "TQPtrList&", marshall_KDockWidgetList }, { "TQPtrList*", marshall_KDockWidgetList }, { "KFileTreeBranchList&", marshall_KFileTreeBranch }, { "KFileTreeViewItemList&", marshall_KFileTreeViewItem }, { "TQPtrList*", marshall_KPartList }, { "TQPtrList", marshall_KPartPluginList }, { "TQPtrList", marshall_KPartReadOnlyPartList }, { "TQPtrList&", marshall_KServiceTypeProfileList }, { "TQValueList", marshall_TDEActionPtrList }, { "TDEActionPtrList", marshall_TDEActionPtrList }, { "TQValueList", marshall_KAboutPersonList }, { "TQValueList", marshall_KAboutTranslatorList }, { "TQValueList&", marshall_KIOCopyInfoList }, { "TDEIO::UDSEntry&", marshall_UDSEntry }, { "TDEIO::UDSEntryList&", marshall_UDSEntryList }, { "KServiceTypeProfile::OfferList", marshall_KServiceOfferList }, { "KEntryMap", marshall_TQMapKEntryKeyKEntry }, { "KEntryMap&", marshall_TQMapKEntryKeyKEntry }, { "KEntryMap*", marshall_TQMapKEntryKeyKEntry }, { "TQMap", marshall_TQMapTQCStringDCOPRef }, { "TQValueList&", marshall_WIdList }, { "TQValueList", marshall_WIdList }, { 0, 0 } };