As shown in the Consumer API, a file may consist of many content and container objects. Each of these objects may have properties or attributes associated with it. This section outlines how applications can retrieve these using the CAF API.
Different agents may use different terms to describe the same concept. Generic attributes provide a way for applications to query standardised information about a content object.
These standardised attributes are given by the enumeration
ContentAccess::TAttribute
. It is possible for agents to
extend this set of attributes, starting from
EAgentSpecificAttributeBase
.
The attribute functions are implemented in
ContentAccess::CContent
, ContentAccess::CData
and
ContentAccess::CManager
.
The attributes of one content object in a file may not necessarily be the same as the attributes of other content objects within the same file. Attributes relate to a single content object within a file.
It is possible that the attribute may not make sense for a particular
content object. In that case, the agent will return a
KErrCANotSupported
error. If an attempt is made to retrieve the
attributes of a content object that does not exist, the agent will return
KErrNotFound
.
The following code fragment illustrates how to retrieve an attribute for a particular object within a content file.
// check if DRM rights are pending for the object specified by uniqueId
TInt attributeValue;
TInt err = content->GetAttribute(ERightsPending, attributeValue, uniqueId);
if(err == KErrNone)
{
// Check the value of the attribute
if(attributeValue == ETrue)
{
// Rights are pending, display waiting for rights countdown
}
else if(attributeValue == EFalse)
{
// Rights are not pending
}
}
else if(err == KErrCANotSupported)
{
// This attribute does not apply to this content object
}
else if(err == KErrNotFound)
{
// Cannot find the object specified by the given uniqueId
}
For some agent implementations it may be more efficient to retrieve all
the attributes for a content object in one function call. The
ContentAccess::RAttributeSet
object is used here to
provide a way to request and store several attributes.
Querying two attributes using the CManager
API
would look like the following:
// Prepare the attributes to query using the CAttributeSet object
RAttributeSet attributeSet;
CleanupClosePushL(attributeSet);
attributeSet.AddL(EProtected);
attributeSet.AddL(ECanView);
CManager *manager = new CManager();
// Retrieve the attribute values from the agent
User::LeaveIfError(manager->GetAttributeSet(attributeSet,virtualPath);
// Check if the content object is protected
TInt attributeValue;
TInt err = attributeSet.GetValue(EProtected, attributeValue);
if(err == KErrNone && attributeValue)
{
// content object is DRM protected
}
// Check if the content object can be display on screen
TInt err = attributeSet.GetValue(ECanView, attributeValue);
if(err == KErrNone && attributeValue)
{
// content object has rights that allow it to be displayed on screen
}
String attributes are similar to the attributes described above except the value associated with the attribute is a string. A good example of where a string attribute is required is the MIME type of a content object within a file.
The string attributes are standardised by the
ContentAccess::TStringAttribute
enumeration. This allows
applications to request information such as the MIME type in a generic way for
all agents.
Agents can extend this mechanism to provide agent specific attributes
starting at EAgentSpecificStringAttributeBase
.
The following example finds the author of a content object.
// define a buffer to store the attribute value string
TBuf <100> buf;
// retrieve the attribute
err = content->GetAttribute(EAuthor, buf, uniqueId);
// Display the author's name on screen
DisplayAuthor(buf);
If the Agent does not support this attribute, it will return
KErrCANotSupported
.
For some agent implementations, it may be more efficient to retrieve
several string attributes for a content object in one function call. The
ContentAccess::RStringAttributeSet
object is used here to
provide a way to request and store several attributes.
Querying three attributes using the CManager
API
would look like the following:
// Prepare the attributes to query using the CAttributeSet object
RStringAttributeSet stringAttributeSet;
CleanupClosePushL(stringAttributeSet);
stringAttributeSet.AddL(ETitle);
stringAttributeSet.AddL(EAuthor);
stringAttributeSet.AddL(EDescription);
CManager *manager = new CManager();
// Retrieve the attribute values from the agent
User::LeaveIfError(manager->GetStringAttributeSet(stringAttributeSet,virtualPath));
// Display the values
TBuf <256> value;
TInt err = stringAttributeSet.GetValue(ETitle, value);
if(err == KErrNone)
{
Printf("Title : %s", value);
}
err = stringAttributeSet.GetValue(EAuthor, value);
if(err == KErrNone)
{
Printf("Author : %s", value);
}
err = stringAttributeSet.GetValue(EDescription, value);
if(err == KErrNone)
{
Printf("Description : %s", value);
}
Some agents may expose meta data so they can be read using a
CData
object. The format of these meta-data objects is not
specified by the Content Access Framework but could be useful for applications
familiar with the agent to read meta data this way.
CData
objects for agent specific meta-data can be opened
in the same way content objects are opened, using the
ContentAccess::CContent::OpenContentL()
function.
// Create an array to store the embedded objects
RStreamablePtrArray<CEmbeddedObject> myArray;
CleanupClosePushL(myArray);
// Get the embedded "Agent Specific" objects in the current container
content->GetEmbeddedObjectsL(myArray, EAgentSpecificObject);
// Get the unique Id of the first meta-data object
TPtrC uniqueId = myArray[0]->UniqueId();
// create a CData object to read the meta data
CData *myMetaData = content->OpenContent(EPeek, uniqueId);