Sophie

Sophie

distrib > Fedora > 14 > x86_64 > by-pkgid > 87b89b73c41f4440bb86afd421c7548f > files > 155

libnl-devel-1.1-14.fc14.x86_64.rpm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>libnl: Object API</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.7.3 -->
<div id="top">
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td style="padding-left: 0.5em;">
   <div id="projectname">libnl&#160;<span id="projectnumber">1.1</span></div>
  </td>
 </tr>
 </tbody>
</table>
</div>
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Data&#160;Structures</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
</div>
<div class="header">
  <div class="summary">
<a href="#nested-classes">Data Structures</a> &#124;
<a href="#define-members">Defines</a>  </div>
  <div class="headertitle">
<h1>Object API</h1>  </div>
<div class="ingroups"><a class="el" href="group__object.html">Object</a></div></div>
<div class="contents">
<table class="memberdecls">
<tr><td colspan="2"><h2><a name="nested-classes"></a>
Data Structures</h2></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">struct &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="structnl__object__ops.html">nl_object_ops</a></td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Object Operations.  <a href="structnl__object__ops.html#_details">More...</a><br/></td></tr>
<tr><td colspan="2"><h2><a name="define-members"></a>
Defines</h2></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__object__api.html#ga0f84d461252a52ed33e307432bd0b3f8">NLHDR_COMMON</a></td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Common Object Header.  <a href="#ga0f84d461252a52ed33e307432bd0b3f8"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__object__api.html#gaaea44dd0350eb403226ba5edba05ecbc">AVAILABLE</a>(A, B, ATTR)&#160;&#160;&#160;(((A)-&gt;ce_mask &amp; (B)-&gt;ce_mask) &amp; (ATTR))</td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Return true if attribute is available in both objects.  <a href="#gaaea44dd0350eb403226ba5edba05ecbc"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__object__api.html#gafefec474eb34fd780b5233b6289773e9">ATTR_MISMATCH</a>(A, B, ATTR, EXPR)&#160;&#160;&#160;(!AVAILABLE(A, B, ATTR) || (EXPR))</td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Return true if attributes mismatch.  <a href="#gafefec474eb34fd780b5233b6289773e9"></a><br/></td></tr>
<tr><td class="memItemLeft" align="right" valign="top">#define&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="group__object__api.html#ga726810b073cacc182dc6e2ea6cc2f14a">ATTR_DIFF</a>(LIST, ATTR, A, B, EXPR)</td></tr>
<tr><td class="mdescLeft">&#160;</td><td class="mdescRight">Return attribute bit if attribute does not match.  <a href="#ga726810b073cacc182dc6e2ea6cc2f14a"></a><br/></td></tr>
</table>
<hr/><a name="_details"></a><h2>Detailed Description</h2>
<dl class="user"><dt><b>1) Object Definition</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="comment">// Define your object starting with the common object header</span>
 <span class="keyword">struct </span>my_obj {
        <a class="code" href="group__object__api.html#ga0f84d461252a52ed33e307432bd0b3f8" title="Common Object Header.">NLHDR_COMMON</a>
        <span class="keywordtype">int</span>             my_data;
 };

 <span class="comment">// Fill out the object operations structure</span>
 <span class="keyword">struct </span><a class="code" href="structnl__object__ops.html" title="Object Operations.">nl_object_ops</a> my_ops = {
        .<a class="code" href="structnl__object__ops.html#a5225584343fe711642303e000b036ee9" title="Unique name of object type.">oo_name</a>        = <span class="stringliteral">&quot;my_obj&quot;</span>,
        .oo_size        = <span class="keyword">sizeof</span>(<span class="keyword">struct </span>my_obj),
 };

 <span class="comment">// At this point the object can be allocated, you may want to provide a</span>
 <span class="comment">// separate _alloc() function to ease allocting objects of this kind.</span>
 <span class="keyword">struct </span>nl_object *obj = <a class="code" href="group__object.html#ga9c1f2fd887d8325839f452879cdf982a" title="Allocate a new object of kind specified by the operations handle.">nl_object_alloc</a>(&amp;my_ops);

 <span class="comment">// And release it again...</span>
 <a class="code" href="group__object.html#ga9905da094bf4c03cf4ac78aeaa86a12b" title="Release a reference from an object.">nl_object_put</a>(obj);
