Re: Converting from Indy 9 to Indy 10

Giganews Newsgroups
Subject: Re: Converting from Indy 9 to Indy 10
Posted by:  Remy Lebeau \(Indy Team\) (no.spam@no.spam.com)
Date: Mon, 27 Aug 2007

"Malcolm Smith" <malco…@mjfreelancing.com> wrote in message
news:FF8C6F76E432E340malco…@mjfreelancing.com...

> Is the following code the best conversion that can be achieved.

If you are looking for a literal translation, then yes.  But if you are
looking for performance, then you would be better off not using TIdBytes
since that requires you to operate on a secondary copy of the data, as you
have already noticed.  One way to get around that is to derive a new class
from TCustomMemoryStream.  That way, you can have Indy access your memory
buffers directly.  For example:

    class TMyMemoryStream : public TCustomMemoryStream
    {
    public:
        __fastcall TMyMemoryStream(void *APtr, int ASize)
            : TCustomMemoryStream()
        {
            SetPointer(APtr, ASize);
        }
    };

    #include <memory>

    void __fastcall Nmjfindy::ReadBuffer(TIdTCPConnection *AConnection, void
*ADest, int ASize)
    {
        std::auto_ptr<TMyMemoryStream> strm(new TMyMemoryStream(ADest,
ASize));
        AConnection->IOHandler->ReadStream(strm.get(), ASize, false);
    }

    void __fastcall Nmjfindy::WriteBuffer(TIdTCPConnection *AConnection,
const Nmjfindy::TDynamicBuffer &ASource, int AByteCount)
    {
        int SourceSize = min(max(AByteCount, 0), ASource.size());
        Nmjfindy::WriteInt(AConnection, SourceSize);

        if( SourceSize > 0 )
        {
            std::auto_ptr<TMyMemoryStream> strm(new
TMyMemoryStream(&ASource[0], SourceSize));
            AConnection->IOHandler->Write(strm.get(), SourceSize, false);
        }
    }

If you want optimal performance uring reading, you could bypass Indy's
higher-level reading methods and access the InputBuffer directly instead:

    void __fastcall Nmjfindy::ReadBuffer(TIdTCPConnection *AConnection, void
*ADest, int ASize)
    {
        while( AConnection->IOHandler->InputBuffer->Size < ASize )
        {
            AConnection->IOHandler->ReadFromSource(false);
            AConnection->IOHandler->CheckForDisconnect(true, true);
        }
        std::auto_ptr<TMyMemoryStream> strm(new TMyMemoryStream(ADest,
ASize));
        AConnection->IOHandler->InputBuffer->ExtractToStream(strm.get(),
ASize);
    }

> I don't like having to create temporary objects all the time in each
> function as my code is time critical.

The above code still uses temp objects, but the overhead should be much
smaller then using TIdBytes and copying bytes around in memory.

Gambit

Replies

In response to

Converting from Indy 9 to Indy 10 posted by Malcolm Smith on Sat, 25 Aug 2007