{"id":54,"date":"2007-11-13T19:49:21","date_gmt":"2007-11-13T19:49:21","guid":{"rendered":"http:\/\/blog.danplanet.com\/wordpress\/?p=54"},"modified":"2011-11-29T16:56:19","modified_gmt":"2011-11-29T16:56:19","slug":"easier-method-providers-with-libcmpiutil","status":"publish","type":"post","link":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/","title":{"rendered":"Easier method providers with libcmpiutil"},"content":{"rendered":"<p>While writing the <a href=\"http:\/\/libvirt.org\/CIM\">libvirt-cim<\/a> provider, I decided that the constant repetition of common tasks in CMPI CIM providers was getting old.\u00a0 There were lots of things that get done over and over again that really should be generalized for the sake of the people who have to read and maintain the provider code.\u00a0 Fetching values from argument lists, instances, and object paths are some of the first tasks that I aimed to fix with <a href=\"http:\/\/libvirt.org\/hg\/libcmpiutil\">libcmpiutil<\/a>.\u00a0 In addition to these standardized utility functions, I created a standardized method dispatch infrastructure that makes writing method providers as simple and clean as it should have been in the first place.<\/p>\n<p>Most of the CMPI providers I&#8217;ve seen (I can&#8217;t say I&#8217;m a real expert here) implement a method provider like this:<\/p>\n<blockquote>\n<p style=\"font-family: Courier New,Courier,mono;\">CMPIStatus Foo_InvokeMethod(CMPIMethodMI *self,<br \/>\nconst CMPIContext *context,<br \/>\nconst CMPIResult *results,<br \/>\nconst CMPIObjectPath *reference,<br \/>\nconst char *methodname,<br \/>\nconst CMPIArgs *argsin,<br \/>\nCMPIArgs *argsout)<br \/>\n{<br \/>\nif (strcmp(methodname, &#8220;MethodA&#8221<img decoding=\"async\" src=\"https:\/\/www.danplanet.com\/blog\/wp-content\/themes\/wordpress-grey-opaque-master\/images\/smilies\/icon_wink.gif\" alt=\"Smilie: ;)\" title=\"Smilie: ;)\" \/> == 0) {<br \/>\n\/* Do MethodA work *\/<br \/>\n} else if (strcmp(methodname, &#8220;MethodB&#8221<img decoding=\"async\" src=\"https:\/\/www.danplanet.com\/blog\/wp-content\/themes\/wordpress-grey-opaque-master\/images\/smilies\/icon_wink.gif\" alt=\"Smilie: ;)\" title=\"Smilie: ;)\" \/> == 0) {<br \/>\n\/* Do MethodB work *\/<br \/>\n} else {<br \/>\n\/* Return no such method *\/<br \/>\n}<br \/>\n}<\/p>\n<\/blockquote>\n<p>If you&#8217;re lucky, the author will have written separate functions for each task (MethodA, MethodB, etc), however many of the providers I&#8217;ve seen just put the &#8220;work&#8221; in the body of the if, which results in hundreds of lines of muck that implements every possible method of the class in a massive function-from-hell.\u00a0 At the very least, the dispatch that fires off the appropriate code depending on the method name is implemented in every provider.\u00a0 Further, each method implementation must fetch and check its arguments for presence and type.\u00a0 Can you imagine how disgusting this gets for a class with 10 methods, each with a few arguments, when written by someone who doesn&#8217;t understand the benefit of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Functional_decomposition#Computer_programming_and_software_engineering\">functional depcomposition<\/a>?<\/p>\n<p>Enter the std_invokemethod module of libcmpiutil.\u00a0 Not only is the dispatch code modularized in such a way that &#8220;encourages&#8221; (read: &#8220;forces&#8221<img decoding=\"async\" src=\"https:\/\/www.danplanet.com\/blog\/wp-content\/themes\/wordpress-grey-opaque-master\/images\/smilies\/icon_wink.gif\" alt=\"Smilie: ;)\" title=\"Smilie: ;)\" \/> the author to write separate functions, it also does argument checking.\u00a0 It makes sure that all of your parameters are present and of the correct type before it calls your handler function.\u00a0 The handler can then grab the arguments without excessive checks at every stage.\u00a0 The above method provider becomes this:<\/p>\n<blockquote>\n<p style=\"font-family: Courier New,Courier,mono;\">static CMPIStatus methodA(CMPIMethodMI *self,<br \/>\nconst CMPIContext *context,<br \/>\nconst CMPIResult *results,<br \/>\nconst CMPIObjectPath *reference,<br \/>\nconst CMPIArgs *argsin,<br \/>\nCMPIArgs *argsout)<br \/>\n{<br \/>\n\/* Do MethodA work *\/<br \/>\n}<\/p>\n<p>\/* Another function here for MethodB *\/<\/p>\n<p>static struct method_handler _methodA = {<br \/>\n.name = &#8220;MethodA&#8221;,<br \/>\n.handler = methodA,<br \/>\n.args = {{&#8220;ParamX&#8221;, CMPI_uint16},<br \/>\n{&#8220;ParamY&#8221;, CMPI_string},<br \/>\nARG_END<br \/>\n}<br \/>\n};<\/p>\n<p>\/* Another handler struct here for MethodB *\/<\/p>\n<p>static struct method_handler *my_handlers[] = {<br \/>\n&amp;_methodA,<br \/>\n&amp;_methodB,<br \/>\nNULL<br \/>\n};<\/p><\/blockquote>\n<p>Instead of using the standard MI creation macro, you use a special one for the std_invokemethod module, which takes a pointer to the handler list.\u00a0 Then, you sit back and relax as your handler functions are dispatched pre-checked for argument type correctness!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>While writing the libvirt-cim provider, I decided that the constant repetition of common tasks in CMPI CIM providers was getting old.\u00a0 There were lots of things that get done over and over again that really should be generalized for the &hellip; <a href=\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[28,42,40],"class_list":["post-54","post","type-post","status-publish","format-standard","hentry","category-codemonkeying","tag-cim","tag-pegasus","tag-sfcb"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.6 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Easier method providers with libcmpiutil - Right Angles<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Easier method providers with libcmpiutil - Right Angles\" \/>\n<meta property=\"og:description\" content=\"While writing the libvirt-cim provider, I decided that the constant repetition of common tasks in CMPI CIM providers was getting old.\u00a0 There were lots of things that get done over and over again that really should be generalized for the &hellip; Continue reading &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/\" \/>\n<meta property=\"og:site_name\" content=\"Right Angles\" \/>\n<meta property=\"article:published_time\" content=\"2007-11-13T19:49:21+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2011-11-29T16:56:19+00:00\" \/>\n<meta name=\"author\" content=\"Dan\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Dan\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/\"},\"author\":{\"name\":\"Dan\",\"@id\":\"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/0f6920aa6d63cae437bf8b122200287c\"},\"headline\":\"Easier method providers with libcmpiutil\",\"datePublished\":\"2007-11-13T19:49:21+00:00\",\"dateModified\":\"2011-11-29T16:56:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/\"},\"wordCount\":477,\"publisher\":{\"@id\":\"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/0f6920aa6d63cae437bf8b122200287c\"},\"keywords\":[\"CIM\",\"pegasus\",\"sfcb\"],\"articleSection\":[\"Codemonkeying\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/\",\"url\":\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/\",\"name\":\"Easier method providers with libcmpiutil - Right Angles\",\"isPartOf\":{\"@id\":\"https:\/\/www.danplanet.com\/blog\/#website\"},\"datePublished\":\"2007-11-13T19:49:21+00:00\",\"dateModified\":\"2011-11-29T16:56:19+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.danplanet.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Easier method providers with libcmpiutil\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.danplanet.com\/blog\/#website\",\"url\":\"https:\/\/www.danplanet.com\/blog\/\",\"name\":\"Right Angles\",\"description\":\"If they&#039;re not right...they&#039;re wrong\",\"publisher\":{\"@id\":\"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/0f6920aa6d63cae437bf8b122200287c\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.danplanet.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/0f6920aa6d63cae437bf8b122200287c\",\"name\":\"Dan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/9b73782704be64dd8c030087af2d1ae0c1dc488cad69093ff0366dbaad2de673?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/9b73782704be64dd8c030087af2d1ae0c1dc488cad69093ff0366dbaad2de673?s=96&d=mm&r=g\",\"caption\":\"Dan\"},\"logo\":{\"@id\":\"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/image\/\"},\"url\":\"https:\/\/www.danplanet.com\/blog\/author\/dan\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Easier method providers with libcmpiutil - Right Angles","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/","og_locale":"en_US","og_type":"article","og_title":"Easier method providers with libcmpiutil - Right Angles","og_description":"While writing the libvirt-cim provider, I decided that the constant repetition of common tasks in CMPI CIM providers was getting old.\u00a0 There were lots of things that get done over and over again that really should be generalized for the &hellip; Continue reading &rarr;","og_url":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/","og_site_name":"Right Angles","article_published_time":"2007-11-13T19:49:21+00:00","article_modified_time":"2011-11-29T16:56:19+00:00","author":"Dan","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Dan","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/#article","isPartOf":{"@id":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/"},"author":{"name":"Dan","@id":"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/0f6920aa6d63cae437bf8b122200287c"},"headline":"Easier method providers with libcmpiutil","datePublished":"2007-11-13T19:49:21+00:00","dateModified":"2011-11-29T16:56:19+00:00","mainEntityOfPage":{"@id":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/"},"wordCount":477,"publisher":{"@id":"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/0f6920aa6d63cae437bf8b122200287c"},"keywords":["CIM","pegasus","sfcb"],"articleSection":["Codemonkeying"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/","url":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/","name":"Easier method providers with libcmpiutil - Right Angles","isPartOf":{"@id":"https:\/\/www.danplanet.com\/blog\/#website"},"datePublished":"2007-11-13T19:49:21+00:00","dateModified":"2011-11-29T16:56:19+00:00","breadcrumb":{"@id":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.danplanet.com\/blog\/2007\/11\/13\/easier-method-providers-with-libcmpiutil\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.danplanet.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Easier method providers with libcmpiutil"}]},{"@type":"WebSite","@id":"https:\/\/www.danplanet.com\/blog\/#website","url":"https:\/\/www.danplanet.com\/blog\/","name":"Right Angles","description":"If they&#039;re not right...they&#039;re wrong","publisher":{"@id":"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/0f6920aa6d63cae437bf8b122200287c"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.danplanet.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/0f6920aa6d63cae437bf8b122200287c","name":"Dan","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/9b73782704be64dd8c030087af2d1ae0c1dc488cad69093ff0366dbaad2de673?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/9b73782704be64dd8c030087af2d1ae0c1dc488cad69093ff0366dbaad2de673?s=96&d=mm&r=g","caption":"Dan"},"logo":{"@id":"https:\/\/www.danplanet.com\/blog\/#\/schema\/person\/image\/"},"url":"https:\/\/www.danplanet.com\/blog\/author\/dan\/"}]}},"_links":{"self":[{"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/posts\/54","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/comments?post=54"}],"version-history":[{"count":1,"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/posts\/54\/revisions"}],"predecessor-version":[{"id":154,"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/posts\/54\/revisions\/154"}],"wp:attachment":[{"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/media?parent=54"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/categories?post=54"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.danplanet.com\/blog\/wp-json\/wp\/v2\/tags?post=54"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}