</pre></div></dd></dl>
<dl class="user"><dt><b>2) Allocating additional data</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="comment">// You may require to allocate additional data and store it inside</span>
 <span class="comment">// object, f.e. assuming there is a field `ptr&#39;.</span>
 <span class="keyword">struct </span>my_obj {
        <a class="code" href="group__object__api.html#ga0f84d461252a52ed33e307432bd0b3f8" title="Common Object Header.">NLHDR_COMMON</a>
        <span class="keywordtype">void</span> *          ptr;
 };

 <span class="comment">// And at some point you may assign allocated data to this field:</span>
 my_obj-&gt;ptr = calloc(1, ...);

 <span class="comment">// In order to not introduce any memory leaks you have to release</span>
 <span class="comment">// this data again when the last reference is given back.</span>
 <span class="keyword">static</span> <span class="keywordtype">void</span> my_obj_free_data(<span class="keyword">struct</span> nl_object *obj)
 {
        <span class="keyword">struct </span>my_obj *my_obj = nl_object_priv(obj);

        free(my_obj-&gt;ptr);
 }

 <span class="comment">// Also when the object is cloned, you must ensure for your pointer</span>
 <span class="comment">// stay valid even if one of the clones is freed by either making</span>
 <span class="comment">// a clone as well or increase the reference count.</span>
 <span class="keyword">static</span> <span class="keywordtype">int</span> my_obj_clone(<span class="keyword">struct</span> nl_object *src, <span class="keyword">struct</span> nl_object *dst)
 {
        <span class="keyword">struct </span>my_obj *my_src = nl_object_priv(src);
        <span class="keyword">struct </span>my_obj *my_dst = nl_object_priv(dst);

        <span class="keywordflow">if</span> (src-&gt;ptr) {
                dst-&gt;ptr = calloc(1, ...);
                memcpy(dst-&gt;ptr, src-&gt;ptr, ...);
        }
 }

 <span class="keyword">struct </span><a class="code" href="structnl__object__ops.html" title="Object Operations.">nl_object_ops</a> my_ops = {
        ...
        .<a class="code" href="structnl__object__ops.html#a38797e8754a31bb259120ef9101bbb0a" title="Destructor function.">oo_free_data</a>   = my_obj_free_data,
        .oo_clone       = my_obj_clone,
 };
