AutoCAD has supported the eXtended Data for long time, back to the ADS era. In the AutoCAD .NET world, those functionalities regarding the XData manipulations and even those extended DXF codes are wrapped nicely into some classes, structs, methods and enums.
However, because of the different syntaxes in the new AutoCAD .NET and the old ADS, even for people coming from the ADS time and using those old ResultBuffer a lot, they may still be confused about some classes, methods, and enum values as far as XData and ResultBuffer are concerned.
In this post, let us see what limitation for the XData string length that AutoCAD and its API (the .NET API on behalf) impose on us. Let us put aside all figures from anywhere and make a small tiny experiment first. Here is the code and command.
[CommandMethod("StringXDataLimit")]
public static void StringXDataLimit_Method()
{
const string TestAppName = "StringXDataLimit_TestApp";
Database db = HostApplicationServices.WorkingDatabase;
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
try
{
PromptEntityResult prEntRes = ed.GetEntity("Select an Entity to do the test");
if (prEntRes.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
RegAppTable regAppTable = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead);
if (!regAppTable.Has(TestAppName))
{
using (RegAppTableRecord regAppRecord = new RegAppTableRecord())
{
regAppRecord.Name = TestAppName;
regAppTable.UpgradeOpen();
regAppTable.Add(regAppRecord);
tr.AddNewlyCreatedDBObject(regAppRecord, true);
}
}
string str = string.Empty;
for (int i = 0; i < int.MaxValue; i++)
{
try
{
using (Transaction subTr = db.TransactionManager.StartTransaction())
{
str += "A";
Entity ent = (Entity)subTr.GetObject(prEntRes.ObjectId, OpenMode.ForWrite);
ent.XData = new ResultBuffer
(
new TypedValue((int)DxfCode.ExtendedDataRegAppName, TestAppName),
new TypedValue((int)DxfCode.ExtendedDataAsciiString, str)
);
subTr.Commit();
}
}
catch (Autodesk.AutoCAD.Runtime.Exception ex)
{
if (ex.ErrorStatus == ErrorStatus.ExternalDataSizeExceeded)
{
ed.WriteMessage("\nThe maximum length of XData string is: {0}", i);
break;
}
}
}
tr.Commit(); //We commit the outter transaction here to try something else next such as the Audit command.
//tr.Abort(); //We'd better abort the transaction to avoid database mess up if the test is done in a DB in use.
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.ToString());
}
}
Here is the output in the AutoCAD command line window after it is run.
Command: StringXDataLimit
Select an Entity to do the test:
The maximum length of XData string is: 8188
So clearly, AutoCAD APIs (including the .NET one of course) allow us to write as many as 8188 ANSI characters to the string XData type indicated by the 1000 DXF code. Wait a moment, however, what will happen if we try to Audit the entity that has just been attached the XData. Here is what the AutoCAD Audit command would complaint about the entity having so long an XData string.
Command: audit
Fix any errors detected? [Yes/No] <N>:
Auditing Header
Auditing Tables
Auditing Entities Pass 1
Pass 1 200 objects auditedAcDbPolyline(A78) XData String Length 8188 >
255 Truncate to 255
AcDbPolyline(A78) was not repaired.
Auditing Entities Pass 2
Pass 2 200 objects auditedAcDbPolyline(A78) XData String Length 8188 >
255 Truncate to 255
AcDbPolyline(A78) was not repaired.
Auditing Blocks
9 Blocks audited
Total errors found 2 fixed 0
Erased 0 objects
What?! The permissible XData String Length has been dramatically reduced from the physical length (from the .NET API perspective) of 8188 to the theoretical (in the AutoCAD Audit sense) of 255.
Which one supersedes then?
It depends, really!
If there are a lot of other errors that need the power of the Audit to help fix, please forget about the attractive physical allowed length (8188) but bear in mind the insufficient theoretical one (255) in many cases, or there is such a need that the whole drawing exchanges data with other applications or AutoCAD versions through the DXF format and/or DXFOut/DXFIn commands. Otherwise, things should be just fine.
Some different figures such as more than double of the 8188 may have been mentioned here and there, but they apparently do not apply to the AutoCAD 2012 64bit that the experiment was tested upon. Therefore, once again, the 8188 can be thought as a practical number for the XData string length.
The code seems simple and straightforward, but there are still some tips and tricks there.
• The DBObject.GetXDataForApplication() method can retrieve the XData with the specified application name from a DBObject or Entity.
• All XData starts with the 1001 (DxfCode.ExtendedDataRegAppName) code.
• The XData Application Name can be registered through creating a RegAppTableRecord and adding it to the RegAppTable (another kind of AutoCAD symbol table).
• The ResultBuffer is a list of TypedValue which is a pair of type and value.
• The ResultBuffer is not database resident, so we can assign a single result buffer to multiple instances of DBObject (in turn Entity) or to the same object many times through the XData property.
• The ErrorStatus.ExternalDataSizeExceeded particularly tells us when exactly the XData string length really exceeds the maximum size from the very API perspective including .NET of course.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides project wizards in C#, VB.NET and CLI/Managed C++, and various item wizards such as Event Handlers, Command/LispFunction Definers, and Entity/Draw Jiggers in both C# and VB.NET, to help program AutoCAD addins.
Posted by: |