I wrote this as a C++/CLI exercise in automagically disposing of managed class fields,
but it might also serve as an example of how to read a file into a Resultbuffer that can later be stored in an Xrecord.
//++-- Chunker.h
#pragma once
#include "Space.h"
namespace AcMethod
{
public ref class Chunker
{
FileStream fs;
BinaryReader br;
public:
Chunker(String^ path);
~Chunker(void);
void Close();
ResultBuffer ^ChunkIt();
};
}
#include "StdAfx.h"
#include "Chunker.h"
namespace AcMethod
{
Chunker::Chunker(String^ path): fs(path, FileMode::Open),br(%fs)
{
}
Chunker::~Chunker()
{
Close();
}
void Chunker::Close()
{
br.Close();
fs.Close();
}
ResultBuffer^ Chunker::ChunkIt()
{
ResultBuffer^ pRb = gcnew ResultBuffer();
while (br.BaseStream->Position < br.BaseStream->Length)
{
if ((br.BaseStream->Length - br.BaseStream->Position) > 127)
pRb->Add(gcnew TypedValue((short)DxfCode::BinaryChunk, br.ReadBytes(127)));
else
pRb->Add(gcnew TypedValue((short)DxfCode::BinaryChunk,
br.ReadBytes(Convert::ToInt32(br.BaseStream->Length - br.BaseStream->Position))));
}
return pRb;
}
}
//++-- DeChunker.h
#pragma once
#include "Space.h"
namespace AcMethod
{
public ref class DeChunker
{
FileStream fs;
BinaryWriter br;
public:
DeChunker(String^ path);
~DeChunker(void);
void Close();
void DeChunkIt(ResultBuffer^ pRb);
};
}
#include "StdAfx.h"
#include "DeChunker.h"
namespace AcMethod
{
DeChunker::DeChunker(String^ path): fs(path, FileMode::Create),br(%fs)
{
}
DeChunker::~DeChunker()
{
Close();
}
void DeChunker::Close()
{
br.Flush();
br.Close();
fs.Close();
}
void DeChunker::DeChunkIt(ResultBuffer^ pRb)
{
for each(TypedValue T in pRb)
{
br.Write((array<System::Byte>^)T.Value);
}
}
}
and my quick test
// AcMethod::h
#include "Space.h"
namespace AcMethod
{
public ref class Commands
{
internal:
public:
[CommandMethod("doit")]
static void doit();
[CommandMethod("undoit")]
static void undoit();
};
}
// This is the main DLL file.
#include "stdafx.h"
#include "AcMethod.h"
#include "Chunker.h"
#include "DeChunker.h"
[assembly: CommandClass(AcMethod::Commands::typeid)];
namespace AcMethod
{
void Commands::doit()
{
Editor ^pEditor = Application::DocumentManager->MdiActiveDocument->Editor;
Database ^pDatabase = HostApplicationServices::WorkingDatabase;
AcDb::TransactionManager ^pManager = pDatabase->TransactionManager;
try
{
Transaction ^pTransaction = pManager->StartTransaction();
try
{
Chunker chunker("C:\\golden_co.txt");
ResultBuffer ^pRb = chunker.ChunkIt();
LayoutManager ^m = LayoutManager::Current;
Layout ^pLayout = (Layout^)pTransaction->GetObject
(m->GetLayoutId("Model"),OpenMode::ForWrite);
Xrecord ^xrec = gcnew Xrecord();
xrec->Data = pRb;
if (pLayout->ExtensionDictionary.IsNull)
{
pLayout->CreateExtensionDictionary();
}
DBDictionary ^extDict=(DBDictionary^)pTransaction->GetObject(
pLayout->ExtensionDictionary,OpenMode::ForWrite,false);
extDict->SetAt("MyData",xrec);
pTransaction->AddNewlyCreatedDBObject(xrec,true);
pTransaction->Commit();
}
finally
{
delete pManager;
}
}
catch (System::Exception ^ex)
{
pEditor->WriteMessage("(\n{0}\n{1})",ex->Message,ex->StackTrace);
}
}
//++--
void Commands::undoit()
{
Editor ^pEditor = Application::DocumentManager->MdiActiveDocument->Editor;
Database ^pDatabase = HostApplicationServices::WorkingDatabase;
AcDb::TransactionManager ^pManager = pDatabase->TransactionManager;
try
{
Transaction ^pTransaction = pManager->StartTransaction();
try
{
DeChunker deChunker("C:\\golden_co1.txt");
LayoutManager ^m = LayoutManager::Current;
Layout ^pLayout = (Layout^)pTransaction->GetObject
(m->GetLayoutId("Model"),OpenMode::ForRead);
DBDictionary ^extDict = (DBDictionary^) pTransaction->GetObject
(pLayout->ExtensionDictionary, OpenMode::ForRead);
Xrecord ^pXrecord = (Xrecord^)pTransaction->GetObject
(extDict->GetAt("MyData"), OpenMode::ForRead);
deChunker.DeChunkIt(pXrecord->Data);
}
finally
{
delete pManager;
}
}
catch (System::Exception ^ex)
{
pEditor->WriteMessage("(\n{0}\n{1})",ex->Message,ex->StackTrace);
}
}
}