</pre></div></dd></dl>
<dl class="user"><dt><b>3) Object Dumping</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="keyword">static</span> <span class="keywordtype">int</span> my_obj_dump_detailed(<span class="keyword">struct</span> nl_object *obj,
                                   <span class="keyword">struct</span> <a class="code" href="structnl__dump__params.html" title="Dumping parameters.">nl_dump_params</a> *params)
 {
        <span class="keyword">struct </span>my_obj *my_obj = nl_object_priv(obj);
        <span class="keywordtype">int</span> line = 1;   <span class="comment">// We will print at least one line for sure</span>

        <span class="comment">// It is absolutely essential to use nl_dump() when printing</span>
        <span class="comment">// any text to make sure the dumping parameters are respected.</span>
        <a class="code" href="group__utils.html#ga527075856a5427170865a6f409298cdf" title="Dump a formatted character string.">nl_dump</a>(params, <span class="stringliteral">&quot;Obj Integer: %d\n&quot;</span>, my_obj-&gt;my_int);

        <span class="comment">// Before we can dump the next line, make sure to prefix</span>
        <span class="comment">// this line correctly.</span>
        <a class="code" href="group__utils.html#ga8d036ba05aa233203e8d7fb79f925c2c" title="Handle a new line while dumping.">nl_new_line</a>(params, line++);

        <span class="comment">// You may also split a line into multiple nl_dump() calls.</span>
        <a class="code" href="group__utils.html#ga527075856a5427170865a6f409298cdf" title="Dump a formatted character string.">nl_dump</a>(params, <span class="stringliteral">&quot;String: %s &quot;</span>, my_obj-&gt;my_string);
        <a class="code" href="group__utils.html#ga527075856a5427170865a6f409298cdf" title="Dump a formatted character string.">nl_dump</a>(params, <span class="stringliteral">&quot;String-2: %s\n&quot;</span>, my_obj-&gt;another_string);

        <span class="comment">// Return the number of lines dumped</span>
        <span class="keywordflow">return</span> line;
 }

 <span class="keyword">struct </span><a class="code" href="structnl__object__ops.html" title="Object Operations.">nl_object_ops</a> my_ops = {
        ...
        .<a class="code" href="structnl__object__ops.html#a0a3d28af43d7f75cda0b8cbc23ad7432" title="Dumping functions.">oo_dump</a>[<a class="code" href="group__utils.html#ggacfb5566c73f0965c5241d7d49bc717e9a1445106c7af529b2c99ee289fbcd3179" title="Dump all attributes but no statistics.">NL_DUMP_FULL</a>]  = my_obj_dump_detailed,
 };
</pre></div></dd></dl>
<dl class="user"><dt><b>4) Object Attributes</b></dt><dd><div class="fragment"><pre class="fragment"> <span class="comment">// The concept of object attributes is optional but can ease the typical</span>
 <span class="comment">// case of objects that have optional attributes, e.g. a route may have a</span>
 <span class="comment">// nexthop assigned but it is not required to.</span>

 <span class="comment">// The first step to define your object specific bitmask listing all</span>
 <span class="comment">// attributes</span>
<span class="preprocessor"> #define MY_ATTR_FOO            (1&lt;&lt;0)</span>
<span class="preprocessor"></span><span class="preprocessor"> #define MY_ATTR_BAR            (1&lt;&lt;1)</span>
<span class="preprocessor"></span>
 <span class="comment">// When assigning an optional attribute to the object, make sure</span>
 <span class="comment">// to mark its availability.</span>
 my_obj-&gt;foo = 123123;
 my_obj-&gt;ce_mask |= MY_ATTR_FOO;

 <span class="comment">// At any time you may use this mask to check for the availability</span>
 <span class="comment">// of the attribute, e.g. while dumping</span>
 <span class="keywordflow">if</span> (my_obj-&gt;ce_mask &amp; MY_ATTR_FOO)
        <a class="code" href="group__utils.html#ga527075856a5427170865a6f409298cdf" title="Dump a formatted character string.">nl_dump</a>(params, <span class="stringliteral">&quot;foo %d &quot;</span>, my_obj-&gt;foo);

 <span class="comment">// One of the big advantages of this concept is that it allows for</span>
 <span class="comment">// standardized comparisons which make it trivial for caches to</span>
 <span class="comment">// identify unique objects by use of unified comparison functions.</span>
 <span class="comment">// In order for it to work, your object implementation must provide</span>
 <span class="comment">// a comparison function and define a list of attributes which</span>
 <span class="comment">// combined together make an object unique.</span>

 <span class="keyword">static</span> <span class="keywordtype">int</span> my_obj_compare(<span class="keyword">struct</span> nl_object *_a, <span class="keyword">struct</span> nl_object *_b,
                             uint32_t attrs, <span class="keywordtype">int</span> flags)
 {
        <span class="keyword">struct </span>my_obj *a = nl_object_priv(_a):
        struct my_obj *b = nl_object_priv(_b):
        int diff = 0;

        <span class="comment">// We help ourselves in defining our own DIFF macro which will</span>
        <span class="comment">// call ATTR_DIFF() on both objects which will make sure to only</span>
        <span class="comment">// compare the attributes if required.</span>
<span class="preprocessor">        #define MY_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, MY_ATTR_##ATTR, a, b, EXPR)</span>
<span class="preprocessor"></span>
        <span class="comment">// Call our own diff macro for each attribute to build a bitmask</span>
        <span class="comment">// representing the attributes which mismatch.</span>
        diff |= MY_DIFF(FOO, a-&gt;foo != b-&gt;foo)
        diff |= MY_DIFF(BAR, strcmp(a-&gt;bar, b-&gt;bar))

        return diff;
 }

 <span class="comment">// In order to identify identical objects with differing attributes</span>
 <span class="comment">// you must specify the attributes required to uniquely identify</span>
 <span class="comment">// your object. Make sure to not include too many attributes, this</span>
 <span class="comment">// list is used when caches look for an old version of an object.</span>
 struct <a class="code" href="structnl__object__ops.html" title="Object Operations.">nl_object_ops</a> my_ops = {
        ...
        .oo_id_attrs            = MY_ATTR_FOO,
        .oo_compare             = my_obj_compare,
 };
