[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    SEGV reading Akonadi::Attribute from retrieveItem
From:       Jesús Pérez <kdelists () chuso ! net>
Date:       2014-05-28 8:52:24
Message-ID: CALXXZNbVYDvT3nS5-TL_t47eVuHDkbwLwa99GttaY4bDY9_cuQ () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Hi, I'm learning to develop Akonadi resources.

Everything is going well until I set a custom attribute in collection and I
try to read this attribute in retrieveItem() getting a segmentation
violation for trying to access a null pointer.

This is how I did it:

I extend Akonadi::Attribute class to implement my custom property.
Then, I register my custom attribute in resource constructor:

testResource::testResource( const QString &id )
  : ResourceBase( id )
{
  // ...
  AttributeFactory::registerAttribute<TestAttribute>();
}

When retrieving collections, I set this attribute to collection:

void testResource::retrieveCollections()
{
  Collection c;
  // ...
  TestAttribute *attr = new TestAttribute("value1");
  c.addAttribute(attr);
}

I've checked that I can successfully read this value from retrieveItems:

void testResource::retrieveItems( const Akonadi::Collection &collection )
{
  TestAttribute *attr = collection.attribute<TestAttribute>();
  QByteArray attr_value = attr->serialized();
  qDebug("retrieveItems value: %s", attr_value.constData());
  // ...
}

But when trying to get attribute from retrieveItem, it gives a null
pointer. So trying to read any class attribute will give a SEGV:

bool testResource::retrieveItem( const Akonadi::Item &item, const
QSet<QByteArray> &parts )
{
  TestAttribute *attr = item.parentCollection().attribute<TestAttribute>();
// NULL pointer
  QByteArray attr_value = attr->serialized(); // SEGV
  qDebug("retrieveItem value: %s", attr_value.constData());
}

I've also tried copying attribute from collection to item in retrieveItems
and then read item attribute in retrieveItem with same result:

void testResource::retrieveItems( const Akonadi::Collection &collection )
{
  TestAttribute *attr = collection.attribute<TestAttribute>();
  // ...
  foreach (Akonadi::Item item, itemList)
    item.addAttribute(attr);
  // ...
}

bool testResource::retrieveItem( const Akonadi::Item &item, const
QSet<QByteArray> &parts )
{
  TestAttribute *attr = item.attribute<TestAttribute>(); // NULL pointer
  QByteArray attr_value = attr->serialized(); // SEGV
  qDebug("retrieveItem value: %s", attr_value.constData());
}

In both cases, I've checked with akonadiconsole that attribute is
successfully set, so the problem seems to be accessing to it from
retrieveItem.

I've made a full test project by taking sample agent available at
http://techbase.kde.org/Development/Tutorials/Akonadi/Resources and adding
custom attribute:

http://anongit.chuso.net/testresource/tree/testresource.cpp#n48

Also, the second case adding attribute to item:

http://anongit.chuso.net/testresource/tree/testresource.cpp?h=attribute-on-items#n48

What am I doing wrong? Am I trying to do something that is not possible to
do?

[Attachment #5 (text/html)]

<div dir="ltr"><div>Hi, I&#39;m learning to develop Akonadi \
resources.</div><div><br></div><div>Everything is going well until I set a custom \
attribute in collection and I try to read this attribute in retrieveItem() getting a \
segmentation violation for trying to access a null pointer.</div>

<div><br></div><div>This is how I did it:</div><div><br></div><div>I extend \
Akonadi::Attribute class to implement my custom property.</div><div>Then, I register \
my custom attribute in resource constructor:</div><div><br> </div>
<div>testResource::testResource( const QString &amp;id )</div><div>   : ResourceBase( \
id )</div><div>{</div><div>   // ...</div><div>   \
AttributeFactory::registerAttribute&lt;TestAttribute&gt;();</div><div>}</div><div><br></div>


<div>When retrieving collections, I set this attribute to \
collection:</div><div><br></div><div>void \
testResource::retrieveCollections()</div><div>{</div><div>   Collection c;</div><div> \
// ...</div><div>   TestAttribute *attr = new \
TestAttribute(&quot;value1&quot;);</div>

<div>   c.addAttribute(attr);</div><div>}</div><div><br></div><div>I&#39;ve checked \
that I can successfully read this value from \
retrieveItems:</div><div><br></div><div>void testResource::retrieveItems( const \
Akonadi::Collection &amp;collection )</div>

<div>{</div><div>   TestAttribute *attr = \
collection.attribute&lt;TestAttribute&gt;();</div><div>   QByteArray attr_value = \
attr-&gt;serialized();</div><div>   qDebug(&quot;retrieveItems value: %s&quot;, \
attr_value.constData());</div>

<div>   // ...</div><div>}</div><div><br></div><div>But when trying to get attribute \
from retrieveItem, it gives a null pointer. So trying to read any class attribute \
will give a SEGV:</div><div><br></div><div>bool testResource::retrieveItem( const \
Akonadi::Item &amp;item, const QSet&lt;QByteArray&gt; &amp;parts )</div>

<div>{</div><div>   TestAttribute *attr = \
item.parentCollection().attribute&lt;TestAttribute&gt;(); // NULL pointer</div><div>  \
QByteArray attr_value = attr-&gt;serialized(); // SEGV</div><div>   \
qDebug(&quot;retrieveItem value: %s&quot;, attr_value.constData());</div>

<div>}</div><div><br></div><div>I&#39;ve also tried copying attribute from collection \
to item in retrieveItems and then read item attribute in retrieveItem with same \
result:</div><div><br></div><div>void testResource::retrieveItems( const \
Akonadi::Collection &amp;collection )</div>

<div>{</div><div>   TestAttribute *attr = \
collection.attribute&lt;TestAttribute&gt;();</div><div>   // ...</div><div>   foreach \
(Akonadi::Item item, itemList)</div><div>      item.addAttribute(attr);</div><div>   \
// ...</div><div>

}</div><div><br></div><div>bool testResource::retrieveItem( const Akonadi::Item \
&amp;item, const QSet&lt;QByteArray&gt; &amp;parts )</div><div>{</div><div>   \
TestAttribute *attr = item.attribute&lt;TestAttribute&gt;(); // NULL pointer</div>

<div>   QByteArray attr_value = attr-&gt;serialized(); // SEGV</div><div>   \
qDebug(&quot;retrieveItem value: %s&quot;, \
attr_value.constData());</div><div>}</div><div><br></div><div>In both cases, I&#39;ve \
checked with akonadiconsole that attribute is successfully set, so the problem seems \
to be accessing to it from retrieveItem.</div>

<div><br></div><div>I&#39;ve made a full test project by taking sample agent \
available at <a href="http://techbase.kde.org/Development/Tutorials/Akonadi/Resources">http://techbase.kde.org/Development/Tutorials/Akonadi/Resources</a> \
and adding custom attribute:</div>

<div><br></div><div><a \
href="http://anongit.chuso.net/testresource/tree/testresource.cpp#n48">http://anongit. \
chuso.net/testresource/tree/testresource.cpp#n48</a></div><div><br></div><div>Also, \
the second case adding attribute to item:</div>

<div><br></div><div><a \
href="http://anongit.chuso.net/testresource/tree/testresource.cpp?h=attribute-on-items \
#n48">http://anongit.chuso.net/testresource/tree/testresource.cpp?h=attribute-on-items#n48</a></div><div><br></div>


<div>What am I doing wrong? Am I trying to do something that is not possible to \
do?</div></div>



>> Visit http://mail.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic