Author Topic: Chunker / DeChunker  (Read 2219 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8829
  • AKA Daniel
Chunker / DeChunker
« on: December 20, 2008, 10:26:32 PM »
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.

Code: [Select]
//++-- 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();
  };
}

Code: [Select]
#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;
  }
}

Code: [Select]
//++-- 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);
  };
}

Code: [Select]
#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

Code: [Select]
// AcMethod::h

#include "Space.h"

namespace AcMethod
{
  public ref class Commands
  {
  internal:
   
  public:
    [CommandMethod("doit")]
     static void doit();
    [CommandMethod("undoit")]
     static void undoit();
  };
}

Code: [Select]
// 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);
    }
  }
}
« Last Edit: December 20, 2008, 10:32:11 PM by Daniel »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8829
  • AKA Daniel
Re: Chunker / DeChunker
« Reply #1 on: December 20, 2008, 10:34:49 PM »
In case anyone is interested, here is the reflected output of the Chunker class.
Note how the compiler added the dispose calls for the fields   FileStream fs; and BinaryReader br;


Code: [Select]
public class Chunker : IDisposable
{
    // Fields
    private readonly BinaryReader modreq(IsByValue) br;
    private readonly FileStream modreq(IsByValue) fs;

    // Methods
    public Chunker(string path)
    {
        FileStream modopt(IsConst) stream = new FileStream(path, FileMode.Open);
        try
        {
            this.fs = stream;
            BinaryReader modopt(IsConst) reader = new BinaryReader(this.fs);
            try
            {
                this.br = reader;
                base..ctor();
            }
            fault
            {
                this.br.Dispose();
            }
        }
        fault
        {
            this.fs.Dispose();
        }
    }

    private void ~Chunker()
    {
        this.Close();
    }

    public ResultBuffer ChunkIt()
    {
        ResultBuffer pRb = null;
        pRb = new ResultBuffer();
        while (this.br.BaseStream.Position < this.br.BaseStream.Length)
        {
            if ((this.br.BaseStream.Length - this.br.BaseStream.Position) > 0x7fL)
            {
                TypedValue value3 = new TypedValue();
                ValueType modopt(TypedValue) modopt(IsBoxed) type2 = value3;
                (TypedValue) type2 = new TypedValue(310, this.br.ReadBytes(0x7f));
                pRb.Add(type2);
            }
            else
            {
                TypedValue value2 = new TypedValue();
                ValueType modopt(TypedValue) modopt(IsBoxed) type = value2;
                (TypedValue) type = new TypedValue(310, this.br.ReadBytes
                       (Convert.ToInt32((long) (this.br.BaseStream.Length - this.br.BaseStream.Position))));
                pRb.Add(type);
            }
        }
        return pRb;
    }

    public void Close()
    {
        this.br.Close();
        this.fs.Close();
    }

    public sealed override void Dispose()
    {
        this.Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1)
    {
        if (flag1)
        {
            try
            {
                this.~Chunker();
            }
            finally
            {
                try
                {
                    this.br.Dispose();
                }
                finally
                {
                    try
                    {
                        this.fs.Dispose();
                    }
                    finally
                    {
                    }
                }
            }
        }
        else
        {
            base.Finalize();
        }
    }
}

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Chunker / DeChunker
« Reply #2 on: December 20, 2008, 11:52:18 PM »


protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1) >>>>>>>>>>

took me a bit to work through :)

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8829
  • AKA Daniel
Re: Chunker / DeChunker
« Reply #3 on: December 21, 2008, 12:34:49 AM »
Here is the book if anyone is interested in C++/CLI  http://books.google.com/books?id=wZoQyVi5f60C