Extended data (xdata) is created by applications written with ObjectARX ® or AutoLISP ® and can be added to any object. Xdata consists of a linked list of resbufs used by the application. (AutoCAD maintains the information but doesn't use it.) The data is associated with a DXF group code in the range of 1000 to 1071.
This mechanism is space-efficient and can be useful for adding lightweight data to an object. However, xdata is limited to 16K and to the existing set of DXF group codes and types.
For a more detailed description of xdata, see the AutoCAD DXF Reference.
Use the AcDbObject::xData() function to obtain the resbuf chain containing a copy of the xdata for an object:
virtual resbuf* AcDbObject::xData(const char* regappName = NULL) const;
Use the AcDbObject::setXData() function to specify the xdata for an object:
virtual Acad::ErrorStatus AcDbObject::setXData(const resbuf* xdata);
The following example uses the xData() function to obtain the xdata for a selected object and then prints the xdata to the screen. It then adds a string (testrun) to the xdata and calls the setXdata() function to modify the object's xdata. This example also illustrates the use of the upgradeOpen() and downgradeOpen() functions.
// This function calls the selectObject() function to allow
// the user to pick an object; then it accesses the xdata of
// the object and sends the list to the printList() function
// that lists the restype and resval values.
//
void
printXdata()
{
// Select and open an object.
//
AcDbObject *pObj;
if ((pObj = selectObject(AcDb::kForRead)) == NULL) {
return;
}
// Get the application name for the xdata.
//
char appname[133];
if (acedGetString(NULL,
"\nEnter the desired Xdata application name: ",
appname) != RTNORM)
{
return;
}
// Get the xdata for the application name.
//
struct resbuf *pRb;
pRb = pObj->xData(appname);
if (pRb != NULL) {
// Print the existing xdata if any is present.
// Notice that there is no -3 group, as there is in
// LISP. This is ONLY the xdata, so
// the -3 xdata-start marker isn't needed.
//
printList(pRb);
acutRelRb(pRb);
} else {
acutPrintf("\nNo xdata for this appname");
}
pObj->close();
}
void
addXdata()
{
AcDbObject* pObj = selectObject(AcDb::kForRead);
if (!pObj) {
acutPrintf("Error selecting object\n");
return;
}
// Get the application name and string to be added to
// xdata.
//
char appName[132], resString[200];
appName[0] = resString[0] = '\0';
acedGetString(NULL, "Enter application name: ",
appName);
acedGetString(NULL, "Enter string to be added: ",
resString);
struct resbuf *pRb, *pTemp;
pRb = pObj->xData(appName);
if (pRb != NULL) {
// If xdata is present, then walk to the
// end of the list.
//
for (pTemp = pRb; pTemp->rbnext != NULL;
pTemp = pTemp->rbnext)
{ ; }
} else {
// If xdata is not present, register the application
// and add appName to the first resbuf in the list.
// Notice that there is no -3 group as there is in
// AutoLISP. This is ONLY the xdata so
// the -3 xdata-start marker isn't needed.
//
acdbRegApp(appName);
pRb = acutNewRb(AcDb::kDxfRegAppName);
pTemp = pRb;
pTemp->resval.rstring
= (char*) malloc(strlen(appName) + 1);
strcpy(pTemp->resval.rstring, appName);
}
// Add user-specified string to the xdata.
//
pTemp->rbnext = acutNewRb(AcDb::kDxfXdAsciiString);
pTemp = pTemp->rbnext;
pTemp->resval.rstring
= (char*) malloc(strlen(resString) + 1);
strcpy(pTemp->resval.rstring, resString);
// The following code shows the use of upgradeOpen()
// to change the entity from read to write.
//
pObj->upgradeOpen();
pObj->setXData(pRb);
pObj->close();
acutRelRb(pRb);
}