</pre></div> </dd></dl>
<hr/><h2>Define Documentation</h2>
<a class="anchor" id="ga0f84d461252a52ed33e307432bd0b3f8"></a><!-- doxytag: member="object&#45;api.h::NLHDR_COMMON" ref="ga0f84d461252a52ed33e307432bd0b3f8" args="" -->
<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">#define NLHDR_COMMON</td>
        </tr>
      </table>
</div>
<div class="memdoc">
<b>Value:</b><div class="fragment"><pre class="fragment"><span class="keywordtype">int</span>                     ce_refcnt;      \
        <span class="keyword">struct </span><a class="code" href="structnl__object__ops.html" title="Object Operations.">nl_object_ops</a> *  ce_ops;         \
        <span class="keyword">struct </span>nl_cache *       ce_cache;       \
        <span class="keyword">struct </span><a class="code" href="structnl__list__head.html">nl_list_head</a>     ce_list;        \
        <span class="keywordtype">int</span>                     ce_msgtype;     \
        <span class="keywordtype">int</span>                     ce_flags;       \
        uint32_t                ce_mask;
</pre></div><p>This macro must be included as first member in every object definition to allow objects to be cached. </p>

<p>Definition at line <a class="el" href="object-api_8h_source.html#l00188">188</a> of file <a class="el" href="object-api_8h_source.html">object-api.h</a>.</p>

</div>
</div>
<a class="anchor" id="gaaea44dd0350eb403226ba5edba05ecbc"></a><!-- doxytag: member="object&#45;api.h::AVAILABLE" ref="gaaea44dd0350eb403226ba5edba05ecbc" args="(A, B, ATTR)" -->
<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">#define AVAILABLE</td>
          <td>(</td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">A, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">B, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">ATTR&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td>&#160;&#160;&#160;(((A)-&gt;ce_mask &amp; (B)-&gt;ce_mask) &amp; (ATTR))</td>
        </tr>
      </table>
</div>
<div class="memdoc">
<dl><dt><b>Parameters:</b></dt><dd>
  <table class="params">
    <tr><td class="paramname">A</td><td>an object </td></tr>
    <tr><td class="paramname">B</td><td>another object </td></tr>
    <tr><td class="paramname">ATTR</td><td>attribute bit</td></tr>
  </table>
  </dd>
</dl>
<dl class="return"><dt><b>Returns:</b></dt><dd>True if the attribute is available, otherwise false is returned. </dd></dl>

<p>Definition at line <a class="el" href="object-api_8h_source.html#l00205">205</a> of file <a class="el" href="object-api_8h_source.html">object-api.h</a>.</p>

</div>
</div>
<a class="anchor" id="gafefec474eb34fd780b5233b6289773e9"></a><!-- doxytag: member="object&#45;api.h::ATTR_MISMATCH" ref="gafefec474eb34fd780b5233b6289773e9" args="(A, B, ATTR, EXPR)" -->
<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">#define ATTR_MISMATCH</td>
          <td>(</td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">A, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">B, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">ATTR, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">EXPR&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td>&#160;&#160;&#160;(!AVAILABLE(A, B, ATTR) || (EXPR))</td>
        </tr>
      </table>
</div>
<div class="memdoc">
<dl><dt><b>Parameters:</b></dt><dd>
  <table class="params">
    <tr><td class="paramname">A</td><td>an object </td></tr>
    <tr><td class="paramname">B</td><td>another object </td></tr>
    <tr><td class="paramname">ATTR</td><td>attribute bit </td></tr>
    <tr><td class="paramname">EXPR</td><td>Comparison expression</td></tr>
  </table>
  </dd>
</dl>
<p>This function will check if the attribute in question is available in both objects, if not this will count as a mismatch.</p>
<p>If available the function will execute the expression which must return true if the attributes mismatch.</p>
<dl class="return"><dt><b>Returns:</b></dt><dd>True if the attribute mismatch, or false if they match. </dd></dl>

<p>Definition at line <a class="el" href="object-api_8h_source.html#l00222">222</a> of file <a class="el" href="object-api_8h_source.html">object-api.h</a>.</p>

</div>
</div>
<a class="anchor" id="ga726810b073cacc182dc6e2ea6cc2f14a"></a><!-- doxytag: member="object&#45;api.h::ATTR_DIFF" ref="ga726810b073cacc182dc6e2ea6cc2f14a" args="(LIST, ATTR, A, B, EXPR)" -->
<div class="memitem">
<div class="memproto">
      <table class="memname">
        <tr>
          <td class="memname">#define ATTR_DIFF</td>
          <td>(</td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">LIST, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">ATTR, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">A, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">B, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">&#160;</td>
          <td class="paramname">EXPR&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
</div>
<div class="memdoc">
<b>Value:</b><div class="fragment"><pre class="fragment">({      <span class="keywordtype">int</span> diff = 0; \
        <span class="keywordflow">if</span> (((LIST) &amp; (ATTR)) &amp;&amp; <a class="code" href="group__object__api.html#gafefec474eb34fd780b5233b6289773e9" title="Return true if attributes mismatch.">ATTR_MISMATCH</a>(A, B, ATTR, EXPR)) \
                diff = ATTR; \
        diff; })
</pre></div><dl><dt><b>Parameters:</b></dt><dd>
  <table class="params">
    <tr><td class="paramname">LIST</td><td>list of attributes to be compared </td></tr>
    <tr><td class="paramname">ATTR</td><td>attribute bit </td></tr>
    <tr><td class="paramname">A</td><td>an object </td></tr>
    <tr><td class="paramname">B</td><td>another object </td></tr>
    <tr><td class="paramname">EXPR</td><td>Comparison expression</td></tr>
  </table>
  </dd>
</dl>
<p>This function will check if the attribute in question is available in both objects, if not this will count as a mismatch.</p>
<p>If available the function will execute the expression which must return true if the attributes mismatch.</p>
<p>In case the attributes mismatch, the attribute is returned, otherwise 0 is returned.</p>
<div class="fragment"><pre class="fragment"> diff |= <a class="code" href="group__object__api.html#ga726810b073cacc182dc6e2ea6cc2f14a" title="Return attribute bit if attribute does not match.">ATTR_DIFF</a>(attrs, MY_ATTR_FOO, a, b, a-&gt;foo != b-&gt;foo);
</pre></div> 
<p>Definition at line <a class="el" href="object-api_8h_source.html#l00245">245</a> of file <a class="el" href="object-api_8h_source.html">object-api.h</a>.</p>

</div>
</div>
</div>
<hr class="footer"/><address class="footer"><small>Generated on Mon Mar 21 2011 for libnl by&#160;
<a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/></a> 1.7.3 </small></address>
</body>
</html>